use of com.emc.storageos.svcs.errorhandling.resources.InternalException in project coprhd-controller by CoprHD.
the class RPDeviceController method exportGroupCreate.
/*
* RPDeviceController.exportGroupCreate()
*
* This method is a mini-orchestration of all of the steps necessary to create an export based on
* a Bourne Snapshot object associated with a RecoverPoint bookmark.
*
* This controller does not service block devices for export, only RP bookmark snapshots.
*
* The method is responsible for performing the following steps:
* - Enable the volumes to a specific bookmark.
* - Call the block controller to export the target volume
*
* @param protectionDevice The RP System used to manage the protection
*
* @param exportgroupID The export group
*
* @param snapshots snapshot list
*
* @param initatorURIs initiators to send to the block controller
*
* @param token The task object
*/
@Override
public void exportGroupCreate(URI protectionDevice, URI exportGroupID, List<URI> initiatorURIs, Map<URI, Integer> snapshots, String token) throws ControllerException {
TaskCompleter taskCompleter = null;
try {
// Grab the RP System information; we'll need it to talk to the RP client
ProtectionSystem rpSystem = getRPSystem(protectionDevice);
taskCompleter = new RPCGExportCompleter(exportGroupID, token);
// Ensure the bookmarks actually exist before creating the export group
searchForBookmarks(protectionDevice, snapshots.keySet());
// 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, "exportGroupCreate", true, newToken);
// Tasks 1: Activate the bookmarks
//
// Enable image access on the target volumes
addEnableImageAccessStep(workflow, rpSystem, snapshots, null);
// Tasks 2: Export Volumes
//
// Export the volumes associated with the snapshots to the host
addExportSnapshotSteps(workflow, rpSystem, exportGroupID, snapshots, initiatorURIs);
// Execute the plan and allow the WorkflowExecutor to fire the taskCompleter.
String successMessage = String.format("Workflow of Export Group %s successfully created", exportGroupID);
workflow.executePlan(taskCompleter, successMessage);
} catch (InternalException e) {
_log.error("Operation failed with Exception: ", e);
if (taskCompleter != null) {
taskCompleter.error(_dbClient, e);
}
} catch (Exception e) {
_log.error("Operation failed with Exception: ", e);
if (taskCompleter != null) {
taskCompleter.error(_dbClient, DeviceControllerException.errors.jobFailed(e));
}
}
}
use of com.emc.storageos.svcs.errorhandling.resources.InternalException 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.svcs.errorhandling.resources.InternalException in project coprhd-controller by CoprHD.
the class RPDeviceController method disableImageAccessForCreateReplicaStep.
/**
* Disable image access for after create native array replica operation
*
* @param protectionDevice
* @param clazz
* type of replica (such as Volume, BlockSnapshot or BlockSnapshotSession)
* @param copyList
* list of replica ids
* @param volumeWWNs
* wwns of volumes that are parents to replica objects
* @param opId
* @throws ControllerException
*/
public void disableImageAccessForCreateReplicaStep(URI protectionDevice, Class<? extends DataObject> clazz, List<URI> copyList, Set<String> volumeWWNs, String opId) throws ControllerException {
TaskCompleter completer = null;
try {
_log.info("Deactivating a bookmark on the RP CG(s)");
completer = new RPCGCopyVolumeCompleter(clazz, copyList, opId);
// Verify non-null storage device returned from the database client.
ProtectionSystem system = _dbClient.queryObject(ProtectionSystem.class, protectionDevice);
if (system == null || system.getInactive()) {
throw DeviceControllerExceptions.recoverpoint.databaseExceptionActivateSnapshot(protectionDevice);
}
// disable image access to that bookmark
RecoverPointClient rp = RPHelper.getRecoverPointClient(system);
MultiCopyDisableImageRequestParams request = new MultiCopyDisableImageRequestParams();
request.setVolumeWWNSet(volumeWWNs);
MultiCopyDisableImageResponse response = rp.disableImageCopies(request);
if (response == null) {
throw DeviceControllerExceptions.recoverpoint.failedDisableAccessOnRP();
}
completer.ready(_dbClient);
} 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.svcs.errorhandling.resources.InternalException 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;
}
}
use of com.emc.storageos.svcs.errorhandling.resources.InternalException in project coprhd-controller by CoprHD.
the class BlockDeviceController method rollbackListSnapshot.
public void rollbackListSnapshot(URI storage, List<URI> snapshotList, String taskId) {
WorkflowStepCompleter.stepExecuting(taskId);
try {
List<BlockSnapshot> snapshotsNoRollback = new ArrayList<BlockSnapshot>();
List<BlockSnapshot> snapshotsToRollback = new ArrayList<BlockSnapshot>();
Iterator<BlockSnapshot> itr = _dbClient.queryIterativeObjects(BlockSnapshot.class, snapshotList);
while (itr.hasNext()) {
BlockSnapshot snapshot = itr.next();
if (snapshot != null && !snapshot.getInactive()) {
if (isNullOrEmpty(snapshot.getNativeId())) {
snapshot.setInactive(true);
snapshotsNoRollback.add(snapshot);
} else {
snapshotsToRollback.add(snapshot);
}
}
}
if (!snapshotsNoRollback.isEmpty()) {
_dbClient.updateObject(snapshotsNoRollback);
}
if (!snapshotsToRollback.isEmpty()) {
List<URI> snapshotURIsToRollback = new ArrayList<URI>(transform(snapshotsToRollback, fctnDataObjectToID()));
String snapshotNativeIds = Joiner.on(", ").join(transform(snapshotsToRollback, fctnBlockObjectToNativeID()));
_log.info("Attempting to delete {} for rollback", snapshotNativeIds);
for (URI snapshotURI : snapshotURIsToRollback) {
deleteSelectedSnapshot(storage, snapshotURI, generateStepIdForDependentCallDuringRollback());
}
}
WorkflowStepCompleter.stepSucceded(taskId);
} catch (InternalException ie) {
_log.error(String.format("rollbackListSnapshot failed - Array:%s, Snapshots:%s", storage, Joiner.on("\t").join(snapshotList)));
doFailTask(BlockSnapshot.class, snapshotList, taskId, ie);
WorkflowStepCompleter.stepFailed(taskId, ie);
} catch (Exception e) {
ServiceError serviceError = DeviceControllerException.errors.jobFailed(e);
WorkflowStepCompleter.stepFailed(taskId, serviceError);
doFailTask(BlockSnapshot.class, snapshotList, taskId, serviceError);
}
}
Aggregations