// For VMAX V3 only for now
 public CIMInstance getDefaultReplicationSettingData(StorageSystem storage) throws WBEMException {
   CIMInstance defaultInstance = null;
   CloseableIterator<CIMInstance> repSvcCapIter = null;
   try {
     repSvcCapIter =
         _helper.getAssociatorInstances(
             storage,
             _cimPath.getControllerReplicationSvcPath(storage),
             null,
             _cimPath.prefixWithParamName(SmisConstants.REPLICATION_SERVICE_CAPABILTIES),
             null,
             null,
             null);
     if (repSvcCapIter != null && repSvcCapIter.hasNext()) {
       CIMInstance instance = repSvcCapIter.next();
       CIMArgument[] in = _helper.getDefaultReplicationSettingDataInputArgumentsForLocalMirror();
       CIMArgument[] out = new CIMArgument[5];
       _helper.invokeMethod(
           storage,
           instance.getObjectPath(),
           SmisConstants.GET_DEFAULT_REPLICATION_SETTING_DATA,
           in,
           out);
       defaultInstance =
           (CIMInstance) _cimPath.getFromOutputArgs(out, SmisConstants.DEFAULT_INSTANCE);
     }
   } finally {
     if (repSvcCapIter != null) {
       repSvcCapIter.close();
     }
   }
   return defaultInstance;
 }
  @Override
  public void deleteSingleVolumeMirror(
      StorageSystem storage, URI mirror, TaskCompleter taskCompleter)
      throws DeviceControllerException {
    _log.info("deleteSingleVolumeMirror operation START");
    try {
      BlockMirror mirrorObj = _dbClient.queryObject(BlockMirror.class, mirror);
      if (storage.checkIfVmax3()) {
        _helper.removeVolumeFromParkingSLOStorageGroup(storage, mirrorObj.getNativeId(), false);
        _log.info(
            "Done invoking remove volume {} from parking SLO storage group",
            mirrorObj.getNativeId());
      }

      CIMObjectPath mirrorPath = _cimPath.getBlockObjectPath(storage, mirrorObj);
      CIMObjectPath configSvcPath = _cimPath.getConfigSvcPath(storage);
      CIMArgument[] inArgs = _helper.getDeleteMirrorInputArguments(storage, mirrorPath);
      CIMArgument[] outArgs = new CIMArgument[5];
      _helper.invokeMethod(
          storage, configSvcPath, SmisConstants.RETURN_TO_STORAGE_POOL, inArgs, outArgs);
      CIMObjectPath job = _cimPath.getCimObjectPathFromOutputArgs(outArgs, SmisConstants.JOB);
      if (job != null) {
        ControllerServiceImpl.enqueueJob(
            new QueueJob(new SmisBlockDeleteMirrorJob(job, storage.getId(), taskCompleter)));
      }
    } catch (Exception e) {
      _log.info("Problem making SMI-S call: ", e);
      ServiceError serviceError =
          DeviceControllerErrors.smis.unableToCallStorageProvider(e.getMessage());
      taskCompleter.error(_dbClient, serviceError);
    }
  }
 @Override
 public void fractureSingleVolumeMirror(
     StorageSystem storage, URI mirror, Boolean sync, TaskCompleter taskCompleter)
     throws DeviceControllerException {
   _log.info("fractureSingleVolumeMirror operation START");
   CloseableIterator<CIMObjectPath> storageSyncRefs = null;
   try {
     BlockMirror mirrorObj = _dbClient.queryObject(BlockMirror.class, mirror);
     CIMObjectPath mirrorPath = _cimPath.getBlockObjectPath(storage, mirrorObj);
     // Get reference to the CIM_StorageSynchronized instance
     storageSyncRefs =
         _helper.getReference(storage, mirrorPath, SmisConstants.CIM_STORAGE_SYNCHRONIZED, null);
     boolean isVmax3 = storage.checkIfVmax3();
     while (storageSyncRefs.hasNext()) {
       CIMObjectPath storageSync = storageSyncRefs.next();
       CIMArgument[] inArgs =
           isVmax3
               ? _helper.getFractureMirrorInputArgumentsWithCopyState(storageSync, sync)
               : _helper.getFractureMirrorInputArguments(storageSync, sync);
       CIMArgument[] outArgs = new CIMArgument[5];
       // Invoke method to fracture the synchronization
       _helper.callModifyReplica(storage, inArgs, outArgs);
       taskCompleter.ready(_dbClient);
     }
   } catch (Exception e) {
     _log.info("Problem making SMI-S call", e);
     ServiceError serviceError = DeviceControllerException.errors.jobFailed(e);
     taskCompleter.error(_dbClient, serviceError);
   } finally {
     if (storageSyncRefs != null) {
       storageSyncRefs.close();
     }
   }
 }
  @Override
  public void createSingleVolumeMirror(
      StorageSystem storage, URI mirror, Boolean createInactive, TaskCompleter taskCompleter)
      throws DeviceControllerException {
    _log.info("createSingleVolumeMirror operation START");
    try {
      BlockMirror mirrorObj = _dbClient.queryObject(BlockMirror.class, mirror);
      StoragePool targetPool = _dbClient.queryObject(StoragePool.class, mirrorObj.getPool());
      Volume source = _dbClient.queryObject(Volume.class, mirrorObj.getSource());
      TenantOrg tenant = _dbClient.queryObject(TenantOrg.class, source.getTenant().getURI());
      String tenantName = tenant.getLabel();
      String targetLabelToUse =
          _nameGenerator.generate(
              tenantName,
              mirrorObj.getLabel(),
              mirror.toString(),
              '-',
              SmisConstants.MAX_VOLUME_NAME_LENGTH);
      CIMObjectPath replicationSvcPath = _cimPath.getControllerReplicationSvcPath(storage);
      CIMArgument[] inArgs = null;
      if (storage.checkIfVmax3()) {
        CIMObjectPath volumeGroupPath = _helper.getVolumeGroupPath(storage, source, targetPool);
        CIMInstance replicaSettingData = getDefaultReplicationSettingData(storage);
        inArgs =
            _helper.getCreateElementReplicaMirrorInputArguments(
                storage,
                source,
                targetPool,
                createInactive,
                targetLabelToUse,
                volumeGroupPath,
                replicaSettingData);
      } else {
        inArgs =
            _helper.getCreateElementReplicaMirrorInputArguments(
                storage, source, targetPool, createInactive, targetLabelToUse);
      }

      CIMArgument[] outArgs = new CIMArgument[5];
      _helper.invokeMethod(
          storage, replicationSvcPath, SmisConstants.CREATE_ELEMENT_REPLICA, inArgs, outArgs);
      CIMObjectPath job = _cimPath.getCimObjectPathFromOutputArgs(outArgs, SmisConstants.JOB);
      if (job != null) {
        ControllerServiceImpl.enqueueJob(
            new QueueJob(
                new SmisBlockCreateMirrorJob(
                    job, storage.getId(), !createInactive, taskCompleter)));
        // Resynchronizing state applies to the initial copy as well as future
        // re-synchronization's.
        mirrorObj.setSyncState(SynchronizationState.RESYNCHRONIZING.toString());
        _dbClient.persistObject(mirrorObj);
      }
    } catch (final InternalException e) {
      _log.info("Problem making SMI-S call: ", e);
      taskCompleter.error(_dbClient, e);
    } catch (Exception e) {
      _log.info("Problem making SMI-S call: ", e);
      ServiceError serviceError =
          DeviceControllerErrors.smis.unableToCallStorageProvider(e.getMessage());
      taskCompleter.error(_dbClient, serviceError);
    }
  }
  @Override
  public void deleteGroupMirrors(
      StorageSystem storage, List<URI> mirrorList, TaskCompleter taskCompleter)
      throws DeviceControllerException {
    _log.info("deleteGroupMirrors operation START");
    if (!((storage.getUsingSmis80() && storage.deviceIsType(Type.vmax))
        || storage.deviceIsType(Type.vnxblock))) {
      throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
    }

    try {
      String[] deviceIds = null;
      BlockMirror firstMirror = _dbClient.queryObject(BlockMirror.class, mirrorList.get(0));
      String repGroupName = firstMirror.getReplicationGroupInstance();
      if (NullColumnValueGetter.isNotNullValue(repGroupName)) {
        CIMObjectPath repGroupPath = _cimPath.getReplicationGroupPath(storage, repGroupName);
        Set<String> deviceIdsSet =
            _helper.getVolumeDeviceIdsFromStorageGroup(storage, repGroupPath);
        deviceIds = deviceIdsSet.toArray(new String[deviceIdsSet.size()]);

        // Delete replication group
        ReplicationUtils.deleteReplicationGroup(
            storage, repGroupName, _dbClient, _helper, _cimPath);
        // Set mirrors replication group to null
        List<BlockMirror> mirrors = _dbClient.queryObject(BlockMirror.class, mirrorList);
        for (BlockMirror mirror : mirrors) {
          mirror.setConsistencyGroup(NullColumnValueGetter.getNullURI());
          mirror.setReplicationGroupInstance(NullColumnValueGetter.getNullStr());
        }

        _dbClient.persistObject(mirrors);
      } else {
        deviceIds = _helper.getBlockObjectNativeIds(mirrorList);
      }

      if (storage.checkIfVmax3()) {
        for (String deviceId : deviceIds) {
          _helper.removeVolumeFromParkingSLOStorageGroup(storage, deviceId, false);
          _log.info("Done invoking remove volume {} from parking SLO storage group", deviceId);
        }
      }

      CIMObjectPath[] mirrorPaths = _cimPath.getVolumePaths(storage, deviceIds);
      CIMObjectPath configSvcPath = _cimPath.getConfigSvcPath(storage);
      CIMArgument[] inArgs = null;
      if (storage.deviceIsType(Type.vnxblock)) {
        inArgs = _helper.getReturnElementsToStoragePoolArguments(mirrorPaths);
      } else {
        inArgs =
            _helper.getReturnElementsToStoragePoolArguments(
                mirrorPaths, SmisConstants.CONTINUE_ON_NONEXISTENT_ELEMENT);
      }
      CIMArgument[] outArgs = new CIMArgument[5];
      _helper.invokeMethod(
          storage, configSvcPath, SmisConstants.RETURN_ELEMENTS_TO_STORAGE_POOL, inArgs, outArgs);
      CIMObjectPath job = _cimPath.getCimObjectPathFromOutputArgs(outArgs, SmisConstants.JOB);
      ControllerServiceImpl.enqueueJob(
          new QueueJob(new SmisBlockDeleteCGMirrorJob(job, storage.getId(), taskCompleter)));
    } catch (Exception e) {
      _log.error("Problem making SMI-S call: ", e);
      ServiceError serviceError =
          DeviceControllerErrors.smis.unableToCallStorageProvider(e.getMessage());
      taskCompleter.error(_dbClient, serviceError);
    }
  }
 @Override
 public void resumeSingleVolumeMirror(
     StorageSystem storage, URI mirror, TaskCompleter taskCompleter)
     throws DeviceControllerException {
   _log.info("resumeSingleVolumeMirror operation START");
   CloseableIterator<CIMObjectPath> storageSyncRefs = null;
   try {
     BlockMirror mirrorObj = _dbClient.queryObject(BlockMirror.class, mirror);
     CIMObjectPath mirrorPath = _cimPath.getBlockObjectPath(storage, mirrorObj);
     // Get reference to the CIM_StorageSynchronized instance
     storageSyncRefs =
         _helper.getReference(storage, mirrorPath, SmisConstants.CIM_STORAGE_SYNCHRONIZED, null);
     if (!storageSyncRefs.hasNext()) {
       _log.error("No synchronization instance found for {}", mirror);
       taskCompleter.error(
           _dbClient, DeviceControllerException.exceptions.resumeVolumeMirrorFailed(mirror));
       return;
     }
     boolean isVmax3 = storage.checkIfVmax3();
     while (storageSyncRefs.hasNext()) {
       CIMObjectPath storageSync = storageSyncRefs.next();
       _log.debug(storageSync.toString());
       /**
        * JIRA CTRL-11855 User created mirror and did pause operation using SMI 4.6.2. Then He
        * upgraded to SMI 8.0.3. While doing mirror resume getting exception from SMI because of
        * the existing mirrorObj.getSynchronizedInstance() contains
        * SystemName=\"SYMMETRIX+000195701573\"" This is wrong with 8.0.3 as
        * SystemName=\"SYMMETRIX-+-000195701573\"". To resolve this issue setting new value
        * collected from current smis provider here.
        */
       mirrorObj.setSynchronizedInstance(storageSync.toString());
       _dbClient.persistObject(mirrorObj);
       CIMArgument[] inArgs =
           isVmax3
               ? _helper.getResumeSynchronizationInputArgumentsWithCopyState(storageSync)
               : _helper.getResumeSynchronizationInputArguments(storageSync);
       CIMArgument[] outArgs = new CIMArgument[5];
       _helper.callModifyReplica(storage, inArgs, outArgs);
       CIMObjectPath job = _cimPath.getCimObjectPathFromOutputArgs(outArgs, SmisConstants.JOB);
       if (job != null) {
         ControllerServiceImpl.enqueueJob(
             new QueueJob(new SmisBlockResumeMirrorJob(job, storage.getId(), taskCompleter)));
       } else {
         CIMInstance syncObject =
             _helper.getInstance(
                 storage, storageSync, false, false, new String[] {SmisConstants.CP_SYNC_STATE});
         mirrorObj.setSyncState(
             CIMPropertyFactory.getPropertyValue(syncObject, SmisConstants.CP_SYNC_STATE));
         _dbClient.persistObject(mirrorObj);
         taskCompleter.ready(_dbClient);
       }
     }
   } catch (Exception e) {
     _log.error("Failed to resume single volume mirror: {}", mirror);
     ServiceError serviceError = DeviceControllerException.errors.jobFailed(e);
     taskCompleter.error(_dbClient, serviceError);
   } finally {
     if (storageSyncRefs != null) {
       storageSyncRefs.close();
     }
   }
 }