// If there is one already with the given agent name then update that record, overlaying it with the data from agentInstall.
// If there is nothing with the given agent name, persist a new record with the data in agentInstall.
// Note that if the caller didn't give us either an install ID or an agent name, we still persist the entity
// with the expectation that the new ID will be used later by a new agent (new agent will register with this new ID and
// will tell us what agent name it wants to use).
AgentInstall existing = getAgentInstallByAgentName(user, agentInstall.getAgentName());
if (existing != null) {
existing.overlay(agentInstall); // note: "existing" is detached
agentInstall = entityManager.merge(existing);
} else {
entityManager.persist(agentInstall);
}
} else {
// Caller gave us an agentInstall with an ID. See if there is already an entity with the given ID.
// If there is an entity with the given ID, but that entity's agentName does not match the agentName given in agentInstall,
// abort - one agent can't change another agent's install data.
// If there is an entity with the given ID and the agentName matches then update that record, overlaying it with data from agentInstall.
// If there is no entity with the given ID then throw an error.
AgentInstall existing = entityManager.find(AgentInstall.class, agentInstall.getId());
if (existing != null) {
if (agentInstall.getAgentName() != null) {
if (existing.getAgentName() != null && !agentInstall.getAgentName().equals(existing.getAgentName())) {
throw new IllegalStateException("Updating agent install ID [" + agentInstall.getId()
+ "] with a mismatched agent name is not allowed");
}
// It is possible some past installs were aborted, or this agent is getting reinstalled.
// This cases like this, we'll have duplicate rows with the same agent name - this just deletes
// those older rows since this new agent supercedes the other ones.
Query q = entityManager.createNamedQuery(AgentInstall.QUERY_FIND_BY_NAME);
q.setParameter("agentName", agentInstall.getAgentName());
List<AgentInstall> otherAgentInstalls = q.getResultList();
if (otherAgentInstalls != null) {
for (AgentInstall otherAgentInstall : otherAgentInstalls) {
if (otherAgentInstall.getId() != agentInstall.getId()) {
entityManager.remove(otherAgentInstall);
}
}
}
}
existing.overlay(agentInstall); // modify the attached hibernate entity
agentInstall = existing;
} else {
throw new IllegalStateException("Agent install ID [" + agentInstall.getId()
+ "] does not exist. Cannot update install info for agent [" + agentInstall.getAgentName() + "]");
}