use of com.emc.storageos.volumecontroller.TaskCompleter 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.volumecontroller.TaskCompleter in project coprhd-controller by CoprHD.
the class RPDeviceController method constructSnapshotObjectFromBookmark.
/**
* Amend the BlockSnapshot object based on the results of the Bookmark creation operation
*
* @param result
* result from the snapshot creation command
* @param system
* protection system
* @param snapshotList
* snapshot list generated
* @param name
* emName
* @param opId
* operation ID for task completer
* @throws InternalException
* @throws FunctionalAPIInternalError_Exception
* @throws FunctionalAPIActionFailedException_Exception
*/
private void constructSnapshotObjectFromBookmark(CreateBookmarkResponse response, ProtectionSystem system, List<URI> snapshotList, String name, String opId) throws InternalException {
ProtectionSet protectionSet = null;
RecoverPointClient rp = RPHelper.getRecoverPointClient(system);
// Update each snapshot object with the respective information.
for (URI snapshotID : snapshotList) {
// Get the snapshot and the associated volume
BlockSnapshot snapshot = _dbClient.queryObject(BlockSnapshot.class, snapshotID);
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);
}
if (protectionSet == null || !protectionSet.getId().equals(volume.getProtectionSet().getURI())) {
protectionSet = _dbClient.queryObject(ProtectionSet.class, volume.getProtectionSet());
}
// Gather the bookmark date, which is different than the snapshot date
Date bookmarkDate = new Date();
if (response.getVolumeWWNBookmarkDateMap() != null) {
bookmarkDate = response.getVolumeWWNBookmarkDateMap().get(RPHelper.getRPWWn(volume.getId(), _dbClient));
} else {
_log.warn("Bookmark date was not filled-in. Will use current date/time.");
}
snapshot.setEmName(name);
snapshot.setInactive(false);
snapshot.setEmBookmarkTime("" + bookmarkDate.getTime());
snapshot.setCreationTime(Calendar.getInstance());
snapshot.setTechnologyType(TechnologyType.RP.toString());
Volume targetVolume = RPHelper.getRPTargetVolumeFromSource(_dbClient, volume, snapshot.getVirtualArray());
// This section will identify and store the COPY ID associated with the bookmarks created.
// It is critical to store this information so we can later determine which bookmarks have
// been deleted from the RPA.
//
// May be able to remove this if the protection set object is more detailed (for instance, if
// we store the copy id with the volume)
RecoverPointVolumeProtectionInfo protectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(targetVolume.getId(), _dbClient));
for (RPConsistencyGroup rpcg : response.getCgBookmarkMap().keySet()) {
if (rpcg.getCGUID().getId() == protectionInfo.getRpVolumeGroupID()) {
for (RPBookmark bookmark : response.getCgBookmarkMap().get(rpcg)) {
if (bookmark.getBookmarkName() != null && bookmark.getBookmarkName().equalsIgnoreCase(name) && bookmark.getCGGroupCopyUID().getGlobalCopyUID().getCopyUID() == protectionInfo.getRpVolumeGroupCopyID()) {
snapshot.setEmCGGroupCopyId(protectionInfo.getRpVolumeGroupCopyID());
break;
}
}
}
}
if (targetVolume.getId().equals(volume.getId())) {
_log.error("The source and the target volumes are the same");
throw DeviceControllerExceptions.recoverpoint.cannotActivateSnapshotNoTargetVolume();
}
snapshot.setDeviceLabel(targetVolume.getDeviceLabel());
snapshot.setStorageController(targetVolume.getStorageController());
snapshot.setSystemType(targetVolume.getSystemType());
snapshot.setVirtualArray(targetVolume.getVirtualArray());
snapshot.setNativeId(targetVolume.getNativeId());
snapshot.setAlternateName(targetVolume.getAlternateName());
snapshot.setNativeGuid(NativeGUIDGenerator.generateNativeGuid(system, snapshot));
snapshot.setIsSyncActive(false);
// Setting the WWN of the bookmark to the WWN of the volume, no functional reason for now.
snapshot.setWWN(RPHelper.getRPWWn(targetVolume.getId(), _dbClient));
snapshot.setProtectionController(system.getId());
snapshot.setProtectionSet(volume.getProtectionSet().getURI());
_log.info(String.format("Updated bookmark %1$s associated with block volume %2$s on site %3$s.", name, volume.getDeviceLabel(), snapshot.getEmInternalSiteName()));
_dbClient.updateObject(snapshot);
List<URI> taskSnapshotURIList = new ArrayList<URI>();
taskSnapshotURIList.add(snapshot.getId());
TaskCompleter completer = new BlockSnapshotCreateCompleter(taskSnapshotURIList, opId);
completer.ready(_dbClient);
}
// Get information about the bookmarks created so we can get to them later.
_log.info("Bookmark(s) created for snapshot operation");
return;
}
use of com.emc.storageos.volumecontroller.TaskCompleter in project coprhd-controller by CoprHD.
the class RPDeviceController method enableImageAccessForCreateReplicaStep.
/**
* Enable image access before 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 bookmarkName
* name of the bookmark created for this operation
* @param volumeWWNs
* wwns of volumes that are parents to replica objects
* @param opId
* @return
* @throws ControllerException
*/
public boolean enableImageAccessForCreateReplicaStep(URI protectionDevice, Class<? extends DataObject> clazz, List<URI> copyList, String bookmarkName, Set<String> volumeWWNs, String opId) throws ControllerException {
TaskCompleter completer = null;
try {
WorkflowStepCompleter.stepExecuting(opId);
_log.info(String.format("Activating bookmark %s on the RP CG(s)", bookmarkName));
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);
}
// enable image access to that bookmark
RecoverPointClient rp = RPHelper.getRecoverPointClient(system);
MultiCopyEnableImageRequestParams request = new MultiCopyEnableImageRequestParams();
request.setVolumeWWNSet(volumeWWNs);
request.setBookmark(bookmarkName);
MultiCopyEnableImageResponse response = rp.enableImageCopies(request);
if (response == null) {
throw DeviceControllerExceptions.recoverpoint.failedEnableAccessOnRP();
}
completer.ready(_dbClient);
// Update the workflow state.
WorkflowStepCompleter.stepSucceded(opId);
return true;
} catch (InternalException e) {
_log.error("Operation failed with Exception: ", e);
if (completer != null) {
completer.error(_dbClient, e);
}
stepFailed(opId, "enableImageAccessStep: Failed to enable image");
return false;
} catch (Exception e) {
_log.error("Operation failed with Exception: ", e);
if (completer != null) {
completer.error(_dbClient, DeviceControllerException.errors.jobFailed(e));
}
stepFailed(opId, "enableImageAccessStep: Failed to enable image");
return false;
}
}
use of com.emc.storageos.volumecontroller.TaskCompleter in project coprhd-controller by CoprHD.
the class RPDeviceController method updateApplication.
/*
* (non-Javadoc)
*
* @see com.emc.storageos.protectioncontroller.RPController#updateApplication(java.net.URI,
* com.emc.storageos.volumecontroller.ApplicationAddVolumeList, java.util.List, java.net.URI, java.lang.String)
*/
@Override
public void updateApplication(URI systemURI, ApplicationAddVolumeList addVolList, List<URI> removeVolumeURIs, URI applicationId, String taskId) {
// get all source and target devices
// for remove volumes source and targets can be processed in the same step
// for add volumes, split up volumes into source and target
// assign a different replication group name for target volumes so they don't end up in the same group as source
// volumes
// create one step for remove volumes and add source volumes and a separate step for add target volumes
TaskCompleter completer = null;
try {
Set<URI> impactedCGs = new HashSet<URI>();
List<URI> allRemoveVolumes = new ArrayList<URI>();
Set<URI> removeVolumeSet = new HashSet<URI>();
if (removeVolumeURIs != null && !removeVolumeURIs.isEmpty()) {
// get source and target volumes to be removed from the application
removeVolumeSet = RPHelper.getReplicationSetVolumes(removeVolumeURIs, _dbClient);
for (URI removeUri : removeVolumeSet) {
Volume removeVol = _dbClient.queryObject(Volume.class, removeUri);
URI cguri = removeVol.getConsistencyGroup();
impactedCGs.add(cguri);
addBackendVolumes(removeVol, false, allRemoveVolumes, null);
}
}
Set<URI> vplexVolumes = new HashSet<URI>();
Set<URI> addVolumeSet = new HashSet<URI>();
ApplicationAddVolumeList addSourceVols = new ApplicationAddVolumeList();
ApplicationAddVolumeList addTargetVols = new ApplicationAddVolumeList();
boolean existingSnapOrClone = false;
URI protectionSystemId = null;
ProtectionSystem protectionSystem = null;
Set<String> volumeWWNs = new HashSet<String>();
Volume aSrcVolume = null;
if (addVolList != null && addVolList.getVolumes() != null && !addVolList.getVolumes().isEmpty()) {
URI addVolCg = null;
// get source and target volumes to be added the application
addVolumeSet = RPHelper.getReplicationSetVolumes(addVolList.getVolumes(), _dbClient);
// split up add volumes list by source and target
List<URI> allAddSourceVolumes = new ArrayList<URI>();
List<URI> allAddTargetVolumes = new ArrayList<URI>();
for (URI volUri : addVolumeSet) {
Volume vol = _dbClient.queryObject(Volume.class, volUri);
if (protectionSystemId == null) {
protectionSystemId = vol.getProtectionController();
}
URI cguri = vol.getConsistencyGroup();
if (addVolCg == null && cguri != null) {
addVolCg = cguri;
}
impactedCGs.add(cguri);
if (vol.checkPersonality(Volume.PersonalityTypes.SOURCE.name())) {
addBackendVolumes(vol, true, allAddSourceVolumes, vplexVolumes);
aSrcVolume = vol;
} else if (vol.checkPersonality(Volume.PersonalityTypes.TARGET.name())) {
addBackendVolumes(vol, true, allAddTargetVolumes, vplexVolumes);
volumeWWNs.add(RPHelper.getRPWWn(vol.getId(), _dbClient));
}
}
if (protectionSystemId != null) {
protectionSystem = _dbClient.queryObject(ProtectionSystem.class, protectionSystemId);
}
addSourceVols.setConsistencyGroup(addVolCg);
addSourceVols.setReplicationGroupName(addVolList.getReplicationGroupName());
addSourceVols.setVolumes(allAddSourceVolumes);
String targetReplicationGroupName = addVolList.getReplicationGroupName() + REPLICATION_GROUP_RPTARGET_SUFFIX;
addTargetVols.setConsistencyGroup(addVolCg);
addTargetVols.setReplicationGroupName(targetReplicationGroupName);
addTargetVols.setVolumes(allAddTargetVolumes);
// if there are any target clones or snapshots, need to create a bookmark and enable image access
List<Volume> existingVols = CustomQueryUtility.queryActiveResourcesByConstraint(_dbClient, Volume.class, AlternateIdConstraint.Factory.getVolumeByReplicationGroupInstance(targetReplicationGroupName));
for (Volume existingVol : existingVols) {
if (existingVol.getFullCopies() != null && !existingVol.getFullCopies().isEmpty()) {
existingSnapOrClone = true;
break;
} else if (ControllerUtils.checkIfVolumeHasSnapshotSession(existingVol.getId(), _dbClient)) {
existingSnapOrClone = true;
break;
} else if (ControllerUtils.checkIfVolumeHasSnapshot(existingVol, _dbClient)) {
existingSnapOrClone = true;
break;
}
}
}
// Get a new workflow to execute the volume group update.
Workflow workflow = _workflowService.getNewWorkflow(this, BlockDeviceController.UPDATE_VOLUMES_FOR_APPLICATION_WS_NAME, false, taskId);
// create the completer add the steps and execute the plan.
completer = new VolumeGroupUpdateTaskCompleter(applicationId, addVolumeSet, removeVolumeSet, impactedCGs, taskId);
String waitFor = null;
if (existingSnapOrClone) {
// A temporary date/time stamp for the bookmark name
String bookmarkName = VIPR_SNAPSHOT_PREFIX + (new Random()).nextInt();
// Step 1 - Create a RP bookmark
String rpWaitFor = addCreateBookmarkStep(workflow, new ArrayList<URI>(), protectionSystem, bookmarkName, volumeWWNs, false, waitFor);
// Lock CG for the duration of the workflow so enable and disable can complete before another workflow
// tries to enable image
// access
List<String> locks = new ArrayList<String>();
String lockName = ControllerLockingUtil.getConsistencyGroupStorageKey(_dbClient, aSrcVolume.getConsistencyGroup(), protectionSystem.getId());
if (null != lockName) {
locks.add(lockName);
acquireWorkflowLockOrThrow(workflow, locks);
}
// Step 2 - Enable image access
waitFor = addEnableImageAccessForCreateReplicaStep(workflow, protectionSystem, null, new ArrayList<URI>(), bookmarkName, volumeWWNs, rpWaitFor);
}
// add steps for add source and remove vols
waitFor = _blockDeviceController.addStepsForUpdateApplication(workflow, addSourceVols, allRemoveVolumes, waitFor, taskId);
// add steps for add target vols
waitFor = _blockDeviceController.addStepsForUpdateApplication(workflow, addTargetVols, null, waitFor, taskId);
if (existingSnapOrClone) {
waitFor = addDisableImageAccessForCreateReplicaStep(workflow, protectionSystem, null, new ArrayList<URI>(), volumeWWNs, waitFor);
}
if (!vplexVolumes.isEmpty()) {
_vplexDeviceController.addStepsForImportClonesOfApplicationVolumes(workflow, waitFor, new ArrayList<URI>(vplexVolumes), taskId);
}
_log.info("Executing workflow plan {}", BlockDeviceController.UPDATE_VOLUMES_FOR_APPLICATION_WS_NAME);
String successMessage = String.format("Update application successful for %s", applicationId.toString());
workflow.executePlan(completer, successMessage);
} catch (Exception e) {
_log.error("Exception while updating the application", e);
if (completer != null) {
completer.error(_dbClient, DeviceControllerException.exceptions.failedToUpdateVolumesFromAppication(applicationId.toString(), e.getMessage()));
}
throw e;
}
}
use of com.emc.storageos.volumecontroller.TaskCompleter in project coprhd-controller by CoprHD.
the class ImageServerControllerImpl method installOperatingSystem.
/**
* Install OS
* @param task {@link AsyncTask}
* @param computeImageJob {@link URI} compute imageJob id
* @throws InternalException
*/
@Override
public void installOperatingSystem(AsyncTask task, URI computeImageJob) throws InternalException {
log.info("installOperatingSystem");
Host host = dbClient.queryObject(Host.class, task._id);
ComputeElement ce = dbClient.queryObject(ComputeElement.class, host.getComputeElement());
ComputeSystem cs = dbClient.queryObject(ComputeSystem.class, ce.getComputeSystem());
ComputeImageJob job = dbClient.queryObject(ComputeImageJob.class, computeImageJob);
ComputeImageServer imageServer = dbClient.queryObject(ComputeImageServer.class, job.getComputeImageServerId());
ComputeImage img = dbClient.queryObject(ComputeImage.class, job.getComputeImageId());
TaskCompleter completer = null;
try {
completer = new OsInstallCompleter(host.getId(), task._opId, job.getId(), EVENT_SERVICE_TYPE);
boolean imageServerVerified = verifyImageServer(imageServer);
if (!imageServerVerified) {
throw ImageServerControllerException.exceptions.imageServerNotSetup("Can't install operating system: " + imageServerErrorMsg);
}
Workflow workflow = workflowService.getNewWorkflow(this, OS_INSTALL_WF, true, task._opId);
String waitFor = null;
waitFor = workflow.createStep(OS_INSTALL_IMAGE_SERVER_CHECK_STEP, "image server check pre os install", waitFor, img.getId(), img.getImageType(), this.getClass(), new Workflow.Method("preOsInstallImageServerCheck", job.getId()), new Workflow.Method(ROLLBACK_NOTHING_METHOD), null);
waitFor = workflow.createStep(OS_INSTALL_PREPARE_PXE_STEP, "prepare pxe boot", waitFor, img.getId(), img.getImageType(), this.getClass(), new Workflow.Method("preparePxeBootMethod", job.getId()), new Workflow.Method(ROLLBACK_NOTHING_METHOD), null);
String prepStepId = workflow.createStepId();
waitFor = computeDeviceController.addStepsPreOsInstall(workflow, waitFor, cs.getId(), host.getId(), prepStepId);
waitFor = workflow.createStep(OS_INSTALL_WAIT_FOR_FINISH_STEP, "wait for os install to finish", waitFor, img.getId(), img.getImageType(), this.getClass(), new Workflow.Method("waitForFinishMethod", job.getId(), host.getHostName()), new Workflow.Method(ROLLBACK_NOTHING_METHOD), null);
waitFor = computeDeviceController.addStepsPostOsInstall(workflow, waitFor, cs.getId(), ce.getId(), host.getId(), prepStepId, job.getVolumeId());
workflow.executePlan(completer, SUCCESS);
} catch (Exception e) {
log.error("installOperatingSystem caught an exception.", e);
ServiceError serviceError = DeviceControllerException.errors.jobFailed(e);
completer.error(dbClient, serviceError);
}
}
Aggregations