modules/core/domain/src/main/java/org/rhq/core/domain/measurement/DataType.java | 49 +++---
modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementDefinition.java | 15 +
modules/core/domain/src/main/java/org/rhq/core/domain/measurement/ResourceMeasurementScheduleRequest.java | 68 +++++---
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java | 78 +++++++---
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AvailabilityExecutor.java | 16 +-
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java | 3
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/MeasurementMetadataManagerBean.java | 51 ++++++
7 files changed, 193 insertions(+), 87 deletions(-)
New commits:
commit e226ffec4f5a465680c049170c2d31631ee5ca6e
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Feb 14 17:13:09 2012 -0500
[Bug 789454 - Drift detection fails for whole directory if special-file is present]
Fix an issue in the original commit for this bug.
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 c8845fe..e381593 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
@@ -378,7 +378,7 @@ public class DriftDetector implements Runnable {
long lastModified = file.lastModified();
long length = file.length();
- result = addedFileEntry(relativePath(basedir, file), sha256(file), file.lastModified(), file.length());
+ result = addedFileEntry(relativePath, sha256, lastModified, length);
} catch (FileNotFoundException e) {
if (log.isDebugEnabled()) {
commit bab4e5417bb6c98ca9f044762bde1e8c0264c4e4
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Feb 14 16:23:08 2012 -0500
Part 1 of Prioritized Avail Checking
Add a new "Availability Type" metric definition for all non-platform
resources. The metric definition is implicit in that it will be added
to the type if the type itself does not define it in the plugin
descriptor. It's collection interval is the defined avail scan period
for the resource. Since it's a metric it can be configured at
template/group/resource granularity. The defauly collection interval is
1 minute for servers and 5 minutes for services. Explicit definition on
the type can set it to any value, or disable it, which will defer to the
parent's avail type.
Part 2 (TBD): A new avail checking strategy on the agent, to handle the
variable collection intervals.
Part 3 (TBD): A review and addition of explicit settings for our most
important plugin types.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/DataType.java b/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/DataType.java
index 267d040..a6a179c 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/DataType.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/DataType.java
@@ -1,25 +1,25 @@
- /*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License and the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
package org.rhq.core.domain.measurement;
/**
@@ -27,11 +27,12 @@ package org.rhq.core.domain.measurement;
* normally changes over time (see {@link NumericType} for further classification of this kind of data). A "trait" is
* typically a value that changes rarely (e.g. number of CPUs on a platform, or an install path). "Complex" data is
* tabular in nature with N columns of N rows of values. Call-time data is the min/max/avg call durations for each
- * destination (e.g. URL or session EJB method) in a set of destinations.
+ * destination (e.g. URL or session EJB method) in a set of destinations. Availability is used only for the
+ * built-in AvailabilityScanPeriod measurement.
*
* @author John Mazzitelli
* @see NumericType
*/
public enum DataType {
- MEASUREMENT, TRAIT, COMPLEX, CALLTIME
+ MEASUREMENT, TRAIT, COMPLEX, CALLTIME, AVAILABILITY
}
\ No newline at end of file
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementDefinition.java b/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementDefinition.java
index e3f5600..cb00371 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementDefinition.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementDefinition.java
@@ -55,7 +55,7 @@ import org.rhq.core.domain.resource.ResourceType;
//@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@Entity
-@NamedQueries( {
+@NamedQueries({
@NamedQuery(name = MeasurementDefinition.FIND_BY_RESOURCE_TYPE_DATA_TYPE_DISPLAY_TYPE, query = "" //
+ " SELECT md " //
+ " FROM MeasurementDefinition md " //
@@ -76,11 +76,10 @@ import org.rhq.core.domain.resource.ResourceType;
+ " SET md.defaultOn = false"),
@NamedQuery(name = MeasurementDefinition.FIND_RAW_OR_PER_MINUTE_BY_NAME_AND_RESOURCE_TYPE_NAME, query = "" //
+ " SELECT md FROM MeasurementDefinition md"
- + " WHERE md.name = :name "
+ + " WHERE md.name = :name "
+ " AND md.resourceType.name = :resourceTypeName"
- + " AND md.resourceType.plugin = :resourceTypePlugin"
- + " AND ((:perMinute = 1 AND md.rawNumericType IS NOT NULL) OR (:perMinute = 0 AND md.rawNumericType IS NULL))")
-})
+ + " AND md.resourceType.plugin = :resourceTypePlugin"
+ + " AND ((:perMinute = 1 AND md.rawNumericType IS NOT NULL) OR (:perMinute = 0 AND md.rawNumericType IS NULL))") })
@SequenceGenerator(name = "id", sequenceName = "RHQ_MEASUREMENT_DEF_ID_SEQ")
@Table(name = "RHQ_MEASUREMENT_DEF")
@XmlAccessorType(XmlAccessType.FIELD)
@@ -111,7 +110,9 @@ public class MeasurementDefinition implements Serializable {
public static final String FIND_BY_IDS = "MeasurementDefinition.findByIds";
public static final String DISABLE_ALL = "MeasurementDefinition.disableAll";
public static final String FIND_RAW_OR_PER_MINUTE_BY_NAME_AND_RESOURCE_TYPE_NAME = "MeasurementDefinition.findRawOrPerMinuteByNameAndResourceTypeName";
-
+
+ public static final String AVAILABILITY_TYPE_NAME = "_AvailabilityType_";
+
@Column(name = "ID", nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO, generator = "id")
@Id
@@ -211,7 +212,7 @@ public class MeasurementDefinition implements Serializable {
/**
* Version for optimistic locking. Don't ever set this yourself
*/
- @SuppressWarnings( { "unused" })
+ @SuppressWarnings({ "unused" })
@Version
private int version;
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/ResourceMeasurementScheduleRequest.java b/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/ResourceMeasurementScheduleRequest.java
index 19da7fe..d88df3a 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/ResourceMeasurementScheduleRequest.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/ResourceMeasurementScheduleRequest.java
@@ -1,25 +1,25 @@
- /*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License and the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
package org.rhq.core.domain.measurement;
import java.io.Serializable;
@@ -37,6 +37,11 @@ public class ResourceMeasurementScheduleRequest implements Serializable {
private Set<MeasurementScheduleRequest> measurementSchedules = new HashSet<MeasurementScheduleRequest>();
private final int resourceId;
+ // The avail schedule is stripped out on set and must be explicitly requested. This allows the avail
+ // schedule to piggyback on all other standard schedule sync/updates while protecting all standard
+ // handling of measurement schedules.
+ private MeasurementScheduleRequest availabilitySchedule;
+
/**
* Creates a {@link ResourceMeasurementScheduleRequest} object that will contain measurement schedules for the given
* resource.
@@ -48,15 +53,30 @@ public class ResourceMeasurementScheduleRequest implements Serializable {
}
public void addMeasurementScheduleRequest(MeasurementScheduleRequest scheduleRequest) {
- this.measurementSchedules.add(scheduleRequest);
+ if (MeasurementDefinition.AVAILABILITY_TYPE_NAME.equals(scheduleRequest.getName())) {
+ this.availabilitySchedule = scheduleRequest;
+ } else {
+ this.measurementSchedules.add(scheduleRequest);
+ }
}
public Set<MeasurementScheduleRequest> getMeasurementSchedules() {
return measurementSchedules;
}
+ public MeasurementScheduleRequest getAvailabilitySchedule() {
+ return availabilitySchedule;
+ }
+
public void setMeasurementSchedules(Set<MeasurementScheduleRequest> measurementSchedules) {
- this.measurementSchedules = measurementSchedules;
+ this.measurementSchedules = new HashSet<MeasurementScheduleRequest>(measurementSchedules.size());
+ for (MeasurementScheduleRequest scheduleRequest : measurementSchedules) {
+ if (MeasurementDefinition.AVAILABILITY_TYPE_NAME.equals(scheduleRequest.getName())) {
+ this.availabilitySchedule = scheduleRequest;
+ } else {
+ this.measurementSchedules.add(scheduleRequest);
+ }
+ }
}
public int getResourceId() {
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index c39f6f2..e2203b3 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -1863,7 +1863,8 @@ public class InventoryManager extends AgentService implements ContainerService,
if ((container != null) && (container.getResourceComponentState() == ResourceComponentState.STARTED)) {
// Copy child Resources to an array and iterate that, rather than iterating the Set, which could cause
// a ConcurrentModificationException if another thread tries to modify the Set while we're iterating it.
- Resource[] childResources = resource.getChildResources().toArray(new Resource[resource.getChildResources().size()]);
+ Resource[] childResources = resource.getChildResources().toArray(
+ new Resource[resource.getChildResources().size()]);
for (Resource child : childResources) {
deactivateResource(child);
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/MeasurementMetadataManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/MeasurementMetadataManagerBean.java
index 9a38f29..011a670 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/MeasurementMetadataManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/MeasurementMetadataManagerBean.java
@@ -1,6 +1,7 @@
package org.rhq.enterprise.server.resource.metadata;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -16,6 +17,8 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.criteria.MeasurementDefinitionCriteria;
+import org.rhq.core.domain.measurement.DataType;
+import org.rhq.core.domain.measurement.MeasurementCategory;
import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.measurement.MeasurementSchedule;
import org.rhq.core.domain.resource.ResourceType;
@@ -29,6 +32,9 @@ public class MeasurementMetadataManagerBean implements MeasurementMetadataManage
private final Log log = LogFactory.getLog(MeasurementMetadataManagerBean.class);
+ private static final Long AVAILABILITY_DEFAULT_PERIOD_SERVER = 60L * 1000; // 1 minute in ms
+ private static final Long AVAILABILITY_DEFAULT_PERIOD_SERVICE = 60L * 1000 * 5; // 5 minutes in ms
+
@PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME)
private EntityManager entityMgr;
@@ -48,6 +54,10 @@ public class MeasurementMetadataManagerBean implements MeasurementMetadataManage
existingType = entityMgr.find(ResourceType.class, existingType.getId());
Set<MeasurementDefinition> existingDefinitions = existingType.getMetricDefinitions();
+
+ // if necessary insert the mandatory AvailabilityScanPeriod metric
+ Set<MeasurementDefinition> newTypeMetricDefinitions = getMetricDefinitions(newType);
+
if (existingDefinitions.isEmpty()) {
if (log.isDebugEnabled()) {
log.debug(existingType + " currently does not define any metric definitions.");
@@ -58,7 +68,7 @@ public class MeasurementMetadataManagerBean implements MeasurementMetadataManage
if (newDefinition.getDefaultInterval() < MeasurementSchedule.MINIMUM_INTERVAL) {
newDefinition.setDefaultInterval(MeasurementSchedule.MINIMUM_INTERVAL);
log.info("Definition [" + newDefinition
- + "] has too short of a default interval, setting to minimum");
+ + "] has too short of a default interval, setting to minimum");
}
existingType.addMetricDefinition(newDefinition);
entityMgr.persist(newDefinition);
@@ -72,7 +82,7 @@ public class MeasurementMetadataManagerBean implements MeasurementMetadataManage
boolean found = false;
for (MeasurementDefinition existingDefinition : existingDefinitions) {
if (existingDefinition.getName().equals(newDefinition.getName())
- && (existingDefinition.isPerMinute() == newDefinition.isPerMinute())) {
+ && (existingDefinition.isPerMinute() == newDefinition.isPerMinute())) {
found = true;
if (log.isDebugEnabled()) {
@@ -86,7 +96,7 @@ public class MeasurementMetadataManagerBean implements MeasurementMetadataManage
if (existingDefinition.getDefaultInterval() < MeasurementSchedule.MINIMUM_INTERVAL) {
existingDefinition.setDefaultInterval(MeasurementSchedule.MINIMUM_INTERVAL);
log.info("Definition [" + existingDefinition
- + "] has too short of a default interval, setting to minimum");
+ + "] has too short of a default interval, setting to minimum");
}
entityMgr.merge(existingDefinition);
@@ -128,7 +138,7 @@ public class MeasurementMetadataManagerBean implements MeasurementMetadataManage
}
if (!definitionsToDelete.isEmpty() && log.isDebugEnabled()) {
log.debug("Metadata update: Measurement definitions deleted from resource type ["
- + existingType.getName() + "]:" + definitionsToDelete);
+ + existingType.getName() + "]:" + definitionsToDelete);
}
entityMgr.flush();
@@ -137,6 +147,39 @@ public class MeasurementMetadataManagerBean implements MeasurementMetadataManage
// not needed see JBNADM-1639
}
+ private Set<MeasurementDefinition> getMetricDefinitions(ResourceType newType) {
+ Set<MeasurementDefinition> result = newType.getMetricDefinitions();
+ result = (null == result) ? new HashSet<MeasurementDefinition>(1) : result;
+ long period;
+
+ switch (newType.getCategory()) {
+ case PLATFORM:
+ return result;
+ case SERVER:
+ period = AVAILABILITY_DEFAULT_PERIOD_SERVER;
+ break;
+ default:
+ period = AVAILABILITY_DEFAULT_PERIOD_SERVICE;
+ }
+
+ MeasurementDefinition availabilityScanPeriod = new MeasurementDefinition(newType,
+ MeasurementDefinition.AVAILABILITY_TYPE_NAME);
+ // TODO I18N for this?
+ availabilityScanPeriod.setDisplayName("Availability Type");
+ availabilityScanPeriod.setCategory(MeasurementCategory.AVAILABILITY);
+ availabilityScanPeriod
+ .setDescription("The number of seconds between availability checks. The agent honors this setting as best as possible but the actual period can be longer based on agent activity.");
+ availabilityScanPeriod.setDefaultInterval(period);
+ availabilityScanPeriod.setDataType(DataType.AVAILABILITY);
+ availabilityScanPeriod.setDefaultOn(true);
+
+ if (!result.contains(availabilityScanPeriod)) {
+ result.add(availabilityScanPeriod);
+ }
+
+ return result;
+ }
+
@Override
public void deleteMetadata(ResourceType existingType) {
log.debug("Deleting metric definitions for " + existingType);
commit e78d58329d468473676c22564d814f35cd28bfa6
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Feb 14 16:01:40 2012 -0500
[Bug 789454 - Drift detection fails for whole directory if special-file is present]
File.canRead() returning true means that the process has read access to
a file, it is a security check. It does not mean that the file can be
parsed as a Stream. In particular, FileInputStream(File) can throw
FileNotFoundException on a file it can't actually handle, like a
socket file.
I added more protection for this situation, for files which drift monitoring
can not and should not be performed. They will be skipped (and logged in
debug). Moreover, taking Heiko's suggestion, don't fail drift detection
dur to a problematic file, even if the problem is unexpected.
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 76d7afb..c8845fe 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
@@ -27,6 +27,7 @@ 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.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Collection;
@@ -282,15 +283,17 @@ 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());
-
- addedEntries.add(newEntry);
+ FileEntry addedFileEntry = getAddedFileEntry(basedir, file);
+ if (null != addedFileEntry) {
+ addedEntries.add(addedFileEntry);
+ }
- } 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 (Throwable t) {
+ // report the error but keep going, perhaps it is specific to a single file, try to
+ // finish the change set generation.
+ log.error(
+ "An unexpected error occurred while generating a drift change set for file " + file.getPath()
+ + " in schedule " + schedule + ". Skipping file.", t);
}
}
@@ -353,6 +356,39 @@ public class DriftDetector implements Runnable {
}
}
+ /**
+ * File.canRead() is basically a security check and does not guarantee that the file contents can truly be read.
+ * Certain files, like socket files on linux, can not be processed and it's not known until actually trying to
+ * construct a FileInputStream, as is done when we actually try to generate the digest. These files will generate
+ * a FileNotFoundException. This method will catch, log and suppress that issue, and return null
+ * indicating the file is not suitable for drift detection.
+ *
+ * @param basedir the drift def base directory
+ * @param file the new file to add
+ * @return the new FileEntry, or null if this file is not appropriate for drift detection (typically if the
+ * underlying file does not support the needed File operations.
+ * @throws Will throw unexpected IOExceptions, outside of the FileNotFoundException it looks for.
+ */
+ private FileEntry getAddedFileEntry(File basedir, File file) throws IOException {
+ FileEntry result = null;
+
+ try {
+ String sha256 = sha256(file);
+ String relativePath = relativePath(basedir, file);
+ long lastModified = file.lastModified();
+ long length = file.length();
+
+ result = addedFileEntry(relativePath(basedir, file), sha256(file), file.lastModified(), file.length());
+
+ } catch (FileNotFoundException e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Skipping " + file.getPath() + " since it is missing or is not a physically readable file.");
+ }
+ }
+
+ return result;
+ }
+
static private void safeClear(Collection<?>... collections) {
if (null == collections) {
return;
@@ -431,8 +467,8 @@ public class DriftDetector implements Runnable {
}
if (isChanged) {
- FileEntry changedEntry = changedFileEntry(entry.getFile(), entry.getNewSHA(), currentSHA, file
- .lastModified(), file.length());
+ FileEntry changedEntry = changedFileEntry(entry.getFile(), entry.getNewSHA(), currentSHA,
+ file.lastModified(), file.length());
changedEntries.add(changedEntry);
if (null != changedPinnedEntries) {
@@ -456,7 +492,6 @@ public class DriftDetector implements Runnable {
return result;
}
- @SuppressWarnings("unused")
private boolean isPreviousChangeSetEmpty(int resourceId, DriftDefinition definition) throws IOException {
File changeSet = changeSetMgr.findChangeSet(resourceId, definition.getName(), DRIFT);
if (!changeSet.exists()) {
@@ -652,20 +687,25 @@ public class DriftDetector implements Runnable {
try {
if (!file.canRead()) {
if (log.isDebugEnabled()) {
- log.debug("Skipping " + file.getPath() + " since it is not readable.");
+ log.debug("Skipping " + file.getPath() + " since we do not have read access.");
}
return;
}
+
if (log.isDebugEnabled()) {
log.debug("Adding " + file.getPath() + " to coverage change set for " + schedule);
}
- 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());
- throw new DriftDetectionException(
- "An error occurred while generating a coverage change set for " + schedule, e);
+
+ FileEntry addedFileEntry = getAddedFileEntry(basedir, file);
+ if (null != addedFileEntry) {
+ writer.write(addedFileEntry);
+ }
+
+ } catch (Throwable t) {
+ // report the error but keep going, perhaps it is specific to a single file, try to
+ // finish the detection.
+ log.error("An unexpected error occurred while generating a coverage change set for file "
+ + file.getPath() + " in schedule " + schedule + ". Skipping file.", t);
}
}
}));
commit 32552c01e0398435a593225c291e17ab7b3a260e
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 13 09:04:18 2012 -0500
When performing an avail scan propagate a non-UP parent avail to the
children. This was done before but assumed DOWN.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AvailabilityExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AvailabilityExecutor.java
index 48bc173..777e130 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AvailabilityExecutor.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AvailabilityExecutor.java
@@ -127,7 +127,7 @@ public class AvailabilityExecutor implements Runnable, Callable<AvailabilityRepo
long start = System.currentTimeMillis();
checkInventory(inventoryManager.getPlatform(), availabilityReport,
- availabilityReport.isChangesOnlyReport(), true, false);
+ availabilityReport.isChangesOnlyReport(), true, AvailabilityType.UP);
// If the report is empty (meaning, nothing has changed since the last availability check), don't
// send any report. In the past we needed to send a report as it doubled as an Agent heartbeat, but
@@ -153,7 +153,7 @@ public class AvailabilityExecutor implements Runnable, Callable<AvailabilityRepo
}
private void checkInventory(Resource resource, AvailabilityReport availabilityReport, boolean reportChangesOnly,
- boolean checkChildren, boolean parentIsDown) {
+ boolean checkChildren, AvailabilityType parentAvailType) {
// Only report avail for committed Resources - that's all the Server cares about.
if (resource.getId() == 0 || resource.getInventoryStatus() != InventoryStatus.COMMITTED) {
return;
@@ -181,11 +181,11 @@ public class AvailabilityExecutor implements Runnable, Callable<AvailabilityRepo
Availability previous = (reportChangesOnly) ? this.inventoryManager.getAvailabilityIfKnown(resource) : null;
AvailabilityType current;
- if (parentIsDown) {
- // If the resource's parent is down, the rules are that the resource and all of the parent's other
- // descendants, must also be down, so there's no need to even ask the resource component for its
- // current availability - its current avail is DOWN and that's that.
- current = AvailabilityType.DOWN;
+ if (AvailabilityType.UP != parentAvailType) {
+ // If the resource's parent is not up, the rules are that the resource and all of the parent's other
+ // descendants, must also be of the parent avail type, so there's no need to even ask the resource component
+ // for its current availability - its current avail is set to the parent avail type and that's that.
+ current = parentAvailType;
} else {
current = null;
try {
@@ -233,7 +233,7 @@ public class AvailabilityExecutor implements Runnable, Callable<AvailabilityRepo
// Wrap in a fresh HashSet to avoid ConcurrentModificationExceptions.
Set<Resource> children = new HashSet<Resource>(resource.getChildResources());
for (Resource child : children) {
- checkInventory(child, availabilityReport, reportChangesOnly, true, current == AvailabilityType.DOWN);
+ checkInventory(child, availabilityReport, reportChangesOnly, true, current);
}
}