use of com.emc.storageos.db.client.model.Volume in project coprhd-controller by CoprHD.
the class RPDeviceController method disableImageForSnapshots.
/**
* Disable image access for RP snapshots.
*
* @param protectionDevice
* protection system
* @param snapshotList
* list of snapshots to enable
* @param setSnapshotSyncActive
* true if the isSyncActive field on BlockSnapshot should be true, false otherwise.
* @param opId
* @throws ControllerException
*/
private void disableImageForSnapshots(URI protectionDevice, List<URI> snapshotList, boolean setSnapshotSyncActive, String opId) throws ControllerException {
BlockSnapshotDeactivateCompleter completer = null;
try {
_log.info("Deactivating a bookmark on the RP CG(s)");
completer = new BlockSnapshotDeactivateCompleter(snapshotList, setSnapshotSyncActive, opId);
ProtectionSystem system = null;
try {
system = _dbClient.queryObject(ProtectionSystem.class, protectionDevice);
} catch (DatabaseException e) {
throw DeviceControllerExceptions.recoverpoint.databaseExceptionDeactivateSnapshot(protectionDevice);
}
if (system == null) {
throw DeviceControllerExceptions.recoverpoint.databaseExceptionDeactivateSnapshot(protectionDevice);
}
// Keep a mapping of the emNames(bookmark names) to target copy volume WWNs
Map<String, Set<String>> emNamesToVolumeWWNs = new HashMap<String, Set<String>>();
// Keep a mapping of the emNames(bookmark names) to BlockSnapshot objects
Map<String, Set<URI>> emNamesToSnapshots = new HashMap<String, Set<URI>>();
for (URI snapshotID : snapshotList) {
BlockSnapshot snapshot = _dbClient.queryObject(BlockSnapshot.class, snapshotID);
// Determine if we can actually disable image access to the copy associated with the snapshot first
if (!doDisableImageCopies(snapshot)) {
// Skip this snapshot because we cannot disable image access. Likely due to the snapshot
// being exported to multiple hosts.
_log.warn(String.format("Cannot disable image access for snapshot %s so it will be skipped. Likely due to the snapshot being exported to multiple hosts", snapshot.getId()));
continue;
}
String emName = snapshot.getEmName();
if (NullColumnValueGetter.isNotNullValue(emName)) {
if (!emNamesToVolumeWWNs.containsKey(emName)) {
emNamesToVolumeWWNs.put(emName, new HashSet<String>());
}
if (!emNamesToSnapshots.containsKey(emName)) {
emNamesToSnapshots.put(emName, new HashSet<URI>());
}
emNamesToSnapshots.get(emName).add(snapshotID);
} else {
throw DeviceControllerExceptions.recoverpoint.failedToDeactivateSnapshotEmNameMissing(snapshotID);
}
// Get the volume associated with this snapshot
Volume volume = _dbClient.queryObject(Volume.class, snapshot.getParent().getURI());
// Fetch the VPLEX volume that is created with this volume as the back-end volume.
if (Volume.checkForVplexBackEndVolume(_dbClient, volume)) {
volume = Volume.fetchVplexVolume(_dbClient, volume);
}
String wwn = null;
// If the personality is SOURCE, then the enable image access request is part of export operation.
if (volume.checkPersonality(Volume.PersonalityTypes.TARGET.toString())) {
wwn = RPHelper.getRPWWn(volume.getId(), _dbClient);
} else {
// Now determine the target volume that corresponds to the site of the snapshot
ProtectionSet protectionSet = _dbClient.queryObject(ProtectionSet.class, volume.getProtectionSet());
Volume targetVolume = ProtectionSet.getTargetVolumeFromSourceAndInternalSiteName(_dbClient, protectionSet, volume, snapshot.getEmInternalSiteName());
wwn = RPHelper.getRPWWn(targetVolume.getId(), _dbClient);
}
// Add the volume WWN
emNamesToVolumeWWNs.get(emName).add(wwn);
}
// Now disable image access on the bookmark copies
RecoverPointClient rp = RPHelper.getRecoverPointClient(system);
// correponding to each emName.
for (Map.Entry<String, Set<String>> emNameEntry : emNamesToVolumeWWNs.entrySet()) {
MultiCopyDisableImageRequestParams request = new MultiCopyDisableImageRequestParams();
request.setVolumeWWNSet(emNameEntry.getValue());
request.setEmName(emNameEntry.getKey());
MultiCopyDisableImageResponse response = rp.disableImageCopies(request);
if (response == null) {
throw DeviceControllerExceptions.recoverpoint.failedDisableAccessOnRP();
}
// Let the completer know about the deactivated snapshots (ones who's associated copies
// had image access disabled). This will be used to update the BlockSnapshot fields accordingly.
// This is done because not all snapshots used when creating the completer will be deactivated.
// We need to maintain a collection of snapshots so that those exported to multiple hosts to not
// get deactivated.
completer.addDeactivatedSnapshots(emNamesToSnapshots.get(emNameEntry.getKey()));
}
completer.ready(_dbClient);
} catch (InternalException e) {
_log.error("Operation failed with Exception: ", e);
if (completer != null) {
completer.error(_dbClient, e);
}
} catch (URISyntaxException e) {
_log.error("Operation failed with Exception: ", e);
if (completer != null) {
completer.error(_dbClient, DeviceControllerException.errors.invalidURI(e));
}
} catch (Exception e) {
_log.error("Operation failed with Exception: ", e);
if (completer != null) {
completer.error(_dbClient, DeviceControllerException.errors.jobFailed(e));
}
}
}
use of com.emc.storageos.db.client.model.Volume in project coprhd-controller by CoprHD.
the class RPDeviceController method addExportRemoveVolumesSteps.
/**
* Add the steps that will remove the volumes from the export group
* TODO: This could stand to be refactored to be simpler.
*
* @param workflow
* workflow object
* @param waitFor
* step that these steps are dependent on
* @param filteredSourceVolumeDescriptors
* volumes to act on
* @return "waitFor" step that future steps should wait on
* @throws InternalException
*/
private String addExportRemoveVolumesSteps(Workflow workflow, String waitFor, List<VolumeDescriptor> filteredSourceVolumeDescriptors) throws InternalException {
_log.info("Adding steps to remove volumes from export groups.");
String returnStep = waitFor;
Set<URI> volumeURIs = RPHelper.getVolumesToDelete(VolumeDescriptor.getVolumeURIs(filteredSourceVolumeDescriptors), _dbClient);
_log.info(String.format("Following volume(s) will be unexported from their RP export groups : [%s]", Joiner.on("--").join(volumeURIs)));
Map<URI, RPExport> rpExports = new HashMap<URI, RPExport>();
for (URI volumeURI : volumeURIs) {
Volume volume = _dbClient.queryObject(Volume.class, volumeURI);
if (volume == null) {
_log.warn("Could not load volume with given URI: " + volumeURI);
continue;
}
// get the protection system for this volume
URI rpSystemId = volume.getProtectionController();
ProtectionSystem rpSystem = null;
if (rpSystemId != null) {
rpSystem = _dbClient.queryObject(ProtectionSystem.class, rpSystemId);
if (rpSystem == null || rpSystem.getInactive()) {
_log.warn("No protection system information found for volume {}. Volume cannot be removed from RP export groups.", volume.getLabel());
continue;
}
}
// Get the storage controller URI of the volume
URI storageURI = volume.getStorageController();
// Get the vpool of the volume
VirtualPool virtualPool = _dbClient.queryObject(VirtualPool.class, volume.getVirtualPool());
if (VirtualPool.isRPVPlexProtectHASide(virtualPool)) {
_log.info(String.format("RP+VPLEX protect HA Source Volume [%s] to be removed from RP export group.", volume.getLabel()));
// the HA side export group only.
if (volume.getAssociatedVolumes() != null && volume.getAssociatedVolumes().size() == 2) {
for (String associatedVolURI : volume.getAssociatedVolumes()) {
Volume associatedVolume = _dbClient.queryObject(Volume.class, URI.create(associatedVolURI));
if (associatedVolume.getVirtualArray().toString().equals(virtualPool.getHaVarrayConnectedToRp())) {
ExportGroup exportGroup = getExportGroup(rpSystem, volume.getId(), associatedVolume.getVirtualArray(), associatedVolume.getInternalSiteName());
if (exportGroup != null) {
_log.info(String.format("Removing volume [%s] from RP export group [%s].", volume.getLabel(), exportGroup.getGeneratedName()));
}
// Assuming we've found the correct Export Group for this volume, let's
// then add the information we need to the rpExports map.
addExportGroup(rpExports, exportGroup, volumeURI, storageURI);
break;
}
}
}
} else if (volume.getAssociatedVolumes() != null && volume.getAssociatedVolumes().size() == 2) {
for (String associatedVolURI : volume.getAssociatedVolumes()) {
_log.info(String.format("VPLEX %s Volume [%s] to be removed from RP export group.", volume.getPersonality(), associatedVolURI));
Volume associatedVolume = _dbClient.queryObject(Volume.class, URI.create(associatedVolURI));
String internalSiteName = associatedVolume.getInternalSiteName();
URI virtualArray = associatedVolume.getVirtualArray();
if (!VirtualPool.vPoolSpecifiesMetroPoint(virtualPool)) {
// Only MetroPoint associated volumes will have the internalSiteName set. For VPlex distributed volumes
// the parent (virtual volume) internal site name should be used.
internalSiteName = volume.getInternalSiteName();
// If we are using the parent volume's internal site name, we also need to use the parent volume's virtual array.
// Again, only in the case of MetroPoint volumes would we want to use the associated volume's virtual array.
virtualArray = volume.getVirtualArray();
}
ExportGroup exportGroup = getExportGroup(rpSystem, volume.getId(), virtualArray, internalSiteName);
if (exportGroup != null) {
_log.info(String.format("Removing volume [%s] from RP export group [%s].", volume.getLabel(), exportGroup.getGeneratedName()));
}
// Assuming we've found the correct Export Group for this volume, let's
// then add the information we need to the rpExports map.
addExportGroup(rpExports, exportGroup, volumeURI, storageURI);
}
} else {
_log.info(String.format("Volume [%s] to be removed from RP export group.", volume.getLabel()));
// Find the Export Group for this regular RP volume
ExportGroup exportGroup = getExportGroup(rpSystem, volume.getId(), volume.getVirtualArray(), volume.getInternalSiteName());
if (exportGroup != null) {
_log.info(String.format("Removing volume [%s] from RP export group [%s].", volume.getLabel(), exportGroup.getGeneratedName()));
}
// Assuming we've found the correct Export Group for this volume, let's
// then add the information we need to the rpExports map.
addExportGroup(rpExports, exportGroup, volumeURI, storageURI);
}
}
// Generate the workflow steps for export volume removal and volume deletion
for (URI exportURI : rpExports.keySet()) {
_log.info(String.format("RP export group will have these volumes removed: [%s]", Joiner.on(',').join(rpExports.get(exportURI).getVolumes())));
RPExport rpExport = rpExports.get(exportURI);
if (!rpExport.getVolumes().isEmpty()) {
_exportWfUtils.generateExportGroupRemoveVolumes(workflow, STEP_DV_REMOVE_VOLUME_EXPORT, waitFor, rpExport.getStorageSystem(), exportURI, rpExport.getVolumes());
returnStep = STEP_DV_REMOVE_VOLUME_EXPORT;
}
}
_log.info("Completed adding steps to remove volumes from RP export groups.");
return returnStep;
}
use of com.emc.storageos.db.client.model.Volume in project coprhd-controller by CoprHD.
the class RPDeviceController method createSnapshot.
/*
* (non-Javadoc)
*
* @see com.emc.storageos.protectioncontroller.RPController#createSnapshot(java.net.URI, java.net.URI, java.util.List,
* java.lang.Boolean, java.lang.Boolean, java.lang.String)
*/
@Override
public void createSnapshot(URI protectionDevice, URI storageURI, List<URI> snapshotList, Boolean createInactive, Boolean readOnly, String opId) throws InternalException {
TaskCompleter completer = new BlockSnapshotCreateCompleter(snapshotList, opId);
// if snapshot is part of a CG, add CG id to the completer
List<BlockSnapshot> snapshots = _dbClient.queryObject(BlockSnapshot.class, snapshotList);
ControllerUtils.checkSnapshotsInConsistencyGroup(snapshots, _dbClient, completer);
Map<URI, Integer> snapshotMap = new HashMap<URI, Integer>();
try {
ProtectionSystem system = null;
system = _dbClient.queryObject(ProtectionSystem.class, protectionDevice);
// Verify non-null storage device returned from the database client.
if (system == null) {
throw DeviceControllerExceptions.recoverpoint.failedConnectingForMonitoring(protectionDevice);
}
// Make sure we have at least 1 snap/bookmark otherwise there is nothing to create
if (snapshotList == null || snapshotList.isEmpty()) {
throw DeviceControllerExceptions.recoverpoint.failedToFindExpectedBookmarks();
}
// A temporary date/time stamp
String snapshotName = VIPR_SNAPSHOT_PREFIX + new SimpleDateFormat("yyMMdd-HHmmss").format(new java.util.Date());
Set<String> volumeWWNs = new HashSet<String>();
boolean rpBookmarkOnly = false;
for (URI snapshotID : snapshotList) {
// create a snapshot map, a map is required to re-use the existing enable image access method.
// using a lun number of -1 for all snaps, this value is not used, hence ok to use that value.
snapshotMap.put(snapshotID, ExportGroup.LUN_UNASSIGNED);
}
// Get the volume associated with this snapshot.
// Note we could have multiple snapshots in this request depending on the number of targets for the
// source. We only need 1 of the snapshots to create the bookmark on RP. So just grab the
// first one in the list.
BlockSnapshot snapshot = _dbClient.queryObject(BlockSnapshot.class, snapshotList.get(0));
if (snapshot.getEmName() != null) {
rpBookmarkOnly = true;
snapshotName = snapshot.getEmName();
}
Volume volume = _dbClient.queryObject(Volume.class, snapshot.getParent().getURI());
// if not, then the "volume" object is a regular block volume that is RP protected.
if (Volume.checkForVplexBackEndVolume(_dbClient, volume)) {
volumeWWNs.add(RPHelper.getRPWWn(Volume.fetchVplexVolume(_dbClient, volume).getId(), _dbClient));
} else {
volumeWWNs.add(RPHelper.getRPWWn(volume.getId(), _dbClient));
}
// Create a new token/taskid and use that in the workflow.
// Multiple threads entering this method might collide with each others workflows in cassandra if the taskid
// is not unique.
String newToken = UUID.randomUUID().toString();
// Set up workflow steps.
Workflow workflow = _workflowService.getNewWorkflow(this, "createSnapshot", true, newToken);
// Step 1 - Create a RP bookmark
String waitFor = addCreateBookmarkStep(workflow, snapshotList, system, snapshotName, volumeWWNs, rpBookmarkOnly, null);
if (!rpBookmarkOnly) {
// Local array snap, additional steps required for snap operation
// Step 2 - Enable image access
waitFor = addEnableImageAccessStep(workflow, system, snapshotMap, waitFor);
// Step 3 - Invoke block storage doCreateSnapshot
waitFor = addCreateBlockSnapshotStep(workflow, waitFor, storageURI, snapshotList, createInactive, readOnly, system);
// Step 4 - Disable image access
addBlockSnapshotDisableImageAccessStep(workflow, waitFor, snapshotList, system);
} else {
_log.info("RP Bookmark only requested...");
}
String successMessage = String.format("Successfully created snapshot for %s", Joiner.on(",").join(snapshotList));
workflow.executePlan(completer, successMessage);
} catch (InternalException e) {
_log.error("Operation failed with Exception: ", e);
if (completer != null) {
completer.error(_dbClient, e);
}
} catch (Exception e) {
_log.error("Operation failed with Exception: ", e);
if (completer != null) {
completer.error(_dbClient, DeviceControllerException.errors.jobFailed(e));
}
}
}
use of com.emc.storageos.db.client.model.Volume in project coprhd-controller by CoprHD.
the class RPDeviceController method upgradeRPVPlexToMetroPoint.
/**
* Upgrades a RP+VPLEX CG to MetroPoint by adding a standby journal to the HA side.
*
* Prerequisite: All RSets(volumes) in the CG must have had their HA sides already exported to RP in VPLEX.
*
* @param sourceVolume
* A single source volume from the CG, we only need one.
* @param rpSystem
* The rpSystem we're using
*/
private void upgradeRPVPlexToMetroPoint(Volume sourceVolume, VirtualPool newVpool, VirtualPool oldVpool, ProtectionSystem rpSystem) {
// Grab the new standby journal from the CG
String standbyCopyName = RPHelper.getStandbyProductionCopyName(_dbClient, sourceVolume);
List<Volume> existingStandbyJournals = RPHelper.findExistingJournalsForCopy(_dbClient, sourceVolume.getConsistencyGroup(), standbyCopyName);
if (existingStandbyJournals.isEmpty()) {
_log.error(String.format("Could not find standby journal during upgrade to MetroPoint operation. " + "Expected to find a new standby journal for RP copy [%s]", standbyCopyName));
throw RecoverPointException.exceptions.cannotFindJournal(String.format("for RP copy [%s]", standbyCopyName));
}
Volume standbyProdJournal = existingStandbyJournals.get(0);
// Add new standby journal
if (standbyProdJournal != null) {
_log.info(String.format("Upgrade RP+VPLEX CG to MetroPoint by adding new standby journal [%s] to the CG", standbyProdJournal.getLabel()));
RecoverPointClient rp = RPHelper.getRecoverPointClient(rpSystem);
RecoverPointVolumeProtectionInfo protectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(sourceVolume.getId(), _dbClient));
_log.info(String.format("RecoverPointVolumeProtectionInfo [%s] retrieved", protectionInfo.getRpProtectionName()));
RPCopyRequestParams copyParams = new RPCopyRequestParams();
copyParams.setCopyVolumeInfo(protectionInfo);
List<CreateVolumeParams> journaVols = new ArrayList<CreateVolumeParams>();
CreateVolumeParams journalVolParams = new CreateVolumeParams();
journalVolParams.setWwn(RPHelper.getRPWWn(standbyProdJournal.getId(), _dbClient));
journalVolParams.setInternalSiteName(standbyProdJournal.getInternalSiteName());
journaVols.add(journalVolParams);
CreateCopyParams standbyProdCopyParams = new CreateCopyParams();
standbyProdCopyParams.setName(standbyProdJournal.getRpCopyName());
standbyProdCopyParams.setJournals(journaVols);
_log.info(String.format("Adding standby journal [%s] to teh RP CG...", standbyProdJournal.getLabel()));
// TODO BH - Empty, not sure why we need this
List<CreateRSetParams> rSets = new ArrayList<CreateRSetParams>();
rp.addStandbyProductionCopy(standbyProdCopyParams, null, rSets, copyParams);
_log.info("Standby journal added successfully.");
// TODO Add new Targets if they exist ??
// Next we need to update the vpool reference of any existing related volumes
// that were referencing the old vpool.
// We'll start by getting all source volumes from the ViPR CG
BlockConsistencyGroup viprCG = _dbClient.queryObject(BlockConsistencyGroup.class, sourceVolume.getConsistencyGroup());
List<Volume> allSourceVolumesInCG = BlockConsistencyGroupUtils.getActiveVplexVolumesInCG(viprCG, _dbClient, Volume.PersonalityTypes.SOURCE);
for (Volume sourceVol : allSourceVolumesInCG) {
// For each source volume, we'll get all the related volumes (Targets, Journals, Backing volumes for
// VPLEX...etc)
Set<Volume> allRelatedVolumes = RPHelper.getAllRelatedVolumesForSource(sourceVol.getId(), _dbClient, true, true);
// If it is, update the reference and persist the change.
for (Volume rpRelatedVol : allRelatedVolumes) {
if (rpRelatedVol.getVirtualPool().equals(oldVpool.getId())) {
rpRelatedVol.setVirtualPool(newVpool.getId());
_dbClient.updateObject(rpRelatedVol);
_log.info(String.format("Volume [%s] has had its virtual pool updated to [%s].", rpRelatedVol.getLabel(), newVpool.getLabel()));
}
}
}
}
}
use of com.emc.storageos.db.client.model.Volume in project coprhd-controller by CoprHD.
the class RPDeviceController method enableImageForSnapshots.
/**
* Enable image access for RP snapshots.
*
* @param protectionDevice
* protection system
* @param storageDevice
* storage device of the backing (parent) volume
* @param snapshotList
* list of snapshots to enable
* @param opId
* task ID
* @return true if operation was successful
* @throws ControllerException
* @throws URISyntaxException
*/
private boolean enableImageForSnapshots(URI protectionDevice, URI storageDevice, List<URI> snapshotList, String opId) throws ControllerException, URISyntaxException {
TaskCompleter completer = null;
try {
_log.info("Activating a bookmark on the RP CG(s)");
completer = new BlockSnapshotActivateCompleter(snapshotList, opId);
ProtectionSystem system = null;
try {
system = _dbClient.queryObject(ProtectionSystem.class, protectionDevice);
} catch (DatabaseException e) {
throw DeviceControllerExceptions.recoverpoint.databaseExceptionActivateSnapshot(protectionDevice);
}
// Verify non-null storage device returned from the database client.
if (system == null) {
throw DeviceControllerExceptions.recoverpoint.databaseExceptionActivateSnapshot(protectionDevice);
}
// is still creating the snapshot
if (snapshotList != null && !snapshotList.isEmpty()) {
BlockSnapshot snapshot = _dbClient.queryObject(BlockSnapshot.class, snapshotList.get(0));
Volume parent = _dbClient.queryObject(Volume.class, snapshot.getParent().getURI());
final List<Volume> vplexVolumes = CustomQueryUtility.queryActiveResourcesByConstraint(_dbClient, Volume.class, getVolumesByAssociatedId(parent.getId().toString()));
if (vplexVolumes != null && !vplexVolumes.isEmpty()) {
parent = vplexVolumes.get(0);
}
String lockName = ControllerLockingUtil.getConsistencyGroupStorageKey(_dbClient, parent.getConsistencyGroup(), system.getId());
if (null != lockName) {
List<String> locks = new ArrayList<String>();
locks.add(lockName);
acquireWorkflowLockOrThrow(_workflowService.getWorkflowFromStepId(opId), locks);
}
}
// Keep a mapping of the emNames(bookmark names) to target copy volume WWNs
Map<String, Set<String>> emNamesToVolumeWWNs = new HashMap<String, Set<String>>();
// Keep a mapping of the emNames(bookmark names) to BlockSnapshot objects
Map<String, Set<URI>> emNamesToSnapshots = new HashMap<String, Set<URI>>();
for (URI snapshotID : snapshotList) {
BlockSnapshot snapshot = _dbClient.queryObject(BlockSnapshot.class, snapshotID);
String emName = snapshot.getEmName();
if (NullColumnValueGetter.isNotNullValue(emName)) {
if (!emNamesToVolumeWWNs.containsKey(emName)) {
emNamesToVolumeWWNs.put(emName, new HashSet<String>());
}
if (!emNamesToSnapshots.containsKey(emName)) {
emNamesToSnapshots.put(emName, new HashSet<URI>());
}
emNamesToSnapshots.get(emName).add(snapshotID);
} else {
throw DeviceControllerExceptions.recoverpoint.failedToActivateSnapshotEmNameMissing(snapshotID);
}
// Get the volume associated with this snapshot
Volume volume = _dbClient.queryObject(Volume.class, snapshot.getParent().getURI());
// Fetch the VPLEX volume that is created with this volume as the back-end volume.
if (Volume.checkForVplexBackEndVolume(_dbClient, volume)) {
volume = Volume.fetchVplexVolume(_dbClient, volume);
}
String wwn = null;
// If the personality is SOURCE, then the enable image access request is part of export operation.
if (volume.checkPersonality(Volume.PersonalityTypes.TARGET.toString())) {
wwn = RPHelper.getRPWWn(volume.getId(), _dbClient);
} else {
// Now determine the target volume that corresponds to the site of the snapshot
ProtectionSet protectionSet = _dbClient.queryObject(ProtectionSet.class, volume.getProtectionSet());
Volume targetVolume = ProtectionSet.getTargetVolumeFromSourceAndInternalSiteName(_dbClient, protectionSet, volume, snapshot.getEmInternalSiteName());
wwn = RPHelper.getRPWWn(targetVolume.getId(), _dbClient);
}
// Add the volume WWN
emNamesToVolumeWWNs.get(emName).add(wwn);
}
// Now enable image access to that bookmark
RecoverPointClient rp = RPHelper.getRecoverPointClient(system);
// correponding to each emName.
for (Map.Entry<String, Set<String>> emNameEntry : emNamesToVolumeWWNs.entrySet()) {
MultiCopyEnableImageRequestParams request = new MultiCopyEnableImageRequestParams();
request.setVolumeWWNSet(emNameEntry.getValue());
request.setBookmark(emNameEntry.getKey());
MultiCopyEnableImageResponse response = rp.enableImageCopies(request);
if (response == null) {
throw DeviceControllerExceptions.recoverpoint.failedEnableAccessOnRP();
}
}
completer.ready(_dbClient);
return true;
} catch (InternalException e) {
_log.error("Operation failed with Exception: ", e);
if (completer != null) {
completer.error(_dbClient, e);
}
throw e;
} catch (URISyntaxException e) {
_log.error("Operation failed with Exception: ", e);
if (completer != null) {
completer.error(_dbClient, DeviceControllerException.errors.invalidURI(e));
}
throw e;
} catch (Exception e) {
_log.error("Operation failed with Exception: ", e);
if (completer != null) {
completer.error(_dbClient, DeviceControllerException.errors.jobFailed(e));
}
throw e;
}
}
Aggregations