/**
   * Return the rdfGroupId based on the personality. For source volume, we will not have RDFGroup
   * hence we should get it from its targets.
   *
   * @param unManagedVolumeInformation
   * @return
   */
  private URI getRDFGroupBasedOnPersonality(StringSetMap unManagedVolumeInformation) {
    String type =
        PropertySetterUtil.extractValueFromStringSet(
            SupportedVolumeInformation.REMOTE_VOLUME_TYPE.toString(), unManagedVolumeInformation);
    URI rdfGroupId = null;
    if (RemoteMirrorObject.Types.SOURCE.toString().equalsIgnoreCase(type)) {
      StringSet targetUnManagedVolumeGuids =
          unManagedVolumeInformation.get(SupportedVolumeInformation.REMOTE_MIRRORS.toString());
      if (null != targetUnManagedVolumeGuids && !targetUnManagedVolumeGuids.isEmpty()) {
        StringSet targetVolumeNativeGuids =
            VolumeIngestionUtil.getListofVolumeIds(targetUnManagedVolumeGuids);
        List<URI> targetUris =
            VolumeIngestionUtil.getVolumeUris(targetVolumeNativeGuids, _dbClient);
        if (null == targetUris || targetUris.isEmpty()) {
          List<URI> unmanagedTargetVolumes =
              VolumeIngestionUtil.getUnManagedVolumeUris(targetUnManagedVolumeGuids, _dbClient);
          for (URI targetUmv : unmanagedTargetVolumes) {
            _logger.info("RDFGroup Found using unmanaged Target volume {}", targetUmv);
            UnManagedVolume umv = _dbClient.queryObject(UnManagedVolume.class, targetUmv);
            rdfGroupId =
                URI.create(
                    PropertySetterUtil.extractValueFromStringSet(
                        SupportedVolumeInformation.REMOTE_MIRROR_RDF_GROUP.toString(),
                        umv.getVolumeInformation()));
            break;
          }
        } else {
          // If targets are already ingested.
          List<Volume> targetVolumes = _dbClient.queryObject(Volume.class, targetUris);
          if (null != targetVolumes && !targetVolumes.isEmpty()) {
            for (Volume targetVolume : targetVolumes) {
              _logger.info(
                  "RDFGroup Found for using ingested Target volumes {}.",
                  targetVolume.getNativeGuid());
              rdfGroupId = targetVolume.getSrdfGroup();
              break;
            }
          }
        }
      }

    } else if (RemoteMirrorObject.Types.TARGET.toString().equalsIgnoreCase(type)) {
      rdfGroupId =
          URI.create(
              PropertySetterUtil.extractValueFromStringSet(
                  SupportedVolumeInformation.REMOTE_MIRROR_RDF_GROUP.toString(),
                  unManagedVolumeInformation));
    }

    return rdfGroupId;
  }
 /**
  * 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());
     }
   }
 }
 /**
  * Decorates the block objects with srdf properties.
  *
  * @param blockObject
  * @param unManagedVolume
  */
 private void decorateBlockObjectWithSRDFProperties(
     BlockObject blockObject, UnManagedVolume unManagedVolume) {
   Volume volume = (Volume) blockObject;
   StringSetMap unManagedVolumeInformation = unManagedVolume.getVolumeInformation();
   String type =
       PropertySetterUtil.extractValueFromStringSet(
           SupportedVolumeInformation.REMOTE_VOLUME_TYPE.toString(), unManagedVolumeInformation);
   if (RemoteMirrorObject.Types.SOURCE.toString().equalsIgnoreCase(type)) {
     volume.setPersonality(PersonalityTypes.SOURCE.toString());
   } else if (RemoteMirrorObject.Types.TARGET.toString().equalsIgnoreCase(type)) {
     volume.setPersonality(PersonalityTypes.TARGET.toString());
     String copyMode =
         PropertySetterUtil.extractValueFromStringSet(
             SupportedVolumeInformation.REMOTE_COPY_MODE.toString(), unManagedVolumeInformation);
     String raGroup =
         PropertySetterUtil.extractValueFromStringSet(
             SupportedVolumeInformation.REMOTE_MIRROR_RDF_GROUP.toString(),
             unManagedVolumeInformation);
     volume.setSrdfCopyMode(copyMode);
     volume.setSrdfGroup(URI.create(raGroup));
   }
 }
  /**
   * Validates the UnManagedVolume SRDF Properties.
   *
   * @param unManagedVolume
   * @param virtualArray
   * @param virtualPool
   */
  private void validateUnManagedVolumeProperties(
      UnManagedVolume unManagedVolume,
      VirtualArray virtualArray,
      VirtualPool virtualPool,
      Project project) {
    StringSetMap unManagedVolumeInformation = unManagedVolume.getVolumeInformation();
    URI rdfGroupId = getRDFGroupBasedOnPersonality(unManagedVolumeInformation);
    // To make sure rdfGroup is populated for both R1 & R2 volumes.
    if (null == rdfGroupId) {
      _logger.warn(
          "SRDF Volume ingestion failed for unmanagedVolume {} as not able to find RDFGroup.",
          unManagedVolume.getNativeGuid());
      throw IngestionException.exceptions.unmanagedVolumeRDFGroupMissing(
          unManagedVolume.getNativeGuid());
    }
    RemoteDirectorGroup rdfGroup = _dbClient.queryObject(RemoteDirectorGroup.class, rdfGroupId);
    // name check, "V-<projectname>" or "<projectname>"
    StringSet grpNames = SRDFUtils.getQualifyingRDFGroupNames(project);
    // Validate the project Name with the unmanaged volume rdfGroup name.
    if (null == rdfGroup.getLabel()
        || !SRDFUtils.containsRaGroupName(grpNames, rdfGroup.getLabel())) {
      _logger.warn(
          "SRDF Volume ingestion failed for unmanagedVolume {} due to mismatch in RDF group name",
          unManagedVolume.getNativeGuid());
      throw IngestionException.exceptions.unmanagedVolumeRDFGroupMismatch(
          unManagedVolume.getNativeGuid(),
          rdfGroup.getLabel(),
          project.getLabel(),
          StringUtils.join(grpNames, ","));
    }

    String type =
        PropertySetterUtil.extractValueFromStringSet(
            SupportedVolumeInformation.REMOTE_VOLUME_TYPE.toString(), unManagedVolumeInformation);
    if (null == type) {
      _logger.warn(
          "SRDF Volume ingestion failed for unmanagedVolume {}", unManagedVolume.getNativeGuid());
      throw IngestionException.exceptions.unmanagedVolumeVolumeTypeNotSet(
          unManagedVolume.getNativeGuid());
    }
    _logger.info("Type {} Source Native Guid {}", type, unManagedVolume.getNativeGuid());

    if (RemoteMirrorObject.Types.SOURCE.toString().equalsIgnoreCase(type)) {
      validateSourceVolumeVarrayWithTargetVPool(unManagedVolume, virtualPool);
    } else if (RemoteMirrorObject.Types.TARGET.toString().equalsIgnoreCase(type)) {
      validateTargetVolumeVpoolWithSourceVolume(unManagedVolume, virtualArray);
    }
  }
  @Override
  protected void updateCGPropertiesInVolume(
      URI consistencyGroupUri,
      Volume volume,
      StorageSystem system,
      UnManagedVolume unManagedVolume) {
    if (consistencyGroupUri != null) {

      String cgName =
          PropertySetterUtil.extractValueFromStringSet(
              SupportedVolumeInformation.VPLEX_CONSISTENCY_GROUP_NAME.toString(),
              unManagedVolume.getVolumeInformation());

      BlockConsistencyGroup cg =
          _dbClient.queryObject(BlockConsistencyGroup.class, consistencyGroupUri);

      StringSet unmanagedVolumeClusters =
          unManagedVolume
              .getVolumeInformation()
              .get(SupportedVolumeInformation.VPLEX_CLUSTER_IDS.toString());
      // Add a ViPR CG mapping for each of the VPlex clusters the VPlex CG
      // belongs to.
      if (unmanagedVolumeClusters != null && !unmanagedVolumeClusters.isEmpty()) {
        Iterator<String> unmanagedVolumeClustersItr = unmanagedVolumeClusters.iterator();
        while (unmanagedVolumeClustersItr.hasNext()) {
          cg.addSystemConsistencyGroup(
              system.getId().toString(),
              BlockConsistencyGroupUtils.buildClusterCgName(
                  unmanagedVolumeClustersItr.next(), cgName));
        }

        _dbClient.updateAndReindexObject(cg);
      }

      volume.setConsistencyGroup(consistencyGroupUri);
    }
  }