/**
   * 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 removeOrphanedServices(AuthzSubject overlord) {
   final Collection<Service> services = serviceManager.getOrphanedServices();
   if (!services.isEmpty()) {
     log.info("cleaning up " + services.size() + " orphaned services");
   }
   for (Service service : services) {
     try {
       service = serviceManager.getServiceById(service.getId());
       serviceManager.removeService(overlord, service);
     } 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 removeServices(AuthzSubject subject, Collection<Service> services) {
   final StopWatch watch = new StopWatch();
   watch.markTimeBegin("removeServices");
   final List<Service> svcs = new ArrayList<Service>(services);
   // 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(services). Not sure why.
   for (int i = 0; i < svcs.size(); i++) {
     try {
       final Service service = svcs.get(i);
       appdefBoss.removeService(subject, service.getId());
     } catch (Exception e) {
       log.error("Unable to remove service: " + e, e);
     }
   }
   watch.markTimeEnd("removeServices");
   if (log.isDebugEnabled()) {
     log.debug("Removed " + services.size() + " services");
   }
 }