/**
  *
  *
  * <h2>实际执行添加引擎的动作</h2>
  *
  * <p>有如下添加方式(对应两种情况):
  *
  * <ol>
  *   <li>管理员通过界面主动新建一个监控引擎(而后由脚本安装) 用户输入了如下信息
  *       <ul>
  *         <li>引擎路径(安装目标路径)
  *         <li>引擎地址(也是主机地址)
  *         <li>主机类型
  *         <li>主机登录信息
  *       </ul>
  *       程序在本步骤保持新的引擎对象以及其所在主机信息之后,后继应该使用该主机信息,将引擎安装到相应目录去
  *   <li>用户在特定机器上安装引擎(而后引擎启动时,通过监控服务器SPI自动注册)
  *       <ul>
  *         <li>引擎路径(安装目标路径)
  *         <li>引擎地址(也是主机地址)
  *         <li>进程pids
  *         <li>主机类型
  *       </ul>
  * </ol>
  *
  * 开发者可以通过监控引擎是否有pids值判断是否是界面输入的监控引擎
  *
  * @param engine 新注册的引擎对象
  * @throws ResourceException
  */
 @Override
 protected void performCreate(MonitorEngine engine) throws ResourceException {
   boolean manual;
   manual = engine.getPids() == null || engine.getPids().isEmpty();
   // 新建的引擎,没有真的引擎实例与之关联,所以,必定 不可用, 待批准
   engine.setEngineId(UUID.randomUUID().toString());
   engine.setAvailability(Availability.Unavailable);
   engine.setConfigStatus(ConfigStatus.Unknown);
   engine.setPerformance(Performance.Unknown);
   engine.setApproveStatus(ApproveStatus.Requested);
   // 没有预先创建,自动注册的监控引擎没有name,需要为其生成
   // @see dnt.monitor.engine.support.IdentityManager#createLocalEngine(String)
   if (StringUtils.isBlank(engine.getName())) {
     int maxPending = getRepository().countMaxPending();
     maxPending++;
     engine.setLabel("新监控引擎#" + maxPending);
     String name = "pending_" + maxPending;
     engine.setName(name);
     engine.setApiToken(null); // 防止提交进来
   }
   // 本函数中没有包括创建该引擎所在主机,这个动作是在引擎创建后,
   // 由 SetupEngineAfterCreation这个handler完成
   logger.debug(
       "An engine from {} created in {} mode", engine.getAddress(), (manual ? "manual" : "auto"));
   super.performCreate(engine);
 }
 @Override
 protected void validateOnCreate(MonitorEngine engine) throws ValidationException {
   super.validateOnCreate(engine);
   MonitorEngine exist = findByAddress(engine.getAddress());
   if (exist != null) {
     throw new ValidationException("There is an engine with address " + engine.getAddress());
   }
 }
 @SuppressWarnings("unchecked")
 @Override
 protected void performDelete(MonitorEngine resource) throws ResourceException {
   // 删除engine -> host, engine -> redis等关系
   List<Link> links = linkService.findLinksOf(resource);
   for (Link link : links) {
     linkService.unlink(link);
   }
   super.performDelete(resource);
 }
 @Override
 protected void validateOnUpdate(MonitorEngine exist, MonitorEngine resource)
     throws ValidationException {
   super.validateOnUpdate(exist, resource);
   // IP地址变了
   if (!StringUtils.equals(exist.getAddress(), resource.getAddress())) {
     MonitorEngine another = findByAddress(resource.getAddress());
     if (another != null) {
       throw new ValidationException(
           "There is another engine with address " + resource.getAddress());
     }
   }
 }