/**
  * Get a agent on given id.
  *
  * @param id agent id
  * @return agent
  */
 public AgentInfo getAgent(long id) {
   AgentInfo agentInfo = agentRepository.findOne(id);
   if (agentInfo == null) {
     return null;
   }
   AgentControllerIdentityImplementation agentIdentity =
       agentManager.getAgentIdentityByIp(agentInfo.getIp());
   if (agentIdentity != null) {
     agentInfo.setStatus(agentManager.getAgentState(agentIdentity));
     agentInfo.setPort(agentManager.getAgentConnectingPort(agentIdentity));
     agentInfo.setHostName(agentIdentity.getName());
     agentInfo.setRegion(agentIdentity.getRegion());
     agentInfo.setAgentIdentity(agentIdentity);
   }
   return agentInfo;
 }
 @CacheEvict(allEntries = true, value = "agents")
 private AgentInfo creatAgentInfo(
     AgentControllerIdentityImplementation agentIdentity, List<AgentInfo> agents) {
   AgentInfo agentInfo = new AgentInfo();
   for (AgentInfo each : agents) {
     if (each != null && StringUtils.equals(each.getIp(), agentIdentity.getIp())) {
       agentInfo = each;
       break;
     }
   }
   if (!StringUtils.equals(agentInfo.getHostName(), agentIdentity.getName())
       || !StringUtils.equals(agentInfo.getRegion(), agentIdentity.getRegion())) {
     agentInfo.setHostName(agentIdentity.getName());
     agentInfo.setRegion(agentIdentity.getRegion());
     agentInfo.setIp(agentIdentity.getIp());
     agentInfo = agentRepository.save(agentInfo);
   }
   agentInfo.setPort(agentManager.getAgentConnectingPort(agentIdentity));
   agentInfo.setStatus(agentManager.getAgentState(agentIdentity));
   // need to save agent info into DB, like ip and port maybe changed.
   return agentInfo;
 }
  /**
   * Run a scheduled task to check the agent status.
   *
   * @since 3.1
   */
  public void checkAgentStatus() {
    List<AgentInfo> changeAgents = new ArrayList<AgentInfo>();
    String curRegion = getConfig().getRegion();

    Set<AgentIdentity> allAttachedAgents = getAgentManager().getAllAttachedAgents();
    Map<String, AgentControllerIdentityImplementation> attachedAgentMap =
        newHashMap(allAttachedAgents);
    for (AgentIdentity agentIdentity : allAttachedAgents) {
      AgentControllerIdentityImplementation existingAgent = convert(agentIdentity);
      attachedAgentMap.put(createAgentKey(existingAgent), existingAgent);
    }

    List<AgentInfo> agentsInDB = getAgentRepository().findAll(startWithRegion(curRegion));
    Map<String, AgentInfo> agentsInDBMap = Maps.newHashMap();
    // step1. check all agents in DB, whether they are attached to controller.
    for (AgentInfo eachAgentInDB : agentsInDB) {
      String keyOfAgentInDB = createAgentKey(eachAgentInDB);
      agentsInDBMap.put(keyOfAgentInDB, eachAgentInDB);
      AgentControllerIdentityImplementation agentIdentity = attachedAgentMap.remove(keyOfAgentInDB);

      if (agentIdentity != null) {
        // if the agent attached to current controller
        if (!hasSamePortAndStatus(eachAgentInDB, agentIdentity)) {
          fillUp(eachAgentInDB, agentIdentity);
          changeAgents.add(eachAgentInDB);
        } else if (!StringUtils.equals(eachAgentInDB.getRegion(), agentIdentity.getRegion())) {
          fillUp(eachAgentInDB, agentIdentity);
          eachAgentInDB.setStatus(WRONG_REGION);
          eachAgentInDB.setApproved(false);
          changeAgents.add(eachAgentInDB);
        }

      } else { // the agent in DB is not attached to current controller

        if (eachAgentInDB.getStatus() != INACTIVE) {
          eachAgentInDB.setStatus(INACTIVE);
          changeAgents.add(eachAgentInDB);
        }
      }
    }

    // step2. check all attached agents, whether they are new, and not saved in DB.
    for (AgentControllerIdentityImplementation agentIdentity : attachedAgentMap.values()) {
      AgentInfo agentInfo =
          getAgentRepository().findByIpAndHostName(agentIdentity.getIp(), agentIdentity.getName());
      if (agentInfo == null) {
        agentInfo = new AgentInfo();
      }
      if (StringUtils.equals(extractRegionFromAgentRegion(agentIdentity.getRegion()), curRegion)) {
        AgentInfo newAgentInfo = fillUp(agentInfo, agentIdentity);
        changeAgents.add(newAgentInfo);
      } else {
        if (agentInfo.getStatus() != WRONG_REGION) {
          AgentInfo newAgentInfo = fillUp(agentInfo, agentIdentity);
          agentInfo.setStatus(WRONG_REGION);
          agentInfo.setApproved(false);
          changeAgents.add(newAgentInfo);
        }
      }
    }

    // step3. update into DB
    getAgentRepository().save(changeAgents);
  }