modules/common/drift/src/main/java/org/rhq/common/drift/ChangeSetReaderImpl.java
| 37
modules/common/drift/src/main/java/org/rhq/common/drift/ChangeSetWriter.java
| 28
modules/common/drift/src/main/java/org/rhq/common/drift/ChangeSetWriterImpl.java
| 23
modules/common/drift/src/main/java/org/rhq/common/drift/FileEntry.java
| 45 +
modules/common/drift/src/test/java/org/rhq/common/drift/ChangeSetReaderImplTest.java
| 43 -
modules/common/drift/src/test/java/org/rhq/common/drift/ChangeSetWriterImplTest.java
| 41 -
modules/core/dbutils/src/main/java/org/rhq/core/db/OracleDatabaseType.java
| 23
modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
| 5
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ChangeSetManager.java
| 8
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ChangeSetManagerImpl.java
| 47 -
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetectionSchedule.java
| 1
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
| 381 ++++++----
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
| 12
modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/ChangeSetManagerImplTest.java
| 4
modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java
| 284 ++++---
modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftFilesSenderTest.java
| 62 -
modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftTest.java
| 6
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/DriftManagerBeanTest.java
| 4
18 files changed, 681 insertions(+), 373 deletions(-)
New commits:
commit 260fbda7005ebd20b436c55eca4dd07f8c803d31
Merge: 6e70db5 638de1b
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Thu Dec 15 13:38:47 2011 -0500
Merge branch 'jsanda/drift'
Conflicts:
modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftFilesSenderTest.java
diff --cc
modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftFilesSenderTest.java
index d427229,b102300..c3aa13c
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftFilesSenderTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftFilesSenderTest.java
@@@ -19,29 -19,23 +19,30 @@@
package org.rhq.core.pc.drift;
- import org.rhq.common.drift.ChangeSetWriter;
- import org.rhq.common.drift.Headers;
- import org.rhq.core.domain.drift.DriftChangeSetCategory;
- import org.rhq.core.domain.drift.DriftFile;
- import org.rhq.core.domain.drift.JPADriftFile;
- import org.rhq.core.util.ZipUtil;
- import org.rhq.test.AssertUtils;
- import org.testng.annotations.BeforeMethod;
- import org.testng.annotations.Test;
+ import static org.rhq.common.drift.FileEntry.addedFileEntry;
+ import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE;
+ import static org.testng.Assert.assertEquals;
+ import static org.testng.Assert.assertTrue;
import java.io.File;
+import java.io.FilenameFilter;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedList;
import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
- import static org.rhq.common.drift.FileEntry.addedFileEntry;
- import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE;
- import static org.testng.Assert.assertEquals;
- import static org.testng.Assert.assertTrue;
+ import org.testng.annotations.BeforeMethod;
+ import org.testng.annotations.Test;
+
+ import org.rhq.common.drift.ChangeSetWriter;
+ import org.rhq.common.drift.Headers;
+ import org.rhq.core.domain.drift.DriftChangeSetCategory;
+ import org.rhq.core.domain.drift.DriftFile;
+ import org.rhq.core.domain.drift.JPADriftFile;
++import org.rhq.core.util.ZipUtil;
++import org.rhq.test.AssertUtils;
public class DriftFilesSenderTest extends DriftTest {
@@@ -96,8 -69,10 +97,10 @@@
Headers headers = createHeaders(driftDefName, COVERAGE);
ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(resourceId(),
headers);
- writer.write(addedFileEntry("conf/server-1.conf", server1ConfHash));
- writer.write(addedFileEntry("conf/server-2.conf", server2ConfHash));
- writer.write(addedFileEntry("conf/server-1.conf", server1ConfHash,
server1Conf.lastModified(),
- server1Conf.length()));
- writer.write(addedFileEntry("conf/server-2.conf", server2ConfHash,
server2Conf.lastModified(),
- server2Conf.length()));
++ writer.write(addedFileEntry("conf/server-1.conf", server1ConfHash,
server1Conf.lastModified(), server1Conf
++ .length()));
++ writer.write(addedFileEntry("conf/server-2.conf", server2ConfHash,
server2Conf.lastModified(), server2Conf
++ .length()));
writer.close();
sender.setDriftFiles(driftFiles(server1ConfHash, server2ConfHash));
@@@ -129,10 -107,14 +132,14 @@@
Headers headers = createHeaders(driftDefName, COVERAGE);
ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(resourceId(),
headers);
- writer.write(addedFileEntry("conf/server-1.conf", server1ConfHash));
- writer.write(addedFileEntry("conf/server-2.conf", server2ConfHash));
- writer.write(addedFileEntry("lib/server-1.jar", server1JarHash));
- writer.write(addedFileEntry("lib/server-2.jar", server2JarHash));
- writer.write(addedFileEntry("conf/server-1.conf", server1ConfHash,
server1Conf.lastModified(),
- server1Conf.length()));
- writer.write(addedFileEntry("conf/server-2.conf", server2ConfHash,
server2Conf.lastModified(),
- server2Conf.length()));
- writer.write(addedFileEntry("lib/server-1.jar", server1JarHash,
server1Jar.lastModified(),
- server1Jar.length()));
- writer.write(addedFileEntry("lib/server-2.jar", server2JarHash,
server2Jar.lastModified(),
- server2Jar.length()));
++ writer.write(addedFileEntry("conf/server-1.conf", server1ConfHash,
server1Conf.lastModified(), server1Conf
++ .length()));
++ writer.write(addedFileEntry("conf/server-2.conf", server2ConfHash,
server2Conf.lastModified(), server2Conf
++ .length()));
++ writer
++ .write(addedFileEntry("lib/server-1.jar", server1JarHash,
server1Jar.lastModified(), server1Jar.length()));
++ writer
++ .write(addedFileEntry("lib/server-2.jar", server2JarHash,
server2Jar.lastModified(), server2Jar.length()));
writer.close();
// Note that the order of the drift files is random. When the server sends a
request
@@@ -161,77 -148,25 +168,78 @@@
Headers headers = createHeaders(driftDefName, COVERAGE);
ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(resourceId(),
headers);
- writer.write(addedFileEntry("conf/server-1.conf", server1ConfHash));
- writer.write(addedFileEntry("conf/server-2.conf", server2ConfHash));
- writer.write(addedFileEntry("conf/server-1.conf", server1ConfHash,
server1Conf.lastModified(),
- server1Conf.length()));
- writer.write(addedFileEntry("conf/server-2.conf", server2ConfHash,
server2Conf.lastModified(),
- server2Conf.length()));
++ writer.write(addedFileEntry("conf/server-1.conf", server1ConfHash,
server1Conf.lastModified(), server1Conf
++ .length()));
++ writer.write(addedFileEntry("conf/server-2.conf", server2ConfHash,
server2Conf.lastModified(), server2Conf
++ .length()));
writer.close();
// It is possible that the server can request a file that has been deleted since
it
// it was initially detected during drift detection.
server1Conf.delete();
--
sender.setDriftFiles(driftFiles(server1ConfHash, server2ConfHash));
sender.setHeaders(headers);
sender.run();
- File contentDir = mkdir(changeSetDir, "content");
+ assertContentFileExists(changeSetDir);
+ assertContentFileMatches(changeSetDir, server2ConfHash);
+ }
+
+ @Test
- public void doNotSendEmptyZipFileToServer() throws Exception {
++ public void doNotSendEmptyZipFileToServer() throws Exception {
+ String driftDefName = "empty_content_test";
+
+ File confDir = mkdir(resourceDir, "conf");
+ File serverConf = createRandomFile(confDir, "server.conf");
+
+ String serverConfHash = sha256(serverConf);
+
+ Headers headers = createHeaders(driftDefName, COVERAGE);
+
+ ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(resourceId(),
headers);
+ writer.write(addedFileEntry("conf/server.conf", serverConfHash));
+ writer.close();
+
+ serverConf.delete();
+
+ sender.setDriftFiles(driftFiles(serverConfHash));
+ sender.setHeaders(headers);
+ sender.run();
+
+ assertEquals(driftClient.getSendChangeSetContentInvocationCount(), 0,
- "Do not call DriftClient to send content to server when there is no
content to send.");
++ "Do not call DriftClient to send content to server when there is no
content to send.");
+ assertContentFileExists(changeSetDir(driftDefName));
+ }
+
+ void assertContentFileExists(File changeSetDir) {
+ File[] files = getContentFiles(changeSetDir);
+ assertEquals(files.length, 1, "Expected to find a single content zip file
but found " + Arrays.toString(files));
+ }
+
+ void assertContentFileMatches(File changeSetDir, String... expectedFileNames) throws
Exception {
+ File contentFile = getContentFiles(changeSetDir)[0];
+ final List<String> actualFileNames = new LinkedList<String>();
+
+ ZipUtil.walkZipFile(contentFile, new ZipUtil.ZipEntryVisitor() {
+ @Override
+ public boolean visit(ZipEntry entry, ZipInputStream stream) throws Exception
{
+ actualFileNames.add(entry.getName());
+ return true;
+ }
+ });
+
+ AssertUtils.assertCollectionEqualsNoOrder(Arrays.asList(expectedFileNames),
actualFileNames,
- "The content file " + contentFile.getPath() + " does not
contain the correct entries");
++ "The content file " + contentFile.getPath() + " does not
contain the correct entries");
+ }
- assertEquals(contentDir.list().length, 1, "Expected to find one file in
" + contentDir.getAbsolutePath());
- assertFileCopiedToContentDir(contentDir, server2ConfHash);
+ private File[] getContentFiles(File changeSetDir) {
+ return changeSetDir.listFiles(new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.startsWith("content_") &&
name.endsWith(".zip");
+ }
+ });
}
/**
@@@ -245,8 -180,8 +253,8 @@@
*/
void assertFileCopiedToContentDir(File contentDir, String fileHash) {
File file = new File(contentDir, fileHash);
-- assertTrue(file.exists(), "Expected to find file named " +
file.getName() + " in content directory " +
-- contentDir.getPath() + ". The SHA-256 hash should be used as the file
name.");
++ assertTrue(file.exists(), "Expected to find file named " +
file.getName() + " in content directory "
++ + contentDir.getPath() + ". The SHA-256 hash should be used as the file
name.");
}
Headers createHeaders(String configName, DriftChangeSetCategory type) {
commit 638de1b71e5eb15b137ca2deda01299a30f5482c
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Thu Dec 15 13:18:32 2011 -0500
[Bug 768031 - Pin template failure on upgraded dbs]
Set RHQ_DRIFT_CHANGE_SET.DRIFT_DEFINITION_ID nullable in the db upgrade.
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 9e3bbd6..24c536d 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -3826,7 +3826,10 @@
<schemaSpec version="2.117">
<!-- Remove an obsolete drift table that may be hanging around -->
- <schema-dropTable table="RHQ_DRIFT_TEMPLATE_MAP" />
+ <schema-dropTable table="RHQ_DRIFT_TEMPLATE_MAP" />
+
+ <!-- Remove an unwanted null consraint -->
+ <schema-alterColumn table="RHQ_DRIFT_CHANGE_SET"
column="DRIFT_DEFINITION_ID" nullable="TRUE" />
</schemaSpec>
</dbupgrade>
commit 4da6f3724d6492ae449ea76100aac8d9948f6303
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Thu Dec 15 13:16:59 2011 -0500
Supporting check-in for [Bug 768031 - Pin template failure on upgraded dbs]
- Fix a long standing issue in dbupgrade due to Oracle throwing exceptions
when trying to set nullable to the current value. In other words, the
upgrade would fail on oracle if you tried to set nullable false on a
column that was already nullable false. (same for nullable true). This
caused issues when you can't guarantee the current state, you just know
what you need it to be. Now, catch the relevant exceptions and toss
them as needed.
diff --git a/modules/core/dbutils/src/main/java/org/rhq/core/db/OracleDatabaseType.java
b/modules/core/dbutils/src/main/java/org/rhq/core/db/OracleDatabaseType.java
index b4ea5e9..9dcbb89 100644
--- a/modules/core/dbutils/src/main/java/org/rhq/core/db/OracleDatabaseType.java
+++ b/modules/core/dbutils/src/main/java/org/rhq/core/db/OracleDatabaseType.java
@@ -25,6 +25,8 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
+import mazz.i18n.Logger;
+
/**
* Superclass of all versions of the Oracle database.
*
@@ -32,6 +34,8 @@ import java.util.List;
*
*/
public abstract class OracleDatabaseType extends DatabaseType {
+ private static final Logger LOG =
DbUtilsI18NFactory.getLogger(OracleDatabaseType.class);
+
/**
* The vendor name for all Oracle databases.
*/
@@ -150,7 +154,24 @@ public abstract class OracleDatabaseType extends DatabaseType {
sql += ")";
- executeSql(conn, sql);
+ try {
+ executeSql(conn, sql);
+ } catch (SQLException e) {
+ // Oracle throws an exception if you try to set nullable to its current
setting. Ignore errors
+ // generated when a nullable setting is already the way we want it to be.
+ // ORA-01442: column to be modified to NOT NULL is already NOT NULL
+ // ORA-01451: column to be modified to NULL cannot be modified to NULL
+ if (nullable != null) {
+ String msg = e.getMessage();
+ if (msg.contains("ORA-01442") ||
msg.contains("ORA-01451")) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Ignoring exception, column already set to
nullable=" + nullable, e);
+ }
+ } else {
+ throw e;
+ }
+ }
+ }
if ((reindex != null) && reindex.booleanValue()) {
reindexTable(conn, table);
commit e60b0694356357d6c73b04128606afe6d75e3041
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Dec 14 16:00:07 2011 -0500
[Bug 756100 - RFE: use timestamp and file size during drift detection scans]
Worked in review feedback.
- consolidated removed and cantRead entry logic
- fixed up some comments
- clear collections after they are used to possibly help out gc
Decided to still keep around the "bucket" collections and assemble the
snapshot and delta entry lists using the buckets. It just seemed more
clear to me.
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
index 869e376..76d7afb 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
@@ -16,7 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
package org.rhq.core.pc.drift;
import static org.rhq.common.drift.FileEntry.addedFileEntry;
@@ -30,6 +29,7 @@ import static org.rhq.core.util.file.FileUtil.forEachFile;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
@@ -49,6 +49,11 @@ import org.rhq.core.domain.drift.Filter;
import org.rhq.core.util.MessageDigestGenerator;
import org.rhq.core.util.file.FileVisitor;
+/**
+ * Mechanism to detect and report Drift for active Drift Definitions.
+ *
+ * @author John Sanda
+ */
public class DriftDetector implements Runnable {
private Log log = LogFactory.getLog(DriftDetector.class);
@@ -220,119 +225,142 @@ public class DriftDetector implements Runnable {
}
final List<FileEntry> unchangedEntries = new
LinkedList<FileEntry>();
- final List<FileEntry> removedEntries = new LinkedList<FileEntry>();
- final List<FileEntry> cantReadEntries = new LinkedList<FileEntry>();
final List<FileEntry> changedEntries = new LinkedList<FileEntry>();
+ final List<FileEntry> removedEntries = new LinkedList<FileEntry>();
+ final List<FileEntry> addedEntries = new LinkedList<FileEntry>();
+ // for pinned snapshots, keep track of the original FileEntry objects for changed
entries. These
+ // are used if we re-write the pinned snapshot file.
final List<FileEntry> changedPinnedEntries = isPinned ? new
LinkedList<FileEntry>() : null;
- ChangeSetReader snapshotReader = null;
- int newVersion;
- boolean updateSnapshot = false;
try {
- snapshotReader = changeSetMgr.getChangeSetReader(snapshotFile);
-
- if (!basedir.exists()) {
- log.warn("The base directory [" + basedir.getAbsolutePath() +
"] for " + schedule + " does not exist.");
- }
+ ChangeSetReader snapshotReader = null;
+ int newVersion;
+ boolean updateSnapshot = false;
+ try {
+ snapshotReader = changeSetMgr.getChangeSetReader(snapshotFile);
- if (isPinned) {
- // If pinned we compare against the pinned snapshot but we need to know
the current snapshot version,
- // get it from the current full snapshot.
- ChangeSetReader currentFullSnapshotReader = null;
- try {
- currentFullSnapshotReader =
changeSetMgr.getChangeSetReader(currentFullSnapshot);
- newVersion = currentFullSnapshotReader.getHeaders().getVersion() +
1;
- } finally {
- currentFullSnapshotReader.close();
+ if (!basedir.exists()) {
+ log.warn("The base directory [" + basedir.getAbsolutePath()
+ "] for " + schedule
+ + " does not exist.");
}
- } else {
- newVersion = snapshotReader.getHeaders().getVersion() + 1;
- }
-
- // First look for files that have either been modified or deleted
- updateSnapshot = scanSnapshotFiles(schedule, basedir, snapshotReader,
newFiles, unchangedEntries,
- removedEntries, cantReadEntries, changedEntries, changedPinnedEntries);
- } finally {
- snapshotReader.close();
- }
+ if (isPinned) {
+ // If pinned we compare against the pinned snapshot but we need to
know the current snapshot version,
+ // get it from the current full snapshot.
+ ChangeSetReader currentFullSnapshotReader = null;
+ try {
+ currentFullSnapshotReader =
changeSetMgr.getChangeSetReader(currentFullSnapshot);
+ newVersion = currentFullSnapshotReader.getHeaders().getVersion()
+ 1;
+ } finally {
+ currentFullSnapshotReader.close();
+ }
+ } else {
+ newVersion = snapshotReader.getHeaders().getVersion() + 1;
+ }
- // if necessary, re-write the pinned snapshot file because we've updated
timestamp/filesize info, which
- // on subsequent detection runs will help us avoid SHA generation. It must
maintain the same entries.
- if (isPinned && updateSnapshot) {
- changedPinnedEntries.addAll(unchangedEntries);
+ // First look for files that have either been changed or removed
+ updateSnapshot = scanSnapshot(schedule, basedir, snapshotReader,
newFiles, unchangedEntries,
+ changedEntries, removedEntries, changedPinnedEntries);
- backupAndDeleteCurrentSnapshot(snapshotFile);
- updatePinnedSnapshot(schedule, snapshotFile, changedPinnedEntries);
- }
+ } finally {
+ snapshotReader.close();
+ }
- final List<FileEntry> snapshotEntries = new
LinkedList<FileEntry>(unchangedEntries);
- snapshotEntries.addAll(changedEntries);
+ // if necessary, re-write the pinned snapshot file because we've updated
timestamp/filesize info, which
+ // on subsequent detection runs will help us avoid SHA generation. It must
maintain the same entries.
+ if (isPinned && updateSnapshot) {
+ changedPinnedEntries.addAll(unchangedEntries);
- final List<FileEntry> deltaEntries = new
LinkedList<FileEntry>(changedEntries);
- deltaEntries.addAll(removedEntries);
- deltaEntries.addAll(cantReadEntries);
+ backupAndDeleteCurrentSnapshot(snapshotFile);
+ updatePinnedSnapshot(schedule, snapshotFile, changedPinnedEntries);
+ }
- for (File file : newFiles) {
- try {
- if (log.isInfoEnabled()) {
- log.info("Detected added file for " + schedule + "
--> " + file.getAbsolutePath());
- }
+ // add new files to the snapshotEntries and deltaEntries
+ for (File file : newFiles) {
+ try {
+ if (log.isInfoEnabled()) {
+ log.info("Detected added file for " + schedule + "
--> " + file.getAbsolutePath());
+ }
- FileEntry newEntry = addedFileEntry(relativePath(basedir, file),
sha256(file), file.lastModified(),
- file.length());
+ FileEntry newEntry = addedFileEntry(relativePath(basedir, file),
sha256(file), file.lastModified(),
+ file.length());
- deltaEntries.add(newEntry);
- snapshotEntries.add(newEntry);
+ addedEntries.add(newEntry);
- } catch (IOException e) {
- log.error("An error occurred while generating a drift change set for
" + schedule + ": "
- + e.getMessage());
- throw new DriftDetectionException("An error occurred while
generating a drift change set", e);
+ } catch (IOException e) {
+ log.error("An error occurred while generating a drift change set
for " + schedule + ": "
+ + e.getMessage());
+ throw new DriftDetectionException("An error occurred while
generating a drift change set", e);
+ }
}
- }
-
- if (deltaEntries.isEmpty()) {
- File newSnapshot = currentFullSnapshot;
- if (!isPinned) {
- // If unpinned and there is no detected drift then we generally don't
need to add/update any files.
- // But, if we have timestamp/filesize updates then we want to replace the
current snapshot with
- // the updated entries, so we can avoid SHA generation on subsequent
runs.
- if (updateSnapshot) {
- currentFullSnapshot.delete();
- newSnapshot = updateCurrentSnapshot(schedule, snapshotEntries,
newVersion - 1);
+ // The new snapshot contains all changed, unchanged and added files. Not
removed files.
+ final List<FileEntry> snapshotEntries = new
LinkedList<FileEntry>(unchangedEntries);
+ snapshotEntries.addAll(changedEntries);
+ snapshotEntries.addAll(addedEntries);
+
+ // The snapshot delta contains all changed, added and removed files.
+ final List<FileEntry> deltaEntries = new
LinkedList<FileEntry>(changedEntries);
+ deltaEntries.addAll(removedEntries);
+ deltaEntries.addAll(addedEntries);
+
+ if (deltaEntries.isEmpty()) {
+ File newSnapshot = currentFullSnapshot;
+
+ if (!isPinned) {
+ // If unpinned and there is no detected drift then we generally
don't need to add/update any files.
+ // But, if we have timestamp/filesize updates then we want to replace
the current snapshot with
+ // the updated entries, so we can avoid SHA generation on subsequent
runs.
+ if (updateSnapshot) {
+ currentFullSnapshot.delete();
+ newSnapshot = updateCurrentSnapshot(schedule, snapshotEntries,
newVersion - 1);
+ }
+ } else {
+ // If pinned and returning to compliance (meaning no drift now but
the previous snapshot did have drift)
+ // then we need to reset the current snapshot to match the pinned
snapshot. Note though that we
+ // increment the snapshot version in order to let the server know
about the state change.
+ if (newVersion > 1
+ && !isPreviousChangeSetEmpty(schedule.getResourceId(),
schedule.getDriftDefinition())) {
+ currentFullSnapshot.delete();
+ newSnapshot = updateCurrentSnapshot(schedule, snapshotEntries,
newVersion);
+
+ updateDeltaSnapshot(summary, schedule, deltaEntries, newVersion,
currentFullSnapshot,
+ newSnapshot);
+ }
}
+
+ summary.setNewSnapshot(newSnapshot);
+
} else {
- // If pinned and returning to compliance (meaning no drift now but the
previous snapshot did have drift)
- // then we need to reset the current snapshot to match the pinned
snapshot. Note though that we
- // increment the snapshot version in order to let the server know about
the state change.
- if (newVersion > 1
- && !isPreviousChangeSetEmpty(schedule.getResourceId(),
schedule.getDriftDefinition())) {
- currentFullSnapshot.delete();
- newSnapshot = updateCurrentSnapshot(schedule, snapshotEntries,
newVersion);
-
- updateDeltaSnapshot(summary, schedule, deltaEntries, newVersion,
currentFullSnapshot, newSnapshot);
- }
- }
+ // if there is drift, but we're pinned and the drift is the same as
the previous detection, just
+ // mark it as a repeat to indicate that we're out of compliance but
not in any new way.
+ if (isPinned && newVersion > 1 &&
isSameAsPreviousChangeSet(deltaEntries, currentFullSnapshot)) {
+ summary.setVersion(newVersion - 1);
+ summary.setRepeat(true);
- summary.setNewSnapshot(newSnapshot);
+ return;
+ }
- } else {
- // if there is drift, but we're pinned and the drift is the same as the
previous detection, just
- // mark it as a repeat to indicate that we're out of compliance but not
in any new way.
- if (isPinned && newVersion > 1 &&
isSameAsPreviousChangeSet(deltaEntries, currentFullSnapshot)) {
- summary.setVersion(newVersion - 1);
- summary.setRepeat(true);
+ // otherwise, generate a new current snapshot, and a snapshot delta
reflecting the latest drift
+ File oldSnapshot = backupAndDeleteCurrentSnapshot(currentFullSnapshot);
+ File newSnapshot = updateCurrentSnapshot(schedule, snapshotEntries,
newVersion);
- return;
+ updateDeltaSnapshot(summary, schedule, deltaEntries, newVersion,
oldSnapshot, newSnapshot);
}
+ } finally {
+ // Help out the garbage collector by clearing all of our collections
+ safeClear(newFiles, unchangedEntries, changedEntries, changedPinnedEntries);
+ }
+ }
- // otherwise, generate a new current snapshot, and a snapshot delta
reflecting the latest drift
- File oldSnapshot = backupAndDeleteCurrentSnapshot(currentFullSnapshot);
- File newSnapshot = updateCurrentSnapshot(schedule, snapshotEntries,
newVersion);
-
- updateDeltaSnapshot(summary, schedule, deltaEntries, newVersion, oldSnapshot,
newSnapshot);
+ static private void safeClear(Collection<?>... collections) {
+ if (null == collections) {
+ return;
+ }
+ for (Collection<?> c : collections) {
+ if (null != c) {
+ c.clear();
+ }
}
}
@@ -363,10 +391,9 @@ public class DriftDetector implements Runnable {
* snapshot should be re-written to disk even if there was no drift.
* @throws IOException
*/
- private boolean scanSnapshotFiles(DriftDetectionSchedule schedule, File basedir,
ChangeSetReader snapshotReader,
- Set<File> newFiles, List<FileEntry> unchangedEntries,
List<FileEntry> removedEntries,
- List<FileEntry> cantReadEntries, List<FileEntry> modifiedEntries,
List<FileEntry> changedPinnedEntries)
- throws IOException {
+ private boolean scanSnapshot(DriftDetectionSchedule schedule, File basedir,
ChangeSetReader snapshotReader,
+ Set<File> newFiles, List<FileEntry> unchangedEntries,
List<FileEntry> changedEntries,
+ List<FileEntry> removedEntries, List<FileEntry> changedPinnedEntries)
throws IOException {
boolean result = false;
@@ -374,10 +401,11 @@ public class DriftDetector implements Runnable {
File file = new File(basedir, entry.getFile());
newFiles.remove(file);
- if (!file.exists()) {
- // The file has been deleted since the last scan
+ if (!(file.exists() && file.canRead())) {
+ // The file has been deleted or is no longer readable, since the last
scan
if (log.isDebugEnabled()) {
- log.debug("Detected deleted file for " + schedule + "
--> " + file.getAbsolutePath());
+ log.debug("Detected " + (file.exists() ?
"unreadable" : "deleted") + " file for " + schedule
+ + " --> " + file.getAbsolutePath());
}
removedEntries.add(removedFileEntry(entry.getFile(),
entry.getNewSHA()));
@@ -387,37 +415,25 @@ public class DriftDetector implements Runnable {
continue;
- } else if (!file.canRead()) {
- if (log.isDebugEnabled()) {
- log.debug(file.getPath() + " is no longer readable. Treating it
as a deleted file.");
- }
- cantReadEntries.add(removedFileEntry(entry.getFile(),
entry.getNewSHA()));
-
- if (null != changedPinnedEntries) {
- changedPinnedEntries.add(entry);
- }
-
- continue;
-
} else {
String currentSHA = null;
- boolean isModified = false;
+ boolean isChanged = false;
// perform a SHA comparison if we are unable to compare size and
lastModified or if the
- // size or lastModified test fails. We may not have size of lastModified
values for the
+ // size or lastModified test fails. We may not have size or lastModified
values for the
// entry when the current snapshot was provided by the server, either due
to a synch or
// pinning scenario. The server does not store that information and will
provide -1 for defaults.
if (entry.getLastModified() == -1 || entry.getSize() == -1
|| entry.getLastModified() != file.lastModified() || entry.getSize()
!= file.length()) {
currentSHA = sha256(file);
- isModified = !entry.getNewSHA().equals(currentSHA);
+ isChanged = !entry.getNewSHA().equals(currentSHA);
}
- if (isModified) {
- FileEntry modifiedEntry = changedFileEntry(entry.getFile(),
entry.getNewSHA(), currentSHA, file
+ if (isChanged) {
+ FileEntry changedEntry = changedFileEntry(entry.getFile(),
entry.getNewSHA(), currentSHA, file
.lastModified(), file.length());
- modifiedEntries.add(modifiedEntry);
+ changedEntries.add(changedEntry);
if (null != changedPinnedEntries) {
changedPinnedEntries.add(entry);
commit b7ff74899be79a903a40483691e4916f313e3500
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Dec 14 15:59:24 2011 -0500
- Add some unit tests ensuring timestamp info is updated appropriately.
- remove a bunch of IDE warnings
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java
index b0b1143..0f2d30a 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java
@@ -19,12 +19,22 @@
package org.rhq.core.pc.drift;
-import org.rhq.common.drift.*;
-import org.rhq.core.domain.drift.DriftDefinition;
-import org.rhq.core.system.OperatingSystemType;
-import org.rhq.core.system.SystemInfoFactory;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
+import static org.apache.commons.io.FileUtils.copyFile;
+import static org.apache.commons.io.FileUtils.deleteDirectory;
+import static org.apache.commons.io.FileUtils.touch;
+import static org.rhq.common.drift.FileEntry.addedFileEntry;
+import static org.rhq.common.drift.FileEntry.changedFileEntry;
+import static org.rhq.common.drift.FileEntry.removedFileEntry;
+import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE;
+import static org.rhq.core.domain.drift.DriftChangeSetCategory.DRIFT;
+import static org.rhq.test.AssertUtils.assertCollectionMatchesNoOrder;
+import static org.rhq.test.AssertUtils.assertPropertiesMatch;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
import java.io.BufferedReader;
import java.io.File;
@@ -33,15 +43,18 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
-import static java.util.Arrays.asList;
-import static java.util.Collections.emptyList;
-import static org.apache.commons.io.FileUtils.*;
-import static org.rhq.common.drift.FileEntry.*;
-import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE;
-import static org.rhq.core.domain.drift.DriftChangeSetCategory.DRIFT;
-import static org.rhq.test.AssertUtils.assertCollectionMatchesNoOrder;
-import static org.rhq.test.AssertUtils.assertPropertiesMatch;
-import static org.testng.Assert.*;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import org.rhq.common.drift.ChangeSetReader;
+import org.rhq.common.drift.ChangeSetReaderImpl;
+import org.rhq.common.drift.ChangeSetWriter;
+import org.rhq.common.drift.ChangeSetWriterImpl;
+import org.rhq.common.drift.FileEntry;
+import org.rhq.common.drift.Headers;
+import org.rhq.core.domain.drift.DriftDefinition;
+import org.rhq.core.system.OperatingSystemType;
+import org.rhq.core.system.SystemInfoFactory;
public class DriftDetectorTest extends DriftTest {
@@ -66,7 +79,6 @@ public class DriftDetectorTest extends DriftTest {
detector.setScheduleQueue(scheduleQueue);
}
- @SuppressWarnings("unchecked")
@Test
public void excludeEmptyDirsFromCoverageChangeSet() throws Exception {
File confDir = mkdir(resourceDir, "conf");
@@ -74,6 +86,7 @@ public class DriftDetectorTest extends DriftTest {
// create an empty directory
File libDir = mkdir(resourceDir, "lib");
+ assert (libDir.isDirectory());
DriftDefinition driftDef = driftDefinition("coverage-test",
resourceDir.getAbsolutePath());
@@ -82,14 +95,13 @@ public class DriftDetectorTest extends DriftTest {
File changeSet = changeSet(driftDef.getName(), COVERAGE);
Headers headers = createHeaders(driftDef, COVERAGE);
- List<FileEntry> expected =
asList(addedFileEntry("conf/server.conf", sha256(serverConf),
- serverConf.lastModified(), serverConf.length()));
+ List<FileEntry> expected =
asList(addedFileEntry("conf/server.conf", sha256(serverConf), serverConf
+ .lastModified(), serverConf.length()));
assertHeaderEquals(changeSet, headers);
assertFileEntriesMatch("Only files should be included in a change
set.", expected, changeSet);
}
- @SuppressWarnings("unchecked")
@Test
public void includeMultipleFilesInDirInCoverageChangeSet() throws Exception {
File confDir = mkdir(resourceDir, "conf");
@@ -102,16 +114,15 @@ public class DriftDetectorTest extends DriftTest {
detector.run();
File changeSet = changeSet(def.getName(), COVERAGE);
- List<FileEntry> entries = asList(
- addedFileEntry("conf/server-1.conf", sha256(server1Conf),
server1Conf.lastModified(), server1Conf.length()),
- addedFileEntry("conf/server-2.conf", sha256(server2Conf),
server2Conf.lastModified(), server2Conf.length()));
+ List<FileEntry> entries =
asList(addedFileEntry("conf/server-1.conf", sha256(server1Conf), server1Conf
+ .lastModified(), server1Conf.length()),
addedFileEntry("conf/server-2.conf", sha256(server2Conf),
+ server2Conf.lastModified(), server2Conf.length()));
assertHeaderEquals(changeSet, createHeaders(def, COVERAGE));
assertFileEntriesMatch("Each file in a directory should be included in a
coverage change set", entries,
changeSet);
}
- @SuppressWarnings("unchecked")
@Test
public void includedSiblingDirsInCoverageChangeSet() throws Exception {
File confDir = mkdir(resourceDir, "conf");
@@ -126,16 +137,15 @@ public class DriftDetectorTest extends DriftTest {
detector.run();
File changeSet = changeSet(def.getName(), COVERAGE);
- List<FileEntry> entries = asList(
- addedFileEntry("conf/server.conf", sha256(serverConf),
serverConf.lastModified(), serverConf.length()),
- addedFileEntry("lib/server.jar", sha256(serverLib),
serverLib.lastModified(), serverLib.length()));
+ List<FileEntry> entries =
asList(addedFileEntry("conf/server.conf", sha256(serverConf), serverConf
+ .lastModified(), serverConf.length()),
addedFileEntry("lib/server.jar", sha256(serverLib), serverLib
+ .lastModified(), serverLib.length()));
assertHeaderEquals(changeSet, createHeaders(def, COVERAGE));
assertFileEntriesMatch("A coverage change set should include files from
multiple, sibling directories",
entries, changeSet);
}
- @SuppressWarnings("unchecked")
@Test
public void includeNestedDirsInCoverageChangeSet() throws Exception {
File confDir = mkdir(resourceDir, "conf");
@@ -150,9 +160,9 @@ public class DriftDetectorTest extends DriftTest {
detector.run();
File changeSet = changeSet(def.getName(), COVERAGE);
- List<FileEntry> entries = asList(
- addedFileEntry("conf/server-1.conf", sha256(server1Conf),
server1Conf.lastModified(), server1Conf.length()),
- addedFileEntry("conf/subconf/server-2.conf", sha256(server2Conf),
server2Conf.lastModified(), server2Conf.length()));
+ List<FileEntry> entries =
asList(addedFileEntry("conf/server-1.conf", sha256(server1Conf), server1Conf
+ .lastModified(), server1Conf.length()),
addedFileEntry("conf/subconf/server-2.conf", sha256(server2Conf),
+ server2Conf.lastModified(), server2Conf.length()));
assertHeaderEquals(changeSet, createHeaders(def, COVERAGE));
assertFileEntriesMatch("A coverage change set should include files in nested
sub directories", entries,
@@ -161,12 +171,13 @@ public class DriftDetectorTest extends DriftTest {
@Test
public void updateScheduleAfterGeneratingCoverageChangeSet() throws Exception {
- DriftDefinition driftDef =
driftDefinition("update-schedule-after-coverage-changeset",
- resourceDir.getAbsolutePath());
+ DriftDefinition driftDef =
driftDefinition("update-schedule-after-coverage-changeset", resourceDir
+ .getAbsolutePath());
DriftDetectionSchedule schedule = new DriftDetectionSchedule(resourceId(),
driftDef);
File confDir = mkdir(resourceDir, "conf");
File serverConf = createRandomFile(confDir, "server.conf");
+ assert (serverConf.exists());
long currentTime = System.currentTimeMillis();
@@ -174,8 +185,8 @@ public class DriftDetectorTest extends DriftTest {
detector.run();
assertTrue(schedule.getNextScan() >= (currentTime + driftDef.getInterval()),
- "Failed to update schedule. next scan is " +
schedule.getNextScan() + " and should be greater than " +
- (currentTime + driftDef.getInterval()));
+ "Failed to update schedule. next scan is " +
schedule.getNextScan() + " and should be greater than "
+ + (currentTime + driftDef.getInterval()));
}
@Test
@@ -183,11 +194,11 @@ public class DriftDetectorTest extends DriftTest {
}
- @SuppressWarnings("unchecked")
@Test
public void doNotUpdateSnapshotOrGenerateDriftChangeSetIfNothingChanges() throws
Exception {
File confDir = mkdir(resourceDir, "conf");
File serverConf = createRandomFile(confDir, "server.conf");
+ assert (serverConf.exists());
DriftDefinition def = driftDefinition("nothing-to-update",
resourceDir.getAbsolutePath());
@@ -217,7 +228,6 @@ public class DriftDetectorTest extends DriftTest {
+ "no drift");
}
- @SuppressWarnings("unchecked")
@Test
public void skipDetectionForScheduledThatIsDisabled() throws Exception {
detector.setDriftClient(new DriftClientTestStub() {
@@ -245,8 +255,8 @@ public class DriftDetectorTest extends DriftTest {
detector.run();
// make sure that the next scan time is not updated
- assertEquals(schedule.getNextScan(), nextScan, "The next scan time for the
drift detection schedule should " +
- " not get updated if drift detection does not actually run for the
definition.");
+ assertEquals(schedule.getNextScan(), nextScan, "The next scan time for the
drift detection schedule should "
+ + " not get updated if drift detection does not actually run for the
definition.");
}
@Test
@@ -255,7 +265,8 @@ public class DriftDetectorTest extends DriftTest {
DriftDetectionSchedule schedule = new DriftDetectionSchedule(resourceId(),
driftDef);
File confDir = mkdir(resourceDir, "conf");
- File server1Conf = new File(confDir, "server.conf");
+ File server1Conf = createRandomFile(confDir, "server.conf");
+ assert (server1Conf.exists());
scheduleQueue.addSchedule(schedule);
detector.run();
@@ -263,8 +274,8 @@ public class DriftDetectorTest extends DriftTest {
long nextScan = schedule.getNextScan();
detector.run();
- assertEquals(schedule.getNextScan(), nextScan, "The next scan time for the
drift detection schedule should " +
- " not get updated if drift detection does not actually run for the
definition.");
+ assertEquals(schedule.getNextScan(), nextScan, "The next scan time for the
drift detection schedule should "
+ + " not get updated if drift detection does not actually run for the
definition.");
}
@Test
@@ -277,18 +288,17 @@ public class DriftDetectorTest extends DriftTest {
scheduleQueue.addSchedule(new DriftDetectionSchedule(resourceId(), def));
detector.run();
- assertEquals(driftClient.getReportMissingBaseDirInvocationCount(), 1, "A
missing base directory should be " +
- "reported to the server if no initial snapshot has already been
generated.");
- assertEquals(driftClient.getSendChangeSetInvocationCount(), 0, "No initial
change set should be sent to " +
- "the server if the base directory does not exist.");
+ assertEquals(driftClient.getReportMissingBaseDirInvocationCount(), 1, "A
missing base directory should be "
+ + "reported to the server if no initial snapshot has already been
generated.");
+ assertEquals(driftClient.getSendChangeSetInvocationCount(), 0, "No initial
change set should be sent to "
+ + "the server if the base directory does not exist.");
// verify that the initial change set was not generated
File snapshot = changeSet(def.getName(), COVERAGE);
- assertFalse(snapshot.exists(), "An initial snapshot should not be written to
disk if the base directory " +
- "does not exist.");
+ assertFalse(snapshot.exists(), "An initial snapshot should not be written to
disk if the base directory "
+ + "does not exist.");
}
- @SuppressWarnings("unchecked")
@Test
public void skipDetectionWhenPreviousSnapshotFileExists() throws Exception {
// The presence of a previous snapshot file means that the server has
@@ -327,7 +337,6 @@ public class DriftDetectorTest extends DriftTest {
+ "drift detection should not have run until the server acked the
previous snapshot.");
}
- @SuppressWarnings("unchecked")
@Test
public void includeAddedFileInDriftChangeSet() throws Exception {
DriftDefinition def = driftDefinition("file-added-drift-test",
resourceDir.getAbsolutePath());
@@ -336,8 +345,8 @@ public class DriftDetectorTest extends DriftTest {
File server1Conf = createRandomFile(confDir, "server-1.conf");
ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(resourceId(),
createHeaders(def, COVERAGE));
- writer.write(addedFileEntry("conf/server-1.conf", sha256(server1Conf),
server1Conf.lastModified(),
- server1Conf.length()));
+ writer.write(addedFileEntry("conf/server-1.conf", sha256(server1Conf),
server1Conf.lastModified(), server1Conf
+ .length()));
writer.close();
// Create some drift
@@ -347,8 +356,8 @@ public class DriftDetectorTest extends DriftTest {
detector.run();
File driftChangeSet = changeSet(def.getName(), DRIFT);
- List<FileEntry> driftEntries =
asList(addedFileEntry("conf/server-2.conf", sha256(server2Conf),
- server2Conf.lastModified(), server2Conf.length()));
+ List<FileEntry> driftEntries =
asList(addedFileEntry("conf/server-2.conf", sha256(server2Conf), server2Conf
+ .lastModified(), server2Conf.length()));
// verify that the drift change set was generated
assertTrue(driftChangeSet.exists(), "Expected to find drift change set
" + driftChangeSet.getPath());
@@ -356,9 +365,9 @@ public class DriftDetectorTest extends DriftTest {
assertFileEntriesMatch("The drift change set does not match the expected
values", driftEntries, driftChangeSet);
File coverageChangeSet = changeSet(def.getName(), COVERAGE);
- List<FileEntry> coverageEntries = asList(
- addedFileEntry("conf/server-1.conf", sha256(server1Conf),
server1Conf.lastModified(), server1Conf.length()),
- addedFileEntry("conf/server-2.conf", sha256(server2Conf),
server2Conf.lastModified(), server2Conf.length()));
+ List<FileEntry> coverageEntries =
asList(addedFileEntry("conf/server-1.conf", sha256(server1Conf), server1Conf
+ .lastModified(), server1Conf.length()),
addedFileEntry("conf/server-2.conf", sha256(server2Conf),
+ server2Conf.lastModified(), server2Conf.length()));
// verify that the coverage change set was updated
assertHeaderEquals(coverageChangeSet, createHeaders(def, COVERAGE, 1));
@@ -366,7 +375,6 @@ public class DriftDetectorTest extends DriftTest {
coverageChangeSet);
}
- @SuppressWarnings("unchecked")
@Test
public void includeModifiedFileInDriftChangeSet() throws Exception {
DriftDefinition def = driftDefinition("file-modified-drift-test",
resourceDir.getAbsolutePath());
@@ -388,8 +396,8 @@ public class DriftDetectorTest extends DriftTest {
detector.run();
File driftChangeSet = changeSet(def.getName(), DRIFT);
- List<FileEntry> driftEntries =
asList(changedFileEntry("conf/server-1.conf", oldHash, newHash,
- server1Conf.lastModified(), server1Conf.length()));
+ List<FileEntry> driftEntries =
asList(changedFileEntry("conf/server-1.conf", oldHash, newHash, server1Conf
+ .lastModified(), server1Conf.length()));
// verify that the drift change set was generated
assertTrue(driftChangeSet.exists(), "Expected to find drift change set
" + driftChangeSet.getPath());
@@ -397,8 +405,8 @@ public class DriftDetectorTest extends DriftTest {
assertFileEntriesMatch("The drift change set does not match the expected
values", driftEntries, driftChangeSet);
File coverageChangeSet = changeSet(def.getName(), COVERAGE);
- List<FileEntry> coverageEntries =
asList(changedFileEntry("conf/server-1.conf", oldHash, newHash,
- server1Conf.lastModified(), server1Conf.length()));
+ List<FileEntry> coverageEntries =
asList(changedFileEntry("conf/server-1.conf", oldHash, newHash, server1Conf
+ .lastModified(), server1Conf.length()));
// verify that the coverage change set was updated
assertHeaderEquals(coverageChangeSet, createHeaders(def, COVERAGE, 1));
@@ -406,7 +414,6 @@ public class DriftDetectorTest extends DriftTest {
coverageChangeSet);
}
- @SuppressWarnings("unchecked")
@Test(enabled = false)
public void includeFiledAddedInNewDirectoryInDriftChangeSet() throws Exception {
DriftDefinition def = driftDefinition("file-added-in-new-dir",
resourceDir.getAbsolutePath());
@@ -415,8 +422,8 @@ public class DriftDetectorTest extends DriftTest {
File server1Conf = createRandomFile(confDir, "server-1.conf");
ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(resourceId(),
createHeaders(def, COVERAGE));
- writer.write(addedFileEntry("conf/server-1.conf", sha256(server1Conf),
server1Conf.lastModified(),
- server1Conf.length()));
+ writer.write(addedFileEntry("conf/server-1.conf", sha256(server1Conf),
server1Conf.lastModified(), server1Conf
+ .length()));
writer.close();
// create some drift
@@ -436,9 +443,9 @@ public class DriftDetectorTest extends DriftTest {
assertFileEntriesMatch("The drift change set does not match the expected
values", driftEntries, driftChangeSet);
File coverageChangeSet = changeSet(def.getName(), COVERAGE);
- List<FileEntry> coverageEntries = asList(
- addedFileEntry("conf/server-1.conf", sha256(server1Conf),
server1Conf.lastModified(), server1Conf.length()),
- addedFileEntry("conf/subconf/server-2.conf", sha256(server2Conf),
server2Conf.lastModified(), server2Conf.length()));
+ List<FileEntry> coverageEntries =
asList(addedFileEntry("conf/server-1.conf", sha256(server1Conf), server1Conf
+ .lastModified(), server1Conf.length()),
addedFileEntry("conf/subconf/server-2.conf", sha256(server2Conf),
+ server2Conf.lastModified(), server2Conf.length()));
// verify that the coverage change set was updated
assertHeaderEquals(coverageChangeSet, createHeaders(def, COVERAGE, 1));
@@ -446,7 +453,6 @@ public class DriftDetectorTest extends DriftTest {
coverageChangeSet);
}
- @SuppressWarnings("unchecked")
@Test
public void includeRemovedFileInDriftChangeSet() throws Exception {
DriftDefinition def = driftDefinition("file-removed-drift-test",
resourceDir.getAbsolutePath());
@@ -458,10 +464,10 @@ public class DriftDetectorTest extends DriftTest {
String server2ConfHash = sha256(server2Conf);
ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(resourceId(),
createHeaders(def, COVERAGE));
- writer.write(addedFileEntry("conf/server-1.conf", sha256(server1Conf),
server1Conf.lastModified(),
- server1Conf.length()));
- writer.write(addedFileEntry("conf/server-2.conf", server2ConfHash,
server2Conf.lastModified(),
- server2Conf.length()));
+ writer.write(addedFileEntry("conf/server-1.conf", sha256(server1Conf),
server1Conf.lastModified(), server1Conf
+ .length()));
+ writer.write(addedFileEntry("conf/server-2.conf", server2ConfHash,
server2Conf.lastModified(), server2Conf
+ .length()));
writer.close();
// create some drift
@@ -480,8 +486,8 @@ public class DriftDetectorTest extends DriftTest {
// verify that the coverage change set was updated
File coverageChangeSet = changeSet(def.getName(), COVERAGE);
- List<FileEntry> coverageEntries =
asList(addedFileEntry("conf/server-1.conf", sha256(server1Conf),
- server1Conf.lastModified(), server1Conf.length()));
+ List<FileEntry> coverageEntries =
asList(addedFileEntry("conf/server-1.conf", sha256(server1Conf), server1Conf
+ .lastModified(), server1Conf.length()));
assertHeaderEquals(coverageChangeSet, createHeaders(def, COVERAGE, 1));
assertFileEntriesMatch("The coverage change set was not updated as
expected", coverageEntries,
@@ -529,7 +535,6 @@ public class DriftDetectorTest extends DriftTest {
}
- @SuppressWarnings("unchecked")
@Test
public void includeFilesInRemovedDirectoryInDriftChangeSet() throws Exception {
DriftDefinition def = driftDefinition("dir-removed-test",
resourceDir.getAbsolutePath());
@@ -539,7 +544,8 @@ public class DriftDetectorTest extends DriftTest {
String server1Hash = sha256(server1Conf);
ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(resourceId(),
createHeaders(def, COVERAGE));
- writer.write(addedFileEntry("conf/server-1.conf", server1Hash,
server1Conf.lastModified(), server1Conf.length()));
+ writer
+ .write(addedFileEntry("conf/server-1.conf", server1Hash,
server1Conf.lastModified(), server1Conf.length()));
writer.close();
// create some drift
@@ -566,7 +572,6 @@ public class DriftDetectorTest extends DriftTest {
coverageChangeSet);
}
- @SuppressWarnings("unchecked")
@Test
public void revertToPreviousSnapshotWhenSendingChangeSetFails() throws Exception {
DriftDefinition def = driftDefinition("revert-snapshot-test",
resourceDir.getAbsolutePath());
@@ -574,6 +579,7 @@ public class DriftDetectorTest extends DriftTest {
File confDir = mkdir(resourceDir, "conf");
File server1Conf = createRandomFile(confDir, "server.conf");
+ assert (server1Conf.exists());
scheduleQueue.addSchedule(schedule);
// generate the initial snapshot
@@ -612,7 +618,6 @@ public class DriftDetectorTest extends DriftTest {
+ "should be deleted once we have reverted back to it and have a new,
current snapsot file.");
}
- @SuppressWarnings("unchecked")
@Test
public void purgeSnapshotWhenSendingInitialChangeSetFails() throws Exception {
// If we have just generated the initial change set and sending it to
@@ -650,8 +655,8 @@ public class DriftDetectorTest extends DriftTest {
detector.run();
File changeSet = changeSet(def.getName(), COVERAGE);
- List<FileEntry> entries =
asList(addedFileEntry("conf/server-1.conf", sha256(server1Conf),
- server1Conf.lastModified(), server1Conf.length()));
+ List<FileEntry> entries =
asList(addedFileEntry("conf/server-1.conf", sha256(server1Conf), server1Conf
+ .lastModified(), server1Conf.length()));
assertHeaderEquals(changeSet, createHeaders(def, COVERAGE));
assertFileEntriesMatch("Files that are non-readable should be skipped but
other, readable file should still "
@@ -760,14 +765,14 @@ public class DriftDetectorTest extends DriftTest {
String newPinnedHash = sha256(pinnedSnapshot);
- assertEquals(newPinnedHash, originalPinnedHash, "When a snapshot is pinned,
it should not get updated during " +
- "drift detection");
+ assertEquals(newPinnedHash, originalPinnedHash, "When a snapshot is pinned,
it should not get updated during "
+ + "drift detection");
// We always generate/update the current snapshot so we still need to verify that
it
// was generated/updated correctly
- List<FileEntry> fileEntries = asList(
- addedFileEntry("conf/server1.conf", sha256(server1Conf),
server1Conf.lastModified(), server1Conf.length()),
- addedFileEntry("conf/server2.conf", sha256(server2Conf),
server2Conf.lastModified(), server2Conf.length()));
+ List<FileEntry> fileEntries =
asList(addedFileEntry("conf/server1.conf", sha256(server1Conf), server1Conf
+ .lastModified(), server1Conf.length()),
addedFileEntry("conf/server2.conf", sha256(server2Conf),
+ server2Conf.lastModified(), server2Conf.length()));
assertHeaderEquals(currentSnapshot, createHeaders(driftDef, COVERAGE, 1));
assertFileEntriesMatch("The current snapshot file should still get updated
even when using a pinned snapshot",
@@ -801,10 +806,10 @@ public class DriftDetectorTest extends DriftTest {
detector.run();
// verify that the current snapshot was updated
- List<FileEntry> currentSnapshotEntries = asList(
- addedFileEntry("conf/server1.conf", sha256(server1Conf),
server1Conf.lastModified(), server1Conf.length()),
- addedFileEntry("conf/server2.conf", sha256(server2Conf),
server2Conf.lastModified(), server2Conf.length()),
- addedFileEntry("conf/server3.conf", sha256(server3Conf),
server3Conf.lastModified(), server3Conf.length()));
+ List<FileEntry> currentSnapshotEntries =
asList(addedFileEntry("conf/server1.conf", sha256(server1Conf),
+ server1Conf.lastModified(), server1Conf.length()),
addedFileEntry("conf/server2.conf", sha256(server2Conf),
+ server2Conf.lastModified(), server2Conf.length()),
addedFileEntry("conf/server3.conf", sha256(server3Conf),
+ server3Conf.lastModified(), server3Conf.length()));
assertHeaderEquals(currentSnapshot, createHeaders(driftDef, COVERAGE, 2));
assertFileEntriesMatch("The current snapshot file should still get updated
even when using a pinned snapshot",
@@ -812,9 +817,9 @@ public class DriftDetectorTest extends DriftTest {
// verify that the the drift/delta change set was generated
File driftChangeSet = changeSet(driftDef.getName(), DRIFT);
- List<FileEntry> driftEntries = asList(
- addedFileEntry("conf/server2.conf", sha256(server2Conf),
server2Conf.lastModified(), server2Conf.length()),
- addedFileEntry("conf/server3.conf", sha256(server3Conf),
server3Conf.lastModified(), server3Conf.length()));
+ List<FileEntry> driftEntries =
asList(addedFileEntry("conf/server2.conf", sha256(server2Conf), server2Conf
+ .lastModified(), server2Conf.length()),
addedFileEntry("conf/server3.conf", sha256(server3Conf),
+ server3Conf.lastModified(), server3Conf.length()));
assertHeaderEquals(driftChangeSet, createHeaders(driftDef, DRIFT, 2));
assertFileEntriesMatch("The drift change set was not generated correctly
when using a pinned snapshot",
@@ -835,16 +840,16 @@ public class DriftDetectorTest extends DriftTest {
File changeSet = changeSet(driftDef.getName(), COVERAGE);
File pinnedSnapshot = new File(changeSet.getParentFile(),
"snapshot.pinned");
- List<FileEntry> entries =
asList(addedFileEntry("conf/server.conf", sha256(serverConf),
- serverConf.lastModified(), serverConf.length()));
+ List<FileEntry> entries =
asList(addedFileEntry("conf/server.conf", sha256(serverConf), serverConf
+ .lastModified(), serverConf.length()));
assertTrue(changeSet.exists(), "An initial snapshot file should be generated
even when it is pinned");
assertHeaderEquals(changeSet, createHeaders(driftDef, COVERAGE));
assertFileEntriesMatch("Initial snapshot entries are wrong for pinned
snapshot", entries, changeSet);
assertTrue(pinnedSnapshot.exists(), "Pinned snapshot file should be
generated when initial version is pinned");
- assertEquals(sha256(changeSet), sha256(pinnedSnapshot), "The contents of the
pinned snapshot file and the " +
- "initial snapshot should be identical");
+ assertEquals(sha256(changeSet), sha256(pinnedSnapshot), "The contents of the
pinned snapshot file and the "
+ + "initial snapshot should be identical");
}
@Test
@@ -895,8 +900,8 @@ public class DriftDetectorTest extends DriftTest {
public void repeatChangeSet(int resourceId, String driftDefName, int version)
{
repeatChangeSetCalled.set(true);
assertEquals(resourceId, resourceId(), "The resource id for the
repeat change set is wrong");
- assertEquals(driftDefName, driftDef.getName(), "The drift definition
name for the repeat change set " +
- "is wrong");
+ assertEquals(driftDefName, driftDef.getName(), "The drift definition
name for the repeat change set "
+ + "is wrong");
assertEquals(version, 1, "The snapshot version should not have
changed since no new drift was detected");
}
});
@@ -914,8 +919,8 @@ public class DriftDetectorTest extends DriftTest {
assertTrue(repeatChangeSetCalled.get(), "Failed to notify server of repeat
change set");
// verify that the previous version snapshot file has been deleted
- assertFalse(previousSnapshot.exists(), "There should be no previous version
snapshot file because the " +
- "server has already acknowledged the current snapshot.");
+ assertFalse(previousSnapshot.exists(), "There should be no previous version
snapshot file because the "
+ + "server has already acknowledged the current snapshot.");
}
@@ -933,7 +938,8 @@ public class DriftDetectorTest extends DriftTest {
// generate the pinned snapshot which is version zero
File pinnedSnapshot = pinnedSnapshot(driftDef.getName());
ChangeSetWriter writer = new ChangeSetWriterImpl(pinnedSnapshot, headers);
- writer.write(addedFileEntry("conf/server.conf", serverConfHash,
serverConf.lastModified(), serverConf.length()));
+ writer
+ .write(addedFileEntry("conf/server.conf", serverConfHash,
serverConf.lastModified(), serverConf.length()));
writer.close();
// generate the current snapshot file. we will take a shortcut here by
@@ -946,6 +952,7 @@ public class DriftDetectorTest extends DriftTest {
// now generate some drift causing the resource to go out of compliance
File newServerConf = createRandomFile(confDir, "new_server.conf");
String newServerConfHash = sha256(newServerConf);
+ assert (null != newServerConfHash);
// do a drift detection run
DriftDetectionSchedule schedule = new DriftDetectionSchedule(resourceId(),
driftDef);
@@ -965,12 +972,81 @@ public class DriftDetectorTest extends DriftTest {
// verify that that current snapshot has been updated to reflect that
// the resource is back in compliance.
- List<FileEntry> entries =
asList(addedFileEntry("conf/server.conf", serverConfHash,
- serverConf.lastModified(), serverConf.length()));
+ List<FileEntry> entries =
asList(addedFileEntry("conf/server.conf", serverConfHash,
serverConf.lastModified(),
+ serverConf.length()));
assertHeaderEquals(currentSnapshot, createHeaders(driftDef, COVERAGE, 2));
- assertFileEntriesMatch("The entries in the current snapshot should match
those in the pinned snapshot " +
- "once the resource has gone back into compliance.", entries,
currentSnapshot);
+ assertFileEntriesMatch("The entries in the current snapshot should match
those in the pinned snapshot "
+ + "once the resource has gone back into compliance.", entries,
currentSnapshot);
+ }
+
+ @Test
+ public void updateTimestampInfoNoDriftTest() throws Exception {
+ DriftDefinition def = driftDefinition("update-timestamp-nodrift-test",
resourceDir.getAbsolutePath());
+
+ File confDir = mkdir(resourceDir, "conf");
+ File server1Conf = createRandomFile(confDir, "server-1.conf");
+ String server1Hash = sha256(server1Conf);
+
+ ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(resourceId(),
createHeaders(def, COVERAGE));
+ writer.write(addedFileEntry("conf/server-1.conf", server1Hash, -1L,
-1L));
+ writer.close();
+
+ scheduleQueue.addSchedule(new DriftDetectionSchedule(resourceId(), def));
+ detector.run();
+
+ // verify that no drift change set was generated
+ File driftChangeSet = changeSet(def.getName(), DRIFT);
+ assertFalse(driftChangeSet.exists(), "Expected no drift change set " +
driftChangeSet.getPath());
+
+ // verify that the coverage change set was updated with timestamp info, version
is still 0
+ File coverageChangeSet = changeSet(def.getName(), COVERAGE);
+ List<FileEntry> coverageEntries =
asList(addedFileEntry("conf/server-1.conf", server1Hash, server1Conf
+ .lastModified(), server1Conf.length()));
+
+ assertHeaderEquals(coverageChangeSet, createHeaders(def, COVERAGE, 0));
+ assertFileEntriesMatch("The coverage change set was not updated as
expected", coverageEntries,
+ coverageChangeSet);
+ }
+
+ @Test
+ public void updateTimestampInfoDriftTest() throws Exception {
+ DriftDefinition def = driftDefinition("update-timestamp-drift-test",
resourceDir.getAbsolutePath());
+
+ File confDir = mkdir(resourceDir, "conf");
+ File server1Conf = createRandomFile(confDir, "server-1.conf");
+ String server1Hash = sha256(server1Conf);
+ File server2Conf = createRandomFile(confDir, "server-2.conf");
+ String server2Hash = sha256(server2Conf);
+
+ ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(resourceId(),
createHeaders(def, COVERAGE));
+ writer.write(addedFileEntry("conf/server-1.conf", server1Hash, -1L,
-1L));
+ writer.write(addedFileEntry("conf/server-2.conf", server2Hash, -1L,
-1L));
+ writer.close();
+
+ // create some drift
+ server1Conf.delete();
+ confDir.delete();
+
+ scheduleQueue.addSchedule(new DriftDetectionSchedule(resourceId(), def));
+ detector.run();
+
+ File driftChangeSet = changeSet(def.getName(), DRIFT);
+ List<FileEntry> driftEntries =
asList(removedFileEntry("conf/server-1.conf", server1Hash));
+
+ // verify that the drift change set was generated
+ assertTrue(driftChangeSet.exists(), "Expected to find drift change set
" + driftChangeSet.getPath());
+ assertHeaderEquals(driftChangeSet, createHeaders(def, DRIFT, 1));
+ assertFileEntriesMatch("The drift change set does not match the expected
values", driftEntries, driftChangeSet);
+
+ // verify that the coverage change set was updated with timestamp info and
incremented version
+ File coverageChangeSet = changeSet(def.getName(), COVERAGE);
+ List<FileEntry> coverageEntries =
asList(addedFileEntry("conf/server-2.conf", server2Hash, server2Conf
+ .lastModified(), server2Conf.length()));
+
+ assertHeaderEquals(coverageChangeSet, createHeaders(def, COVERAGE, 1));
+ assertFileEntriesMatch("The coverage change set was not updated as
expected", coverageEntries,
+ coverageChangeSet);
}
private void assertHeaderEquals(File changeSet, Headers expected) throws Exception {
commit 2e75028c77cc24a2b097e82385d4c7dfb9b774d5
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Dec 13 17:17:29 2011 -0500
[Bug 756100 - RFE: use timestamp and file size during drift detection scans]
More work on using timestamp (and filesize) info to avoid SHA digest
generation. Handle situations where the current changeset is supplied
by the server, due to pinning or agent sync. In these situations work
to replace the non-timestamped changesets with timestamped versions as
soon as possible.
diff --git a/modules/common/drift/src/main/java/org/rhq/common/drift/FileEntry.java
b/modules/common/drift/src/main/java/org/rhq/common/drift/FileEntry.java
index e1766a3..564e9c5 100644
--- a/modules/common/drift/src/main/java/org/rhq/common/drift/FileEntry.java
+++ b/modules/common/drift/src/main/java/org/rhq/common/drift/FileEntry.java
@@ -29,7 +29,7 @@ import java.util.Date;
import org.rhq.core.domain.drift.DriftCategory;
import org.rhq.core.util.file.FileUtil;
-public class FileEntry implements Serializable {
+public class FileEntry implements Serializable, Comparable<FileEntry> {
private static final long serialVersionUID = 1L;
@@ -117,9 +117,23 @@ public class FileEntry implements Serializable {
return size;
}
+ public void setLastModified(Long lastModified) {
+ this.lastModified = lastModified;
+ }
+
+ public void setSize(Long size) {
+ this.size = size;
+ }
+
@Override
public String toString() {
return getClass().getSimpleName() + "[newSHA: " + newSHA + ",
oldSHA: " + oldSHA + ", file: " + file
+ ", type: " + type.code() + ", lastModified: " + new
Date(lastModified) + ", size: " + size + "]";
}
+
+ // Support Sets and Ordering by deferring to a String compare on the file path
+ @Override
+ public int compareTo(FileEntry o) {
+ return this.file.compareTo(o.getFile());
+ }
}
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
index 10d2006..869e376 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
@@ -184,117 +184,152 @@ public class DriftDetector implements Runnable {
log.debug("Generating drift change set for " + schedule);
- File currentSnapshot = changeSetMgr.findChangeSet(schedule.getResourceId(),
schedule.getDriftDefinition()
+ boolean isPinned = schedule.getDriftDefinition().isPinned();
+ final File basedir = new File(basedir(schedule.getResourceId(),
schedule.getDriftDefinition()));
+
+ File currentFullSnapshot = changeSetMgr.findChangeSet(schedule.getResourceId(),
schedule.getDriftDefinition()
.getName(), COVERAGE);
- File snapshotFile = currentSnapshot;
- if (schedule.getDriftDefinition().isPinned()) {
- snapshotFile = new File(snapshotFile.getParentFile(), FILE_SNAPSHOT_PINNED);
+ // unless pinned use the current full snapshot file for the definition, otherwise
use the pinned snapshot
+ File snapshotFile = isPinned ? new File(currentFullSnapshot.getParentFile(),
FILE_SNAPSHOT_PINNED)
+ : currentFullSnapshot;
+
+ // get a Set of all files in the detection, consider them initially new files,
and we'll knock the
+ // list down as we go. As we build up FileEntries in memory this Set will
shrink. It's marginally
+ // less memory than if we had both in memory at the same time.
+ final Set<File> newFiles = new HashSet<File>(1000);
+
+ // If the basedir is still valid we need to do a directory tree scan to look for
newly added files
+ if (basedir.isDirectory()) {
+ DriftDefinition driftDef = schedule.getDriftDefinition();
+ List<Filter> includes = driftDef.getIncludes();
+ List<Filter> excludes = driftDef.getExcludes();
+
+ for (File dir : getScanDirectories(basedir, includes)) {
+ forEachFile(dir, new FilterFileVisitor(basedir, includes, excludes, new
FileVisitor() {
+ @Override
+ public void visit(File file) {
+ if (file.canRead()) {
+ newFiles.add(file);
+ } else if (log.isDebugEnabled()) {
+ log.debug("Skipping " + file.getPath() + " as
new file since it is not readable.");
+ }
+ }
+ }));
+ }
}
- final File basedir = new File(basedir(schedule.getResourceId(),
schedule.getDriftDefinition()));
- final Set<File> processedFiles = new HashSet<File>();
- final List<FileEntry> snapshotEntries = new LinkedList<FileEntry>();
- final List<FileEntry> deltaEntries = new LinkedList<FileEntry>();
+ final List<FileEntry> unchangedEntries = new
LinkedList<FileEntry>();
+ final List<FileEntry> removedEntries = new LinkedList<FileEntry>();
+ final List<FileEntry> cantReadEntries = new LinkedList<FileEntry>();
+ final List<FileEntry> changedEntries = new LinkedList<FileEntry>();
+ final List<FileEntry> changedPinnedEntries = isPinned ? new
LinkedList<FileEntry>() : null;
- ChangeSetReader coverageReader = null;
+ ChangeSetReader snapshotReader = null;
int newVersion;
+ boolean updateSnapshot = false;
try {
- coverageReader = changeSetMgr.getChangeSetReader(snapshotFile);
+ snapshotReader = changeSetMgr.getChangeSetReader(snapshotFile);
if (!basedir.exists()) {
log.warn("The base directory [" + basedir.getAbsolutePath() +
"] for " + schedule + " does not exist.");
}
- if (schedule.getDriftDefinition().isPinned()) {
- ChangeSetReader snapshotReader = null;
+ if (isPinned) {
+ // If pinned we compare against the pinned snapshot but we need to know
the current snapshot version,
+ // get it from the current full snapshot.
+ ChangeSetReader currentFullSnapshotReader = null;
try {
- snapshotReader = changeSetMgr.getChangeSetReader(currentSnapshot);
- newVersion = snapshotReader.getHeaders().getVersion() + 1;
+ currentFullSnapshotReader =
changeSetMgr.getChangeSetReader(currentFullSnapshot);
+ newVersion = currentFullSnapshotReader.getHeaders().getVersion() +
1;
} finally {
- snapshotReader.close();
+ currentFullSnapshotReader.close();
}
} else {
- newVersion = coverageReader.getHeaders().getVersion() + 1;
+ newVersion = snapshotReader.getHeaders().getVersion() + 1;
}
// First look for files that have either been modified or deleted
- scanForModifiedOrDeletedFiles(schedule, basedir, processedFiles,
snapshotEntries, deltaEntries,
- coverageReader);
+ updateSnapshot = scanSnapshotFiles(schedule, basedir, snapshotReader,
newFiles, unchangedEntries,
+ removedEntries, cantReadEntries, changedEntries, changedPinnedEntries);
+
} finally {
- coverageReader.close();
+ snapshotReader.close();
}
- // If the basedir is still valid we need to do a directory tree scan to look for
newly added files
- if (basedir.isDirectory()) {
- DriftDefinition driftDef = schedule.getDriftDefinition();
- List<Filter> includes = driftDef.getIncludes();
- List<Filter> excludes = driftDef.getExcludes();
+ // if necessary, re-write the pinned snapshot file because we've updated
timestamp/filesize info, which
+ // on subsequent detection runs will help us avoid SHA generation. It must
maintain the same entries.
+ if (isPinned && updateSnapshot) {
+ changedPinnedEntries.addAll(unchangedEntries);
- for (File dir : getScanDirectories(basedir, includes)) {
- forEachFile(dir, new FilterFileVisitor(basedir, includes, excludes, new
FileVisitor() {
- @Override
- public void visit(File file) {
- try {
- if (processedFiles.contains(file)) {
- return;
- }
+ backupAndDeleteCurrentSnapshot(snapshotFile);
+ updatePinnedSnapshot(schedule, snapshotFile, changedPinnedEntries);
+ }
- if (!file.canRead()) {
- if (log.isDebugEnabled()) {
- log.debug("Skipping " + file.getPath() +
" since it is not readable.");
- }
- return;
- }
+ final List<FileEntry> snapshotEntries = new
LinkedList<FileEntry>(unchangedEntries);
+ snapshotEntries.addAll(changedEntries);
- if (log.isInfoEnabled()) {
- log.info("Detected added file for " + schedule
+ " --> " + file.getAbsolutePath());
- }
+ final List<FileEntry> deltaEntries = new
LinkedList<FileEntry>(changedEntries);
+ deltaEntries.addAll(removedEntries);
+ deltaEntries.addAll(cantReadEntries);
- FileEntry newEntry = addedFileEntry(relativePath(basedir,
file), sha256(file), file
- .lastModified(), file.length());
- deltaEntries.add(newEntry);
- snapshotEntries.add(newEntry);
- } catch (IOException e) {
- log.error("An error occurred while generating a drift
change set for " + schedule + ": "
- + e.getMessage());
- throw new DriftDetectionException("An error occurred
while generating a drift change set",
- e);
- }
- }
- }));
+ for (File file : newFiles) {
+ try {
+ if (log.isInfoEnabled()) {
+ log.info("Detected added file for " + schedule + "
--> " + file.getAbsolutePath());
+ }
+
+ FileEntry newEntry = addedFileEntry(relativePath(basedir, file),
sha256(file), file.lastModified(),
+ file.length());
+
+ deltaEntries.add(newEntry);
+ snapshotEntries.add(newEntry);
+
+ } catch (IOException e) {
+ log.error("An error occurred while generating a drift change set for
" + schedule + ": "
+ + e.getMessage());
+ throw new DriftDetectionException("An error occurred while
generating a drift change set", e);
}
}
if (deltaEntries.isEmpty()) {
- summary.setNewSnapshot(currentSnapshot);
-
- // If nothing has changed, there is no need to add/update any files
- // unless the definition is pinned in which case we need to reset
- // the current snapshot to match the pinned snapshot. Note though
- // that we increment the snapshot version in order to let the server
- // know about the state change.
- // if no timestamp must re-gen the files.
- if (schedule.getDriftDefinition().isPinned() && newVersion > 1
- && !isPreviousChangeSetEmpty(schedule.getResourceId(),
schedule.getDriftDefinition())) {
- currentSnapshot.delete();
- File newSnapshot = updateCurrentSnapshot(schedule, snapshotEntries,
newVersion);
-
- updateDeltaSnapshot(summary, schedule, deltaEntries, newVersion,
currentSnapshot, newSnapshot);
- // TODO report back to the server that we are back in compliance
+ File newSnapshot = currentFullSnapshot;
+
+ if (!isPinned) {
+ // If unpinned and there is no detected drift then we generally don't
need to add/update any files.
+ // But, if we have timestamp/filesize updates then we want to replace the
current snapshot with
+ // the updated entries, so we can avoid SHA generation on subsequent
runs.
+ if (updateSnapshot) {
+ currentFullSnapshot.delete();
+ newSnapshot = updateCurrentSnapshot(schedule, snapshotEntries,
newVersion - 1);
+ }
+ } else {
+ // If pinned and returning to compliance (meaning no drift now but the
previous snapshot did have drift)
+ // then we need to reset the current snapshot to match the pinned
snapshot. Note though that we
+ // increment the snapshot version in order to let the server know about
the state change.
+ if (newVersion > 1
+ && !isPreviousChangeSetEmpty(schedule.getResourceId(),
schedule.getDriftDefinition())) {
+ currentFullSnapshot.delete();
+ newSnapshot = updateCurrentSnapshot(schedule, snapshotEntries,
newVersion);
+
+ updateDeltaSnapshot(summary, schedule, deltaEntries, newVersion,
currentFullSnapshot, newSnapshot);
+ }
}
+
+ summary.setNewSnapshot(newSnapshot);
+
} else {
- if (schedule.getDriftDefinition().isPinned() && newVersion > 1
- && isSameAsPreviousChangeSet(deltaEntries, currentSnapshot)) {
- // if we are still out of compliance just report, we report a
- // repeat change set to indicate no changes but also still out
- // of compliance.
+ // if there is drift, but we're pinned and the drift is the same as the
previous detection, just
+ // mark it as a repeat to indicate that we're out of compliance but not
in any new way.
+ if (isPinned && newVersion > 1 &&
isSameAsPreviousChangeSet(deltaEntries, currentFullSnapshot)) {
summary.setVersion(newVersion - 1);
summary.setRepeat(true);
+
return;
}
- File oldSnapshot = backupAndDeleteCurrentSnapshot(currentSnapshot);
+ // otherwise, generate a new current snapshot, and a snapshot delta
reflecting the latest drift
+ File oldSnapshot = backupAndDeleteCurrentSnapshot(currentFullSnapshot);
File newSnapshot = updateCurrentSnapshot(schedule, snapshotEntries,
newVersion);
updateDeltaSnapshot(summary, schedule, deltaEntries, newVersion, oldSnapshot,
newSnapshot);
@@ -321,55 +356,88 @@ public class DriftDetector implements Runnable {
return directories;
}
- private void scanForModifiedOrDeletedFiles(DriftDetectionSchedule schedule, File
basedir, Set<File> processedFiles,
- List<FileEntry> snapshotEntries, List<FileEntry> deltaEntries,
ChangeSetReader coverageReader)
+ /**
+ * Process the entries for the snapshotReader. Each entry will be placed in one of
the various Lists depending
+ * on what bucket it fall into.
+ * @return true if unchangedEntries (meaning no drift) had timestamp/filesize info
updated, in which case the
+ * snapshot should be re-written to disk even if there was no drift.
+ * @throws IOException
+ */
+ private boolean scanSnapshotFiles(DriftDetectionSchedule schedule, File basedir,
ChangeSetReader snapshotReader,
+ Set<File> newFiles, List<FileEntry> unchangedEntries,
List<FileEntry> removedEntries,
+ List<FileEntry> cantReadEntries, List<FileEntry> modifiedEntries,
List<FileEntry> changedPinnedEntries)
throws IOException {
- for (FileEntry entry : coverageReader) {
+ boolean result = false;
+
+ for (FileEntry entry : snapshotReader) {
File file = new File(basedir, entry.getFile());
+ newFiles.remove(file);
+
if (!file.exists()) {
// The file has been deleted since the last scan
if (log.isDebugEnabled()) {
log.debug("Detected deleted file for " + schedule + "
--> " + file.getAbsolutePath());
}
- deltaEntries.add(removedFileEntry(entry.getFile(), entry.getNewSHA()));
+ removedEntries.add(removedFileEntry(entry.getFile(),
entry.getNewSHA()));
+
+ if (null != changedPinnedEntries) {
+ changedPinnedEntries.add(entry);
+ }
+
+ continue;
+
} else if (!file.canRead()) {
- processedFiles.add(file);
if (log.isDebugEnabled()) {
log.debug(file.getPath() + " is no longer readable. Treating it
as a deleted file.");
}
- deltaEntries.add(removedFileEntry(entry.getFile(), entry.getNewSHA()));
+ cantReadEntries.add(removedFileEntry(entry.getFile(),
entry.getNewSHA()));
+
+ if (null != changedPinnedEntries) {
+ changedPinnedEntries.add(entry);
+ }
+
+ continue;
+
} else {
- processedFiles.add(file);
- // if we do not have the last modification time and the file size, then
we
- // have to compare SHAs. We can wind up without a timestamp of a file
size
- // when the agent is restarted and the data directory is purged. The
server
- // sends snapshots down to the agent and since the server does not store
the
- // file modification time or size, the fields will get initialized to
-1.
- if (entry.getLastModified() == -1 || entry.getSize() == -1) {
- String currentSHA = sha256(file);
- if (!entry.getNewSHA().equals(currentSHA)) {
- FileEntry modifiedEntry = changedFileEntry(entry.getFile(),
entry.getNewSHA(), currentSHA, file
- .lastModified(), file.length());
- deltaEntries.add(modifiedEntry);
- snapshotEntries.add(modifiedEntry);
- }
- } else if (entry.getLastModified() != -1 && entry.getSize() !=
-1
- && (entry.getLastModified() != file.lastModified() ||
entry.getSize() != file.length())) {
- if (log.isDebugEnabled()) {
- log.debug("Detected modified file for " + schedule +
" --> " + file.getAbsolutePath());
- }
- String currentSHA = sha256(file);
+ String currentSHA = null;
+ boolean isModified = false;
+
+ // perform a SHA comparison if we are unable to compare size and
lastModified or if the
+ // size or lastModified test fails. We may not have size of lastModified
values for the
+ // entry when the current snapshot was provided by the server, either due
to a synch or
+ // pinning scenario. The server does not store that information and will
provide -1 for defaults.
+ if (entry.getLastModified() == -1 || entry.getSize() == -1
+ || entry.getLastModified() != file.lastModified() || entry.getSize()
!= file.length()) {
+
+ currentSHA = sha256(file);
+ isModified = !entry.getNewSHA().equals(currentSHA);
+ }
+
+ if (isModified) {
FileEntry modifiedEntry = changedFileEntry(entry.getFile(),
entry.getNewSHA(), currentSHA, file
.lastModified(), file.length());
- deltaEntries.add(modifiedEntry);
- snapshotEntries.add(modifiedEntry);
+ modifiedEntries.add(modifiedEntry);
+
+ if (null != changedPinnedEntries) {
+ changedPinnedEntries.add(entry);
+ }
+
} else {
- // The file has not changed
- snapshotEntries.add(entry);
+ if (-1 == entry.getLastModified()) {
+ entry.setLastModified(file.lastModified());
+ result = true;
+ }
+ if (-1 == entry.getSize()) {
+ entry.setSize(file.length());
+ result = true;
+ }
+ unchangedEntries.add(entry);
}
}
}
+
+ return result;
}
@SuppressWarnings("unused")
@@ -449,6 +517,26 @@ public class DriftDetector implements Runnable {
}
}
+ private File updatePinnedSnapshot(DriftDetectionSchedule schedule, File
pinnedSnapshot,
+ List<FileEntry> snapshotEntries) throws IOException {
+
+ ChangeSetWriter newSnapshotWriter = null;
+
+ try {
+ Headers snapshotHeaders = createHeaders(schedule, COVERAGE, 0);
+ newSnapshotWriter = changeSetMgr.getChangeSetWriter(pinnedSnapshot,
snapshotHeaders);
+
+ for (FileEntry entry : snapshotEntries) {
+ newSnapshotWriter.write(entry);
+ }
+
+ return pinnedSnapshot;
+
+ } finally {
+ newSnapshotWriter.close();
+ }
+ }
+
private boolean isSameAsPreviousChangeSet(List<FileEntry> entries, File
currentSnapsotFile) throws IOException {
HashMap<String, FileEntry> entriesMap = new HashMap<String,
FileEntry>();
for (FileEntry e : entries) {
commit bf599134469592012e7ee69a00354cc815e7db8e
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Dec 13 16:22:13 2011 -0500
Make sure the drift def id is also in the copy so it can be applied to
generated changeset headers.
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetectionSchedule.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetectionSchedule.java
index 8ddfc03..60fb35b 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetectionSchedule.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetectionSchedule.java
@@ -43,6 +43,7 @@ public class DriftDetectionSchedule implements
Comparable<DriftDetectionSchedule
public DriftDetectionSchedule copy() {
DriftDetectionSchedule copy = new DriftDetectionSchedule(resourceId, new
DriftDefinition(driftDef
.getConfiguration().deepCopyWithoutProxies()));
+ copy.driftDef.setId(driftDef.getId());
copy.nextScan = nextScan;
return copy;
}
commit 54ccb75ffb746b3e167f8fdfb2fba3cc70dc13e2
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Dec 12 15:53:14 2011 -0500
Ensure we have both the timestamp and the filesize before we skip using
a SHA test.
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
index 11a2d85..10d2006 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
@@ -346,7 +346,7 @@ public class DriftDetector implements Runnable {
// when the agent is restarted and the data directory is purged. The
server
// sends snapshots down to the agent and since the server does not store
the
// file modification time or size, the fields will get initialized to
-1.
- if (entry.getLastModified() == -1 && entry.getSize() == -1) {
+ if (entry.getLastModified() == -1 || entry.getSize() == -1) {
String currentSHA = sha256(file);
if (!entry.getNewSHA().equals(currentSHA)) {
FileEntry modifiedEntry = changedFileEntry(entry.getFile(),
entry.getNewSHA(), currentSHA, file
commit 610d9447060444806f5fd27c29a5f118195636c0
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Dec 12 15:51:46 2011 -0500
Just some cleanup
- remove unused/obsolete methods from ChangeSetManager and the impl
- move some commonly referenced filenames into constants
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ChangeSetManager.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ChangeSetManager.java
index 1fc9fe9..5117ab1 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ChangeSetManager.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ChangeSetManager.java
@@ -26,7 +26,6 @@ import org.rhq.common.drift.ChangeSetReader;
import org.rhq.common.drift.ChangeSetWriter;
import org.rhq.common.drift.Headers;
import org.rhq.core.domain.drift.DriftChangeSetCategory;
-import org.rhq.core.domain.drift.DriftDefinition;
public interface ChangeSetManager {
@@ -66,11 +65,4 @@ public interface ChangeSetManager {
ChangeSetWriter getChangeSetWriter(int resourceId, Headers headers) throws
IOException;
ChangeSetWriter getChangeSetWriter(File changeSetFile, Headers headers) throws
IOException;
-
- ChangeSetWriter getChangeSetWriterForUpdate(int resourceId, Headers headers) throws
IOException;
-
- void updateChangeSet(int resourceId, Headers headers) throws IOException;
-
- void addFileToChangeSet(int resourceId, DriftDefinition driftDefinition, File file);
-
}
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ChangeSetManagerImpl.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ChangeSetManagerImpl.java
index 132a7ca..97e92d3 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ChangeSetManagerImpl.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ChangeSetManagerImpl.java
@@ -21,11 +21,7 @@ package org.rhq.core.pc.drift;
import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE;
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
import java.io.IOException;
import org.rhq.common.drift.ChangeSetReader;
@@ -34,8 +30,6 @@ import org.rhq.common.drift.ChangeSetWriter;
import org.rhq.common.drift.ChangeSetWriterImpl;
import org.rhq.common.drift.Headers;
import org.rhq.core.domain.drift.DriftChangeSetCategory;
-import org.rhq.core.domain.drift.DriftDefinition;
-import org.rhq.core.util.stream.StreamUtil;
public class ChangeSetManagerImpl implements ChangeSetManager {
@@ -51,13 +45,13 @@ public class ChangeSetManagerImpl implements ChangeSetManager {
if (changeSetDir == null || !changeSetDir.exists()) {
return false;
}
- return new File(changeSetDir, "changeset.txt").exists();
+ return new File(changeSetDir, DriftDetector.FILE_CHANGESET_FULL).exists();
}
@Override
public File findChangeSet(int resourceId, String driftDefinitionName) throws
IOException {
File changeSetDir = findChangeSetDir(resourceId, driftDefinitionName);
- File changeSetFile = new File(changeSetDir, "changeset.txt");
+ File changeSetFile = new File(changeSetDir, DriftDetector.FILE_CHANGESET_FULL);
if (changeSetFile.exists()) {
return changeSetFile;
@@ -76,9 +70,9 @@ public class ChangeSetManagerImpl implements ChangeSetManager {
switch (type) {
case COVERAGE:
- return new File(changeSetDir, "changeset.txt");
+ return new File(changeSetDir, DriftDetector.FILE_CHANGESET_FULL);
case DRIFT:
- return new File(changeSetDir, "drift-changeset.txt");
+ return new File(changeSetDir, DriftDetector.FILE_CHANGESET_DELTA);
default:
throw new IllegalArgumentException(type + " is not a recognized,
supported change set type.");
}
@@ -111,9 +105,9 @@ public class ChangeSetManagerImpl implements ChangeSetManager {
File changeSet;
if (headers.getType() == COVERAGE) {
- changeSet = new File(changeSetDir, "changeset.txt");
+ changeSet = new File(changeSetDir, DriftDetector.FILE_CHANGESET_FULL);
} else {
- changeSet = new File(changeSetDir, "drift-changeset.txt");
+ changeSet = new File(changeSetDir, DriftDetector.FILE_CHANGESET_DELTA);
}
return new ChangeSetWriterImpl(changeSet, headers);
}
@@ -123,35 +117,6 @@ public class ChangeSetManagerImpl implements ChangeSetManager {
return new ChangeSetWriterImpl(changeSetFile, headers);
}
- @Override
- public ChangeSetWriter getChangeSetWriterForUpdate(int resourceId, Headers headers)
throws IOException {
- File resourceDir = new File(changeSetsDir, Integer.toString(resourceId));
- File changeSetDir = new File(resourceDir, headers.getDriftDefinitionName());
-
- return new ChangeSetWriterImpl(new File(changeSetDir,
"changeset.working"), headers);
- }
-
- @Override
- public void updateChangeSet(int resourceId, Headers headers) throws IOException {
- File resourceDir = new File(changeSetsDir, Integer.toString(resourceId));
- File changeSetDir = new File(resourceDir, headers.getDriftDefinitionName());
- File newChangeSet = new File(changeSetDir, "changeset.working");
- File changeSet = new File(changeSetDir, "changeset.txt");
-
- if (!newChangeSet.exists()) {
- return;
- }
-
- changeSet.delete();
-
- StreamUtil.copy(new BufferedInputStream(new FileInputStream(newChangeSet)), new
BufferedOutputStream(
- new FileOutputStream(changeSet)));
- }
-
- @Override
- public void addFileToChangeSet(int resourceId, DriftDefinition driftDefinition, File
file) {
- }
-
private File findChangeSetDir(int resourceId, String driftDefinitionName) {
File resourceDir = new File(changeSetsDir, Integer.toString(resourceId));
if (!resourceDir.exists()) {
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
index 848ae93..11a2d85 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
@@ -19,8 +19,26 @@
package org.rhq.core.pc.drift;
+import static org.rhq.common.drift.FileEntry.addedFileEntry;
+import static org.rhq.common.drift.FileEntry.changedFileEntry;
+import static org.rhq.common.drift.FileEntry.removedFileEntry;
+import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE;
+import static org.rhq.core.domain.drift.DriftChangeSetCategory.DRIFT;
+import static org.rhq.core.util.file.FileUtil.copyFile;
+import static org.rhq.core.util.file.FileUtil.forEachFile;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.rhq.common.drift.ChangeSetReader;
import org.rhq.common.drift.ChangeSetWriter;
import org.rhq.common.drift.FileEntry;
@@ -31,20 +49,13 @@ import org.rhq.core.domain.drift.Filter;
import org.rhq.core.util.MessageDigestGenerator;
import org.rhq.core.util.file.FileVisitor;
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.util.*;
-
-import static org.rhq.common.drift.FileEntry.*;
-import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE;
-import static org.rhq.core.domain.drift.DriftChangeSetCategory.DRIFT;
-import static org.rhq.core.util.file.FileUtil.copyFile;
-import static org.rhq.core.util.file.FileUtil.forEachFile;
-
public class DriftDetector implements Runnable {
private Log log = LogFactory.getLog(DriftDetector.class);
+ static final String FILE_CHANGESET_FULL = "changeset.txt";
+ static final String FILE_CHANGESET_DELTA = "drift-changeset.txt";
+ static final String FILE_SNAPSHOT_PINNED = "snapshot.pinned";
+
private ScheduleQueue scheduleQueue;
private ChangeSetManager changeSetMgr;
@@ -178,7 +189,7 @@ public class DriftDetector implements Runnable {
File snapshotFile = currentSnapshot;
if (schedule.getDriftDefinition().isPinned()) {
- snapshotFile = new File(snapshotFile.getParentFile(),
"snapshot.pinned");
+ snapshotFile = new File(snapshotFile.getParentFile(), FILE_SNAPSHOT_PINNED);
}
final File basedir = new File(basedir(schedule.getResourceId(),
schedule.getDriftDefinition()));
@@ -240,14 +251,16 @@ public class DriftDetector implements Runnable {
log.info("Detected added file for " + schedule
+ " --> " + file.getAbsolutePath());
}
- FileEntry newEntry = addedFileEntry(relativePath(basedir, file),
sha256(file),
- file.lastModified(), file.length());
- deltaEntries.add(newEntry);
- snapshotEntries.add(newEntry);
- } catch (IOException e) {
- log.error("An error occurred while generating a drift change
set for " + schedule + ": "
- + e.getMessage());
- throw new DriftDetectionException("An error occurred while
generating a drift change set", e);
+ FileEntry newEntry = addedFileEntry(relativePath(basedir,
file), sha256(file), file
+ .lastModified(), file.length());
+ deltaEntries.add(newEntry);
+ snapshotEntries.add(newEntry);
+ } catch (IOException e) {
+ log.error("An error occurred while generating a drift
change set for " + schedule + ": "
+ + e.getMessage());
+ throw new DriftDetectionException("An error occurred
while generating a drift change set",
+ e);
+ }
}
}));
}
@@ -261,6 +274,7 @@ public class DriftDetector implements Runnable {
// the current snapshot to match the pinned snapshot. Note though
// that we increment the snapshot version in order to let the server
// know about the state change.
+ // if no timestamp must re-gen the files.
if (schedule.getDriftDefinition().isPinned() && newVersion > 1
&& !isPreviousChangeSetEmpty(schedule.getResourceId(),
schedule.getDriftDefinition())) {
currentSnapshot.delete();
@@ -335,19 +349,19 @@ public class DriftDetector implements Runnable {
if (entry.getLastModified() == -1 && entry.getSize() == -1) {
String currentSHA = sha256(file);
if (!entry.getNewSHA().equals(currentSHA)) {
- FileEntry modifiedEntry = changedFileEntry(entry.getFile(),
entry.getNewSHA(), currentSHA,
- file.lastModified(), file.length());
+ FileEntry modifiedEntry = changedFileEntry(entry.getFile(),
entry.getNewSHA(), currentSHA, file
+ .lastModified(), file.length());
deltaEntries.add(modifiedEntry);
snapshotEntries.add(modifiedEntry);
}
- } else if (entry.getLastModified() != -1 && entry.getSize() != -1
&&
- (entry.getLastModified() != file.lastModified() || entry.getSize() !=
file.length())) {
+ } else if (entry.getLastModified() != -1 && entry.getSize() !=
-1
+ && (entry.getLastModified() != file.lastModified() ||
entry.getSize() != file.length())) {
if (log.isDebugEnabled()) {
log.debug("Detected modified file for " + schedule +
" --> " + file.getAbsolutePath());
}
String currentSHA = sha256(file);
- FileEntry modifiedEntry = changedFileEntry(entry.getFile(),
entry.getNewSHA(), currentSHA,
- file.lastModified(), file.length());
+ FileEntry modifiedEntry = changedFileEntry(entry.getFile(),
entry.getNewSHA(), currentSHA, file
+ .lastModified(), file.length());
deltaEntries.add(modifiedEntry);
snapshotEntries.add(modifiedEntry);
} else {
@@ -443,7 +457,7 @@ public class DriftDetector implements Runnable {
ChangeSetReader reader = null;
try {
- File deltaChangeSet = new File(currentSnapsotFile.getParentFile(),
"drift-changeset.txt");
+ File deltaChangeSet = new File(currentSnapsotFile.getParentFile(),
FILE_CHANGESET_DELTA);
reader = changeSetMgr.getChangeSetReader(deltaChangeSet);
int numEntries = 0;
@@ -511,7 +525,7 @@ public class DriftDetector implements Runnable {
writer = null;
}
if (schedule.getDriftDefinition().isPinned()) {
- copyFile(snapshot, new File(snapshot.getParentFile(),
"snapshot.pinned"));
+ copyFile(snapshot, new File(snapshot.getParentFile(),
FILE_SNAPSHOT_PINNED));
}
summary.setNewSnapshot(snapshot);
} finally {
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
index 1182407..386ad73 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
@@ -201,7 +201,7 @@ public class DriftManager extends AgentService implements
DriftAgentService, Dri
// change set.
DriftSnapshot pinnedSnapshot =
driftServer.getSnapshot(driftDefinition.getId(), 0, 0);
Headers pinnedHeaders = createHeaders(resource.getId(),
driftDefinition);
- File pinnedSnapshotFile = new File(currentSnapshotFile.getParent(),
"snapshot.pinned");
+ File pinnedSnapshotFile = new File(currentSnapshotFile.getParent(),
DriftDetector.FILE_SNAPSHOT_PINNED);
log.info("Preparing to write pinned snapshot to disk for "
+ toString(resource.getId(), driftDefinition));
writeSnapshotToFile(pinnedSnapshot, pinnedSnapshotFile, pinnedHeaders);
@@ -212,7 +212,7 @@ public class DriftManager extends AgentService implements
DriftAgentService, Dri
// drift that has already been reported to the server.
DriftSnapshot deltaSnapshot =
driftServer.getSnapshot(driftDefinition.getId(), snapshot
.getVersion(), snapshot.getVersion());
- File deltaFile = new File(currentSnapshotFile.getParentFile(),
"drift-changeset.txt");
+ File deltaFile = new File(currentSnapshotFile.getParentFile(),
DriftDetector.FILE_CHANGESET_DELTA);
Headers deltaHeaders = createHeaders(resource.getId(),
driftDefinition);
deltaHeaders.setVersion(snapshot.getVersion());
deltaHeaders.setType(DRIFT);
@@ -546,7 +546,7 @@ public class DriftManager extends AgentService implements
DriftAgentService, Dri
public void run() {
File currentSnapshot =
changeSetMgr.findChangeSet(schedule.getResourceId(), schedule
.getDriftDefinition().getName(), COVERAGE);
- File pinnedSnapshot = new File(currentSnapshot.getParentFile(),
"snapshot.pinned");
+ File pinnedSnapshot = new File(currentSnapshot.getParentFile(),
DriftDetector.FILE_SNAPSHOT_PINNED);
pinnedSnapshot.delete();
if (log.isDebugEnabled()) {
@@ -561,7 +561,7 @@ public class DriftManager extends AgentService implements
DriftAgentService, Dri
@Override
public void updateDriftDetection(int resourceId, DriftDefinition driftDef,
DriftSnapshot driftSnapshot) {
File currentSnapshot = changeSetMgr.findChangeSet(resourceId, driftDef.getName(),
COVERAGE);
- File pinnedSnapshot = new File(currentSnapshot.getParentFile(),
"snapshot.pinned");
+ File pinnedSnapshot = new File(currentSnapshot.getParentFile(),
DriftDetector.FILE_SNAPSHOT_PINNED);
Headers headers = createHeaders(resourceId, driftDef);
try {
@@ -777,8 +777,8 @@ public class DriftManager extends AgentService implements
DriftAgentService, Dri
writer.write(addedFileEntry(drift.getPath(),
drift.getNewDriftFile().getHashId(), -1L, -1L));
break;
case FILE_CHANGED:
- writer.write(changedFileEntry(drift.getPath(),
drift.getOldDriftFile().getHashId(),
- drift.getNewDriftFile().getHashId(), -1L, -1L));
+ writer.write(changedFileEntry(drift.getPath(),
drift.getOldDriftFile().getHashId(), drift
+ .getNewDriftFile().getHashId(), -1L, -1L));
break;
default: // FILE_REMOVED
writer.write(removedFileEntry(drift.getPath(),
drift.getOldDriftFile().getHashId()));
commit 1ca18175b45456a6963f706cf1c4c7427384edcb
Merge: 579510c e8db9a1
Author: John Sanda <jsanda(a)redhat.com>
Date: Sat Dec 10 12:46:22 2011 -0500
Merge branch 'master' into jsanda/drift
Conflicts:
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
diff --cc
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
index c8c3bb0,21341c4..848ae93
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
@@@ -210,37 -216,42 +216,41 @@@ public class DriftDetector implements R
// If the basedir is still valid we need to do a directory tree scan to look for
newly added files
if (basedir.isDirectory()) {
- forEachFile(basedir, new FilterFileVisitor(basedir,
schedule.getDriftDefinition().getIncludes(), schedule
- .getDriftDefinition().getExcludes(), new FileVisitor() {
- @Override
- public void visit(File file) {
- try {
- if (processedFiles.contains(file)) {
- return;
- }
+ DriftDefinition driftDef = schedule.getDriftDefinition();
+ List<Filter> includes = driftDef.getIncludes();
+ List<Filter> excludes = driftDef.getExcludes();
+
+ for (File dir : getScanDirectories(basedir, includes)) {
+ forEachFile(dir, new FilterFileVisitor(basedir, includes, excludes, new
FileVisitor() {
+ @Override
+ public void visit(File file) {
+ try {
+ if (processedFiles.contains(file)) {
+ return;
+ }
- if (!file.canRead()) {
- if (log.isDebugEnabled()) {
- log.debug("Skipping " + file.getPath() +
" since it is not readable.");
+ if (!file.canRead()) {
+ if (log.isDebugEnabled()) {
+ log.debug("Skipping " + file.getPath() +
" since it is not readable.");
+ }
return;
}
- }
- if (log.isInfoEnabled()) {
- log.info("Detected added file for " + schedule +
" --> " + file.getAbsolutePath());
- }
+ if (log.isInfoEnabled()) {
+ log.info("Detected added file for " + schedule
+ " --> " + file.getAbsolutePath());
+ }
- FileEntry newEntry = addedFileEntry(relativePath(basedir,
file), sha256(file));
- deltaEntries.add(newEntry);
- snapshotEntries.add(newEntry);
- } catch (IOException e) {
- log.error("An error occurred while generating a drift
change set for " + schedule + ": "
- + e.getMessage());
- throw new DriftDetectionException("An error occurred
while generating a drift change set",
- e);
- }
+ FileEntry newEntry = addedFileEntry(relativePath(basedir, file),
sha256(file),
+ file.lastModified(), file.length());
+ deltaEntries.add(newEntry);
+ snapshotEntries.add(newEntry);
+ } catch (IOException e) {
+ log.error("An error occurred while generating a drift
change set for " + schedule + ": "
+ + e.getMessage());
+ throw new DriftDetectionException("An error occurred while
generating a drift change set", e);
}
- }
- }));
+ }));
+ }
}
if (deltaEntries.isEmpty()) {
diff --cc
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
index 4241b31,2790f13..1182407
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
@@@ -758,16 -771,16 +771,16 @@@ public class DriftManager extends Agent
private void writeSnapshotToFile(DriftSnapshot snapshot, File file, Headers headers)
throws IOException {
ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(file, headers);
try {
- for (Drift drift : snapshot.getDriftInstances()) {
+ for (Drift<?, ?> drift : snapshot.getDriftInstances()) {
switch (drift.getCategory()) {
case FILE_ADDED:
- writer.write(addedFileEntry(drift.getPath(),
drift.getNewDriftFile().getHashId()));
+ writer.write(addedFileEntry(drift.getPath(),
drift.getNewDriftFile().getHashId(), -1L, -1L));
break;
case FILE_CHANGED:
- writer.write(changedFileEntry(drift.getPath(),
drift.getOldDriftFile().getHashId(), drift
- .getNewDriftFile().getHashId()));
+ writer.write(changedFileEntry(drift.getPath(),
drift.getOldDriftFile().getHashId(),
+ drift.getNewDriftFile().getHashId(), -1L, -1L));
break;
- default: // FILE_REMOVED
+ default: // FILE_REMOVED
writer.write(removedFileEntry(drift.getPath(),
drift.getOldDriftFile().getHashId()));
}
}
commit 579510cd6bb0e810f551b06a5fa9a0d777a2e50c
Author: John Sanda <jsanda(a)redhat.com>
Date: Tue Nov 22 11:59:44 2011 -0500
[BZ 756100] Use file timestamp and size during drift detection
This commit introduces an enhancement to drift detection by reducing the
amount of digest calculation that is performed. Digest calculation is
CPU-intensive.
The change set parser code has been updated to read/write file timestamp
and size. DriftDetector looks at the addition file info now to determine
if there has been a change. If the timestamp and size have not changed,
DriftDetector will skip recalculating the SHA. This results in a
significant speed up in drift detection.
Since the additional fields are not persisted on the server, there may
be times when the file timestamp and size are not available. This can
happen for example when the agent is restarted and the data directory is
purged. The agent has to download snapshots from the server at that
point, and they will not have the file modification time or size.
diff --git
a/modules/common/drift/src/main/java/org/rhq/common/drift/ChangeSetReaderImpl.java
b/modules/common/drift/src/main/java/org/rhq/common/drift/ChangeSetReaderImpl.java
index 5da6078..f0dd8ac 100644
--- a/modules/common/drift/src/main/java/org/rhq/common/drift/ChangeSetReaderImpl.java
+++ b/modules/common/drift/src/main/java/org/rhq/common/drift/ChangeSetReaderImpl.java
@@ -19,6 +19,10 @@
package org.rhq.common.drift;
+import static org.rhq.common.drift.FileEntry.addedFileEntry;
+import static org.rhq.common.drift.FileEntry.changedFileEntry;
+import static org.rhq.common.drift.FileEntry.removedFileEntry;
+
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
@@ -31,10 +35,6 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.drift.DriftChangeSetCategory;
-import static org.rhq.common.drift.FileEntry.addedFileEntry;
-import static org.rhq.common.drift.FileEntry.changedFileEntry;
-import static org.rhq.common.drift.FileEntry.removedFileEntry;
-
/**
* Note that this implementation does not do any validation for the most part. It
assumes
* that entries in the change set file contain valid, 64 character SHA-256 hashes. It
@@ -121,19 +121,30 @@ public class ChangeSetReaderImpl implements ChangeSetReader {
}
if (line.charAt(0) == 'A') { // file added
- String sha = line.substring(2, 66);
- String fileName = line.substring(69);
- return addedFileEntry(fileName, sha);
+ int fileSizeEndIndex = line.indexOf(' ', 2);
+ long size = Long.parseLong(line.substring(2, fileSizeEndIndex));
+ int lastModifiedEndIndex = line.indexOf(' ', fileSizeEndIndex +
1);
+ long lastModified = Long.parseLong(line.substring(fileSizeEndIndex + 1,
lastModifiedEndIndex));
+ int shaEndIndex = lastModifiedEndIndex + 65;
+ String sha = line.substring(lastModifiedEndIndex + 1, shaEndIndex);
+ String fileName = line.substring(shaEndIndex + 3);
+ return addedFileEntry(fileName, sha, lastModified, size);
}
if (line.charAt(0) == 'C') { // file modified
- String newSha = line.substring(2, 66);
- String oldSha = line.substring(67, 131);
- String fileName = line.substring(132);
- return changedFileEntry(fileName, oldSha, newSha);
+ int fileSizeEndIndex = line.indexOf(' ', 2);
+ long size = Long.parseLong(line.substring(2, fileSizeEndIndex));
+ int lastModifiedEndIndex = line.indexOf(' ', fileSizeEndIndex +
1);
+ long lastModified = Long.parseLong(line.substring(fileSizeEndIndex + 1,
lastModifiedEndIndex));
+ int newShaIndex = lastModifiedEndIndex + 65;
+ String newSha = line.substring(lastModifiedEndIndex + 1, newShaIndex);
+ int oldShaIndex = newShaIndex + 65;
+ String oldSha = line.substring(newShaIndex + 1, oldShaIndex);
+ String fileName = line.substring(oldShaIndex + 1);
+ return changedFileEntry(fileName, oldSha, newSha, lastModified, size);
}
if (line.charAt(0) == 'R') { // file deleted
- String sha = line.substring(4, 68);
- String fileName = line.substring(69);
+ String sha = line.substring(10, 74);
+ String fileName = line.substring(75);
return removedFileEntry(fileName, sha);
}
diff --git a/modules/common/drift/src/main/java/org/rhq/common/drift/ChangeSetWriter.java
b/modules/common/drift/src/main/java/org/rhq/common/drift/ChangeSetWriter.java
index 5e9c6ed..9631490 100644
--- a/modules/common/drift/src/main/java/org/rhq/common/drift/ChangeSetWriter.java
+++ b/modules/common/drift/src/main/java/org/rhq/common/drift/ChangeSetWriter.java
@@ -46,7 +46,15 @@ import java.io.IOException;
* </ul>
* <br/>
* <br/>
- * FILE_ENTRY has four, space-delimited fields - type, new_sha, old_sha,
file_name.<br/>
+ * FILE_ENTRY has six, space-delimited fields:
+ * <ul>
+ * <li>type</li>
+ * <li>file_size</li>
+ * <li>timestamp</li>
+ * <li>new_sha</li>
+ * <li>old_sha</li>
+ * <li>file_name</li>
+ * </ul>
* Here is an example change set:
*
* <pre>
@@ -54,17 +62,19 @@ import java.io.IOException;
* 2345
* Core Server JARs
* /var/lib/myserver
- * C 1706b5c18e4358041b463995efc30f8f721766fab0e018d50d85978b46df013c
1536b5c18e4358041b463995efc30f8f721766fab0e018d50d85978b46df013c lib/foo.jar
- * A 2706b5c18e4358041b463995efc30f8f721766fab0e018d50d85978b46df013a 0 lib/bar.jar
- * R 0 2206b5af8e4358041b463995efc30f8f721766fab0e018d50d85978b46df013a conf/foo.conf
+ * C 1024 1321975943000 1706b5c18e4358041b463995efc30f8f721766fab0e018d50d85978b46df013c
1536b5c18e4358041b463995efc30f8f721766fab0e018d50d85978b46df013c lib/foo.jar
+ * A 512 1121975943000 2706b5c18e4358041b463995efc30f8f721766fab0e018d50d85978b46df013a 0
lib/bar.jar
+ * R -1 -1 0 2206b5af8e4358041b463995efc30f8f721766fab0e018d50d85978b46df013a
conf/foo.conf
* </pre>
*
* Note that the file paths in each entry are relative to the path in the base directory
- * header. For the entry with a path of lib/bar.jar notice that the old_sha field has a
- * value of 0. This is because it is a new file, and there is no previous SHA-256 hash
for
- * the file. For the entry with conf/foo.conf as its path, notices that the new_sha
field
- * has a value of 0 for foo.conf. This is because the file has been deleted and so there
is
- * no new SHA-256 hash.
+ * header. The timestamp field is the last modification time of the file. For the entry
+ * with a path of lib/bar.jar notice that the old_sha field has a value of 0. This is
+ * because it is a new file, and there is no previous SHA-256 hash for the file. For the
+ * entry with conf/foo.conf as its path, notices that the new_sha field has a value of 0
for foo.conf.
+ * This is because the file has been deleted and so there is no new SHA-256 hash. Also
+ * note that this entry has a value of -1 for its file size and timestamp fields. This
+ * denotes that those values are no longer available since the file was removed.
* <p/>
* Lastly and importantly, the format of this file is still subject to change.
Additional
* headers may be added, maybe allowing for optional headers. The format of the file
entry
diff --git
a/modules/common/drift/src/main/java/org/rhq/common/drift/ChangeSetWriterImpl.java
b/modules/common/drift/src/main/java/org/rhq/common/drift/ChangeSetWriterImpl.java
index c0fdf50..57a9c1a 100644
--- a/modules/common/drift/src/main/java/org/rhq/common/drift/ChangeSetWriterImpl.java
+++ b/modules/common/drift/src/main/java/org/rhq/common/drift/ChangeSetWriterImpl.java
@@ -57,14 +57,31 @@ public class ChangeSetWriterImpl implements ChangeSetWriter {
public void write(FileEntry entry) throws IOException {
switch (entry.getType()) {
case FILE_ADDED:
- writer.write(entry.getType().code() + " " + entry.getNewSHA() +
" 0 " + entry.getFile() + "\n");
+ writer.write(
+ entry.getType().code() + " " +
+ entry.getSize() + " " +
+ entry.getLastModified() + " " +
+ entry.getNewSHA() +
+ " 0 " +
+ entry.getFile() + "\n");
break;
case FILE_CHANGED:
- writer.write(entry.getType().code() + " " + entry.getNewSHA() +
" " + entry.getOldSHA() + " " +
+ writer.write(
+ entry.getType().code() + " " +
+ entry.getSize() + " " +
+ entry.getLastModified() + " " +
+ entry.getNewSHA() + " " +
+ entry.getOldSHA() + " " +
entry.getFile() + "\n");
break;
case FILE_REMOVED:
- writer.write(entry.getType().code() + " 0 " + entry.getOldSHA() +
" " + entry.getFile() + "\n");
+ writer.write(
+ entry.getType().code() + " " +
+ "-1 " +
+ "-1 " +
+ "0 " +
+ entry.getOldSHA() + " " +
+ entry.getFile() + "\n");
break;
}
}
diff --git a/modules/common/drift/src/main/java/org/rhq/common/drift/FileEntry.java
b/modules/common/drift/src/main/java/org/rhq/common/drift/FileEntry.java
index bafd297..e1766a3 100644
--- a/modules/common/drift/src/main/java/org/rhq/common/drift/FileEntry.java
+++ b/modules/common/drift/src/main/java/org/rhq/common/drift/FileEntry.java
@@ -24,6 +24,7 @@ import static org.rhq.core.domain.drift.DriftCategory.FILE_CHANGED;
import static org.rhq.core.domain.drift.DriftCategory.FILE_REMOVED;
import java.io.Serializable;
+import java.util.Date;
import org.rhq.core.domain.drift.DriftCategory;
import org.rhq.core.util.file.FileUtil;
@@ -38,26 +39,32 @@ public class FileEntry implements Serializable {
entry.oldSHA = sha;
entry.newSHA = "0";
entry.type = FILE_REMOVED;
+ entry.lastModified = -1L;
+ entry.size = -1L;
return entry;
}
- public static FileEntry addedFileEntry(String file, String sha) {
+ public static FileEntry addedFileEntry(String file, String sha, Long lastModified,
Long size) {
FileEntry entry = new FileEntry();
entry.file = FileUtil.useForwardSlash(file);
entry.oldSHA = "0";
entry.newSHA = sha;
entry.type = FILE_ADDED;
+ entry.lastModified = lastModified;
+ entry.size = size;
return entry;
}
- public static FileEntry changedFileEntry(String file, String oldSHA, String newSHA)
{
+ public static FileEntry changedFileEntry(String file, String oldSHA, String newSHA,
Long lastModified, Long size) {
FileEntry entry = new FileEntry();
entry.file = FileUtil.useForwardSlash(file);
entry.oldSHA = oldSHA;
entry.newSHA = newSHA;
entry.type = FILE_CHANGED;
+ entry.lastModified = lastModified;
+ entry.size = size;
return entry;
}
@@ -70,14 +77,20 @@ public class FileEntry implements Serializable {
private DriftCategory type;
+ private Long lastModified;
+
+ private Long size;
+
private FileEntry() {
}
- public FileEntry(String newSHA, String oldSHA, String file, String type) {
+ public FileEntry(String newSHA, String oldSHA, String file, String type, Long
lastModified, Long size) {
this.newSHA = newSHA;
this.oldSHA = oldSHA;
this.file = file;
this.type = DriftCategory.fromCode(type);
+ this.lastModified = lastModified;
+ this.size = size;
}
public String getFile() {
@@ -96,9 +109,17 @@ public class FileEntry implements Serializable {
return type;
}
+ public Long getLastModified() {
+ return lastModified;
+ }
+
+ public Long getSize() {
+ return size;
+ }
+
@Override
public String toString() {
return getClass().getSimpleName() + "[newSHA: " + newSHA + ",
oldSHA: " + oldSHA + ", file: " + file
- + ", type: " + type.code() + "]";
+ + ", type: " + type.code() + ", lastModified: " + new
Date(lastModified) + ", size: " + size + "]";
}
}
diff --git
a/modules/common/drift/src/test/java/org/rhq/common/drift/ChangeSetReaderImplTest.java
b/modules/common/drift/src/test/java/org/rhq/common/drift/ChangeSetReaderImplTest.java
index 1a6f5dd..e8b1cd6 100644
---
a/modules/common/drift/src/test/java/org/rhq/common/drift/ChangeSetReaderImplTest.java
+++
b/modules/common/drift/src/test/java/org/rhq/common/drift/ChangeSetReaderImplTest.java
@@ -1,15 +1,16 @@
package org.rhq.common.drift;
+import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE;
+import static org.rhq.test.AssertUtils.assertPropertiesMatch;
+import static org.testng.Assert.assertEquals;
+
import java.io.StringReader;
+import java.util.Date;
import org.testng.annotations.Test;
import org.rhq.core.util.MessageDigestGenerator;
-import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE;
-import static org.rhq.test.AssertUtils.assertPropertiesMatch;
-import static org.testng.Assert.assertEquals;
-
public class ChangeSetReaderImplTest {
MessageDigestGenerator digestGenerator = new
MessageDigestGenerator(MessageDigestGenerator.SHA_256);
@@ -18,13 +19,14 @@ public class ChangeSetReaderImplTest {
@SuppressWarnings("unchecked")
public void readFileAddedEntry() throws Exception {
String sha = sha256("myconf.conf");
+ long timestamp = new Date().getTime();
String changeset = "1\n" +
"1\n" +
"file-added-test\n" +
"myresource\n" +
"C\n" +
"1\n" +
- "A " + sha + " 0 conf/myconf.conf";
+ "A 1024 " + timestamp + " " + sha + "
0 conf/myconf.conf";
ChangeSetReaderImpl reader = new ChangeSetReaderImpl(new
StringReader(changeset));
@@ -39,7 +41,7 @@ public class ChangeSetReaderImplTest {
assertHeadersEquals(actualHeaders, expectedHeaders);
- FileEntry expectedFileEntry = new FileEntry(sha, "0",
"conf/myconf.conf", "A");
+ FileEntry expectedFileEntry = new FileEntry(sha, "0",
"conf/myconf.conf", "A", timestamp, 1024L);
FileEntry actualFileEntry = reader.read();
reader.close();
@@ -56,7 +58,7 @@ public class ChangeSetReaderImplTest {
"myresource\n" +
"C\n" +
"1\n" +
- "R 0 " + sha + " conf/myconf.conf";
+ "R -1 -1 0 " + sha + " conf/myconf.conf";
ChangeSetReaderImpl reader = new ChangeSetReaderImpl(new
StringReader(changeset));
@@ -71,7 +73,7 @@ public class ChangeSetReaderImplTest {
assertHeadersEquals(actualHeaders, expectedHeaders);
- FileEntry expectedFileEntry = new FileEntry("0", sha,
"conf/myconf.conf", "R");
+ FileEntry expectedFileEntry = new FileEntry("0", sha,
"conf/myconf.conf", "R", -1L, -1L);
FileEntry actualFileEntry = reader.read();
reader.close();
@@ -83,13 +85,14 @@ public class ChangeSetReaderImplTest {
public void readChangedFileEntry() throws Exception {
String oldSha = sha256("myconf.conf.old");
String newSha = sha256("myconf.conf.new");
+ long timestamp = new Date().getTime();
String changeset = "1\n" +
"1\n" +
"file-changed-test\n" +
"myresource\n" +
"C\n" +
"1\n" +
- "C " + newSha + " " + oldSha + "
conf/myconf.conf";
+ "C 1024 " + timestamp + " " + newSha +
" " + oldSha + " conf/myconf.conf";
ChangeSetReaderImpl reader = new ChangeSetReaderImpl(new
StringReader(changeset));
@@ -104,7 +107,7 @@ public class ChangeSetReaderImplTest {
assertHeadersEquals(actualHeaders, expectedHeaders);
- FileEntry expectedFileEntry = new FileEntry(newSha, oldSha,
"conf/myconf.conf", "C");
+ FileEntry expectedFileEntry = new FileEntry(newSha, oldSha,
"conf/myconf.conf", "C", timestamp, 1024L);
FileEntry actualFileEntry = reader.read();
reader.close();
@@ -115,13 +118,14 @@ public class ChangeSetReaderImplTest {
@SuppressWarnings("unchecked")
public void readFileEntryWithSpacesInPath() throws Exception {
String sha = sha256("file with spaces.conf");
+ long timestamp = new Date().getTime();
String changeset = "1\n" +
"1\n" +
"file-name-test\n" +
"myresource\n" +
"C\n" +
"1\n" +
- "A " + sha + " 0 conf/file with
spaces.conf";
+ "A 1024 " + timestamp + " " + sha + "
0 conf/file with spaces.conf";
ChangeSetReaderImpl reader = new ChangeSetReaderImpl(new
StringReader(changeset));
@@ -136,7 +140,7 @@ public class ChangeSetReaderImplTest {
assertHeadersEquals(actualHeaders, expectedHeaders);
- FileEntry expectedFileEntry = new FileEntry(sha, "0", "conf/file
with spaces.conf", "A");
+ FileEntry expectedFileEntry = new FileEntry(sha, "0", "conf/file
with spaces.conf", "A", timestamp, 1024L);
FileEntry actualFileEntry = reader.read();
reader.close();
@@ -162,8 +166,8 @@ public class ChangeSetReaderImplTest {
"myresource\n" +
"C\n" +
"1\n" +
- "A " + sha256("resource.conf") + " 0
conf/resource.conf\n" +
- "A " + sha256("resource.jar") + " 0
lib/resource.jar";
+ "A 1024 5678 " + sha256("resource.conf") +
" 0 conf/resource.conf\n" +
+ "A 1024 5678 " + sha256("resource.jar") +
" 0 lib/resource.jar";
ChangeSetReaderImpl reader = new ChangeSetReaderImpl(new
StringReader(changeset));
int numEntries = 0;
@@ -185,7 +189,7 @@ public class ChangeSetReaderImplTest {
"myresource\n" +
"C\n" +
"1\n" +
- "A " + sha + " 0 conf/resource.conf\n";
+ "A 1024 5678 " + sha + " 0
conf/resource.conf\n";
ChangeSetReaderImpl reader = new ChangeSetReaderImpl(new
StringReader(changeset));
int numEntries = 0;
@@ -227,9 +231,12 @@ public class ChangeSetReaderImplTest {
void assertFileEntryEquals(FileEntry actual, FileEntry expected) {
assertEquals(actual.getType(), expected.getType(), "The first column, the
entry type, is wrong");
- assertEquals(actual.getNewSHA(), expected.getNewSHA(), "The second column,
the new SHA-256, is wrong");
- assertEquals(actual.getOldSHA (), expected.getOldSHA(), "The third column,
the old SHA-256, is wrong");
- assertEquals(actual.getFile(), expected.getFile(), "The fourth column, the
file name, is wrong");
+ assertEquals(actual.getSize(), expected.getSize(), "The second column, the
file size, is wrong");
+ assertEquals(actual.getLastModified(), expected.getLastModified(), "The
third column, the last modification " +
+ "time, is wrong");
+ assertEquals(actual.getNewSHA(), expected.getNewSHA(), "The fourth column,
the new SHA-256, is wrong");
+ assertEquals(actual.getOldSHA (), expected.getOldSHA(), "The fifth column,
the old SHA-256, is wrong");
+ assertEquals(actual.getFile(), expected.getFile(), "The sixth column, the
file name, is wrong");
}
String sha256(String s) throws Exception {
diff --git
a/modules/common/drift/src/test/java/org/rhq/common/drift/ChangeSetWriterImplTest.java
b/modules/common/drift/src/test/java/org/rhq/common/drift/ChangeSetWriterImplTest.java
index e782cda..73d8d16 100644
---
a/modules/common/drift/src/test/java/org/rhq/common/drift/ChangeSetWriterImplTest.java
+++
b/modules/common/drift/src/test/java/org/rhq/common/drift/ChangeSetWriterImplTest.java
@@ -19,13 +19,6 @@
package org.rhq.common.drift;
-import java.io.File;
-import java.io.FileInputStream;
-import java.util.List;
-
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
import static org.apache.commons.io.FileUtils.deleteDirectory;
import static org.apache.commons.io.IOUtils.readLines;
import static org.rhq.common.drift.FileEntry.addedFileEntry;
@@ -34,6 +27,14 @@ import static org.rhq.common.drift.FileEntry.removedFileEntry;
import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE;
import static org.testng.Assert.assertEquals;
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Date;
+import java.util.List;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
public class ChangeSetWriterImplTest {
File changeSetsDir;
@@ -69,9 +70,10 @@ public class ChangeSetWriterImplTest {
headers.setType(COVERAGE);
headers.setVersion(1);
+ long timestamp = new Date().getTime();
ChangeSetWriterImpl writer = new ChangeSetWriterImpl(changeSetFile, headers);
- writer.write(addedFileEntry("conf/myconf.conf", "a34ef6"));
+ writer.write(addedFileEntry("conf/myconf.conf", "a34ef6",
timestamp, 1024L));
writer.close();
File metaDataFile = writer.getChangeSetFile();
@@ -80,7 +82,7 @@ public class ChangeSetWriterImplTest {
assertEquals(lines.size(), 7, "Expected to find seven lines in " +
metaDataFile.getPath()
+ " - six for the header followed by one file entry.");
assertHeadersEquals(lines, headers);
- assertFileEntryEquals(lines.get(6), "A a34ef6 0 conf/myconf.conf");
+ assertFileEntryEquals(lines.get(6), "A 1024 " + timestamp + "
a34ef6 0 conf/myconf.conf");
}
@Test
@@ -108,7 +110,7 @@ public class ChangeSetWriterImplTest {
assertEquals(lines.size(), 7, "Expected to find seven lines in " +
metaDataFile.getPath()
+ " - six for the header followed by one file entry.");
assertHeadersEquals(lines, headers);
- assertFileEntryEquals(lines.get(6), "R 0 a34ef6 conf/myconf.conf");
+ assertFileEntryEquals(lines.get(6), "R -1 -1 0 a34ef6
conf/myconf.conf");
}
@Test
@@ -127,7 +129,8 @@ public class ChangeSetWriterImplTest {
ChangeSetWriterImpl writer = new ChangeSetWriterImpl(changeSetFile, headers);
- writer.write(changedFileEntry("conf/myconf.conf", "a34ef6",
"c2d55f"));
+ long timestamp = new Date().getTime();
+ writer.write(changedFileEntry("conf/myconf.conf", "a34ef6",
"c2d55f", timestamp, 1024L));
writer.close();
File metaDataFile = writer.getChangeSetFile();
@@ -136,7 +139,7 @@ public class ChangeSetWriterImplTest {
assertEquals(lines.size(), 7, "Expected to find seven lines in " +
metaDataFile.getPath()
+ " - six for the header followed by one file entry.");
assertHeadersEquals(lines, headers);
- assertFileEntryEquals(lines.get(6), "C c2d55f a34ef6
conf/myconf.conf");
+ assertFileEntryEquals(lines.get(6), "C 1024 " + timestamp + "
c2d55f a34ef6 conf/myconf.conf");
}
/**
@@ -173,13 +176,15 @@ public class ChangeSetWriterImplTest {
String[] expectedFields = expected.split(" ");
String[] actualFields = actual.split(" ");
- assertEquals(expectedFields.length, 4, "<" + expected + ">
should contain 4 fields");
- assertEquals(actualFields.length, 4, "<" + actual + ">
should contain 4 fields");
+ assertEquals(expectedFields.length, 6, "<" + expected + ">
should contain 6 fields");
+ assertEquals(actualFields.length, 6, "<" + actual + ">
should contain 6 fields");
- assertEquals(actualFields[0], expectedFields[0], "The first column, the
SHA-256, is wrong");
- assertEquals(actualFields[1], expectedFields[1], "The second column, the old
SHA-256, is wrong");
- assertEquals(actualFields[2], expectedFields[2], "The third column, the file
name, is wrong");
- assertEquals(actualFields[3], expectedFields[3], "The fourth column, the
type, is wrong");
+ assertEquals(actualFields[0], expectedFields[0], "The first column, the
type, is wrong");
+ assertEquals(actualFields[1], expectedFields[1], "The second column, the
file size, is wrong");
+ assertEquals(actualFields[2], expectedFields[2], "The third column, the last
modification time, is wrong");
+ assertEquals(actualFields[3], expectedFields[3], "The fourth column, the
SHA-256, is wrong");
+ assertEquals(actualFields[4], expectedFields[4], "The fifth column, the old
SHA-256, is wrong");
+ assertEquals(actualFields[5], expectedFields[5], "The sixth column, the file
name, is wrong");
}
}
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
index e0f7509..c8c3bb0 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
@@ -230,7 +230,8 @@ public class DriftDetector implements Runnable {
log.info("Detected added file for " + schedule +
" --> " + file.getAbsolutePath());
}
- FileEntry newEntry = addedFileEntry(relativePath(basedir, file),
sha256(file));
+ FileEntry newEntry = addedFileEntry(relativePath(basedir, file),
sha256(file),
+ file.lastModified(), file.length());
deltaEntries.add(newEntry);
snapshotEntries.add(newEntry);
} catch (IOException e) {
@@ -296,12 +297,27 @@ public class DriftDetector implements Runnable {
deltaEntries.add(removedFileEntry(entry.getFile(), entry.getNewSHA()));
} else {
processedFiles.add(file);
- String currentSHA = sha256(file);
- if (!currentSHA.equals(entry.getNewSHA())) {
+ // if we do not have the last modification time and the file size, then
we
+ // have to compare SHAs. We can wind up without a timestamp of a file
size
+ // when the agent is restarted and the data directory is purged. The
server
+ // sends snapshots down to the agent and since the server does not store
the
+ // file modification time or size, the fields will get initialized to
-1.
+ if (entry.getLastModified() == -1 && entry.getSize() == -1) {
+ String currentSHA = sha256(file);
+ if (!entry.getNewSHA().equals(currentSHA)) {
+ FileEntry modifiedEntry = changedFileEntry(entry.getFile(),
entry.getNewSHA(), currentSHA,
+ file.lastModified(), file.length());
+ deltaEntries.add(modifiedEntry);
+ snapshotEntries.add(modifiedEntry);
+ }
+ } else if (entry.getLastModified() != -1 && entry.getSize() != -1
&&
+ (entry.getLastModified() != file.lastModified() || entry.getSize() !=
file.length())) {
if (log.isDebugEnabled()) {
log.debug("Detected modified file for " + schedule +
" --> " + file.getAbsolutePath());
}
- FileEntry modifiedEntry = changedFileEntry(entry.getFile(),
entry.getNewSHA(), currentSHA);
+ String currentSHA = sha256(file);
+ FileEntry modifiedEntry = changedFileEntry(entry.getFile(),
entry.getNewSHA(), currentSHA,
+ file.lastModified(), file.length());
deltaEntries.add(modifiedEntry);
snapshotEntries.add(modifiedEntry);
} else {
@@ -492,7 +508,8 @@ public class DriftDetector implements Runnable {
if (log.isDebugEnabled()) {
log.debug("Adding " + file.getPath() + " to
coverage change set for " + schedule);
}
- writer.write(addedFileEntry(relativePath(basedir, file),
sha256(file)));
+ writer.write(addedFileEntry(relativePath(basedir, file),
sha256(file), file.lastModified(),
+ file.length()));
} catch (IOException e) {
log.error("An error occurred while generating a coverage
change set for " + schedule + ": "
+ e.getMessage());
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
index c70b546..4241b31 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
@@ -761,11 +761,11 @@ public class DriftManager extends AgentService implements
DriftAgentService, Dri
for (Drift drift : snapshot.getDriftInstances()) {
switch (drift.getCategory()) {
case FILE_ADDED:
- writer.write(addedFileEntry(drift.getPath(),
drift.getNewDriftFile().getHashId()));
+ writer.write(addedFileEntry(drift.getPath(),
drift.getNewDriftFile().getHashId(), -1L, -1L));
break;
case FILE_CHANGED:
writer.write(changedFileEntry(drift.getPath(),
drift.getOldDriftFile().getHashId(),
- drift.getNewDriftFile().getHashId()));
+ drift.getNewDriftFile().getHashId(), -1L, -1L));
break;
default: // FILE_REMOVED
writer.write(removedFileEntry(drift.getPath(),
drift.getOldDriftFile().getHashId()));
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/ChangeSetManagerImplTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/ChangeSetManagerImplTest.java
index 6e016b6..351f42f 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/ChangeSetManagerImplTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/ChangeSetManagerImplTest.java
@@ -53,7 +53,7 @@ public class ChangeSetManagerImplTest extends DriftTest {
String serverConfHash = sha256(serverConf);
ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(resourceId(),
createHeaders(config, COVERAGE));
- writer.write(addedFileEntry("conf/server.conf", serverConfHash));
+ writer.write(addedFileEntry("conf/server.conf", serverConfHash,
serverConf.lastModified(), serverConf.length()));
writer.close();
ChangeSetReader reader = changeSetMgr.getChangeSetReader(resourceId(), config);
@@ -72,7 +72,7 @@ public class ChangeSetManagerImplTest extends DriftTest {
Headers headers = createHeaders(config, COVERAGE);
ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(resourceId(), headers);
- writer.write(addedFileEntry("conf/server.conf", sha256(serverConf)));
+ writer.write(addedFileEntry("conf/server.conf", sha256(serverConf),
serverConf.lastModified(), serverConf.length()));
writer.close();
assertTrue(changeSetMgr.changeSetExists(resourceId(), headers), "Expected to
find change set file.");
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java
index 4a2b333..dee1c6d 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java
@@ -95,7 +95,8 @@ public class DriftDetectorTest extends DriftTest {
File changeSet = changeSet(driftDef.getName(), COVERAGE);
Headers headers = createHeaders(driftDef, COVERAGE);
- List<FileEntry> expected =
asList(addedFileEntry("conf/server.conf", sha256(serverConf)));
+ List<FileEntry> expected =
asList(addedFileEntry("conf/server.conf", sha256(serverConf),
+ serverConf.lastModified(), serverConf.length()));
assertHeaderEquals(changeSet, headers);
assertFileEntriesMatch("Only files should be included in a change
set.", expected, changeSet);
@@ -114,8 +115,9 @@ public class DriftDetectorTest extends DriftTest {
detector.run();
File changeSet = changeSet(def.getName(), COVERAGE);
- List<FileEntry> entries =
asList(addedFileEntry("conf/server-1.conf", sha256(server1Conf)),
addedFileEntry(
- "conf/server-2.conf", sha256(server2Conf)));
+ List<FileEntry> entries = asList(
+ addedFileEntry("conf/server-1.conf", sha256(server1Conf),
server1Conf.lastModified(), server1Conf.length()),
+ addedFileEntry("conf/server-2.conf", sha256(server2Conf),
server2Conf.lastModified(), server2Conf.length()));
assertHeaderEquals(changeSet, createHeaders(def, COVERAGE));
assertFileEntriesMatch("Each file in a directory should be included in a
coverage change set", entries,
@@ -137,8 +139,9 @@ public class DriftDetectorTest extends DriftTest {
detector.run();
File changeSet = changeSet(def.getName(), COVERAGE);
- List<FileEntry> entries =
asList(addedFileEntry("conf/server.conf", sha256(serverConf)), addedFileEntry(
- "lib/server.jar", sha256(serverLib)));
+ List<FileEntry> entries = asList(
+ addedFileEntry("conf/server.conf", sha256(serverConf),
serverConf.lastModified(), serverConf.length()),
+ addedFileEntry("lib/server.jar", sha256(serverLib),
serverLib.lastModified(), serverLib.length()));
assertHeaderEquals(changeSet, createHeaders(def, COVERAGE));
assertFileEntriesMatch("A coverage change set should include files from
multiple, sibling directories",
@@ -160,8 +163,9 @@ public class DriftDetectorTest extends DriftTest {
detector.run();
File changeSet = changeSet(def.getName(), COVERAGE);
- List<FileEntry> entries =
asList(addedFileEntry("conf/server-1.conf", sha256(server1Conf)),
addedFileEntry(
- "conf/subconf/server-2.conf", sha256(server2Conf)));
+ List<FileEntry> entries = asList(
+ addedFileEntry("conf/server-1.conf", sha256(server1Conf),
server1Conf.lastModified(), server1Conf.length()),
+ addedFileEntry("conf/subconf/server-2.conf", sha256(server2Conf),
server2Conf.lastModified(), server2Conf.length()));
assertHeaderEquals(changeSet, createHeaders(def, COVERAGE));
assertFileEntriesMatch("A coverage change set should include files in nested
sub directories", entries,
@@ -296,7 +300,8 @@ public class DriftDetectorTest extends DriftTest {
File server1Conf = createRandomFile(confDir, "server-1.conf");
ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(resourceId(),
createHeaders(def, COVERAGE));
- writer.write(addedFileEntry("conf/server-1.conf",
sha256(server1Conf)));
+ writer.write(addedFileEntry("conf/server-1.conf", sha256(server1Conf),
server1Conf.lastModified(),
+ server1Conf.length()));
writer.close();
// Create some drift
@@ -306,7 +311,8 @@ public class DriftDetectorTest extends DriftTest {
detector.run();
File driftChangeSet = changeSet(def.getName(), DRIFT);
- List<FileEntry> driftEntries =
asList(addedFileEntry("conf/server-2.conf", sha256(server2Conf)));
+ List<FileEntry> driftEntries =
asList(addedFileEntry("conf/server-2.conf", sha256(server2Conf),
+ server2Conf.lastModified(), server2Conf.length()));
// verify that the drift change set was generated
assertTrue(driftChangeSet.exists(), "Expected to find drift change set
" + driftChangeSet.getPath());
@@ -314,8 +320,9 @@ public class DriftDetectorTest extends DriftTest {
assertFileEntriesMatch("The drift change set does not match the expected
values", driftEntries, driftChangeSet);
File coverageChangeSet = changeSet(def.getName(), COVERAGE);
- List<FileEntry> coverageEntries =
asList(addedFileEntry("conf/server-1.conf", sha256(server1Conf)),
- addedFileEntry("conf/server-2.conf", sha256(server2Conf)));
+ List<FileEntry> coverageEntries = asList(
+ addedFileEntry("conf/server-1.conf", sha256(server1Conf),
server1Conf.lastModified(), server1Conf.length()),
+ addedFileEntry("conf/server-2.conf", sha256(server2Conf),
server2Conf.lastModified(), server2Conf.length()));
// verify that the coverage change set was updated
assertHeaderEquals(coverageChangeSet, createHeaders(def, COVERAGE, 1));
@@ -333,19 +340,20 @@ public class DriftDetectorTest extends DriftTest {
String oldHash = sha256(server1Conf);
ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(resourceId(),
createHeaders(def, COVERAGE));
- writer.write(addedFileEntry("conf/server-1.conf", oldHash));
+ writer.write(addedFileEntry("conf/server-1.conf", oldHash,
server1Conf.lastModified(), server1Conf.length()));
writer.close();
// create some drift
server1Conf.delete();
- server1Conf = createRandomFile(confDir, "server-1.conf");
+ server1Conf = createRandomFile(confDir, "server-1.conf", 48);
String newHash = sha256(server1Conf);
scheduleQueue.addSchedule(new DriftDetectionSchedule(resourceId(), def));
detector.run();
File driftChangeSet = changeSet(def.getName(), DRIFT);
- List<FileEntry> driftEntries =
asList(changedFileEntry("conf/server-1.conf", oldHash, newHash));
+ List<FileEntry> driftEntries =
asList(changedFileEntry("conf/server-1.conf", oldHash, newHash,
+ server1Conf.lastModified(), server1Conf.length()));
// verify that the drift change set was generated
assertTrue(driftChangeSet.exists(), "Expected to find drift change set
" + driftChangeSet.getPath());
@@ -353,7 +361,8 @@ public class DriftDetectorTest extends DriftTest {
assertFileEntriesMatch("The drift change set does not match the expected
values", driftEntries, driftChangeSet);
File coverageChangeSet = changeSet(def.getName(), COVERAGE);
- List<FileEntry> coverageEntries =
asList(changedFileEntry("conf/server-1.conf", oldHash, newHash));
+ List<FileEntry> coverageEntries =
asList(changedFileEntry("conf/server-1.conf", oldHash, newHash,
+ server1Conf.lastModified(), server1Conf.length()));
// verify that the coverage change set was updated
assertHeaderEquals(coverageChangeSet, createHeaders(def, COVERAGE, 1));
@@ -370,7 +379,8 @@ public class DriftDetectorTest extends DriftTest {
File server1Conf = createRandomFile(confDir, "server-1.conf");
ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(resourceId(),
createHeaders(def, COVERAGE));
- writer.write(addedFileEntry("conf/server-1.conf",
sha256(server1Conf)));
+ writer.write(addedFileEntry("conf/server-1.conf", sha256(server1Conf),
server1Conf.lastModified(),
+ server1Conf.length()));
writer.close();
// create some drift
@@ -381,7 +391,8 @@ public class DriftDetectorTest extends DriftTest {
detector.run();
File driftChangeSet = changeSet(def.getName(), DRIFT);
- List<FileEntry> driftEntries =
asList(addedFileEntry("conf/subconf/server-2.conf", sha256(server2Conf)));
+ List<FileEntry> driftEntries =
asList(addedFileEntry("conf/subconf/server-2.conf", sha256(server2Conf),
+ server2Conf.lastModified(), server2Conf.length()));
// verify that the drift change set was generated
assertTrue(driftChangeSet.exists(), "Expected to find drift change set
" + driftChangeSet.getPath());
@@ -389,8 +400,9 @@ public class DriftDetectorTest extends DriftTest {
assertFileEntriesMatch("The drift change set does not match the expected
values", driftEntries, driftChangeSet);
File coverageChangeSet = changeSet(def.getName(), COVERAGE);
- List<FileEntry> coverageEntries =
asList(addedFileEntry("conf/server-1.conf", sha256(server1Conf)),
- addedFileEntry("conf/subconf/server-2.conf",
sha256(server2Conf)));
+ List<FileEntry> coverageEntries = asList(
+ addedFileEntry("conf/server-1.conf", sha256(server1Conf),
server1Conf.lastModified(), server1Conf.length()),
+ addedFileEntry("conf/subconf/server-2.conf", sha256(server2Conf),
server2Conf.lastModified(), server2Conf.length()));
// verify that the coverage change set was updated
assertHeaderEquals(coverageChangeSet, createHeaders(def, COVERAGE, 1));
@@ -410,8 +422,10 @@ public class DriftDetectorTest extends DriftTest {
String server2ConfHash = sha256(server2Conf);
ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(resourceId(),
createHeaders(def, COVERAGE));
- writer.write(addedFileEntry("conf/server-1.conf",
sha256(server1Conf)));
- writer.write(addedFileEntry("conf/server-2.conf", server2ConfHash));
+ writer.write(addedFileEntry("conf/server-1.conf", sha256(server1Conf),
server1Conf.lastModified(),
+ server1Conf.length()));
+ writer.write(addedFileEntry("conf/server-2.conf", server2ConfHash,
server2Conf.lastModified(),
+ server2Conf.length()));
writer.close();
// create some drift
@@ -430,7 +444,8 @@ public class DriftDetectorTest extends DriftTest {
// verify that the coverage change set was updated
File coverageChangeSet = changeSet(def.getName(), COVERAGE);
- List<FileEntry> coverageEntries =
asList(addedFileEntry("conf/server-1.conf", sha256(server1Conf)));
+ List<FileEntry> coverageEntries =
asList(addedFileEntry("conf/server-1.conf", sha256(server1Conf),
+ server1Conf.lastModified(), server1Conf.length()));
assertHeaderEquals(coverageChangeSet, createHeaders(def, COVERAGE, 1));
assertFileEntriesMatch("The coverage change set was not updated as
expected", coverageEntries,
@@ -488,7 +503,7 @@ public class DriftDetectorTest extends DriftTest {
String server1Hash = sha256(server1Conf);
ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(resourceId(),
createHeaders(def, COVERAGE));
- writer.write(addedFileEntry("conf/server-1.conf", server1Hash));
+ writer.write(addedFileEntry("conf/server-1.conf", server1Hash,
server1Conf.lastModified(), server1Conf.length()));
writer.close();
// create some drift
@@ -599,7 +614,8 @@ public class DriftDetectorTest extends DriftTest {
detector.run();
File changeSet = changeSet(def.getName(), COVERAGE);
- List<FileEntry> entries =
asList(addedFileEntry("conf/server-1.conf", sha256(server1Conf)));
+ List<FileEntry> entries =
asList(addedFileEntry("conf/server-1.conf", sha256(server1Conf),
+ server1Conf.lastModified(), server1Conf.length()));
assertHeaderEquals(changeSet, createHeaders(def, COVERAGE));
assertFileEntriesMatch("Files that are non-readable should be skipped but
other, readable file should still "
@@ -620,7 +636,7 @@ public class DriftDetectorTest extends DriftTest {
// create some drift that includes a new file that is not readable
server1Conf.delete();
- server1Conf = createRandomFile(confDir, "server-1.conf");
+ server1Conf = createRandomFile(confDir, "server-1.conf", 48);
String newServer1Hash = sha256(server1Conf);
File server2Conf = createRandomFile(confDir, "server-2.conf");
@@ -630,7 +646,8 @@ public class DriftDetectorTest extends DriftTest {
detector.run();
File driftChangeSet = changeSet(def.getName(), DRIFT);
- List<FileEntry> driftEntries =
asList(changedFileEntry("conf/server-1.conf", oldServer1Hash, newServer1Hash));
+ List<FileEntry> driftEntries =
asList(changedFileEntry("conf/server-1.conf", oldServer1Hash, newServer1Hash,
+ server1Conf.lastModified(), server1Conf.length()));
// verify that the drift change set was generated
assertTrue(driftChangeSet.exists(), "Expected to find drift change set
" + driftChangeSet.getPath());
@@ -639,7 +656,8 @@ public class DriftDetectorTest extends DriftTest {
// verify that the coverage change set was updated
File coverageChangeSet = changeSet(def.getName(), COVERAGE);
- List<FileEntry> coverageEntries =
asList(changedFileEntry("conf/server-1.conf", oldServer1Hash, newServer1Hash));
+ List<FileEntry> coverageEntries =
asList(changedFileEntry("conf/server-1.conf", oldServer1Hash, newServer1Hash,
+ server1Conf.lastModified(), server1Conf.length()));
assertHeaderEquals(coverageChangeSet, createHeaders(def, COVERAGE, 1));
assertFileEntriesMatch("The coverage change set was not updated as
expected", coverageEntries,
@@ -712,8 +730,8 @@ public class DriftDetectorTest extends DriftTest {
// We always generate/update the current snapshot so we still need to verify that
it
// was generated/updated correctly
List<FileEntry> fileEntries = asList(
- addedFileEntry("conf/server1.conf", sha256(server1Conf)),
- addedFileEntry("conf/server2.conf", sha256(server2Conf)));
+ addedFileEntry("conf/server1.conf", sha256(server1Conf),
server1Conf.lastModified(), server1Conf.length()),
+ addedFileEntry("conf/server2.conf", sha256(server2Conf),
server2Conf.lastModified(), server2Conf.length()));
assertHeaderEquals(currentSnapshot, createHeaders(driftDef, COVERAGE, 1));
assertFileEntriesMatch("The current snapshot file should still get updated
even when using a pinned snapshot",
@@ -748,9 +766,9 @@ public class DriftDetectorTest extends DriftTest {
// verify that the current snapshot was updated
List<FileEntry> currentSnapshotEntries = asList(
- addedFileEntry("conf/server1.conf", sha256(server1Conf)),
- addedFileEntry("conf/server2.conf", sha256(server2Conf)),
- addedFileEntry("conf/server3.conf", sha256(server3Conf)));
+ addedFileEntry("conf/server1.conf", sha256(server1Conf),
server1Conf.lastModified(), server1Conf.length()),
+ addedFileEntry("conf/server2.conf", sha256(server2Conf),
server2Conf.lastModified(), server2Conf.length()),
+ addedFileEntry("conf/server3.conf", sha256(server3Conf),
server3Conf.lastModified(), server3Conf.length()));
assertHeaderEquals(currentSnapshot, createHeaders(driftDef, COVERAGE, 2));
assertFileEntriesMatch("The current snapshot file should still get updated
even when using a pinned snapshot",
@@ -759,8 +777,8 @@ public class DriftDetectorTest extends DriftTest {
// verify that the the drift/delta change set was generated
File driftChangeSet = changeSet(driftDef.getName(), DRIFT);
List<FileEntry> driftEntries = asList(
- addedFileEntry("conf/server2.conf", sha256(server2Conf)),
- addedFileEntry("conf/server3.conf", sha256(server3Conf)));
+ addedFileEntry("conf/server2.conf", sha256(server2Conf),
server2Conf.lastModified(), server2Conf.length()),
+ addedFileEntry("conf/server3.conf", sha256(server3Conf),
server3Conf.lastModified(), server3Conf.length()));
assertHeaderEquals(driftChangeSet, createHeaders(driftDef, DRIFT, 2));
assertFileEntriesMatch("The drift change set was not generated correctly
when using a pinned snapshot",
@@ -781,7 +799,8 @@ public class DriftDetectorTest extends DriftTest {
File changeSet = changeSet(driftDef.getName(), COVERAGE);
File pinnedSnapshot = new File(changeSet.getParentFile(),
"snapshot.pinned");
- List<FileEntry> entries =
asList(addedFileEntry("conf/server.conf", sha256(serverConf)));
+ List<FileEntry> entries =
asList(addedFileEntry("conf/server.conf", sha256(serverConf),
+ serverConf.lastModified(), serverConf.length()));
assertTrue(changeSet.exists(), "An initial snapshot file should be generated
even when it is pinned");
assertHeaderEquals(changeSet, createHeaders(driftDef, COVERAGE));
@@ -878,7 +897,7 @@ public class DriftDetectorTest extends DriftTest {
// generate the pinned snapshot which is version zero
File pinnedSnapshot = pinnedSnapshot(driftDef.getName());
ChangeSetWriter writer = new ChangeSetWriterImpl(pinnedSnapshot, headers);
- writer.write(addedFileEntry("conf/server.conf", serverConfHash));
+ writer.write(addedFileEntry("conf/server.conf", serverConfHash,
serverConf.lastModified(), serverConf.length()));
writer.close();
// generate the current snapshot file. we will take a shortcut here by
@@ -910,7 +929,8 @@ public class DriftDetectorTest extends DriftTest {
// verify that that current snapshot has been updated to reflect that
// the resource is back in compliance.
- List<FileEntry> entries =
asList(addedFileEntry("conf/server.conf", serverConfHash));
+ List<FileEntry> entries =
asList(addedFileEntry("conf/server.conf", serverConfHash,
+ serverConf.lastModified(), serverConf.length()));
assertHeaderEquals(currentSnapshot, createHeaders(driftDef, COVERAGE, 2));
assertFileEntriesMatch("The entries in the current snapshot should match
those in the pinned snapshot " +
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftFilesSenderTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftFilesSenderTest.java
index 5fd6528..b102300 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftFilesSenderTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftFilesSenderTest.java
@@ -19,6 +19,11 @@
package org.rhq.core.pc.drift;
+import static org.rhq.common.drift.FileEntry.addedFileEntry;
+import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@@ -32,11 +37,6 @@ import org.rhq.core.domain.drift.DriftChangeSetCategory;
import org.rhq.core.domain.drift.DriftFile;
import org.rhq.core.domain.drift.JPADriftFile;
-import static org.rhq.common.drift.FileEntry.addedFileEntry;
-import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
public class DriftFilesSenderTest extends DriftTest {
DriftClient driftClient;
@@ -69,8 +69,10 @@ public class DriftFilesSenderTest extends DriftTest {
Headers headers = createHeaders(driftDefName, COVERAGE);
ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(resourceId(), headers);
- writer.write(addedFileEntry("conf/server-1.conf", server1ConfHash));
- writer.write(addedFileEntry("conf/server-2.conf", server2ConfHash));
+ writer.write(addedFileEntry("conf/server-1.conf", server1ConfHash,
server1Conf.lastModified(),
+ server1Conf.length()));
+ writer.write(addedFileEntry("conf/server-2.conf", server2ConfHash,
server2Conf.lastModified(),
+ server2Conf.length()));
writer.close();
sender.setDriftFiles(driftFiles(server1ConfHash, server2ConfHash));
@@ -105,10 +107,14 @@ public class DriftFilesSenderTest extends DriftTest {
Headers headers = createHeaders(driftDefName, COVERAGE);
ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(resourceId(), headers);
- writer.write(addedFileEntry("conf/server-1.conf", server1ConfHash));
- writer.write(addedFileEntry("conf/server-2.conf", server2ConfHash));
- writer.write(addedFileEntry("lib/server-1.jar", server1JarHash));
- writer.write(addedFileEntry("lib/server-2.jar", server2JarHash));
+ writer.write(addedFileEntry("conf/server-1.conf", server1ConfHash,
server1Conf.lastModified(),
+ server1Conf.length()));
+ writer.write(addedFileEntry("conf/server-2.conf", server2ConfHash,
server2Conf.lastModified(),
+ server2Conf.length()));
+ writer.write(addedFileEntry("lib/server-1.jar", server1JarHash,
server1Jar.lastModified(),
+ server1Jar.length()));
+ writer.write(addedFileEntry("lib/server-2.jar", server2JarHash,
server2Jar.lastModified(),
+ server2Jar.length()));
writer.close();
// Note that the order of the drift files is random. When the server sends a
request
@@ -142,8 +148,10 @@ public class DriftFilesSenderTest extends DriftTest {
Headers headers = createHeaders(driftDefName, COVERAGE);
ChangeSetWriter writer = changeSetMgr.getChangeSetWriter(resourceId(), headers);
- writer.write(addedFileEntry("conf/server-1.conf", server1ConfHash));
- writer.write(addedFileEntry("conf/server-2.conf", server2ConfHash));
+ writer.write(addedFileEntry("conf/server-1.conf", server1ConfHash,
server1Conf.lastModified(),
+ server1Conf.length()));
+ writer.write(addedFileEntry("conf/server-2.conf", server2ConfHash,
server2Conf.lastModified(),
+ server2Conf.length()));
writer.close();
// It is possible that the server can request a file that has been deleted since
it
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftTest.java
index 41b725b..2f238f8 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftTest.java
@@ -229,9 +229,13 @@ public class DriftTest {
}
protected File createRandomFile(File dir, String fileName) throws Exception {
+ return createRandomFile(dir, fileName, 32);
+ }
+
+ protected File createRandomFile(File dir, String fileName, int numBytes) throws
Exception {
File file = new File(dir, fileName);
FileOutputStream stream = new FileOutputStream(file);
- byte[] bytes = new byte[32];
+ byte[] bytes = new byte[numBytes];
random.nextBytes(bytes);
write(bytes, stream);
stream.close();
diff --git
a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/DriftManagerBeanTest.java
b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/DriftManagerBeanTest.java
index 5dabd97..f7152a9 100644
---
a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/DriftManagerBeanTest.java
+++
b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/DriftManagerBeanTest.java
@@ -158,7 +158,7 @@ public class DriftManagerBeanTest extends AbstractEJB3Test {
File changeSet1 = new File(changeSetsDir, "changeset-1.txt");
ChangeSetWriter writer = new ChangeSetWriterImpl(changeSet1, headers);
- writer.write(addedFileEntry("test/file-1", file1Hash));
+ writer.write(addedFileEntry("test/file-1", file1Hash, 56789L, 1024L));
writer.close();
File changeSet1Zip = new File(changeSetsDir, "changeset-1.zip");
@@ -188,7 +188,7 @@ public class DriftManagerBeanTest extends AbstractEJB3Test {
File changeSet2 = new File(changeSetsDir, "changeset-2.txt");
writer = new ChangeSetWriterImpl(changeSet2, headers);
- writer.write(changedFileEntry("test/file-1", file1Hash,
modifiedFile1Hash));
+ writer.write(changedFileEntry("test/file-1", file1Hash,
modifiedFile1Hash, 56789L, 1024L));
writer.close();
File changeSet2Zip = new File(changeSetsDir, "changeset-2.zip");