/**
   * get Matched Virtual Pools For Pool. This is called to calculate supported vpools during
   * unmanaged objects discovery
   *
   * @param poolUri
   * @return
   */
  public static StringSet getMatchedVirtualPoolsForPool(
      DbClient dbClient, URI poolUri, String isThinlyProvisionedUnManagedObject) {
    StringSet vpoolUriSet = new StringSet();
    // We should match all virtual pools as below:
    // 1) Virtual pools which have useMatchedPools set to true and have the storage pool in their
    // matched pools
    // 2) Virtual pools which have the storage pool in their assigned pools

    URIQueryResultList vpoolMatchedPoolsResultList = new URIQueryResultList();
    dbClient.queryByConstraint(
        ContainmentConstraint.Factory.getMatchedPoolVirtualPoolConstraint(poolUri),
        vpoolMatchedPoolsResultList);
    List<VirtualPool> vPoolsMatchedPools =
        dbClient.queryObject(VirtualPool.class, vpoolMatchedPoolsResultList);
    String provisioningTypeUnManagedObject =
        UnManagedVolume.SupportedProvisioningType.getProvisioningType(
            isThinlyProvisionedUnManagedObject);
    StoragePool storagePool = dbClient.queryObject(StoragePool.class, poolUri);
    for (VirtualPool vPool : vPoolsMatchedPools) {
      if (!VirtualPool.vPoolSpecifiesHighAvailability(vPool)) {
        List<StoragePool> validPools = VirtualPool.getValidStoragePools(vPool, dbClient, true);
        for (StoragePool sPool : validPools) {
          if (sPool.getId().equals(storagePool.getId())
              && provisioningTypeUnManagedObject.equalsIgnoreCase(
                  vPool.getSupportedProvisioningType())) {
            vpoolUriSet.add(vPool.getId().toString());
            break;
          }
        }
      }
    }

    return vpoolUriSet;
  }
 /**
  * Validate the Target Volume VirtualArray with the Source Volume VPool VirtualArray.
  *
  * @param type
  * @param unManagedVolume
  * @param virtualArray
  */
 private void validateTargetVolumeVpoolWithSourceVolume(
     UnManagedVolume unManagedVolume, VirtualArray virtualArray) {
   String sourceUnManagedVolumeId =
       PropertySetterUtil.extractValueFromStringSet(
           SupportedVolumeInformation.REMOTE_MIRROR_SOURCE_VOLUME.toString(),
           unManagedVolume.getVolumeInformation());
   String sourceVolumeId =
       sourceUnManagedVolumeId.replace(
           VolumeIngestionUtil.UNMANAGEDVOLUME, VolumeIngestionUtil.VOLUME);
   List<URI> sourceUris =
       _dbClient.queryByConstraint(
           AlternateIdConstraint.Factory.getVolumeNativeGuidConstraint(sourceVolumeId));
   if (sourceUris.isEmpty()) {
     _logger.info(
         "Source {} Not found for target {}", sourceVolumeId, unManagedVolume.getNativeGuid());
   } else {
     // if source volume is ingested, then
     Volume sourceVolume = _dbClient.queryObject(Volume.class, sourceUris.get(0));
     // check whether the source Volume's VPool is actually having this
     // target Volume's varray
     // specified as remote
     VirtualPool sourceVPool =
         _dbClient.queryObject(VirtualPool.class, sourceVolume.getVirtualPool());
     Map<URI, VpoolRemoteCopyProtectionSettings> settings =
         sourceVPool.getRemoteProtectionSettings(sourceVPool, _dbClient);
     if (null == settings || settings.isEmpty() || !settings.containsKey(virtualArray.getId())) {
       _logger.info(
           "Target Volume's VArray {} is not matching already ingested source volume virtual pool's remote VArray ",
           virtualArray.getId());
       throw IngestionException.exceptions.unmanagedSRDFTargetVolumeVArrayMismatch(
           unManagedVolume.getLabel(), sourceVolume.getVirtualArray().toString());
     }
   }
 }
  // Getting all the vpools
  public static StringSet getMatchedVirtualPoolsForPool(DbClient dbClient, URI poolUri) {
    StringSet vpoolUriSet = new StringSet();
    // We should match all virtual pools as below:
    // 1) Virtual pools which have useMatchedPools set to true and have the storage pool in their
    // matched pools
    // 2) Virtual pools which have the storage pool in their assigned pools

    URIQueryResultList vpoolMatchedPoolsResultList = new URIQueryResultList();
    dbClient.queryByConstraint(
        ContainmentConstraint.Factory.getMatchedPoolVirtualPoolConstraint(poolUri),
        vpoolMatchedPoolsResultList);
    List<VirtualPool> vPoolsMatchedPools =
        dbClient.queryObject(VirtualPool.class, vpoolMatchedPoolsResultList);
    StoragePool storagePool = dbClient.queryObject(StoragePool.class, poolUri);
    for (VirtualPool vPool : vPoolsMatchedPools) {
      List<StoragePool> validPools = VirtualPool.getValidStoragePools(vPool, dbClient, true);
      for (StoragePool sPool : validPools) {
        if (sPool.getId().equals(storagePool.getId())) {
          vpoolUriSet.add(vPool.getId().toString());
          break;
        }
      }
    }

    return vpoolUriSet;
  }
  /**
   * Checks the UnManaged Volume's policy with vPool's policy.
   *
   * @param vPool the vPool
   * @param autoTierPolicyId the auto tier policy id on unmanaged volume
   * @param system the system
   * @return true, if matching, false otherwise
   */
  public static boolean checkVPoolValidForUnManagedVolumeAutoTieringPolicy(
      VirtualPool vPool, String autoTierPolicyId, StorageSystem system) {

    _log.debug("Policy Id: {}, vPool: {}", autoTierPolicyId, vPool);
    boolean policyMatching = false;
    String policyIdfromVPool = vPool.getAutoTierPolicyName();
    if (autoTierPolicyId != null) {
      if (policyIdfromVPool != null) {
        if (vPool.getUniquePolicyNames()
            || DiscoveredDataObject.Type.vnxblock.name().equalsIgnoreCase(system.getSystemType())) {
          // Unique Policy names field will not be set for VNX. vPool will have policy name, not the
          // policy's nativeGuid
          policyIdfromVPool =
              NativeGUIDGenerator.generateAutoTierPolicyNativeGuid(
                  system.getNativeGuid(),
                  policyIdfromVPool,
                  NativeGUIDGenerator.getTieringPolicyKeyForSystem(system));
          _log.debug("Policy Id generated: {}", policyIdfromVPool);
        }
        if (autoTierPolicyId.equalsIgnoreCase(policyIdfromVPool)) {
          policyMatching = true;
        }
      }
    } else if ((policyIdfromVPool == null) || (policyIdfromVPool.equalsIgnoreCase("none"))) {
      // if policy is not set in both unmanaged volume and vPool. Note
      // that the value in the vpool could be set to "none".
      policyMatching = true;
    }

    // Default policy for VNX - match volume with default policy to vPool with no policy as well
    if (!policyMatching
        && DiscoveredDataObject.Type.vnxblock.name().equalsIgnoreCase(system.getSystemType())) {
      if (autoTierPolicyId != null
          && autoTierPolicyId.contains(VnxFastPolicy.DEFAULT_START_HIGH_THEN_AUTOTIER.name())
          && policyIdfromVPool == null) {
        policyMatching = true;
      }
    }

    // Default policy for HDS - match volume with default policy to vPool with no policy as well
    if (!policyMatching
        && DiscoveredDataObject.Type.hds.name().equalsIgnoreCase(system.getSystemType())) {
      if (autoTierPolicyId != null
          && autoTierPolicyId.contains(HitachiTieringPolicy.All.name())
          && policyIdfromVPool == null) {
        policyMatching = true;
      }
    }

    return policyMatching;
  }
  @Override
  public void process() {
    logger.info("Processing virtual pool auto tiering policy migration");

    DbClient dbClient = getDbClient();
    try {
      List<URI> virtualPoolUris = dbClient.queryByType(VirtualPool.class, true);
      Iterator<VirtualPool> virtualPools =
          dbClient.queryIterativeObjects(VirtualPool.class, virtualPoolUris, true);

      while (virtualPools.hasNext()) {
        VirtualPool virtualPool = virtualPools.next();
        // If there is a FAST policy associated with the vpool, then mark the uniquePolicyNames to
        // true
        if (virtualPool.getAutoTierPolicyName() != null
            && !virtualPool.getAutoTierPolicyName().isEmpty()) {
          // No way other than using contains to differentiate NativeGuid
          if (virtualPool.getAutoTierPolicyName().contains(NATIVE_GUID_DELIMITER)) {
            virtualPool.setUniquePolicyNames(false);
          } else {
            virtualPool.setUniquePolicyNames(true);
          }
          dbClient.persistObject(virtualPool);
          logger.info(
              "Updating VirtualPool (id={}) with  unique policy names set to {}",
              virtualPool.getId().toString(),
              virtualPool.getUniquePolicyNames());
        }
      }
    } catch (Exception ex) {
      logger.error("Exception occured while migrating auto tiering policy of vpool");
      logger.error(ex.getMessage(), ex);
    }
  }
 /**
  * Validate the SourceVolume VArray details with ingested target volumes VArray.
  *
  * @param unManagedVolume
  * @param VirtualPool
  * @return
  */
 private void validateSourceVolumeVarrayWithTargetVPool(
     UnManagedVolume unManagedVolume, VirtualPool sourceVPool) {
   StringSetMap unManagedVolumeInformation = unManagedVolume.getVolumeInformation();
   // find whether all targets are ingested
   StringSet targetUnManagedVolumeGuids =
       unManagedVolumeInformation.get(SupportedVolumeInformation.REMOTE_MIRRORS.toString());
   if (null != targetUnManagedVolumeGuids && !targetUnManagedVolumeGuids.isEmpty()) {
     StringSet targetVolumeNativeGuids =
         VolumeIngestionUtil.getListofVolumeIds(targetUnManagedVolumeGuids);
     // check whether target exists
     List<URI> targetUris = VolumeIngestionUtil.getVolumeUris(targetVolumeNativeGuids, _dbClient);
     if (null == targetUris || targetUris.isEmpty()) {
       _logger.info(
           "None of the targets ingested for source volume: {}", unManagedVolume.getNativeGuid());
     } else {
       List<Volume> targetVolumes = _dbClient.queryObject(Volume.class, targetUris);
       for (Volume targetVolume : targetVolumes) {
         Map<URI, VpoolRemoteCopyProtectionSettings> settings =
             sourceVPool.getRemoteProtectionSettings(sourceVPool, _dbClient);
         if (null == settings
             || settings.size() == 0
             || !settings.containsKey(targetVolume.getVirtualArray())) {
           _logger.info(
               "Target Volume's VArray {} is not matching already ingested source volume virtual pool's remote VArray {}",
               targetVolume.getVirtualArray(),
               Joiner.on(",").join(settings.keySet()));
           throw IngestionException.exceptions.unmanagedSRDFSourceVolumeVArrayMismatch(
               unManagedVolume.getLabel(), targetVolume.getVirtualArray().toString());
         }
       }
     }
   }
 }
  /**
   * Allocate, initialize and persist state of the Bucket being created.
   *
   * @param param
   * @param project
   * @param tenantOrg
   * @param neighborhood
   * @param vpool
   * @param flags
   * @param placement
   * @return
   */
  private Bucket prepareBucket(
      BucketParam param,
      Project project,
      TenantOrg tenantOrg,
      VirtualArray neighborhood,
      VirtualPool vpool,
      DataObject.Flag[] flags,
      BucketRecommendation placement) {
    _log.debug("Preparing Bucket creation for Param : {}", param);
    StoragePool pool = null;
    Bucket bucket = new Bucket();
    bucket.setId(URIUtil.createId(Bucket.class));
    bucket.setLabel(param.getLabel().replaceAll(SPECIAL_CHAR_REGEX, ""));
    bucket.setHardQuota(SizeUtil.translateSize(param.getHardQuota()));
    bucket.setSoftQuota(SizeUtil.translateSize(param.getSoftQuota()));
    bucket.setRetention(Integer.valueOf(param.getRetention()));
    bucket.setOwner(getOwner(param.getOwner()));
    bucket.setNamespace(tenantOrg.getNamespace());
    bucket.setVirtualPool(param.getVpool());
    if (project != null) {
      bucket.setProject(new NamedURI(project.getId(), bucket.getLabel()));
    }
    bucket.setTenant(new NamedURI(tenantOrg.getId(), param.getLabel()));
    bucket.setVirtualArray(neighborhood.getId());

    if (null != placement.getSourceStoragePool()) {
      pool = _dbClient.queryObject(StoragePool.class, placement.getSourceStoragePool());
      if (null != pool) {
        bucket.setProtocol(new StringSet());
        bucket
            .getProtocol()
            .addAll(
                VirtualPoolUtil.getMatchingProtocols(vpool.getProtocols(), pool.getProtocols()));
      }
    }

    bucket.setStorageDevice(placement.getSourceStorageSystem());
    bucket.setPool(placement.getSourceStoragePool());
    bucket.setOpStatus(new OpStatusMap());

    // Bucket name to be used at Storage System
    String bucketName = project.getLabel() + UNDER_SCORE + param.getLabel();
    bucket.setName(bucketName.replaceAll(SPECIAL_CHAR_REGEX, ""));

    // Update Bucket path
    StringBuilder bucketPath = new StringBuilder();
    bucketPath
        .append(tenantOrg.getNamespace())
        .append(SLASH)
        .append(project.getLabel())
        .append(SLASH)
        .append(param.getLabel());
    bucket.setPath(bucketPath.toString());

    if (flags != null) {
      bucket.addInternalFlags(flags);
    }
    _dbClient.createObject(bucket);
    return bucket;
  }
 @Override
 protected void setProtocol(StoragePool pool, Volume volume, VirtualPool vPool) {
   if (null == volume.getProtocol()) {
     volume.setProtocol(new StringSet());
   }
   volume.getProtocol().addAll(vPool.getProtocols());
 }
  /**
   * Filters supported vPools in UnManaged Volume based on Auto-Tiering Policy.
   *
   * @param unManagedVolume the UnManaged volume
   * @param policyName the policy name associated with UnManaged volume
   * @param system the system
   * @param dbClient the db client
   */
  public static void filterSupportedVpoolsBasedOnTieringPolicy(
      UnManagedVolume unManagedVolume, String policyName, StorageSystem system, DbClient dbClient) {

    StringSetMap unManagedVolumeInformation = unManagedVolume.getVolumeInformation();
    StringSet supportedVpoolURIs =
        unManagedVolumeInformation.get(SupportedVolumeInformation.SUPPORTED_VPOOL_LIST.toString());
    List<String> vPoolsToRemove = new ArrayList<String>();
    if (supportedVpoolURIs != null) {
      Iterator<String> itr = supportedVpoolURIs.iterator();
      while (itr.hasNext()) {
        String uri = itr.next();
        VirtualPool vPool = dbClient.queryObject(VirtualPool.class, URI.create(uri));
        if (vPool != null && !vPool.getInactive()) {
          // generate unmanaged volume's policyId
          String autoTierPolicyId =
              NativeGUIDGenerator.generateAutoTierPolicyNativeGuid(
                  system.getNativeGuid(),
                  policyName,
                  NativeGUIDGenerator.getTieringPolicyKeyForSystem(system));
          if (!checkVPoolValidForUnManagedVolumeAutoTieringPolicy(
              vPool, autoTierPolicyId, system)) {
            String msg =
                "Removing vPool %s from SUPPORTED_VPOOL_LIST in UnManagedVolume %s "
                    + "since Auto-tiering Policy %s in UnManaged Volume does not match with vPool's (%s)";
            _log.info(
                String.format(
                    msg,
                    new Object[] {
                      uri, unManagedVolume.getId(), autoTierPolicyId, vPool.getAutoTierPolicyName()
                    }));
            vPoolsToRemove.add(uri);
          }
        } else {
          // remove Inactive vPool URI
          vPoolsToRemove.add(uri);
        }
      }
    }
    for (String uri : vPoolsToRemove) { // UnManagedVolume object is persisted by caller
      supportedVpoolURIs.remove(uri);
    }
  }
  /**
   * Get the summary list of all Quotas for the given tenant
   *
   * @prereq none
   * @param tenant_id the URN of the tenant asking for quotas
   * @param target_tenant_id
   * @brief Get the summary list of all Quotas
   * @return Quota details of target_tenant_id
   */
  @GET
  @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
  @Path("/{target_tenant_id}")
  @CheckPermission(
      roles = {Role.SYSTEM_MONITOR, Role.TENANT_ADMIN},
      acls = {ACL.ANY})
  public Response getQuotaDetails(
      @PathParam("target_tenant_id") String openstack_target_tenant_id,
      @Context HttpHeaders header) {

    Project project =
        getCinderHelper().getProject(openstack_target_tenant_id.toString(), getUserFromContext());

    if (project == null) {
      throw APIException.badRequests.projectWithTagNonexistent(openstack_target_tenant_id);
    }

    long maxQuota = 0;
    if (project.getQuotaEnabled()) {
      maxQuota = (long) (project.getQuota().intValue());
    } else {
      maxQuota = DEFAULT_PROJECT_TOTALGB_QUOTA;
    }

    List<URI> quotas = _dbClient.queryByType(QuotaOfCinder.class, true);
    Map<String, String> vpoolsMap = new HashMap<String, String>();
    boolean bDefProjQuotasExist = false;

    CinderQuotaDetails respCinderQuota = new CinderQuotaDetails();

    for (URI quota : quotas) {
      QuotaOfCinder quotaObj = _dbClient.queryObject(QuotaOfCinder.class, quota);

      if ((quotaObj.getProject() != null)
          && (quotaObj.getProject().toString().equalsIgnoreCase(project.getId().toString()))) {
        if (quotaObj.getVpool() != null) {
          VirtualPool pool = _dbClient.queryObject(VirtualPool.class, quotaObj.getVpool());
          respCinderQuota.quota_set.put(
              "gigabytes" + "_" + pool.getLabel(), String.valueOf(quotaObj.getTotalQuota()));
          respCinderQuota.quota_set.put(
              "snapshots" + "_" + pool.getLabel(), String.valueOf(quotaObj.getSnapshotsLimit()));
          respCinderQuota.quota_set.put(
              "volumes" + "_" + pool.getLabel(), String.valueOf(quotaObj.getVolumesLimit()));
          vpoolsMap.put(pool.getLabel(), pool.getLabel());
        } else {
          respCinderQuota.quota_set.put("gigabytes", String.valueOf(quotaObj.getTotalQuota()));
          respCinderQuota.quota_set.put("snapshots", String.valueOf(quotaObj.getSnapshotsLimit()));
          respCinderQuota.quota_set.put(
              "volumes", String.valueOf(quotaObj.getVolumesLimit().intValue()));
          bDefProjQuotasExist = true;
        }
      }
    }

    if (!bDefProjQuotasExist) {
      respCinderQuota.quota_set.put("gigabytes", String.valueOf(maxQuota));
      respCinderQuota.quota_set.put("snapshots", String.valueOf(DEFAULT_PROJECT_SNAPSHOTS_QUOTA));
      respCinderQuota.quota_set.put("volumes", String.valueOf(DEFAULT_PROJECT_VOLUMES_QUOTA));
      getCinderHelper().createProjectDefaultQuota(project);
    }

    StorageOSUser user = getUserFromContext();
    URI tenantId = URI.create(user.getTenantId());

    List<URI> vpools = _dbClient.queryByType(VirtualPool.class, true);
    for (URI vpool : vpools) {
      VirtualPool pool = _dbClient.queryObject(VirtualPool.class, vpool);
      _log.debug("Looking up vpool {}", pool.getLabel());
      if (pool != null && pool.getType().equalsIgnoreCase(VirtualPool.Type.block.name())) {
        if (_permissionsHelper.tenantHasUsageACL(tenantId, pool)) {
          if (vpoolsMap.containsKey(pool.getLabel())) {
            continue;
          } else {
            respCinderQuota.quota_set.put(
                "gigabytes" + "_" + pool.getLabel(),
                String.valueOf(DEFAULT_VOLUME_TYPE_TOTALGB_QUOTA));
            respCinderQuota.quota_set.put(
                "snapshots" + "_" + pool.getLabel(),
                String.valueOf(DEFAULT_VOLUME_TYPE_SNAPSHOTS_QUOTA));
            respCinderQuota.quota_set.put(
                "volumes" + "_" + pool.getLabel(),
                String.valueOf(DEFAULT_VOLUME_TYPE_VOLUMES_QUOTA));
            getCinderHelper().createVpoolDefaultQuota(project, pool);
          }
        }
      }
    }

    return getQuotaDetailFormat(header, respCinderQuota);
  }
  /**
   * Places and prepares the HA volumes when copying a distributed VPLEX volume.
   *
   * @param name The base name for the volume.
   * @param copyCount The number of copies to be made.
   * @param size The size for the HA volume.
   * @param vplexSystem A reference to the VPLEX storage system.
   * @param vplexSystemProject A reference to the VPLEX system project.
   * @param srcVarray The virtual array for the VPLEX volume being copied.
   * @param srcHAVolume The HA volume of the VPLEX volume being copied.
   * @param taskId The task identifier.
   * @param volumeDescriptors The list of descriptors.
   * @return A list of the prepared HA volumes for the VPLEX volume copy.
   */
  private List<Volume> prepareFullCopyHAVolumes(
      String name,
      int copyCount,
      Long size,
      StorageSystem vplexSystem,
      Project vplexSystemProject,
      VirtualArray srcVarray,
      Volume srcHAVolume,
      String taskId,
      List<VolumeDescriptor> volumeDescriptors) {

    List<Volume> copyHAVolumes = new ArrayList<Volume>();

    // Get the storage placement recommendations for the volumes.
    // Placement must occur on the same VPLEX system
    Set<URI> vplexSystemURIS = new HashSet<URI>();
    vplexSystemURIS.add(vplexSystem.getId());
    VirtualArray haVarray =
        _dbClient.queryObject(VirtualArray.class, srcHAVolume.getVirtualArray());
    VirtualPool haVpool = _dbClient.queryObject(VirtualPool.class, srcHAVolume.getVirtualPool());
    VirtualPoolCapabilityValuesWrapper haCapabilities = new VirtualPoolCapabilityValuesWrapper();
    haCapabilities.put(VirtualPoolCapabilityValuesWrapper.SIZE, size);
    haCapabilities.put(VirtualPoolCapabilityValuesWrapper.RESOURCE_COUNT, copyCount);
    VirtualPool vpool = BlockFullCopyUtils.queryFullCopySourceVPool(srcHAVolume, _dbClient);
    if (VirtualPool.ProvisioningType.Thin.toString()
        .equalsIgnoreCase(vpool.getSupportedProvisioningType())) {
      haCapabilities.put(VirtualPoolCapabilityValuesWrapper.THIN_PROVISIONING, Boolean.TRUE);
      // To guarantee that storage pool for a copy has enough physical
      // space to contain current allocated capacity of thin source volume
      haCapabilities.put(
          VirtualPoolCapabilityValuesWrapper.THIN_VOLUME_PRE_ALLOCATE_SIZE,
          BlockFullCopyUtils.getAllocatedCapacityForFullCopySource(srcHAVolume, _dbClient));
    }
    List<Recommendation> recommendations =
        ((VPlexScheduler) _scheduler)
            .scheduleStorageForImport(
                srcVarray, vplexSystemURIS, haVarray, haVpool, haCapabilities);
    if (recommendations.isEmpty()) {
      throw APIException.badRequests.noStorageForHaVolumesForVplexVolumeCopies();
    }

    // Prepare the HA volumes for the VPLEX volume copy.
    int copyIndex = 1;
    for (Recommendation recommendation : recommendations) {
      VPlexRecommendation haRecommendation = (VPlexRecommendation) recommendation;
      for (int i = 0; i < haRecommendation.getResourceCount(); i++) {
        // Determine the name for the HA volume copy.
        StringBuilder nameBuilder = new StringBuilder(name);
        nameBuilder.append("-1");
        if (copyCount > 1) {
          nameBuilder.append("-");
          nameBuilder.append(copyIndex++);
        }

        // Prepare the volume.
        Volume volume =
            VPlexBlockServiceApiImpl.prepareVolumeForRequest(
                size,
                vplexSystemProject,
                haVarray,
                haVpool,
                haRecommendation.getSourceDevice(),
                haRecommendation.getSourcePool(),
                nameBuilder.toString(),
                null,
                taskId,
                _dbClient);
        volume.addInternalFlags(Flag.INTERNAL_OBJECT);
        _dbClient.persistObject(volume);
        copyHAVolumes.add(volume);

        // Create the volume descriptor and add it to the passed list.
        VolumeDescriptor volumeDescriptor =
            new VolumeDescriptor(
                VolumeDescriptor.Type.BLOCK_DATA,
                volume.getStorageController(),
                volume.getId(),
                volume.getPool(),
                haCapabilities);
        volumeDescriptors.add(volumeDescriptor);
      }
    }

    return copyHAVolumes;
  }
  /**
   * Updates Bucket values like Quota and Retention.
   *
   * @param id Bucket ID
   * @param param Bucket update parameter
   * @return Task resource representation
   * @throws InternalException if update fails
   */
  @PUT
  @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
  @Path("/{id}")
  @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
  @CheckPermission(
      roles = {Role.TENANT_ADMIN},
      acls = {ACL.OWN, ACL.ALL})
  public TaskResourceRep updateBucket(@PathParam("id") URI id, BucketUpdateParam param)
      throws InternalException {
    Bucket bucket = null;
    ArgValidator.checkFieldUriType(id, Bucket.class, "id");
    bucket = _dbClient.queryObject(Bucket.class, id);
    ArgValidator.checkEntity(bucket, id, isIdEmbeddedInURL(id));

    Long softQuota = SizeUtil.translateSize(param.getSoftQuota());
    Long hardQuota = SizeUtil.translateSize(param.getHardQuota());
    Integer retention = null != param.getRetention() ? Integer.valueOf(param.getRetention()) : 0;

    // if no softquota is provided, use the old value
    if (softQuota == 0) {
      softQuota = bucket.getSoftQuota();
    }

    // if no hardquota is provided, use the old value
    if (hardQuota == 0) {
      hardQuota = bucket.getHardQuota();
    }

    // Hard Quota should be more than SoftQuota
    verifyQuotaValues(softQuota, hardQuota, bucket.getLabel());

    // if no retention is provided, use the old value
    if (retention == 0) {
      retention = bucket.getRetention();
    }

    VirtualPool cos = _dbClient.queryObject(VirtualPool.class, bucket.getVirtualPool());
    // verify retention. Its validated only if Retention is configured.
    if (retention != 0 && cos.getMaxRetention() != 0 && retention > cos.getMaxRetention()) {
      throw APIException.badRequests.insufficientRetentionForVirtualPool(cos.getLabel(), "bucket");
    }

    String task = UUID.randomUUID().toString();
    _log.info(String.format("BucketUpdate --- Bucket id: %1$s, Task: %2$s", id, task));

    StorageSystem storageSystem =
        _dbClient.queryObject(StorageSystem.class, bucket.getStorageDevice());

    Operation op =
        _dbClient.createTaskOpStatus(
            Bucket.class, bucket.getId(), task, ResourceOperationTypeEnum.UPDATE_BUCKET);
    op.setDescription("Bucket update");
    ObjectController controller =
        getController(ObjectController.class, storageSystem.getSystemType());

    controller.updateBucket(bucket.getStorageDevice(), id, softQuota, hardQuota, retention, task);

    auditOp(
        OperationTypeEnum.UPDATE_BUCKET,
        true,
        AuditLogManager.AUDITOP_BEGIN,
        bucket.getId().toString(),
        bucket.getStorageDevice().toString());

    return toTask(bucket, task, op);
  }
  /**
   * Update a quota
   *
   * @prereq none
   * @param tenant_id the URN of the tenant
   * @param target_tenant_id the URN of the target tenant for which quota is being modified
   * @brief Update Quota
   * @return Quota details of target_tenant_id
   */
  @PUT
  @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
  @Path("/{target_tenant_id}")
  @CheckPermission(
      roles = {Role.SYSTEM_MONITOR, Role.TENANT_ADMIN},
      acls = {ACL.ANY})
  public Response updateQuota(
      @PathParam("tenant_id") String openstack_tenant_id,
      @PathParam("target_tenant_id") String openstack_target_tenant_id,
      CinderQuotaDetails quotaUpdates,
      @Context HttpHeaders header) {

    _log.info("Updating Quota");
    Project project =
        getCinderHelper().getProject(openstack_target_tenant_id.toString(), getUserFromContext());
    if (project == null) {
      throw APIException.badRequests.projectWithTagNonexistent(openstack_target_tenant_id);
    }

    long maxQuota = 0L;
    if (project.getQuotaEnabled()) {
      maxQuota = (long) (project.getQuota().intValue());
    } else {
      maxQuota = DEFAULT_PROJECT_TOTALGB_QUOTA;
    }

    // bVpoolQuotaUpdate will be set to true if the user is updating the quota of a vpool w.r.t a
    // project
    // bVpoolQuotaUpdate will be set to false if the user is updating the quota of the project
    boolean bVpoolQuotaUpdate = isVpoolQuotaUpdate(quotaUpdates.quota_set);
    String vpoolName = null;
    VirtualPool objVpool = null;

    if (bVpoolQuotaUpdate) {
      vpoolName = getVpoolName(quotaUpdates.quota_set);
      _log.info("Vpool for which quota is being updated is {}", vpoolName);
      objVpool = getCinderHelper().getVpool(vpoolName);

      if (objVpool == null) {
        _log.info("vpool with the given name doesnt exist");
        throw APIException.badRequests.parameterIsNotValid(vpoolName);
      }
      _log.info("objVpool.getLabel() is {}", objVpool.getLabel());
    }

    List<URI> quotas = _dbClient.queryByType(QuotaOfCinder.class, true);
    boolean noEntriesInDB = true;
    for (URI quota : quotas) {
      QuotaOfCinder quotaObj = _dbClient.queryObject(QuotaOfCinder.class, quota);
      if ((quotaObj.getProject() != null)
          && (quotaObj.getProject().toString().equalsIgnoreCase(project.getId().toString()))) {
        _log.info("QuotaObj being updated is {}", quotaObj.toString());

        URI vpoolUri = quotaObj.getVpool();

        if ((!bVpoolQuotaUpdate) && (vpoolUri != null)) {
          // The user requested update of project quota.
          // But the current db entry quota for vpool w.r.t project.
          // Hence just skip the db entry as this is not our concern.
          continue;
        }

        if ((bVpoolQuotaUpdate) && (vpoolUri != null)) {
          // The user requested quota update for a vpool w.r.t a project.
          // The current db entry that we looking into has vpool entry.
          // Hence we should further check if the vpool value is same as the vpool for which the
          // user wants to set quota
          VirtualPool pool = _dbClient.queryObject(VirtualPool.class, vpoolUri);
          if ((pool != null)
              && (pool.getLabel().equals(vpoolName))
              && (vpoolName != null)
              && (vpoolName.length() > 0)) {

            if (quotaUpdates.quota_set.containsKey("gigabytes_" + vpoolName))
              quotaObj.setTotalQuota(
                  new Long(quotaUpdates.quota_set.get("gigabytes_" + vpoolName)));
            if (quotaUpdates.quota_set.containsKey("volumes_" + vpoolName))
              quotaObj.setVolumesLimit(
                  new Long(quotaUpdates.quota_set.get("volumes_" + vpoolName)));
            if (quotaUpdates.quota_set.containsKey("snapshots_" + vpoolName))
              quotaObj.setSnapshotsLimit(
                  new Long(quotaUpdates.quota_set.get("snapshots_" + vpoolName)));
            noEntriesInDB = false;
            _dbClient.updateObject(quotaObj);
            return getQuotaDetailFormat(header, quotaUpdates);
          }
        } else if (!bVpoolQuotaUpdate) {
          // The user requested update of project quota.
          // The current db entry is a project quota entity.(because to reach here vpoolUri should
          // be Null.
          if (quotaUpdates.quota_set.containsKey("gigabytes"))
            quotaObj.setTotalQuota(new Long(quotaUpdates.quota_set.get("gigabytes")));
          if (quotaUpdates.quota_set.containsKey("volumes"))
            quotaObj.setVolumesLimit(new Long(quotaUpdates.quota_set.get("volumes")));
          if (quotaUpdates.quota_set.containsKey("snapshots"))
            quotaObj.setSnapshotsLimit(new Long(quotaUpdates.quota_set.get("snapshots")));
          noEntriesInDB = false;
          _dbClient.updateObject(quotaObj);
          return getQuotaDetailFormat(header, quotaUpdates);
        }
      }
    }

    if (noEntriesInDB) {
      _log.info("No entries in the QuotaOfCinder column family");
      QuotaOfCinder objQuotaOfCinder = new QuotaOfCinder();
      objQuotaOfCinder.setProject(project.getId());

      if (bVpoolQuotaUpdate) {
        objQuotaOfCinder.setVpool(objVpool.getId());
        _log.info("Updating Quota of Vpool");
        if (quotaUpdates.quota_set.containsKey("gigabytes_" + vpoolName))
          objQuotaOfCinder.setTotalQuota(
              new Long(quotaUpdates.quota_set.get("gigabytes_" + vpoolName)));
        else objQuotaOfCinder.setTotalQuota(DEFAULT_VOLUME_TYPE_TOTALGB_QUOTA);

        if (quotaUpdates.quota_set.containsKey("volumes_" + vpoolName))
          objQuotaOfCinder.setVolumesLimit(
              new Long(quotaUpdates.quota_set.get("volumes_" + vpoolName)));
        else objQuotaOfCinder.setVolumesLimit(DEFAULT_VOLUME_TYPE_VOLUMES_QUOTA);

        if (quotaUpdates.quota_set.containsKey("snapshots_" + vpoolName))
          objQuotaOfCinder.setSnapshotsLimit(
              new Long(quotaUpdates.quota_set.get("snapshots_" + vpoolName)));
        else objQuotaOfCinder.setSnapshotsLimit(DEFAULT_VOLUME_TYPE_SNAPSHOTS_QUOTA);

      } else {
        if (quotaUpdates.quota_set.containsKey("gigabytes"))
          objQuotaOfCinder.setTotalQuota(new Long(quotaUpdates.quota_set.get("gigabytes")));
        else objQuotaOfCinder.setTotalQuota(maxQuota);

        if (quotaUpdates.quota_set.containsKey("volumes"))
          objQuotaOfCinder.setVolumesLimit(new Long(quotaUpdates.quota_set.get("volumes")));
        else objQuotaOfCinder.setVolumesLimit(DEFAULT_PROJECT_VOLUMES_QUOTA);

        if (quotaUpdates.quota_set.containsKey("snapshots"))
          objQuotaOfCinder.setSnapshotsLimit(new Long(quotaUpdates.quota_set.get("snapshots")));
        else objQuotaOfCinder.setSnapshotsLimit(DEFAULT_PROJECT_SNAPSHOTS_QUOTA);
      }
      objQuotaOfCinder.setId(URI.create(UUID.randomUUID().toString()));
      _dbClient.createObject(objQuotaOfCinder);
      return getQuotaDetailFormat(header, quotaUpdates);
    }
    return getQuotaDetailFormat(header, quotaUpdates);
  }
  private TaskResourceRep initiateBucketCreation(
      BucketParam param, Project project, TenantOrg tenant, DataObject.Flag[] flags)
      throws InternalException {
    ArgValidator.checkFieldUriType(param.getVpool(), VirtualPool.class, "vpool");
    ArgValidator.checkFieldUriType(param.getVarray(), VirtualArray.class, "varray");

    Long softQuota = SizeUtil.translateSize(param.getSoftQuota());
    Long hardQuota = SizeUtil.translateSize(param.getHardQuota());
    Integer retention = Integer.valueOf(param.getRetention());

    // Hard Quota should be more than SoftQuota
    verifyQuotaValues(softQuota, hardQuota, param.getLabel());

    // check varray
    VirtualArray neighborhood = _dbClient.queryObject(VirtualArray.class, param.getVarray());
    ArgValidator.checkEntity(neighborhood, param.getVarray(), false);
    _permissionsHelper.checkTenantHasAccessToVirtualArray(tenant.getId(), neighborhood);

    // check vpool reference
    VirtualPool cos = _dbClient.queryObject(VirtualPool.class, param.getVpool());
    _permissionsHelper.checkTenantHasAccessToVirtualPool(tenant.getId(), cos);
    ArgValidator.checkEntity(cos, param.getVpool(), false);
    if (!VirtualPool.Type.object.name().equals(cos.getType())) {
      throw APIException.badRequests.virtualPoolNotForObjectStorage(VirtualPool.Type.object.name());
    }

    // verify retention. Its validated only if Retention is configured.
    if (retention != 0 && cos.getMaxRetention() != 0 && retention > cos.getMaxRetention()) {
      throw APIException.badRequests.insufficientRetentionForVirtualPool(cos.getLabel(), "bucket");
    }

    VirtualPoolCapabilityValuesWrapper capabilities = new VirtualPoolCapabilityValuesWrapper();

    capabilities.put(VirtualPoolCapabilityValuesWrapper.RESOURCE_COUNT, Integer.valueOf(1));
    capabilities.put(VirtualPoolCapabilityValuesWrapper.THIN_PROVISIONING, Boolean.FALSE);

    List<BucketRecommendation> placement =
        _bucketScheduler.placeBucket(neighborhood, cos, capabilities);
    if (placement.isEmpty()) {
      throw APIException.badRequests.noMatchingStoragePoolsForVpoolAndVarray(
          cos.getId(), neighborhood.getId());
    }

    // Randomly select a recommended pool
    Collections.shuffle(placement);
    BucketRecommendation recommendation = placement.get(0);

    String task = UUID.randomUUID().toString();
    Bucket bucket = prepareBucket(param, project, tenant, neighborhood, cos, flags, recommendation);

    _log.info(
        String.format(
            "createBucket --- Bucket: %1$s, StoragePool: %2$s, StorageSystem: %3$s",
            bucket.getId(),
            recommendation.getSourceStoragePool(),
            recommendation.getSourceStorageSystem()));

    Operation op =
        _dbClient.createTaskOpStatus(
            Bucket.class, bucket.getId(), task, ResourceOperationTypeEnum.CREATE_BUCKET);
    op.setDescription("Bucket Create");

    // Controller invocation
    StorageSystem system =
        _dbClient.queryObject(StorageSystem.class, recommendation.getSourceStorageSystem());
    ObjectController controller = getController(ObjectController.class, system.getSystemType());
    controller.createBucket(
        recommendation.getSourceStorageSystem(),
        recommendation.getSourceStoragePool(),
        bucket.getId(),
        bucket.getName(),
        bucket.getNamespace(),
        bucket.getRetention(),
        bucket.getHardQuota(),
        bucket.getSoftQuota(),
        bucket.getOwner(),
        task);

    auditOp(
        OperationTypeEnum.CREATE_BUCKET,
        true,
        AuditLogManager.AUDITOP_BEGIN,
        param.getLabel(),
        param.getHardQuota(),
        neighborhood.getId().toString(),
        project == null ? null : project.getId().toString());

    return toTask(bucket, task, op);
  }
 public String getVPoolName() {
   return vPool.getLabel();
 }
 // replace all Special Characters ; /-+!@#$%^&())";:[]{}\ |
 public String getVPoolNameWithNoSpecialCharacters() {
   return stripSpecialCharacters(vPool.getLabel());
 }
  /**
   * Release a file system from its current tenant & project for internal object usage
   *
   * @param id the URN of a ViPR file system to be released
   * @return the updated file system
   * @throws InternalException
   */
  @POST
  @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
  @Path("/{id}/release")
  public FileShareRestRep releaseFileSystemInternal(@PathParam("id") URI id)
      throws InternalException {

    ArgValidator.checkFieldUriType(id, FileShare.class, "id");
    FileShare fs = _fileService.queryResource(id);

    // if the FS is already marked as internal, we can skip all this logic
    // and just return success down at the bottom
    if (!fs.checkInternalFlags(Flag.INTERNAL_OBJECT)) {
      URI tenantURI = fs.getTenant().getURI();
      if (!_permissionsHelper.userHasGivenRole(
          getUserFromContext(), tenantURI, Role.TENANT_ADMIN)) {
        throw APIException.forbidden.onlyAdminsCanReleaseFileSystems(Role.TENANT_ADMIN.toString());
      }

      // we can't release a fs that has exports
      FSExportMap exports = fs.getFsExports();
      if ((exports != null) && (!exports.isEmpty())) {
        throw APIException.badRequests.cannotReleaseFileSystemExportExists(
            exports.keySet().toString());
      }

      // we can't release a fs that has shares
      SMBShareMap shares = fs.getSMBFileShares();
      if ((shares != null) && (!shares.isEmpty())) {
        throw APIException.badRequests.cannotReleaseFileSystemSharesExists(
            shares.keySet().toString());
      }

      // files systems with pending operations can't be released
      if (fs.getOpStatus() != null) {
        for (String opId : fs.getOpStatus().keySet()) {
          Operation op = fs.getOpStatus().get(opId);
          if (Operation.Status.pending.name().equals(op.getStatus())) {
            throw APIException.badRequests.cannotReleaseFileSystemWithTasksPending();
          }
        }
      }

      // file systems with snapshots can't be released
      Integer snapCount = _fileService.getNumSnapshots(fs);
      if (snapCount > 0) {
        throw APIException.badRequests.cannotReleaseFileSystemSnapshotExists(snapCount);
      }

      TenantOrg rootTenant = _permissionsHelper.getRootTenant();

      // we can't release the file system to the root tenant if the root tenant has no access
      // to the filesystem's virtual pool
      ArgValidator.checkFieldNotNull(fs.getVirtualPool(), "virtualPool");
      VirtualPool virtualPool =
          _permissionsHelper.getObjectById(fs.getVirtualPool(), VirtualPool.class);
      ArgValidator.checkEntity(virtualPool, fs.getVirtualPool(), false);
      if (!_permissionsHelper.tenantHasUsageACL(rootTenant.getId(), virtualPool)) {
        throw APIException.badRequests.cannotReleaseFileSystemRootTenantLacksVPoolACL(
            virtualPool.getId().toString());
      }

      fs.setOriginalProject(fs.getProject().getURI());
      fs.setTenant(new NamedURI(rootTenant.getId(), fs.getLabel()));
      fs.setProject(new NamedURI(_internalProject.getId(), fs.getLabel()));
      fs.addInternalFlags(INTERNAL_FILESHARE_FLAGS);
      _dbClient.updateAndReindexObject(fs);

      // audit against the source project, not the new dummy internal project
      auditOp(
          OperationTypeEnum.RELEASE_FILE_SYSTEM,
          true,
          null,
          fs.getId().toString(),
          fs.getOriginalProject().toString());
    }

    return map(fs);
  }
  /**
   * Updates the initiator to target list map in the export mask
   *
   * @throws Exception
   */
  private void updateTargetsInExportMask(
      StorageSystem storage,
      Volume volume,
      Map<Volume, Map<String, List<String>>> volumeToInitiatorTargetMapFromAttachResponse,
      List<Initiator> fcInitiatorList,
      ExportMask exportMask)
      throws Exception {
    log.debug("START - updateTargetsInExportMask");
    // ITLS for initiator URIs vs Target port URIs - This will be the final
    // filtered list to send for the zoning map update
    Map<URI, List<URI>> mapFilteredInitiatorURIVsTargetURIList = new HashMap<URI, List<URI>>();

    // From the initiators list, construct the map of initiator WWNs to
    // their URIs
    Map<String, URI> initiatorsWWNVsURI = getWWNvsURIFCInitiatorsMap(fcInitiatorList);

    URI varrayURI = volume.getVirtualArray();

    /*
     * Get the list of storage ports from the storage system which are
     * associated with the varray This will be map of storage port WWNs with
     * their URIs
     */
    Map<String, URI> mapVarrayTaggedPortWWNVsURI =
        getVarrayTaggedStoragePortWWNs(storage, varrayURI);

    // List of WWN entries, used below for filtering the target port list
    // from attach response
    Set<String> varrayTaggedPortWWNs = mapVarrayTaggedPortWWNVsURI.keySet();

    URI vpoolURI = volume.getVirtualPool();
    VirtualPool vpool = dbClient.queryObject(VirtualPool.class, vpoolURI);
    int pathsPerInitiator = vpool.getPathsPerInitiator();

    // Process the attach response output
    Set<Volume> volumeKeysSet = volumeToInitiatorTargetMapFromAttachResponse.keySet();
    for (Volume volumeRes : volumeKeysSet) {
      log.info(
          String.format(
              "Processing attach response for the volume with URI %s and name %s",
              volumeRes.getId(), volumeRes.getLabel()));
      Map<String, List<String>> initiatorTargetMap =
          volumeToInitiatorTargetMapFromAttachResponse.get(volumeRes);
      Set<String> initiatorKeysSet = initiatorTargetMap.keySet();
      for (String initiatorKey : initiatorKeysSet) {
        // The list of filtered target ports ( which are varray tagged )
        // from the attach response
        List<String> filteredTargetList =
            filterTargetsFromResponse(varrayTaggedPortWWNs, initiatorTargetMap, initiatorKey);
        log.info(
            String.format(
                "For initiator %s accessible storage ports are %s ",
                initiatorKey, filteredTargetList.toString()));

        List<String> tmpTargetList = null;
        if (!isVplex(volumeRes)) {
          // For VPLEX - no path validations
          // Path validations are required only for the Host Exports
          tmpTargetList = checkPathsPerInitiator(pathsPerInitiator, filteredTargetList);

          if (null == tmpTargetList) {
            // Rollback case - throw the exception
            throw new Exception(
                String.format(
                    "Paths per initiator criteria is not met for the initiator : %s "
                        + " Target counts is: %s Expected paths per initiator is: %s",
                    initiatorKey,
                    String.valueOf(filteredTargetList.size()),
                    String.valueOf(pathsPerInitiator)));
          }

        } else {
          tmpTargetList = filteredTargetList;
        }

        // Now populate URIs for the map to be returned - convert WWNs
        // to URIs
        populateInitiatorTargetURIMap(
            mapFilteredInitiatorURIVsTargetURIList,
            initiatorsWWNVsURI,
            mapVarrayTaggedPortWWNVsURI,
            initiatorKey,
            tmpTargetList);
      } // End initiator iteration
    } // End volume iteration

    // Clean all existing targets in the export mask and add new targets
    List<URI> storagePortListFromMask =
        StringSetUtil.stringSetToUriList(exportMask.getStoragePorts());
    for (URI removeUri : storagePortListFromMask) {
      exportMask.removeTarget(removeUri);
    }
    exportMask.setStoragePorts(null);

    // Now add new target ports and populate the zoning map
    Set<URI> initiatorURIKeys = mapFilteredInitiatorURIVsTargetURIList.keySet();
    for (URI initiatorURI : initiatorURIKeys) {
      List<URI> storagePortURIList = mapFilteredInitiatorURIVsTargetURIList.get(initiatorURI);
      for (URI portURI : storagePortURIList) {
        exportMask.addTarget(portURI);
      }
    }

    log.debug("END - updateTargetsInExportMask");
  }
 /**
  * * Check if the request is for vplex.
  *
  * @param volume
  * @return
  */
 private boolean isVplex(Volume volume) {
   boolean isVplex = false;
   VirtualPool vpool = dbClient.queryObject(VirtualPool.class, volume.getVirtualPool());
   isVplex = VirtualPool.vPoolSpecifiesHighAvailability(vpool);
   return isVplex;
 }
  /**
   * Filter vpools from the qualified list. rpSource true: Filter out anything other than RP source
   * vpools rpSource false: Filter out RP and SRDF source vpools
   *
   * @param dbClient dbclient
   * @param unManagedVolume unmanaged volume
   * @param personality SOURCE, TARGET, or METADATA
   */
  private void filterProtectedVpools(
      DbClient dbClient, UnManagedVolume unManagedVolume, String personality) {

    if (unManagedVolume.getSupportedVpoolUris() != null
        && !unManagedVolume.getSupportedVpoolUris().isEmpty()) {
      Iterator<VirtualPool> vpoolItr =
          dbClient.queryIterativeObjects(
              VirtualPool.class, URIUtil.toURIList(unManagedVolume.getSupportedVpoolUris()));
      while (vpoolItr.hasNext()) {
        boolean remove = false;
        VirtualPool vpool = vpoolItr.next();

        // If this is an SRDF source vpool, we can filter out since we're dealing with an RP volume
        if (vpool.getProtectionRemoteCopySettings() != null) {
          remove = true;
        }

        // If this is not an RP source, the vpool should be filtered out if:
        // The vpool is an RP vpool (has settings) and target vpools are non-null
        if (vpool.getProtectionVarraySettings() != null
            && ((Volume.PersonalityTypes.TARGET.name().equalsIgnoreCase(personality))
                || Volume.PersonalityTypes.METADATA.name().equalsIgnoreCase(personality))) {
          boolean foundEmptyTargetVpool = false;
          Map<URI, VpoolProtectionVarraySettings> settings =
              VirtualPool.getProtectionSettings(vpool, dbClient);
          for (Map.Entry<URI, VpoolProtectionVarraySettings> setting : settings.entrySet()) {
            if (NullColumnValueGetter.isNullURI(setting.getValue().getVirtualPool())) {
              foundEmptyTargetVpool = true;
              break;
            }
          }

          // If this is a journal volume, also check the journal vpools. If they're not set, we
          // cannot filter out this vpool.
          if (Volume.PersonalityTypes.METADATA.name().equalsIgnoreCase(personality)
              && (NullColumnValueGetter.isNullValue(vpool.getJournalVpool())
                  || NullColumnValueGetter.isNullValue(vpool.getStandbyJournalVpool()))) {
            foundEmptyTargetVpool = true;
          }

          // If every relevant target (and journal for journal volumes) vpool is filled-in, then
          // you would never assign your target volume to this source vpool, so filter it out.
          if (!foundEmptyTargetVpool) {
            remove = true;
          }
        }

        if (Volume.PersonalityTypes.SOURCE.name().equalsIgnoreCase(personality)) {
          if (!VirtualPool.vPoolSpecifiesProtection(vpool)) {
            // If this an RP source, the vpool must be an RP vpool
            remove = true;
          } else if (unManagedVolume
                  .getVolumeInformation()
                  .containsKey(SupportedVolumeInformation.RP_STANDBY_INTERNAL_SITENAME.toString())
              && !VirtualPool.vPoolSpecifiesMetroPoint(vpool)) {
            // Since this is a Source volume with the presence of RP_STANDBY_INTERNAL_SITENAME
            // it indicates that this volume is MetroPoint, if we get here, this is vpool
            // must be filtered out since it's not MP.
            remove = true;
          }
        }

        if (remove) {
          log.info(
              "Removing virtual pool "
                  + vpool.getLabel()
                  + " from supported vpools for unmanaged volume: "
                  + unManagedVolume.getLabel());
          unManagedVolume.getSupportedVpoolUris().remove(vpool.getId().toString());
        }
      }
    }
  }