use of com.emc.storageos.svcs.errorhandling.model.ServiceCoded in project coprhd-controller by CoprHD.
the class RPDeviceController method performProtectionOperationStep.
/**
* Workflow step to perform RP protection operation
*
* @param protectionSystem
* @param cgId
* @param volId
* @param copyID
* @param pointInTime
* @param imageAccessMode
* @param op
* @param stepId
* @return
* @throws ControllerException
*/
public boolean performProtectionOperationStep(URI protectionSystem, URI cgId, URI volId, URI copyID, String pointInTime, String imageAccessMode, String op, String stepId) throws ControllerException {
WorkflowStepCompleter.stepExecuting(stepId);
try {
ProtectionSystem rpSystem = getRPSystem(protectionSystem);
// Take out a workflow step lock on the CG
_workflowService.getWorkflowFromStepId(stepId);
List<String> lockKeys = new ArrayList<String>();
lockKeys.add(ControllerLockingUtil.getConsistencyGroupStorageKey(_dbClient, cgId, rpSystem.getId()));
boolean lockAcquired = _workflowService.acquireWorkflowStepLocks(stepId, lockKeys, LockTimeoutValue.get(LockType.RP_CG));
if (!lockAcquired) {
throw DeviceControllerException.exceptions.failedToAcquireLock(lockKeys.toString(), String.format("failed to get lock while restoring volumes in RP consistency group: %s", cgId.toString()));
}
// set the protection volume to the source volume if the copyID is null (operation is performed on all
// copies)
// otherwise set it to the volume referenced by the copyID (operation is performed on specifc copy)
Volume protectionVolume = (copyID == null) ? _dbClient.queryObject(Volume.class, volId) : _dbClient.queryObject(Volume.class, copyID);
RecoverPointClient rp = RPHelper.getRecoverPointClient(rpSystem);
RecoverPointVolumeProtectionInfo volumeProtectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(protectionVolume.getId(), _dbClient));
if (op.equals(STOP)) {
rp.disableProtection(volumeProtectionInfo);
setProtectionSetStatus(volumeProtectionInfo, ProtectionStatus.DISABLED.toString(), rpSystem);
_log.info("doStopProtection {} - complete", rpSystem.getId());
} else if (op.equals(START)) {
rp.enableProtection(volumeProtectionInfo);
setProtectionSetStatus(volumeProtectionInfo, ProtectionStatus.ENABLED.toString(), rpSystem);
} else if (op.equals(SYNC)) {
Set<String> volumeWWNs = new HashSet<String>();
volumeWWNs.add(RPHelper.getRPWWn(protectionVolume.getId(), _dbClient));
// Create and enable a temporary bookmark for the volume associated with this volume
CreateBookmarkRequestParams request = new CreateBookmarkRequestParams();
request.setVolumeWWNSet(volumeWWNs);
request.setBookmark("Sync-Snapshot");
rp.createBookmarks(request);
} else if (op.equals(PAUSE)) {
rp.pauseTransfer(volumeProtectionInfo);
setProtectionSetStatus(volumeProtectionInfo, ProtectionStatus.PAUSED.toString(), rpSystem);
} else if (op.equals(RESUME)) {
rp.resumeTransfer(volumeProtectionInfo);
setProtectionSetStatus(volumeProtectionInfo, ProtectionStatus.ENABLED.toString(), rpSystem);
} else if (op.equals(FAILOVER_TEST)) {
RPCopyRequestParams copyParams = new RPCopyRequestParams();
copyParams.setCopyVolumeInfo(volumeProtectionInfo);
rp.failoverCopyTest(copyParams);
} else if (op.equals(FAILOVER)) {
// cancel.
if (protectionVolume.getLinkStatus() != null && protectionVolume.getLinkStatus().equalsIgnoreCase(Volume.LinkStatus.FAILED_OVER.name())) {
// TODO: ViPR 2.0 needs to support this.
// TODO BEGIN: allow re-failover perform the same as a failback in 2.0 since the UI support will not
// be there to do a
// swap or cancel.
// Jira CTRL-2773: Once UI adds support for /swap and /failover-cancel, we can remove this and
// replace with an error.
// If protectionVolume is a source, then the "source" sent in must be a target. Verify.
Volume targetVolume = null;
if (protectionVolume.checkPersonality(Volume.PersonalityTypes.SOURCE.toString())) {
targetVolume = _dbClient.queryObject(Volume.class, volId);
} else {
targetVolume = protectionVolume;
}
// Disable the image access that is in effect.
volumeProtectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(targetVolume.getId(), _dbClient));
RPCopyRequestParams copyParams = new RPCopyRequestParams();
copyParams.setCopyVolumeInfo(volumeProtectionInfo);
rp.failoverCopyCancel(copyParams);
// Set the flags back to where they belong.
updatePostFailoverCancel(targetVolume);
// TODO END
// Replace with this error: taskCompleter.error(_dbClient, _locker,
// DeviceControllerErrors.recoverpoint.stepFailed("performFailoverOperation: source volume specified
// for failover where target volume specified is not in failover state"));
} else {
// Standard failover case.
RPCopyRequestParams copyParams = new RPCopyRequestParams();
copyParams.setCopyVolumeInfo(volumeProtectionInfo);
if (pointInTime != null) {
// Build a Date reference.
copyParams.setApitTime(TimeUtils.getDateTimestamp(pointInTime));
}
rp.failoverCopy(copyParams);
updatePostFailover(protectionVolume);
}
} else if (op.equals(FAILOVER_CANCEL)) {
// cancel.
if (protectionVolume.checkPersonality(Volume.PersonalityTypes.SOURCE.name())) {
throw DeviceControllerExceptions.recoverpoint.failoverWrongTargetSpecified();
} else {
if (protectionVolume.getLinkStatus() != null && protectionVolume.getLinkStatus().equalsIgnoreCase(Volume.LinkStatus.FAILED_OVER.name())) {
// Disable the image access that is in effect.
volumeProtectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(protectionVolume.getId(), _dbClient));
RPCopyRequestParams copyParams = new RPCopyRequestParams();
copyParams.setCopyVolumeInfo(volumeProtectionInfo);
rp.failoverCopyCancel(copyParams);
// Set the flags back to where they belong.
updatePostFailoverCancel(protectionVolume);
} else {
// failed over target.
throw DeviceControllerExceptions.recoverpoint.failoverWrongTargetSpecified();
}
}
} else if (op.equals(SWAP)) {
RPCopyRequestParams copyParams = new RPCopyRequestParams();
copyParams.setCopyVolumeInfo(volumeProtectionInfo);
rp.swapCopy(copyParams);
protectionVolume = updatePostSwapPersonalities(protectionVolume);
rp.setCopyAsProduction(copyParams);
// 3. add back the standby CDP copy
if (RPHelper.isMetroPointVolume(_dbClient, protectionVolume)) {
// copy exists, we can skip all the CG reconstruction steps.
if (!rp.doesStandbyProdCopyExist(volumeProtectionInfo)) {
_log.info(String.format("Adding back standby production copy after swap back to original VPlex Metro for Metropoint volume %s (%s)", protectionVolume.getLabel(), protectionVolume.getId().toString()));
List<Volume> standbyLocalCopyVols = RPHelper.getMetropointStandbyCopies(protectionVolume, _dbClient);
CreateCopyParams standbyLocalCopyParams = null;
List<CreateRSetParams> rSets = new ArrayList<CreateRSetParams>();
Set<URI> journalVolumes = new HashSet<URI>();
if (!standbyLocalCopyVols.isEmpty()) {
for (Volume standbyCopyVol : standbyLocalCopyVols) {
// 1. delete the standby CDP copy if it exists
if (rp.doesProtectionVolumeExist(RPHelper.getRPWWn(standbyCopyVol.getId(), _dbClient))) {
RecoverPointVolumeProtectionInfo standbyCdpCopy = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(standbyCopyVol.getId(), _dbClient));
rp.deleteCopy(standbyCdpCopy);
}
// set up volume info for the standby copy volume
CreateVolumeParams vol = new CreateVolumeParams();
vol.setWwn(RPHelper.getRPWWn(standbyCopyVol.getId(), _dbClient));
vol.setInternalSiteName(standbyCopyVol.getInternalSiteName());
vol.setProduction(false);
List<CreateVolumeParams> volumes = new ArrayList<CreateVolumeParams>();
volumes.add(vol);
CreateRSetParams rSet = new CreateRSetParams();
rSet.setName(standbyCopyVol.getRSetName());
rSet.setVolumes(volumes);
rSets.add(rSet);
List<Volume> standbyJournals = RPHelper.findExistingJournalsForCopy(_dbClient, standbyCopyVol.getConsistencyGroup(), standbyCopyVol.getRpCopyName());
// compile a unique set of journal volumes
for (Volume standbyJournal : standbyJournals) {
journalVolumes.add(standbyJournal.getId());
}
}
// prepare journal volumes info
String rpCopyName = null;
List<CreateVolumeParams> journalVols = new ArrayList<CreateVolumeParams>();
for (URI journalVolId : journalVolumes) {
Volume standbyLocalJournal = _dbClient.queryObject(Volume.class, journalVolId);
if (standbyLocalJournal != null) {
_log.info(String.format("Found standby local journal volume %s (%s) for metropoint volume %s (%s)", standbyLocalJournal.getLabel(), standbyLocalJournal.getId().toString(), protectionVolume.getLabel(), protectionVolume.getId().toString()));
rpCopyName = standbyLocalJournal.getRpCopyName();
CreateVolumeParams journalVolParams = new CreateVolumeParams();
journalVolParams.setWwn(RPHelper.getRPWWn(standbyLocalJournal.getId(), _dbClient));
journalVolParams.setInternalSiteName(standbyLocalJournal.getInternalSiteName());
journalVols.add(journalVolParams);
}
}
// if we found any journal volumes, add them to the local copies list
if (!journalVols.isEmpty()) {
standbyLocalCopyParams = new CreateCopyParams();
standbyLocalCopyParams.setName(rpCopyName);
standbyLocalCopyParams.setJournals(journalVols);
} else {
_log.error("no journal volumes found for standby production copy for source volume " + protectionVolume.getLabel());
}
}
String standbyProductionCopyName = RPHelper.getStandbyProductionCopyName(_dbClient, protectionVolume);
// Build standby production journal
if (standbyProductionCopyName != null) {
List<Volume> existingStandbyJournals = RPHelper.findExistingJournalsForCopy(_dbClient, protectionVolume.getConsistencyGroup(), standbyProductionCopyName);
// Get the first standby production journal
Volume standbyProdJournal = existingStandbyJournals.get(0);
if (standbyProdJournal != null) {
_log.info(String.format("Found standby production journal volume %s (%s) for metropoint volume %s (%s)", standbyProdJournal.getLabel(), standbyProdJournal.getId().toString(), protectionVolume.getLabel(), protectionVolume.getId().toString()));
List<CreateVolumeParams> journalVols = new ArrayList<CreateVolumeParams>();
CreateVolumeParams journalVolParams = new CreateVolumeParams();
journalVolParams.setWwn(RPHelper.getRPWWn(standbyProdJournal.getId(), _dbClient));
journalVolParams.setInternalSiteName(standbyProdJournal.getInternalSiteName());
journalVols.add(journalVolParams);
CreateCopyParams standbyProdCopyParams = new CreateCopyParams();
standbyProdCopyParams.setName(standbyProdJournal.getRpCopyName());
standbyProdCopyParams.setJournals(journalVols);
// 2. and 3. add back the standby production copy; add back the standby CDP copy
rp.addStandbyProductionCopy(standbyProdCopyParams, standbyLocalCopyParams, rSets, copyParams);
} else {
_log.error(String.format("Cannot add standby production copy because the standby production journal could not be found for copy %s.", standbyProductionCopyName));
}
}
}
}
// copy bookmarks before we cleanup the corresponding BlockSnapshot objects from ViPR.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
// When we perform a swap, the target swap copy will become the production copy and lose all
// its bookmarks so we need to sync with RP.
RPHelper.cleanupSnapshots(_dbClient, rpSystem);
} else if (op.equals(FAILOVER_TEST_CANCEL)) {
RPCopyRequestParams copyParams = new RPCopyRequestParams();
copyParams.setCopyVolumeInfo(volumeProtectionInfo);
rp.failoverCopyTestCancel(copyParams);
} else if (op.equals(CHANGE_ACCESS_MODE)) {
RPCopyRequestParams copyParams = new RPCopyRequestParams();
copyParams.setCopyVolumeInfo(volumeProtectionInfo);
copyParams.setImageAccessMode(imageAccessMode);
if (imageAccessMode != null) {
rp.updateImageAccessMode(copyParams);
// BlockSnapshot objects that reference the target copy being set to direct access mode.
if (Copy.ImageAccessMode.DIRECT_ACCESS.name().equalsIgnoreCase(imageAccessMode)) {
_log.info(String.format("Updated imaged access mode for copy %s at %s to DIRECT_ACCESS. Removing all bookmarks associated with that copy and site.", volumeProtectionInfo.getRpCopyName(), volumeProtectionInfo.getRpSiteName()));
// Wait for RP to remove copy snapshots
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
RPHelper.cleanupSnapshots(_dbClient, rpSystem);
}
} else {
throw DeviceControllerExceptions.recoverpoint.imageAccessModeNotSupported(imageAccessMode);
}
} else {
throw DeviceControllerExceptions.recoverpoint.protectionOperationNotSupported(op);
}
_log.info("performProtectionOperation: after " + op + " operation successful");
WorkflowStepCompleter.stepSucceded(stepId);
return true;
} catch (InternalException e) {
_log.error("Operation failed with Exception: ", e);
return stepFailed(stepId, (ServiceCoded) e, "removeProtection operation failed.");
} catch (Exception e) {
stepFailed(stepId, e, "removeProtection operation failed.");
return false;
}
}
use of com.emc.storageos.svcs.errorhandling.model.ServiceCoded in project coprhd-controller by CoprHD.
the class RPDeviceController method doFailAddStep.
private void doFailAddStep(List<VolumeDescriptor> volumeDescriptors, String taskId, Exception e) throws InternalException {
final List<URI> volumeURIs = getVolumeURIs(volumeDescriptors);
final TaskLockingCompleter completer = new RPCGCreateCompleter(volumeURIs, taskId);
_log.error("Could not create protection for RecoverPoint on volumes: " + volumeURIs, e);
final ServiceCoded error;
if (e instanceof ServiceCoded) {
error = (ServiceCoded) e;
} else {
error = DeviceControllerErrors.recoverpoint.couldNotCreateProtectionOnVolumes(volumeURIs);
}
_log.error(error.getMessage());
completer.error(_dbClient, _locker, error);
}
use of com.emc.storageos.svcs.errorhandling.model.ServiceCoded in project coprhd-controller by CoprHD.
the class FileDeviceController method delete.
@Override
public void delete(URI storage, URI pool, URI uri, boolean forceDelete, String deleteType, String opId) throws ControllerException {
ControllerUtils.setThreadLocalLogData(uri, opId);
StorageSystem storageObj = null;
FileObject fileObject = null;
FileShare fsObj = null;
Snapshot snapshotObj = null;
try {
storageObj = _dbClient.queryObject(StorageSystem.class, storage);
String[] params = { storage.toString(), uri.toString(), String.valueOf(forceDelete), deleteType };
_log.info("Delete : storage : {}, URI : {}, forceDelete : {}, delete_type : {} ", params);
FileDeviceInputOutput args = new FileDeviceInputOutput();
boolean isFile = false;
args.setOpId(opId);
if (URIUtil.isType(uri, FileShare.class)) {
isFile = true;
args.setForceDelete(forceDelete);
fsObj = _dbClient.queryObject(FileShare.class, uri);
setVirtualNASinArgs(fsObj.getVirtualNAS(), args);
fileObject = fsObj;
args.addFileShare(fsObj);
args.setFileOperation(isFile);
BiosCommandResult result;
WorkflowStepCompleter.stepExecuting(opId);
if (FileControllerConstants.DeleteTypeEnum.VIPR_ONLY.toString().equalsIgnoreCase(deleteType) && !fsObj.getInactive()) {
result = BiosCommandResult.createSuccessfulResult();
} else {
if (!fsObj.getInactive()) {
// Acquire lock for VNXFILE Storage System
acquireStepLock(storageObj, opId);
result = getDevice(storageObj.getSystemType()).doDeleteFS(storageObj, args);
} else {
result = BiosCommandResult.createSuccessfulResult();
}
}
// In case of VNXe
if (result.getCommandPending()) {
return;
}
fsObj.getOpStatus().updateTaskStatus(opId, result.toOperation());
if (result.isCommandSuccess() && (FileControllerConstants.DeleteTypeEnum.FULL.toString().equalsIgnoreCase(deleteType))) {
fsObj.setInactive(true);
if (forceDelete) {
// Delete Snapshot and its references from DB
doDeleteSnapshotsFromDB(fsObj, true, null, args);
args.addQuotaDirectory(null);
// Delete Quota Directory from DB
doFSDeleteQuotaDirsFromDB(args);
// Delete CIFS Share ACLs from DB
deleteShareACLsFromDB(args);
// Delete Export Rules from DB
doDeleteExportRulesFromDB(true, null, args);
// Remove FileShare Reference from File Policy
doDeletePolicyReferenceFromDB(fsObj);
}
WorkflowStepCompleter.stepSucceded(opId);
} else if (!result.getCommandPending() && FileControllerConstants.DeleteTypeEnum.FULL.toString().equalsIgnoreCase(deleteType)) {
WorkflowStepCompleter.stepFailed(opId, result.getServiceCoded());
}
if (result.isCommandSuccess() && (FileControllerConstants.DeleteTypeEnum.VIPR_ONLY.toString().equalsIgnoreCase(deleteType))) {
boolean snapshotsExist = snapshotsExistsOnFS(fsObj);
boolean quotaDirsExist = quotaDirectoriesExistsOnFS(fsObj);
boolean policyExists = fileProtectionPoliciesExistsOnFS(fsObj);
boolean fsCheck = getDevice(storageObj.getSystemType()).doCheckFSExists(storageObj, args);
if (fsCheck) {
String errMsg = null;
if (snapshotsExist) {
errMsg = new String("delete file system from ViPR database failed because snapshots exist for file system " + fsObj.getLabel() + " and once deleted the snapshot cannot be ingested into ViPR");
} else if (quotaDirsExist && !quotaDirectoryIngestionSupported(storageObj.getSystemType())) {
errMsg = new String("delete file system from ViPR database failed because quota directories exist for file system " + fsObj.getLabel() + " and once deleted the quota directory cannot be ingested into ViPR");
} else if (policyExists) {
errMsg = new String("delete file system from ViPR database failed because file protection policies exist for file system " + fsObj.getLabel() + " and once deleted the policy cannot be ingested into ViPR");
}
if (errMsg != null) {
_log.error(errMsg);
final ServiceCoded serviceCoded = DeviceControllerException.errors.jobFailedOpMsg(OperationTypeEnum.DELETE_FILE_SYSTEM.toString(), errMsg);
result = BiosCommandResult.createErrorResult(serviceCoded);
fsObj.getOpStatus().updateTaskStatus(opId, result.toOperation());
recordFileDeviceOperation(_dbClient, OperationTypeEnum.DELETE_FILE_SYSTEM, result.isCommandSuccess(), "", "", fsObj, storageObj);
_dbClient.updateObject(fsObj);
WorkflowStepCompleter.stepFailed(opId, result.getServiceCoded());
return;
}
}
// Delete Snapshot and its references from DB
doDeleteSnapshotsFromDB(fsObj, true, null, args);
args.addQuotaDirectory(null);
doFSDeleteQuotaDirsFromDB(args);
deleteShareACLsFromDB(args);
doDeleteExportRulesFromDB(true, null, args);
// Remove FileShare Reference from File Policy
doDeletePolicyReferenceFromDB(fsObj);
SMBShareMap cifsSharesMap = fsObj.getSMBFileShares();
if (cifsSharesMap != null && !cifsSharesMap.isEmpty()) {
cifsSharesMap.clear();
}
fsObj.setInactive(true);
WorkflowStepCompleter.stepSucceded(opId);
} else if (!result.getCommandPending() && FileControllerConstants.DeleteTypeEnum.VIPR_ONLY.toString().equalsIgnoreCase(deleteType)) {
WorkflowStepCompleter.stepFailed(opId, result.getServiceCoded());
}
_dbClient.updateObject(fsObj);
recordFileDeviceOperation(_dbClient, OperationTypeEnum.DELETE_FILE_SYSTEM, result.isCommandSuccess(), "", "", fsObj, storageObj);
} else {
snapshotObj = _dbClient.queryObject(Snapshot.class, uri);
fileObject = snapshotObj;
args.addSnapshot(snapshotObj);
fsObj = _dbClient.queryObject(FileShare.class, snapshotObj.getParent());
setVirtualNASinArgs(fsObj.getVirtualNAS(), args);
args.addFileShare(fsObj);
args.setFileOperation(isFile);
WorkflowStepCompleter.stepExecuting(opId);
// Acquire lock for VNXFILE Storage System
acquireStepLock(storageObj, opId);
BiosCommandResult result = getDevice(storageObj.getSystemType()).doDeleteSnapshot(storageObj, args);
if (result.getCommandPending()) {
return;
}
if (!result.isCommandSuccess() && !result.getCommandPending()) {
WorkflowStepCompleter.stepFailed(opId, result.getServiceCoded());
}
snapshotObj.getOpStatus().updateTaskStatus(opId, result.toOperation());
if (result.isCommandSuccess()) {
WorkflowStepCompleter.stepSucceded(opId);
snapshotObj.setInactive(true);
// delete the corresponding export rules if available.
args.addSnapshot(snapshotObj);
doDeleteExportRulesFromDB(true, null, args);
}
_dbClient.updateObject(snapshotObj);
recordFileDeviceOperation(_dbClient, OperationTypeEnum.DELETE_FILE_SNAPSHOT, result.isCommandSuccess(), "", "", snapshotObj, fsObj, storageObj);
}
} catch (Exception e) {
String[] params = { storage.toString(), uri.toString(), String.valueOf(forceDelete), e.getMessage() };
_log.error("Unable to delete file system or snapshot: storage {}, FS/snapshot {}, forceDelete {}: {}", params);
updateTaskStatus(opId, fileObject, e);
// work flow fail for fileshare delete
if (URIUtil.isType(uri, FileShare.class)) {
ServiceError serviceError = DeviceControllerException.errors.jobFailed(e);
WorkflowStepCompleter.stepFailed(opId, serviceError);
}
if (URIUtil.isType(uri, FileShare.class)) {
if ((fsObj != null) && (storageObj != null)) {
recordFileDeviceOperation(_dbClient, OperationTypeEnum.DELETE_FILE_SYSTEM, false, e.getMessage(), "", fsObj, storageObj);
}
} else {
if ((fsObj != null) && (storageObj != null) && (snapshotObj != null)) {
recordFileDeviceOperation(_dbClient, OperationTypeEnum.DELETE_FILE_SNAPSHOT, false, e.getMessage(), "", snapshotObj, fsObj, storageObj);
}
}
}
}
use of com.emc.storageos.svcs.errorhandling.model.ServiceCoded in project coprhd-controller by CoprHD.
the class FileService method getFailureResponse.
private TaskResourceRep getFailureResponse(FileShare fs, String task, ResourceOperationTypeEnum type, String message) {
Operation op = new Operation();
op.setResourceType(type);
op.setMessage(message);
ServiceCoded coded = ServiceError.buildServiceError(ServiceCode.API_BAD_REQUEST, message);
op.error(coded);
_dbClient.createTaskOpStatus(FileShare.class, fs.getId(), task, op);
return toTask(fs, task, op);
}
use of com.emc.storageos.svcs.errorhandling.model.ServiceCoded in project coprhd-controller by CoprHD.
the class BlockMirrorServiceApiImpl method deactivateMirror.
/**
* {@inheritDoc}
*
* @throws ControllerException
*/
@SuppressWarnings("unchecked")
@Override
public TaskList deactivateMirror(StorageSystem storageSystem, URI mirrorURI, String taskId, String deleteType) throws ControllerException {
_log.info("START: deactivate mirror");
TaskList taskList = new TaskList();
BlockMirror mirror = _dbClient.queryObject(BlockMirror.class, mirrorURI);
Volume sourceVolume = _dbClient.queryObject(Volume.class, mirror.getSource().getURI());
List<URI> mirrorURIs = new ArrayList<URI>();
boolean isCG = sourceVolume.isInCG();
List<URI> promotees = null;
if (isCG) {
// for group mirrors, deactivate task will detach and delete the mirror that user asked to deactivate, and
// promote other mirrors
// in the group
Map<BlockMirror, Volume> groupMirrorSourceMap = getGroupMirrorSourceMap(mirror, sourceVolume);
mirrorURIs = new ArrayList<URI>(transform(new ArrayList<BlockMirror>(groupMirrorSourceMap.keySet()), FCTN_MIRROR_TO_URI));
if (VolumeDeleteTypeEnum.VIPR_ONLY.name().equals(deleteType)) {
// Create a task for each source/mirror pair.
for (Entry<BlockMirror, Volume> entry : groupMirrorSourceMap.entrySet()) {
Operation op = _dbClient.createTaskOpStatus(Volume.class, entry.getValue().getId(), taskId, ResourceOperationTypeEnum.DEACTIVATE_VOLUME_MIRROR, entry.getKey().getId().toString());
taskList.getTaskList().add(toTask(entry.getValue(), Arrays.asList(entry.getKey()), taskId, op));
}
} else {
// deactivate (detach and delete) mirrorURI
Operation op = _dbClient.createTaskOpStatus(Volume.class, sourceVolume.getId(), taskId, ResourceOperationTypeEnum.DEACTIVATE_VOLUME_MIRROR, mirrorURI.toString());
taskList.getTaskList().add(toTask(sourceVolume, Arrays.asList(mirror), taskId, op));
// detach and promote other mirrors in the group
groupMirrorSourceMap.remove(mirror);
populateTaskList(sourceVolume, groupMirrorSourceMap, taskList, taskId, ResourceOperationTypeEnum.DETACH_BLOCK_MIRROR);
// detached mirrors (except the one deleted), will be promoted to regular block volumes
promotees = preparePromotedVolumes(new ArrayList<BlockMirror>(groupMirrorSourceMap.keySet()), taskList, taskId);
}
} else {
// for single volume mirror, deactivate task will detach and delete the mirror
mirrorURIs = Arrays.asList(mirror.getId());
Operation op = _dbClient.createTaskOpStatus(Volume.class, sourceVolume.getId(), taskId, ResourceOperationTypeEnum.DEACTIVATE_VOLUME_MIRROR, mirror.getId().toString());
taskList.getTaskList().add(toTask(sourceVolume, Arrays.asList(mirror), taskId, op));
}
try {
if (VolumeDeleteTypeEnum.VIPR_ONLY.name().equals(deleteType)) {
_log.info("Perform ViPR-only delete for mirrors %s", mirrorURIs);
// Perform any database cleanup that is required.
cleanupForViPROnlyMirrorDelete(mirrorURIs);
// Mark them inactive.
_dbClient.markForDeletion(_dbClient.queryObject(BlockMirror.class, mirrorURIs));
// Update the task status for each snapshot to successfully completed.
for (TaskResourceRep taskResourceRep : taskList.getTaskList()) {
Volume taskVolume = _dbClient.queryObject(Volume.class, taskResourceRep.getResource().getId());
Operation op = taskVolume.getOpStatus().get(taskId);
op.ready("Continuous copy succesfully deleted from ViPR");
taskVolume.getOpStatus().updateTaskStatus(taskId, op);
_dbClient.updateObject(taskVolume);
}
} else {
BlockController controller = getController(BlockController.class, storageSystem.getSystemType());
controller.deactivateMirror(storageSystem.getId(), mirrorURIs, promotees, isCG, taskId);
}
} catch (ControllerException e) {
String errorMsg = format("Failed to deactivate continuous copy %s: %s", mirror.getId().toString(), e.getMessage());
_log.error(errorMsg);
for (TaskResourceRep taskResourceRep : taskList.getTaskList()) {
taskResourceRep.setState(Operation.Status.error.name());
taskResourceRep.setMessage(errorMsg);
_dbClient.error(URIUtil.getModelClass(taskResourceRep.getResource().getId()), taskResourceRep.getResource().getId(), taskId, e);
}
// Mark the mirrors that would have been promoted inactive.
if (promotees != null && !promotees.isEmpty()) {
List<Volume> volumes = _dbClient.queryObject(Volume.class, promotees);
for (Volume volume : volumes) {
volume.setInactive(true);
}
_dbClient.updateObject(volumes);
}
} catch (Exception e) {
String errorMsg = format("Failed to deactivate continuous copy %s: %s", mirror.getId().toString(), e.getMessage());
_log.error(errorMsg);
ServiceCoded sc = APIException.internalServerErrors.genericApisvcError(errorMsg, e);
for (TaskResourceRep taskResourceRep : taskList.getTaskList()) {
taskResourceRep.setState(Operation.Status.error.name());
taskResourceRep.setMessage(sc.getMessage());
_dbClient.error(URIUtil.getModelClass(taskResourceRep.getResource().getId()), taskResourceRep.getResource().getId(), taskId, sc);
}
// Mark the mirrors that would have been promoted inactive.
if (promotees != null && !promotees.isEmpty()) {
List<Volume> volumes = _dbClient.queryObject(Volume.class, promotees);
for (Volume volume : volumes) {
volume.setInactive(true);
}
_dbClient.updateObject(volumes);
}
}
return taskList;
}
Aggregations