/**
   * Register an Agent with the server. This method calls out to verify it can talk to the agent,
   * and then adds it to the database. With all the connection info used to make further
   * connections.
   */
  private RegisterAgent_result cmdRegisterAgent(LatherContext ctx, RegisterAgent_args args)
      throws LatherRemoteException {
    try {
      checkUserCanManageAgent(ctx, args.getUser(), args.getPword(), "register");
    } catch (PermissionException exc) {
      return new RegisterAgent_result("Permission denied");
    }
    Collection<Integer> ids = new ArrayList<Integer>();

    RegisterAgent_result result = registerAgent(args, ids);

    /**
     * Reschedule all metrics on a platform when it is started for the first time. This allows the
     * schedule to be updated immediately on either agent updates, or if the user removes the agent
     * data directory.
     */
    if (!ids.isEmpty()) {
      try {
        List<ResourceRefreshZevent> zevents = new ArrayList<ResourceRefreshZevent>();
        ResourceRefreshZevent zevent;
        AuthzSubject overlord = authzSubjectManager.getOverlordPojo();
        for (Integer id : ids) {

          Platform platform = platformManager.findPlatformById(id);

          zevent = new ResourceRefreshZevent(overlord, platform.getEntityId());
          zevents.add(zevent);

          Collection<Server> servers = platform.getServers();
          for (Server server : servers) {

            zevent = new ResourceRefreshZevent(overlord, server.getEntityId());
            zevents.add(zevent);

            Collection<Service> services = server.getServices();
            for (Service service : services) {

              zevent = new ResourceRefreshZevent(overlord, service.getEntityId());
              zevents.add(zevent);
            }
          }
        }

        zeventManager.enqueueEventsAfterCommit(zevents);

      } catch (Exception e) {
        // Not fatal, the metrics will eventually be rescheduled...
        log.error("Unable to refresh agent schedule", e);
      }
    }
    return result;
  }
 private void removeOrphanedServers(AuthzSubject overlord) {
   final Collection<Server> servers = serverManager.getOrphanedServers();
   if (!servers.isEmpty()) {
     log.info("cleaning up " + servers.size() + " orphaned servers");
   }
   for (Server server : servers) {
     try {
       server = serverManager.getServerById(server.getId());
       serverManager.removeServer(overlord, server);
     } catch (ObjectNotFoundException e) {
       log.warn(e);
       log.debug(e, e);
     } catch (PermissionException e) {
       log.warn(e);
       log.debug(e, e);
     } catch (VetoException e) {
       log.warn(e);
       log.debug(e, e);
     }
   }
 }
 private final void removeServers(AuthzSubject subject, Collection<Server> servers) {
   final StopWatch watch = new StopWatch();
   watch.markTimeBegin("removeServers");
   final List<Server> svrs = new ArrayList<Server>(servers);
   // can't use iterator for loop here. Since we are modifying the
   // internal hibernate collection, which this collection is based on,
   // it will throw a ConcurrentModificationException
   // This occurs even if you disassociate the Collection by trying
   // something like new ArrayList(servers). Not sure why.
   for (int i = 0; i < svrs.size(); i++) {
     try {
       final Server server = svrs.get(i);
       // removeServices(subject, server.getServices());
       appdefBoss.removeServer(subject, server.getId());
     } catch (Exception e) {
       log.error("Unable to remove server: " + e, e);
     }
   }
   watch.markTimeEnd("removeServers");
   if (log.isDebugEnabled()) {
     log.debug("Removed " + servers.size() + " services");
   }
 }