@Override
 protected Map<String, Pair<String, String>> getExclusiveLocks() {
   return Collections.singletonMap(
       getStoragePoolId().toString(),
       LockMessagesMatchUtil.makeLockingPair(
           LockingGroup.POOL, VdcBllMessages.ACTION_TYPE_FAILED_OBJECT_LOCKED));
 }
 @Override
 protected Map<String, Pair<String, String>> getSharedLocks() {
   return Collections.singletonMap(
       getVmId().toString(),
       LockMessagesMatchUtil.makeLockingPair(
           LockingGroup.VM, EngineMessage.ACTION_TYPE_FAILED_VM_IS_LOCKED));
 }
 @Override
 protected Map<String, Pair<String, String>> getExclusiveLocks() {
   if (getVmTemplate() != null) {
     return Collections.singletonMap(
         getVmTemplateId().toString(),
         LockMessagesMatchUtil.makeLockingPair(
             LockingGroup.TEMPLATE, getTemplateExclusiveLockMessage()));
   }
   return null;
 }
  @Override
  protected boolean validate() {
    if (!super.validate()
        || !checkStoragePool()
        || !checkStoragePoolStatusNotEqual(
            StoragePoolStatus.Up, EngineMessage.ERROR_CANNOT_REMOVE_ACTIVE_STORAGE_POOL)) {
      return false;
    }

    if (getStoragePool().getStatus() != StoragePoolStatus.Uninitialized
        && !getParameters().getForceDelete()
        && !initializeVds()) {
      return false;
    }

    final List<StorageDomain> poolDomains =
        getStorageDomainDao().getAllForStoragePool(getStoragePool().getId());
    final List<StorageDomain> activeOrLockedDomains = getActiveOrLockedDomainList(poolDomains);

    if (!activeOrLockedDomains.isEmpty()) {
      return failValidation(EngineMessage.ERROR_CANNOT_REMOVE_POOL_WITH_ACTIVE_DOMAINS);
    }
    if (!getParameters().getForceDelete()) {
      if (poolDomains.size() > 1) {
        return failValidation(
            EngineMessage.ERROR_CANNOT_REMOVE_STORAGE_POOL_WITH_NONMASTER_DOMAINS);
      }
      if (!poolDomains.isEmpty() && !canDetachStorageDomainWithVmsAndDisks(poolDomains.get(0))) {
        return false;
      }
    } else {
      List<VDS> poolHosts = getVdsDao().getAllForStoragePool(getParameters().getStoragePoolId());

      sharedLocks = new HashMap<>();
      for (VDS host : poolHosts) {
        sharedLocks.put(
            host.getId().toString(),
            LockMessagesMatchUtil.makeLockingPair(
                LockingGroup.VDS, EngineMessage.ACTION_TYPE_FAILED_OBJECT_LOCKED));
      }

      if (!poolHosts.isEmpty() && acquireLockInternal()) {
        for (VDS host : poolHosts) {
          if (host.getStatus() != VDSStatus.Maintenance) {
            return failValidation(
                EngineMessage.ERROR_CANNOT_FORCE_REMOVE_STORAGE_POOL_WITH_VDS_NOT_IN_MAINTENANCE);
          }
        }
      }
    }
    return true;
  }
  @Override
  protected Map<String, Pair<String, String>> getExclusiveLocks() {
    Map<String, Pair<String, String>> exclusiveLock = null;

    if (getDisk() != null) {
      exclusiveLock = new HashMap<>();

      exclusiveLock.put(
          getDisk().getId().toString(),
          LockMessagesMatchUtil.makeLockingPair(
              LockingGroup.DISK,
              EngineMessage.ACTION_TYPE_FAILED_DISKS_LOCKED.name()
                  + String.format("$diskAliases %1$s", getDiskAlias())));

      if (getDisk().isBoot()) {
        exclusiveLock.put(
            getVmId().toString(),
            LockMessagesMatchUtil.makeLockingPair(
                LockingGroup.VM_DISK_BOOT, EngineMessage.ACTION_TYPE_FAILED_OBJECT_LOCKED));
      }
    }
    return exclusiveLock;
  }
  @Override
  protected Map<String, Pair<String, String>> getExclusiveLocks() {
    if (disk == null) {
      return null;
    }

    Map<String, Pair<String, String>> locks = new HashMap<>();
    if (!disk.isShareable()) {
      locks.put(
          disk.getId().toString(),
          LockMessagesMatchUtil.makeLockingPair(
              LockingGroup.DISK, EngineMessage.ACTION_TYPE_FAILED_OBJECT_LOCKED));
    }

    if (disk.isBoot()) {
      locks.put(
          getParameters().getVmId().toString(),
          LockMessagesMatchUtil.makeLockingPair(
              LockingGroup.VM_DISK_BOOT, EngineMessage.ACTION_TYPE_FAILED_OBJECT_LOCKED));
    }

    return locks;
  }
  @Override
  protected Map<String, Pair<String, String>> getExclusiveLocks() {
    if (getNetworkName() == null) {
      return null;
    }

    Map<String, Pair<String, String>> locks =
        Collections.singletonMap(
            getNetworkName(),
            LockMessagesMatchUtil.makeLockingPair(
                LockingGroup.NETWORK, VdcBllMessages.ACTION_TYPE_FAILED_NETWORK_IS_USED));

    return locks;
  }
 /**
  * To prevent concurrent deletion.
  *
  * @return first: true ~ successfully locked, false otherwise; second: fail reasons in form
  *     suitable for canDoActionMessages
  */
 private boolean acquireBaseTemplateSuccessorLock() {
   final Map<String, Pair<String, String>> lockSharedMap =
       Collections.singletonMap(
           baseTemplateSuccessor.getId().toString(),
           LockMessagesMatchUtil.makeLockingPair(
               LockingGroup.TEMPLATE, createSubTemplateLockMessage(baseTemplateSuccessor)));
   baseTemplateSuccessorLock = new EngineLock(null, lockSharedMap);
   final Pair<Boolean, Set<String>> isLockedAndFailReason =
       getLockManager().acquireLock(baseTemplateSuccessorLock);
   if (isLockedAndFailReason.getFirst()) {
     return true;
   }
   baseTemplateSuccessorLock = null;
   getReturnValue()
       .getCanDoActionMessages()
       .addAll(extractVariableDeclarations(isLockedAndFailReason.getSecond()));
   return false;
 }