modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AvailabilityExecutor.java
| 170 ++++------
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/ResourceContainer.java
| 2
2 files changed, 81 insertions(+), 91 deletions(-)
New commits:
commit 551ec3b94fd778e1756d827b2aa2ae1530433c44
Merge: ac089af... 94090ca...
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Wed Jul 28 13:58:42 2010 -0400
Merge branch 'release-3.0.0' of
ssh://git.fedorahosted.org/git/rhq/rhq into
release-3.0.0
commit ac089af2c4b4471876e4b84b9d45169cf7cb9cce
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Wed Jul 28 13:56:56 2010 -0400
Revert "fix so that when the Server moves a Resource to a new parent as a result
of that Resource's type's parent type changing, that Resource also gets moved to
the new parent in the plugin container's local inventory the next time the PC
InventoryManager performs an inventory sync (fix for second half of
https://bugzilla.redhat.com/show_bug.cgi?id=618879)"
This reverts commit e60acb24efe12dc9aac8e0b5f708c551c17a6768.
This fix is attached to
https://bugzilla.redhat.com/show_bug.cgi?id=618879 as a patch,
which we'll most likely apply after JON 2.4 has been released.
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 6e9a503..0c86f8f 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
@@ -237,7 +237,6 @@ public class InventoryManager extends AgentService implements
ContainerService,
inventoryThreadPoolExecutor.scheduleWithFixedDelay(serviceScanExecutor,
configuration
.getServiceDiscoveryInitialDelay(),
configuration.getServiceDiscoveryPeriod(), TimeUnit.SECONDS);
}
-
} finally {
inventoryLock.writeLock().unlock();
}
@@ -2258,41 +2257,22 @@ public class InventoryManager extends AgentService implements
ContainerService,
if (log.isDebugEnabled()) {
log.debug("Merging [" + resource + "] into local
inventory...");
}
- Resource passedResource = resource; // Keep a reference to the passed Resource
for debugging purposes.
-
- ResourceContainer existingResourceContainer = getResourceContainer(resource);
- if (existingResourceContainer == null) {
- existingResourceContainer = getResourceContainer(resource.getId());
- }
- Resource existingResourceViaContainer = (existingResourceContainer != null) ?
- existingResourceContainer.getResource() : null;
- Resource existingParent = (existingResourceViaContainer != null) ?
- existingResourceViaContainer.getParentResource() : null;
-
- Resource newParent;
+ Resource passedResource = resource; // always keep a reference to the passed
resource
+ Resource parentResource;
if (resource.getParentResource() != null) {
ResourceContainer parentResourceContainer =
getResourceContainer(resource.getParentResource());
if (parentResourceContainer == null) {
parentResourceContainer =
getResourceContainer(resource.getParentResource().getId());
}
- if (parentResourceContainer != null) {
- newParent = parentResourceContainer.getResource();
- } else {
- newParent = null; // TODO right thing to do? Or directly return?
- }
+ if (parentResourceContainer != null)
+ parentResource = parentResourceContainer.getResource();
+ else
+ parentResource = null; // TODO right thing to do? Or directly return?
} else {
- newParent = null;
+ parentResource = null;
}
-
- if (newParent != null && existingParent != null &&
- !matches(newParent, existingParent)) {
- // The Server must have moved the Resource to a new parent - remove it from
its old parent in our
- // local inventory. We'll add
- existingParent.removeChildResource(existingResourceViaContainer);
- }
-
- Resource existingResourceViaParent = findMatchingChildResource(resource,
newParent);
- if (newParent == null && existingResourceViaParent == null) {
+ Resource existingResource = findMatchingChildResource(resource, parentResource);
+ if (parentResource == null && existingResource == null) {
// This should never happen, but add a check so we'll know if it ever
does.
log.error("Existing platform [" + this.platform + "] has
different Resource type and/or Resource key than "
+ "platform in Server inventory: " + resource);
@@ -2301,31 +2281,31 @@ public class InventoryManager extends AgentService implements
ContainerService,
boolean pluginConfigUpdated = false;
this.inventoryLock.writeLock().lock();
try {
- if (existingResourceViaParent != null) {
+ if (existingResource != null) {
// First grab the existing Resource's container, so we can reuse it.
- resourceContainer =
this.resourceContainers.remove(existingResourceViaParent.getUuid());
+ resourceContainer =
this.resourceContainers.remove(existingResource.getUuid());
if (resourceContainer != null) {
this.resourceContainers.put(resource.getUuid(), resourceContainer);
}
- if (newParent != null) {
+ if (parentResource != null) {
// It's critical to remove the existing Resource from the
parent's child Set if the UUID has
// changed (i.e. altering the hashCode of an item in a Set == BAD),
so just always remove it.
- newParent.removeChildResource(existingResourceViaParent);
+ parentResource.removeChildResource(existingResource);
}
// Now merge the new Resource into the existing Resource...
- pluginConfigUpdated = mergeResource(resource,
existingResourceViaParent);
- resource = existingResourceViaParent;
+ pluginConfigUpdated = mergeResource(resource, existingResource);
+ resource = existingResource;
}
- if (newParent != null) {
- newParent.addChildResource(resource);
+ if (parentResource != null) {
+ parentResource.addChildResource(resource);
} else {
this.platform = resource;
}
// Replace the stripped-down ResourceType that came from the Server with the
full ResourceType - it's
// critical to do this before refreshing the state (i.e. calling start on the
ResourceComponent)
- // and critical to do this before initializing the container (since it's
needed for the classloader creation).
+ // and critical to do this before initializing the container (since its
needed for the classloader creation).
ResourceType fullResourceType =
this.pluginManager.getMetadataManager().getType(resource.getResourceType());
if (fullResourceType == null) {
log.error("Unable to merge Resource " + resource + " - its
type is unknown - perhaps the ["
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index 3d1ddd7..185562a 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -622,21 +622,14 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
// parent to that type.
if (validParentTypes.contains(resourceParentType)) {
- log.debug("Moving " + existingResource + " from old parent
" + existingResource.getParentResource()
- + " to new parent " + resource.getParentResource() +
"...");
if (existingResource.getParentResource() != null) {
existingResource.getParentResource().removeChildResource(existingResource);
}
if (resource.getParentResource() != null) {
parentResource = getExistingResource(resource.getParentResource());
parentResource.addChildResource(existingResource);
-
}
existingResource.setParentResource(resource.getParentResource());
-
- // IMPORTANT: Update the Resource's mtime, so the Agent will know to
update the Resource's parent during
- // its inventory sync.
- existingResource.setMtime(System.currentTimeMillis());
} else {
log.debug("Existing Resource " + existingResource + " has
invalid parent type ("
+ existingResourceParentType + ") and so does plugin-reported
Resource " + resource + " ("
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java
index a0b01ac..64e9afd 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java
@@ -843,16 +843,10 @@ public class ResourceMetadataManagerBean implements
ResourceMetadataManagerLocal
}
}
if (newParent != null) {
- log.debug("Moving " + resource + " from old parent "
+ resource.getParentResource() + " to new parent "
- + newParent + "...");
if (resource.getParentResource() != null) {
resource.getParentResource().removeChildResource(resource);
}
newParent.addChildResource(resource);
-
- // IMPORTANT: Update the Resource's mtime, so the Agent will know to
update the Resource's parent during
- // its inventory sync.
- resource.setMtime(System.currentTimeMillis());
} else {
log.debug("We were unable to move " + resource + " from
invalid parent " + resource.getParentResource()
+ " to a new valid parent with one of the following types:
" + newParentTypes);
commit 87316df996bb23032a68861f47639f90b5dda532
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Wed Jul 28 13:54:35 2010 -0400
a few cosmetic + javadoc changes
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 04e1fb3..b1e39f8 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
@@ -99,11 +99,12 @@ public class AvailabilityExecutor implements Runnable,
Callable<AvailabilityRepo
*
* <p>This will return <code>null</code> if there is no committed
inventory and thus no availability reports should
* be sent. This will rarely happen - only if this is a brand new agent whose
inventory hasn't been committed yet or
- * if the platform and all its children have been deleted (in which case the agent
should be uninstalled or the user
+ * if the platform and all its children have been deleted (in which case the agent
should be uninstalled, or the user
* will want to re-import the platform). In either case, it will be in rare, corner
cases that this will ever return
* null, and the condition that caused the null should eventually go away.</p>
*
- * @return the report containing all the availabilities that need to be sent to the
Server
+ * @return the report containing all the availabilities that need to be sent to the
Server, or <code>null</code> if
+ * there is no committed inventory and thus no availability reports should be
sent
*
* @throws Exception if failed to create and prepare the report
*/
@@ -153,16 +154,16 @@ public class AvailabilityExecutor implements Runnable,
Callable<AvailabilityRepo
}
private void checkInventory(Resource resource, AvailabilityReport availabilityReport,
boolean reportChangesOnly,
- boolean checkChildren, boolean parentIsDown) {
+ boolean checkChildren, boolean parentIsDown) {
// Only report avail for committed Resources - that's all the Server cares
about.
- if (resource.getInventoryStatus() != InventoryStatus.COMMITTED) {
+ if (resource.getId() == 0 || resource.getInventoryStatus() !=
InventoryStatus.COMMITTED) {
return;
}
ResourceContainer resourceContainer =
this.inventoryManager.getResourceContainer(resource);
// Only report avail for synchronized Resources, otherwise chances are the Server
will know nothing of the
// Resource.
- if (resourceContainer == null ||
- resourceContainer.getSynchronizationState() !=
ResourceContainer.SynchronizationState.SYNCHRONIZED) {
+ if (resourceContainer == null
+ || resourceContainer.getSynchronizationState() !=
ResourceContainer.SynchronizationState.SYNCHRONIZED) {
return;
}
AvailabilityFacet resourceComponent;
@@ -177,17 +178,17 @@ public class AvailabilityExecutor implements Runnable,
Callable<AvailabilityRepo
return;
}
- AvailabilityType current = null;
-
- // Find out what the avail was the last time we checked it.
- Availability previous = this.inventoryManager.getAvailabilityIfKnown(resource);
+ // If this is a changed-only report, find out what the avail was the last time we
checked it.
+ 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;
} else {
+ current = null;
try {
// if the component is started, ask what its current availability is as
of right now;
// if it's not started, then assume it's down, and the next time
we check,
commit e60acb24efe12dc9aac8e0b5f708c551c17a6768
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Wed Jul 28 13:11:02 2010 -0400
fix so that when the Server moves a Resource to a new parent as a result of that
Resource's type's parent type changing, that Resource also gets moved to the new
parent in the plugin container's local inventory the next time the PC InventoryManager
performs an inventory sync (fix for second half of
https://bugzilla.redhat.com/show_bug.cgi?id=618879)
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 0c86f8f..6e9a503 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
@@ -237,6 +237,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
inventoryThreadPoolExecutor.scheduleWithFixedDelay(serviceScanExecutor,
configuration
.getServiceDiscoveryInitialDelay(),
configuration.getServiceDiscoveryPeriod(), TimeUnit.SECONDS);
}
+
} finally {
inventoryLock.writeLock().unlock();
}
@@ -2257,22 +2258,41 @@ public class InventoryManager extends AgentService implements
ContainerService,
if (log.isDebugEnabled()) {
log.debug("Merging [" + resource + "] into local
inventory...");
}
- Resource passedResource = resource; // always keep a reference to the passed
resource
- Resource parentResource;
+ Resource passedResource = resource; // Keep a reference to the passed Resource
for debugging purposes.
+
+ ResourceContainer existingResourceContainer = getResourceContainer(resource);
+ if (existingResourceContainer == null) {
+ existingResourceContainer = getResourceContainer(resource.getId());
+ }
+ Resource existingResourceViaContainer = (existingResourceContainer != null) ?
+ existingResourceContainer.getResource() : null;
+ Resource existingParent = (existingResourceViaContainer != null) ?
+ existingResourceViaContainer.getParentResource() : null;
+
+ Resource newParent;
if (resource.getParentResource() != null) {
ResourceContainer parentResourceContainer =
getResourceContainer(resource.getParentResource());
if (parentResourceContainer == null) {
parentResourceContainer =
getResourceContainer(resource.getParentResource().getId());
}
- if (parentResourceContainer != null)
- parentResource = parentResourceContainer.getResource();
- else
- parentResource = null; // TODO right thing to do? Or directly return?
+ if (parentResourceContainer != null) {
+ newParent = parentResourceContainer.getResource();
+ } else {
+ newParent = null; // TODO right thing to do? Or directly return?
+ }
} else {
- parentResource = null;
+ newParent = null;
}
- Resource existingResource = findMatchingChildResource(resource, parentResource);
- if (parentResource == null && existingResource == null) {
+
+ if (newParent != null && existingParent != null &&
+ !matches(newParent, existingParent)) {
+ // The Server must have moved the Resource to a new parent - remove it from
its old parent in our
+ // local inventory. We'll add
+ existingParent.removeChildResource(existingResourceViaContainer);
+ }
+
+ Resource existingResourceViaParent = findMatchingChildResource(resource,
newParent);
+ if (newParent == null && existingResourceViaParent == null) {
// This should never happen, but add a check so we'll know if it ever
does.
log.error("Existing platform [" + this.platform + "] has
different Resource type and/or Resource key than "
+ "platform in Server inventory: " + resource);
@@ -2281,31 +2301,31 @@ public class InventoryManager extends AgentService implements
ContainerService,
boolean pluginConfigUpdated = false;
this.inventoryLock.writeLock().lock();
try {
- if (existingResource != null) {
+ if (existingResourceViaParent != null) {
// First grab the existing Resource's container, so we can reuse it.
- resourceContainer =
this.resourceContainers.remove(existingResource.getUuid());
+ resourceContainer =
this.resourceContainers.remove(existingResourceViaParent.getUuid());
if (resourceContainer != null) {
this.resourceContainers.put(resource.getUuid(), resourceContainer);
}
- if (parentResource != null) {
+ if (newParent != null) {
// It's critical to remove the existing Resource from the
parent's child Set if the UUID has
// changed (i.e. altering the hashCode of an item in a Set == BAD),
so just always remove it.
- parentResource.removeChildResource(existingResource);
+ newParent.removeChildResource(existingResourceViaParent);
}
// Now merge the new Resource into the existing Resource...
- pluginConfigUpdated = mergeResource(resource, existingResource);
- resource = existingResource;
+ pluginConfigUpdated = mergeResource(resource,
existingResourceViaParent);
+ resource = existingResourceViaParent;
}
- if (parentResource != null) {
- parentResource.addChildResource(resource);
+ if (newParent != null) {
+ newParent.addChildResource(resource);
} else {
this.platform = resource;
}
// Replace the stripped-down ResourceType that came from the Server with the
full ResourceType - it's
// critical to do this before refreshing the state (i.e. calling start on the
ResourceComponent)
- // and critical to do this before initializing the container (since its
needed for the classloader creation).
+ // and critical to do this before initializing the container (since it's
needed for the classloader creation).
ResourceType fullResourceType =
this.pluginManager.getMetadataManager().getType(resource.getResourceType());
if (fullResourceType == null) {
log.error("Unable to merge Resource " + resource + " - its
type is unknown - perhaps the ["
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index 185562a..3d1ddd7 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -622,14 +622,21 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
// parent to that type.
if (validParentTypes.contains(resourceParentType)) {
+ log.debug("Moving " + existingResource + " from old parent
" + existingResource.getParentResource()
+ + " to new parent " + resource.getParentResource() +
"...");
if (existingResource.getParentResource() != null) {
existingResource.getParentResource().removeChildResource(existingResource);
}
if (resource.getParentResource() != null) {
parentResource = getExistingResource(resource.getParentResource());
parentResource.addChildResource(existingResource);
+
}
existingResource.setParentResource(resource.getParentResource());
+
+ // IMPORTANT: Update the Resource's mtime, so the Agent will know to
update the Resource's parent during
+ // its inventory sync.
+ existingResource.setMtime(System.currentTimeMillis());
} else {
log.debug("Existing Resource " + existingResource + " has
invalid parent type ("
+ existingResourceParentType + ") and so does plugin-reported
Resource " + resource + " ("
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java
index 64e9afd..a0b01ac 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java
@@ -843,10 +843,16 @@ public class ResourceMetadataManagerBean implements
ResourceMetadataManagerLocal
}
}
if (newParent != null) {
+ log.debug("Moving " + resource + " from old parent "
+ resource.getParentResource() + " to new parent "
+ + newParent + "...");
if (resource.getParentResource() != null) {
resource.getParentResource().removeChildResource(resource);
}
newParent.addChildResource(resource);
+
+ // IMPORTANT: Update the Resource's mtime, so the Agent will know to
update the Resource's parent during
+ // its inventory sync.
+ resource.setMtime(System.currentTimeMillis());
} else {
log.debug("We were unable to move " + resource + " from
invalid parent " + resource.getParentResource()
+ " to a new valid parent with one of the following types:
" + newParentTypes);
commit 5cb61cd55e617104661544da182e47d197fdf401
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Tue Jul 27 23:07:57 2010 -0400
fix so unsynced (invStatus!=COMMITED || id==0) Resources are not included in avail
reports sent by the PC (fixes half of
https://bugzilla.redhat.com/show_bug.cgi?id=618879)
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 d916bbc..04e1fb3 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
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
+ * Copyright (C) 2005-2010 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -48,7 +48,8 @@ import org.rhq.core.pluginapi.availability.AvailabilityFacet;
* Runs a periodic scan for resource availability.
*
* @author Greg Hinkle
- * @author John Mazzitelli
+ * @author John Mazzitelli
+ * @author Ian Springer
*/
public class AvailabilityExecutor implements Runnable, Callable<AvailabilityReport>
{
// the get-availability-timeout will rarely, if ever, want to be overridden. It will
default to be 5 seconds
@@ -94,15 +95,15 @@ public class AvailabilityExecutor implements Runnable,
Callable<AvailabilityRepo
}
/**
- * Returns the availability report that should be sent to the server.
+ * Returns the availability report that should be sent to the Server.
*
* <p>This will return <code>null</code> if there is no committed
inventory and thus no availability reports should
* be sent. This will rarely happen - only if this is a brand new agent whose
inventory hasn't been committed yet or
* if the platform and all its children have been deleted (in which case the agent
should be uninstalled or the user
* will want to re-import the platform). In either case, it will be in rare, corner
cases that this will ever return
- * null and the condition that caused the null should eventually go away.</p>
+ * null, and the condition that caused the null should eventually go away.</p>
*
- * @return the report containing all the availabilities that need to be sent to the
server
+ * @return the report containing all the availabilities that need to be sent to the
Server
*
* @throws Exception if failed to create and prepare the report
*/
@@ -122,13 +123,13 @@ public class AvailabilityExecutor implements Runnable,
Callable<AvailabilityRepo
long start = System.currentTimeMillis();
checkInventory(inventoryManager.getPlatform(), availabilityReport,
- availabilityReport.isChangesOnlyReport(), true);
+ availabilityReport.isChangesOnlyReport(), true, false);
// In enterprise mode, the server will need at least one resource so it can
derive what agent
// is sending this report. If the report is empty (meaning, nothing has
changed since the last
// availability check), let's add the platform record to the report
- if (availabilityReport.getResourceAvailability().size() == 0) {
- checkInventory(inventoryManager.getPlatform(), availabilityReport, false,
false);
+ if (availabilityReport.getResourceAvailability().isEmpty()) {
+ checkInventory(inventoryManager.getPlatform(), availabilityReport, false,
false, false);
}
// if we have non-platform resources in the report, the agent has had
@@ -152,103 +153,91 @@ public class AvailabilityExecutor implements Runnable,
Callable<AvailabilityRepo
}
private void checkInventory(Resource resource, AvailabilityReport availabilityReport,
boolean reportChangesOnly,
- boolean checkChildren) {
+ boolean checkChildren, boolean parentIsDown) {
+ // Only report avail for committed Resources - that's all the Server cares
about.
+ if (resource.getInventoryStatus() != InventoryStatus.COMMITTED) {
+ return;
+ }
ResourceContainer resourceContainer =
this.inventoryManager.getResourceContainer(resource);
- AvailabilityFacet resourceComponent = null;
- if (resourceContainer != null && resource.getInventoryStatus() ==
InventoryStatus.COMMITTED) {
- try {
- resourceComponent =
resourceContainer.createResourceComponentProxy(AvailabilityFacet.class,
- FacetLockType.NONE, GET_AVAILABILITY_TIMEOUT, true, false);
- } catch (PluginContainerException e) {
- if (log.isDebugEnabled()) {
- log.debug("Could not create resource component proxy for "
+ resource + " due to " + e);
- }
+ // Only report avail for synchronized Resources, otherwise chances are the Server
will know nothing of the
+ // Resource.
+ if (resourceContainer == null ||
+ resourceContainer.getSynchronizationState() !=
ResourceContainer.SynchronizationState.SYNCHRONIZED) {
+ return;
+ }
+ AvailabilityFacet resourceComponent;
+ try {
+ resourceComponent =
resourceContainer.createResourceComponentProxy(AvailabilityFacet.class,
+ FacetLockType.NONE, GET_AVAILABILITY_TIMEOUT, true, false);
+ } catch (PluginContainerException e) {
+ // TODO (ips): Why aren't we logging this as an error?
+ if (log.isDebugEnabled()) {
+ log.debug("Could not create resource component proxy for " +
resource + ".", e);
}
+ return;
}
- if (resourceComponent != null) {
- AvailabilityType current = null;
-
- // Only report availability for committed resources; don't bother with
new, ignored or deleted resources.
- if (resource.getInventoryStatus() == InventoryStatus.COMMITTED) {
+ AvailabilityType current = null;
- // this is what we think the availability is, based on a previous check
- Availability previous =
this.inventoryManager.getAvailabilityIfKnown(resource);
+ // Find out what the avail was the last time we checked it.
+ Availability previous = this.inventoryManager.getAvailabilityIfKnown(resource);
- try {
- // if the component is started, ask what its current availability is
as of right now
- // if its not started, then assume its down, our next time checking
we'll see if its
- // started and check for real then - otherwise, keep assuming its
down (this is for
- // the case when a plugin component can't start for whatever
reason or is just slow
- // to start)
+ 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;
+ } else {
+ try {
+ // if the component is started, ask what its current availability is as
of right now;
+ // if it's not started, then assume it's down, and the next time
we check,
+ // we'll see if it's started and check for real then - otherwise,
keep assuming it's
+ // down (this is for the case when a plugin component can't start for
whatever reason
+ // or is just slow to start)
+ if (resourceContainer.getResourceComponentState() ==
ResourceComponentState.STARTED) {
+ current = resourceComponent.getAvailability();
+ } else {
+ this.inventoryManager.activateResource(resource, resourceContainer,
false);
if (resourceContainer.getResourceComponentState() ==
ResourceComponentState.STARTED) {
current = resourceComponent.getAvailability();
- } else {
- this.inventoryManager.activateResource(resource,
resourceContainer, false);
- if (resourceContainer.getResourceComponentState() ==
ResourceComponentState.STARTED) {
- current = resourceComponent.getAvailability();
- }
}
- } catch (Throwable t) {
- ResourceError resourceError = new ResourceError(resource,
ResourceErrorType.AVAILABILITY_CHECK, t,
- System.currentTimeMillis());
- this.inventoryManager.sendResourceErrorToServer(resourceError);
- // TODO GH: Put errors in report, rather than sending them to the
Server separately.
- if (log.isDebugEnabled()) {
- if (t instanceof TimeoutException)
- // no need to log the stack trace for timeouts...
- log.debug("Failed to collect availability on resource
" + resource + " (call timed out)");
- else
- log.debug("Failed to collect availability on resource
" + resource, t);
- }
- }
-
- if (current == null) {
- current = AvailabilityType.DOWN;
}
-
- if (resourceContainer.getSynchronizationState() ==
ResourceContainer.SynchronizationState.SYNCHRONIZED) {
- Availability availability =
this.inventoryManager.updateAvailability(resource, current);
-
- // only add the availability to the report if it changed from its
previous state
- // if this is the first time we've been executed,
reportChangesOnly will be false
- // and we will send a full report as our very first report
- if ((previous == null) || (previous.getAvailabilityType() != current)
|| !reportChangesOnly) {
- availabilityReport.addAvailability(availability);
+ } catch (Throwable t) {
+ ResourceError resourceError = new ResourceError(resource,
ResourceErrorType.AVAILABILITY_CHECK, t,
+ System.currentTimeMillis());
+ this.inventoryManager.sendResourceErrorToServer(resourceError);
+ // TODO GH: Put errors in report, rather than sending them to the Server
separately.
+ if (log.isDebugEnabled()) {
+ if (t instanceof TimeoutException) {
+ // no need to log the stack trace for timeouts...
+ log.debug("Failed to collect availability on " +
resource + " (call timed out)");
+ } else {
+ log.debug("Failed to collect availability on " +
resource, t);
}
}
}
-
- if (checkChildren) {
- // Wrap in a fresh HashSet to avoid ConcurrentModificationExceptions.
- Set<Resource> children = new
HashSet<Resource>(resource.getChildResources());
- if (current == AvailabilityType.UP) {
- for (Resource child : children)
- checkInventory(child, availabilityReport, reportChangesOnly,
true);
- } else {
- for (Resource child : children)
- markDown(child, availabilityReport, reportChangesOnly);
- }
+ if (current == null) {
+ current = AvailabilityType.DOWN;
}
}
- return;
- }
-
- /**
- * Marks the specified Resource and all its descendants as DOWN for the report.
- */
- private void markDown(Resource resource, AvailabilityReport availabilityReport,
boolean changesOnly) {
- Availability previous = this.inventoryManager.getAvailabilityIfKnown(resource);
- if (!changesOnly || previous == null || previous.getAvailabilityType() !=
AvailabilityType.DOWN) {
- Availability availability =
this.inventoryManager.updateAvailability(resource, AvailabilityType.DOWN);
+ // Only add the availability to the report if it changed from its previous
state.
+ // If this is the first time we've been executed, reportChangesOnly will be
false,
+ // and we will send a full report as our very first report.
+ if ((previous == null) || (previous.getAvailabilityType() != current) ||
!reportChangesOnly) {
+ Availability availability =
this.inventoryManager.updateAvailability(resource, current);
availabilityReport.addAvailability(availability);
}
- // Wrap in a fresh HashSet to avoid ConcurrentModificationExceptions.
- Set<Resource> children = new HashSet(resource.getChildResources());
- for (Resource child : children) {
- markDown(child, availabilityReport, changesOnly);
+
+ if (checkChildren) {
+ // 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);
+ }
}
+
+ return;
}
/**
@@ -267,4 +256,4 @@ public class AvailabilityExecutor implements Runnable,
Callable<AvailabilityRepo
void sendChangedOnlyReportNextTime() {
this.sendChangedOnlyReport.set(true);
}
-}
\ No newline at end of file
+}
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/ResourceContainer.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/ResourceContainer.java
index 3d27295..ab8d30e 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/ResourceContainer.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/ResourceContainer.java
@@ -299,7 +299,7 @@ public class ResourceContainer implements Serializable {
* @param daemonThread whether or not the thread used for the invocation should be
a daemon thread
* @param onlyIfStarted if <code>true</code>, and the component is not
started, an exception is thrown
*
- * @return a proxy that wraps the given component and exposes the given facet
interface
+ * @return a proxy that wraps the given component and exposes the given facet
interface; will never be null
*
* @throws PluginContainerException if the component does not exist or does not
implement the interface
*/