entityManager.detach(resource);
if (null != doomedAgent) {
entityManager.detach(doomedAgent);
}
AgentClient agentClient = null;
try {
// The test code does not always generate agents for the resources. Catch and log any problem but continue
agentClient = agentManager.getAgentClient(overlord, resourceId);
} catch (Throwable t) {
LOG.warn("No AgentClient found for resource [" + resource
+ "]. Unable to inform agent of inventory removal (this may be ok): " + t);
}
// since we delete the resource asynchronously, make sure we remove things that would cause system
// side effects after markForDeletion completed but before the resource is actually removed from the DB
// delete the resource and all its children
if (isDebugEnabled) {
LOG.debug("Marking resource [" + resource + "] for asynchronous uninventory");
}
// set agent references null
// foobar the resourceKeys
// update the inventory status to UNINVENTORY
List<Integer> toBeDeletedResourceIds = getDescendents(resourceId);
int i = 0;
if (isDebugEnabled) {
LOG.debug("== total size : " + toBeDeletedResourceIds.size());
}
while (i < toBeDeletedResourceIds.size()) {
int j = i + 1000;
if (j > toBeDeletedResourceIds.size())
j = toBeDeletedResourceIds.size();
List<Integer> idsToDelete = toBeDeletedResourceIds.subList(i, j);
if (isDebugEnabled) {
LOG.debug("== Bounds " + i + ", " + j);
}
// refresh overlord session for each batch to avoid session timeout
overlord = subjectManager.getOverlord();
boolean hasErrors = uninventoryResourcesBulkDelete(overlord, idsToDelete);
if (hasErrors) {
throw new IllegalArgumentException("Could not remove resources from their containing groups");
}
i = j;
}
// QUERY_MARK_RESOURCES_FOR_ASYNC_DELETION is an expensive recursive query
// But luckily we have already (through such a recursive query above) determined the doomed resources
// Query markDeletedQuery = entityManager.createNamedQuery(Resource.QUERY_MARK_RESOURCES_FOR_ASYNC_DELETION);
// markDeletedQuery.setParameter("resourceId", resourceId);
// markDeletedQuery.setParameter("status", InventoryStatus.UNINVENTORIED);
// int resourcesDeleted = markDeletedQuery.executeUpdate();
i = 0;
int resourcesDeleted = 0;
while (i < toBeDeletedResourceIds.size()) {
int j = i + 1000;
if (j > toBeDeletedResourceIds.size())
j = toBeDeletedResourceIds.size();
List<Integer> idsToDelete = toBeDeletedResourceIds.subList(i, j);
Query markDeletedQuery = entityManager
.createNamedQuery(Resource.QUERY_MARK_RESOURCES_FOR_ASYNC_DELETION_QUICK);
markDeletedQuery.setParameter("resourceIds", idsToDelete);
markDeletedQuery.setParameter("status", InventoryStatus.UNINVENTORIED);
resourcesDeleted += markDeletedQuery.executeUpdate();
i = j;
}
if (resourcesDeleted != toBeDeletedResourceIds.size()) {
LOG.error("Tried to uninventory " + toBeDeletedResourceIds.size()
+ " resources, but actually uninventoried " + resourcesDeleted);
}
// flush to make sure the db is successfully updated with changes before we make more slsb calls and
// before we notify the agent
entityManager.flush();
// still need to tell the agent about the removed resources so it stops avail reports
// but not if this is a synthetic agent that was created in the REST-api
// See org.rhq.enterprise.server.rest.ResourceHandlerBean.createPlatformInternal()
// See also https://docs.jboss.org/author/display/RHQ/Virtual+platforms+and+synthetic+agents
if (agentClient != null) {
if (agentClient.getAgent() == null || agentClient.getAgent().getName() == null
|| !agentClient.getAgent().getName().startsWith(ResourceHandlerBean.DUMMY_AGENT_NAME_PREFIX)) { // don't do that on "REST-agents"
try {
if (agentClient.pingService(3000L)) {
agentClient.getDiscoveryAgentService().uninventoryResource(resourceId);
} else {
LOG.warn(" Unable to inform agent [" + agentClient.getAgent().getName()
+ "] of inventory removal for resource [" + resourceId
+ "]. Agent can not be reached or is not accepting service requests.");
}
} catch (Exception e) {
LOG.warn(" Unable to inform agent of inventory removal for resource [" + resourceId + "]", e);