Resource res = getResourceById(subject, resourceId);
// platforms are never unknown, just up or down, so we need to default the availability to a different value
// depending on the resource's category
ResourceAvailability result = new ResourceAvailability(res,
res.getResourceType().getCategory() == ResourceCategory.PLATFORM ? AvailabilityType.DOWN
: AvailabilityType.UNKNOWN);
try {
// validate the resource and agent, protect against REST dummy agent
Agent agent = agentManager.getAgentByResourceId(subjectManager.getOverlord(), resourceId);
if (agent == null) {
if (LOG.isDebugEnabled()) {
LOG.debug("Resource [" + resourceId + "] does not exist or has no agent assigned");
}
new IllegalStateException("No agent is associated with the resource with id [" + resourceId + "]");
} else if (agent.getName().startsWith(ResourceHandlerBean.DUMMY_AGENT_NAME_PREFIX)
&& agent.getAgentToken().startsWith(ResourceHandlerBean.DUMMY_AGENT_TOKEN_PREFIX)) {
return getResourceById(subject, resourceId).getCurrentAvailability();
}
AgentClient client = agentManager.getAgentClient(agent);
if (client == null) {
throw new IllegalStateException("No agent is associated with the resource with id [" + resourceId + "]");
}
AvailabilityReport report = null;
// first, quickly see if we can even ping the agent, if not, don't bother trying to get the resource avail
boolean agentPing = client.pingService(5000L);
if (agentPing) {
// we can't serialize the resource due to the hibernate proxies (agent can't deserialize hibernate objs)
// but we know we only need the basics for the agent to collect availability, so create a bare resource object
Resource bareResource = new Resource(res.getResourceKey(), res.getName(), res.getResourceType());
bareResource.setId(res.getId());
bareResource.setUuid(res.getUuid());
// root the avail check at the desired resource. Ask for a full report to guarantee that we
// get back the agent-side avail for the resource and keep the server in sync. This also means we'll
// get the descendants as well.
report = client.getDiscoveryAgentService().getCurrentAvailability(bareResource, false);
}
if (report != null) {
// although the data came from the agent this should be processed like a server-side report
// because it was requested and initiated by the server (bz 1094540). The availabilities will
// still be merged but certain backfill logic will remain unscathed.
report.setServerSideReport(true);
AvailabilityType foundAvail = report.forResource(res.getId());
if (foundAvail != null) {
availabilityManager.mergeAvailabilityReport(report);
} else {
foundAvail = res.getCurrentAvailability() == null ? AvailabilityType.UNKNOWN : res
.getCurrentAvailability().getAvailabilityType();
}
// make sure we don't somehow leak/persist a MISSING avail
foundAvail = (AvailabilityType.MISSING == foundAvail) ? AvailabilityType.DOWN : foundAvail;
result.setAvailabilityType(foundAvail);
}
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to get live availability: " + e.getMessage());