use of com.emc.storageos.db.client.model.BlockSnapshotSession in project coprhd-controller by CoprHD.
the class BlockDeviceController method createSnapshotSession.
/**
* {@inheritDoc}
*/
@Override
public void createSnapshotSession(URI systemURI, URI snapSessionURI, List<List<URI>> sessionSnapshotURIs, String copyMode, String opId) throws InternalException {
TaskCompleter completer = new BlockSnapshotSessionCreateWorkflowCompleter(snapSessionURI, sessionSnapshotURIs, opId);
try {
// Get a new workflow to execute creation of the snapshot session and if
// necessary creation and linking of target volumes to the new session.
Workflow workflow = _workflowService.getNewWorkflow(this, CREATE_SAPSHOT_SESSION_WF_NAME, false, opId);
_log.info("Created new workflow to create a new snapshot session for source with operation id {}", opId);
// When creating a group snapshot we need the name of the group.
String groupName = null;
boolean isCG = checkSnapshotSessionConsistencyGroup(snapSessionURI, _dbClient, completer);
if (isCG) {
BlockSnapshotSession snapSession = _dbClient.queryObject(BlockSnapshotSession.class, snapSessionURI);
groupName = snapSession.getReplicationGroupInstance();
}
// Create a step to create the session.
String waitFor = workflow.createStep(CREATE_SNAPSHOT_SESSION_STEP_GROUP, String.format("Creating block snapshot session"), null, systemURI, getDeviceType(systemURI), getClass(), createBlockSnapshotSessionMethod(systemURI, snapSessionURI, groupName), rollbackMethodNullMethod(), null);
// Add steps to create any new targets and link them to the session, if necessary
if ((sessionSnapshotURIs != null) && (!sessionSnapshotURIs.isEmpty())) {
if (isCG) {
for (List<URI> snapshotURIs : sessionSnapshotURIs) {
workflow.createStep(LINK_SNAPSHOT_SESSION_TARGET_STEP_GROUP, String.format("Linking group targets snapshot sessions %s", snapSessionURI), waitFor, systemURI, getDeviceType(systemURI), getClass(), linkBlockSnapshotSessionTargetGroupMethod(systemURI, snapSessionURI, snapshotURIs, copyMode, Boolean.FALSE), rollbackLinkBlockSnapshotSessionTargetMethod(systemURI, snapSessionURI, snapshotURIs.get(0)), null);
}
} else {
for (List<URI> snapshotURIs : sessionSnapshotURIs) {
if ((snapshotURIs != null) && (!snapshotURIs.isEmpty())) {
for (URI snapshotURI : snapshotURIs) {
workflow.createStep(LINK_SNAPSHOT_SESSION_TARGET_STEP_GROUP, String.format("Linking targets for snapshot session %s", snapSessionURI), waitFor, systemURI, getDeviceType(systemURI), getClass(), linkBlockSnapshotSessionTargetMethod(systemURI, snapSessionURI, snapshotURI, copyMode, Boolean.FALSE), rollbackLinkBlockSnapshotSessionTargetMethod(systemURI, snapSessionURI, snapshotURI), null);
}
}
}
}
}
workflow.executePlan(completer, "Create block snapshot session successful");
} catch (Exception e) {
_log.error("Create block snapshot session failed", e);
ServiceCoded serviceException = DeviceControllerException.exceptions.createBlockSnapshotSessionFailed(e);
completer.error(_dbClient, serviceException);
}
}
use of com.emc.storageos.db.client.model.BlockSnapshotSession in project coprhd-controller by CoprHD.
the class SmisBlockSnapshotSessionLinkTargetJob method updateStatus.
/**
* {@inheritDoc}
*/
@Override
public void updateStatus(JobContext jobContext) throws Exception {
JobStatus jobStatus = getJobStatus();
CloseableIterator<CIMObjectPath> volumeIter = null;
try {
DbClient dbClient = jobContext.getDbClient();
TaskCompleter completer = getTaskCompleter();
BlockSnapshot snapshot = dbClient.queryObject(BlockSnapshot.class, _snapshotURI);
if (jobStatus == JobStatus.IN_PROGRESS) {
return;
}
if (jobStatus == JobStatus.SUCCESS) {
s_logger.info("Post-processing successful link snapshot session target {} for task {}", snapshot.getId(), completer.getOpId());
// Get the snapshot session to which the target is being linked.
BlockSnapshotSession snapSession = dbClient.queryObject(BlockSnapshotSession.class, completer.getId());
// Get the snapshot device ID and set it against the BlockSnapshot object.
BlockObject sourceObj = BlockObject.fetch(dbClient, snapshot.getParent().getURI());
CIMConnectionFactory cimConnectionFactory = jobContext.getCimConnectionFactory();
WBEMClient client = getWBEMClient(dbClient, cimConnectionFactory);
volumeIter = client.associatorNames(getCimJob(), null, SmisConstants.CIM_STORAGE_VOLUME, null, null);
while (volumeIter.hasNext()) {
// Get the sync volume native device id
CIMObjectPath volumePath = volumeIter.next();
s_logger.info("volumePath: {}", volumePath.toString());
CIMInstance volume = client.getInstance(volumePath, false, false, null);
String volumeDeviceId = volumePath.getKey(SmisConstants.CP_DEVICE_ID).getValue().toString();
s_logger.info("volumeDeviceId: {}", volumeDeviceId);
if (volumeDeviceId.equals(sourceObj.getNativeId())) {
// Don't want the source, we want the linked target.
continue;
}
String volumeElementName = CIMPropertyFactory.getPropertyValue(volume, SmisConstants.CP_ELEMENT_NAME);
s_logger.info("volumeElementName: {}", volumeElementName);
String volumeWWN = CIMPropertyFactory.getPropertyValue(volume, SmisConstants.CP_WWN_NAME);
s_logger.info("volumeWWN: {}", volumeWWN);
String volumeAltName = CIMPropertyFactory.getPropertyValue(volume, SmisConstants.CP_NAME);
s_logger.info("volumeAltName: {}", volumeAltName);
StorageSystem system = dbClient.queryObject(StorageSystem.class, getStorageSystemURI());
snapshot.setNativeId(volumeDeviceId);
snapshot.setNativeGuid(NativeGUIDGenerator.generateNativeGuid(system, snapshot));
snapshot.setDeviceLabel(volumeElementName);
snapshot.setInactive(false);
snapshot.setIsSyncActive(Boolean.TRUE);
snapshot.setCreationTime(Calendar.getInstance());
snapshot.setWWN(volumeWWN.toUpperCase());
snapshot.setAlternateName(volumeAltName);
snapshot.setSettingsInstance(snapSession.getSessionInstance());
commonSnapshotUpdate(snapshot, volume, client, system, sourceObj.getNativeId(), volumeDeviceId, false, dbClient);
s_logger.info(String.format("For target volume path %1$s, going to set blocksnapshot %2$s nativeId to %3$s (%4$s). Associated volume is %5$s (%6$s)", volumePath.toString(), snapshot.getId().toString(), volumeDeviceId, volumeElementName, sourceObj.getNativeId(), sourceObj.getDeviceLabel()));
dbClient.updateObject(snapshot);
}
} else if (jobStatus == JobStatus.FAILED || jobStatus == JobStatus.FATAL_ERROR) {
s_logger.info("Failed to link snapshot session target {} for task {}", snapshot.getId(), completer.getOpId());
snapshot.setInactive(true);
dbClient.updateObject(snapshot);
}
} catch (Exception e) {
setPostProcessingErrorStatus("Encountered an internal error in link snapshot session target job status processing: " + e.getMessage());
s_logger.error("Encountered an internal error in link snapshot session target job status processing", e);
} finally {
if (volumeIter != null) {
volumeIter.close();
}
super.updateStatus(jobContext);
}
}
use of com.emc.storageos.db.client.model.BlockSnapshotSession in project coprhd-controller by CoprHD.
the class SmisSnapShotJob method setSettingsInstance.
/**
* Set settings instance for VMAX V3 only. If the flag so indicates, this function
* will also create a snapshot session to represent this settings instance, which is
* the CIM instance ID for a synchronization aspect. The session needs to be created
* for legacy code that created VMAX3 BlockSnapshots w/o representing the snapshot session.
*
* @param storage storage A reference to the storage system.
* @param snapshot BlockSnapshot to be updated
* @param sourceElementId String of source volume (or source group) ID
* @param elementName String used as ElementName when creating ReplicationSettingData during single snapshot creation,
* or RelationshipName used in CreateGroupReplica for group snapshot. Note elementName should be target device's DeviceID
* or target group ID.
* @param createSession true if a BlockSnapshotSession should be created to represent the settings instance.
* @param dbClient A reference to a database client.
*/
private void setSettingsInstance(StorageSystem storage, BlockSnapshot snapshot, String sourceElementId, String elementName, boolean createSession, DbClient dbClient) {
if ((storage.checkIfVmax3()) && (createSession)) {
setSettingsInstance(storage, snapshot, sourceElementId, elementName);
// If the flag so indicates create a BlockSnapshotSession instance to represent this
// settings instance.
BlockSnapshotSession snapSession = getSnapshotSession(snapshot, dbClient);
if (snapSession.getId() == null) {
snapSession.setId(URIUtil.createId(BlockSnapshotSession.class));
snapSession.setLabel(snapshot.getLabel());
snapSession.setSessionLabel(SmisUtils.getSessionLabelFromSettingsInstance(snapshot));
snapSession.setSessionInstance(snapshot.getSettingsInstance());
snapSession.setProject(snapshot.getProject());
snapSession.setStorageController(storage.getId());
setParentOrConsistencyGroupAssociation(snapSession, snapshot, dbClient);
}
addSnapshotAsLinkedTarget(snapSession, snapshot);
createOrUpdateSession(snapSession, dbClient);
}
}
use of com.emc.storageos.db.client.model.BlockSnapshotSession in project coprhd-controller by CoprHD.
the class VPlexDeviceController method relinkTargetsToSnapshotSession.
/**
* {@inheritDoc}
*/
@Override
public void relinkTargetsToSnapshotSession(URI vplexURI, URI tgtSnapSessionURI, List<URI> snapshotURIs, String opId) throws InternalException {
try {
// Create a new the Workflow.
Workflow workflow = _workflowService.getNewWorkflow(this, RELINK_SNAPSHOT_SESSION_TARGETS_WF_NAME, false, opId);
_log.info("Created relink snapshot session targets workflow with operation id {}", opId);
// First if this is a group operation, we make sure we only process
// one snapshot per replication group.
List<URI> filteredSnapshotURIs = new ArrayList<URI>();
BlockSnapshotSession tgtSnapSession = _dbClient.queryObject(BlockSnapshotSession.class, tgtSnapSessionURI);
if (tgtSnapSession.hasConsistencyGroup() && NullColumnValueGetter.isNotNullValue(tgtSnapSession.getReplicationGroupInstance())) {
filteredSnapshotURIs.addAll(ControllerUtils.ensureOneSnapshotPerReplicationGroup(snapshotURIs, _dbClient));
} else {
filteredSnapshotURIs.addAll(snapshotURIs);
}
// Now we need to make sure we get all the snapshots in each
// replication group. If a snapshot is not in a replication group,
// this will just add the snapshot.
List<BlockSnapshot> snapshotsToRelink = new ArrayList<BlockSnapshot>();
for (URI filteredSnapshotURI : filteredSnapshotURIs) {
BlockSnapshot snapshot = _dbClient.queryObject(BlockSnapshot.class, filteredSnapshotURI);
snapshotsToRelink.addAll(ControllerUtils.getSnapshotsPartOfReplicationGroup(snapshot, _dbClient));
}
// Get a list of the VPLEX volumes, if any, that are built
// using the snapshot target volumes.
List<Volume> vplexVolumes = VPlexUtil.getVPlexVolumesBuiltOnSnapshots(snapshotsToRelink, _dbClient);
// Create the workflow steps.
if (vplexVolumes.isEmpty()) {
// If there are no VPLEX volumes built on the snapshots to be relinked,
// then we just need a single step to invoke the block device controller to
// relink the snapshots.
createWorkflowStepForRelinkNativeTargets(workflow, tgtSnapSession, snapshotURIs, null, null);
} else {
String waitFor = null;
// Maps Vplex volume that needs to be flushed to underlying array volume
Map<Volume, Volume> vplexToArrayVolumesToFlush = new HashMap<Volume, Volume>();
for (Volume vplexVolume : vplexVolumes) {
Volume arrayVolumeToBeRelinked = VPlexUtil.getVPLEXBackendVolume(vplexVolume, true, _dbClient);
vplexToArrayVolumesToFlush.put(vplexVolume, arrayVolumeToBeRelinked);
}
// Generate pre restore steps
Map<URI, String> vplexVolumeIdToDetachStep = new HashMap<URI, String>();
waitFor = addPreRestoreResyncSteps(workflow, vplexToArrayVolumesToFlush, vplexVolumeIdToDetachStep, waitFor);
// Now create a workflow step to natively relink the snapshots.
// Note that if a snapshot is associated with a CG, then block
// controller will relink all snapshots in the snapshot set. We
// execute this after the invalidate cache.
waitFor = createWorkflowStepForRelinkNativeTargets(workflow, tgtSnapSession, snapshotURIs, waitFor, rollbackMethodNullMethod());
// Generate post restore steps
addPostRestoreResyncSteps(workflow, vplexToArrayVolumesToFlush, vplexVolumeIdToDetachStep, waitFor);
}
// Execute the workflow.
_log.info("Executing workflow plan");
TaskCompleter completer = new BlockSnapshotSessionRelinkTargetsWorkflowCompleter(tgtSnapSessionURI, Boolean.TRUE, opId);
String successMsg = String.format("Relink VPLEX native snapshot session targets %s to session %s " + "completed successfully", snapshotURIs, tgtSnapSessionURI);
workflow.executePlan(completer, successMsg);
_log.info("Workflow plan executing");
} catch (Exception e) {
String failMsg = String.format("Relink VPLEX native snapshot session targets %s to session %s failed", snapshotURIs, tgtSnapSessionURI);
_log.error(failMsg, e);
TaskCompleter completer = new BlockSnapshotSessionRelinkTargetsWorkflowCompleter(tgtSnapSessionURI, Boolean.TRUE, opId);
ServiceError serviceError = VPlexApiException.errors.relinkSnapshotSessionTargetsFailed(snapshotURIs, tgtSnapSessionURI, e);
failStep(completer, opId, serviceError);
}
}
use of com.emc.storageos.db.client.model.BlockSnapshotSession in project coprhd-controller by CoprHD.
the class VPlexDeviceController method restoreSnapshotSession.
/**
* {@inheritDoc}
*/
@Override
public void restoreSnapshotSession(URI vplexURI, URI snapSessionURI, String opId) throws InternalException {
BlockSnapshotSession snapSession = getDataObject(BlockSnapshotSession.class, snapSessionURI, _dbClient);
try {
// Generate the Workflow.
Workflow workflow = _workflowService.getNewWorkflow(this, RESTORE_SNAP_SESSION_WF_NAME, false, opId);
_log.info("Created restore snapshot session workflow with operation id {}", opId);
// Get the VPLEX volume(s) to be restored.
List<Volume> vplexVolumes = new ArrayList<Volume>();
if (!snapSession.hasConsistencyGroup()) {
// If the snap session is not in a CG, the only VPLEX
// volume to restore is the VPLEX volume using the
// snap session parent.
URI parentVolumeURI = snapSession.getParent().getURI();
URIQueryResultList queryResults = new URIQueryResultList();
_dbClient.queryByConstraint(AlternateIdConstraint.Factory.getVolumeByAssociatedVolumesConstraint(parentVolumeURI.toString()), queryResults);
vplexVolumes.add(_dbClient.queryObject(Volume.class, queryResults.iterator().next()));
} else {
BlockConsistencyGroup cg = _dbClient.queryObject(BlockConsistencyGroup.class, snapSession.getConsistencyGroup());
List<Volume> allVplexVolumesInCG = BlockConsistencyGroupUtils.getActiveVplexVolumesInCG(cg, _dbClient, null);
List<BlockObject> allVplexVolumesInRG = ControllerUtils.getAllVolumesForRGInCG(allVplexVolumesInCG, snapSession.getReplicationGroupInstance(), snapSession.getStorageController(), _dbClient);
// that are RP source volumes.
for (BlockObject vplexVolume : allVplexVolumesInRG) {
// RP target and sources restore is supported
vplexVolumes.add((Volume) vplexVolume);
}
}
// Determine the backend storage system containing the native snapshot session.
Volume firstVplexVolume = vplexVolumes.get(0);
Volume firstSnapSessionParentVolume = VPlexUtil.getVPLEXBackendVolume(firstVplexVolume, true, _dbClient);
StorageSystem snapSessionSystem = getDataObject(StorageSystem.class, firstSnapSessionParentVolume.getStorageController(), _dbClient);
// Maps Vplex volume that needs to be flushed to underlying array volume
Map<Volume, Volume> vplexToArrayVolumesToFlush = new HashMap<Volume, Volume>();
for (Volume vplexVolume : vplexVolumes) {
Volume arrayVolumeToBeRestored = VPlexUtil.getVPLEXBackendVolume(vplexVolume, true, _dbClient);
vplexToArrayVolumesToFlush.put(vplexVolume, arrayVolumeToBeRestored);
}
Map<URI, String> vplexVolumeIdToDetachStep = new HashMap<URI, String>();
boolean isRP = firstVplexVolume.checkForRp();
if (null == firstVplexVolume.getAssociatedVolumes() || firstVplexVolume.getAssociatedVolumes().isEmpty()) {
_log.error("VPLEX volume {} has no backend volumes.", firstVplexVolume.forDisplay());
throw InternalServerErrorException.internalServerErrors.noAssociatedVolumesForVPLEXVolume(firstVplexVolume.forDisplay());
}
boolean isDistributed = firstVplexVolume.getAssociatedVolumes().size() > 1;
String waitFor = null;
if (isRP && isDistributed) {
ProtectionSystem rpSystem = getDataObject(ProtectionSystem.class, firstVplexVolume.getProtectionController(), _dbClient);
// Create the pre restore step which will be the first step executed
// in the workflow.
createWorkflowStepForDeleteReplicationSet(workflow, rpSystem, vplexVolumes, null);
}
// Generate pre restore steps
waitFor = addPreRestoreResyncSteps(workflow, vplexToArrayVolumesToFlush, vplexVolumeIdToDetachStep, waitFor);
// Now create a workflow step to natively restore the backend
// volume. We execute this after the invalidate cache.
createWorkflowStepForRestoreNativeSnapshotSession(workflow, snapSessionSystem, snapSessionURI, waitFor, rollbackMethodNullMethod());
// Generate post restore steps
waitFor = addPostRestoreResyncSteps(workflow, vplexToArrayVolumesToFlush, vplexVolumeIdToDetachStep, waitFor);
if (isRP && isDistributed) {
ProtectionSystem rpSystem = getDataObject(ProtectionSystem.class, firstVplexVolume.getProtectionController(), _dbClient);
// Create the post restore step, which will be the last step executed
// in the workflow after the volume shave been rebuilt.
waitFor = createWorkflowStepForRecreateReplicationSet(workflow, rpSystem, vplexVolumes, waitFor);
}
// Execute the workflow.
_log.info("Executing workflow plan");
TaskCompleter completer = new BlockSnapshotSessionRestoreWorkflowCompleter(snapSessionURI, Boolean.TRUE, opId);
String successMsg = String.format("Restore VPLEX volume(s) from snapshot session %s" + "completed successfully", snapSessionURI);
workflow.executePlan(completer, successMsg);
_log.info("Workflow plan executing");
} catch (Exception e) {
String failMsg = String.format("Restore VPLEX volume from snapshot session %s failed", snapSessionURI);
_log.error(failMsg, e);
TaskCompleter completer = new BlockSnapshotSessionRestoreWorkflowCompleter(snapSessionURI, Boolean.TRUE, opId);
ServiceError serviceError = VPlexApiException.errors.restoreVolumeFailed(snapSessionURI.toString(), e);
failStep(completer, opId, serviceError);
}
}
Aggregations