/*
* Copyright (c) 2012 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.api.service.impl.resource.snapshot;
import java.net.URI;
import java.util.List;
import java.util.Map;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
import com.emc.storageos.api.service.authorization.PermissionsHelper;
import com.emc.storageos.api.service.impl.resource.fullcopy.BlockFullCopyManager;
import com.emc.storageos.coordinator.client.service.CoordinatorClient;
import com.emc.storageos.db.client.DbClient;
import com.emc.storageos.db.client.URIUtil;
import com.emc.storageos.db.client.model.BlockObject;
import com.emc.storageos.db.client.model.BlockSnapshot;
import com.emc.storageos.db.client.model.BlockSnapshotSession;
import com.emc.storageos.db.client.model.Project;
import com.emc.storageos.db.client.model.Volume;
import com.emc.storageos.protectioncontroller.impl.recoverpoint.RPHelper;
import com.emc.storageos.services.OperationTypeEnum;
import com.emc.storageos.svcs.errorhandling.resources.APIException;
/**
* Block snapshot session implementation for RP protected volumes.
*/
public class RPBlockSnapshotSessionApiImpl extends DefaultBlockSnapshotSessionApiImpl {
/**
* Private default constructor should not be called outside class.
*/
@SuppressWarnings("unused")
private RPBlockSnapshotSessionApiImpl() {
super();
}
/**
* Constructor.
*
* @param dbClient A reference to a data base client.
* @param coordinator A reference to the coordinator client.
* @param permissionsHelper A reference to a permission helper.
* @param securityContext A reference to the security context.
* @param blockSnapshotSessionMgr A reference to the snapshot session manager.
*/
public RPBlockSnapshotSessionApiImpl(DbClient dbClient, CoordinatorClient coordinator, PermissionsHelper permissionsHelper,
SecurityContext securityContext, BlockSnapshotSessionManager blockSnapshotSessionMgr) {
super(dbClient, coordinator, permissionsHelper, securityContext, blockSnapshotSessionMgr);
}
/**
* {@inheritDoc}
*/
@Override
public void validateSnapshotSessionCreateRequest(BlockObject requestedSourceObj, List<BlockObject> sourceObjList, Project project,
String name, int newTargetsCount, String newTargetsName, String newTargetCopyMode, boolean skipInternalCheck,
BlockFullCopyManager fcManager) {
// If the requested source is a simple volume that is RP protected,
// then we simply do platform specific validation for that volume's
// platform.
URI requestedSourceURI = requestedSourceObj.getId();
if (URIUtil.isType(requestedSourceURI, Volume.class)) {
Volume sourceVolume = (Volume) requestedSourceObj;
boolean protectionBased = RPHelper.isProtectionBasedSnapshot(sourceVolume,
BlockSnapshot.TechnologyType.NATIVE.name(), _dbClient);
if (protectionBased) {
throw APIException.badRequests.createSnapSessionNotSupportedForRPProtected();
}
// Validate using the appropriate implementation.
BlockSnapshotSessionApi snapSessionImpl = getImplementationForBackendSystem(requestedSourceObj.getStorageController());
snapSessionImpl.validateSnapshotSessionCreateRequest(requestedSourceObj, sourceObjList, project, name, newTargetsCount,
newTargetsName, newTargetCopyMode, skipInternalCheck, fcManager);
}
}
/**
* {@inheritDoc}
*/
@Override
public void createSnapshotSession(BlockObject sourceObj, URI snapSessionURI,
List<List<URI>> snapSessionSnapshotURIs, String copyMode, String taskId) {
BlockSnapshotSessionApi snapSessionImpl = getImplementationForBackendSystem(sourceObj.getStorageController());
snapSessionImpl.createSnapshotSession(sourceObj, snapSessionURI, snapSessionSnapshotURIs, copyMode, taskId);
}
/**
* {@inheritDoc}
*/
@Override
public void validateLinkNewTargetsRequest(BlockObject snapSessionSourceObj, Project project, int newTargetsCount,
String newTargetsName, String newTargetCopyMode) {
BlockSnapshotSessionApi snapSessionImpl = getImplementationForBackendSystem(snapSessionSourceObj.getStorageController());
snapSessionImpl.validateLinkNewTargetsRequest(snapSessionSourceObj, project, newTargetsCount, newTargetsName, newTargetCopyMode);
}
/**
* {@inheritDoc}
*/
@Override
public void linkNewTargetVolumesToSnapshotSession(BlockObject snapSessionSourceObj, BlockSnapshotSession snapSession,
List<List<URI>> snapshotURIs, String copyMode, String taskId) {
BlockSnapshotSessionApi snapSessionImpl = getImplementationForBackendSystem(snapSessionSourceObj.getStorageController());
snapSessionImpl.linkNewTargetVolumesToSnapshotSession(snapSessionSourceObj, snapSession, snapshotURIs, copyMode, taskId);
}
/**
* {@inheritDoc}
*/
@Override
public void validateRelinkSnapshotSessionTargets(BlockObject snapSessionSourceObj, BlockSnapshotSession tgtSnapSession,
Project project, List<URI> snapshotURIs, UriInfo uriInfo) {
BlockSnapshotSessionApi snapSessionImpl = getImplementationForBackendSystem(snapSessionSourceObj.getStorageController());
snapSessionImpl.validateRelinkSnapshotSessionTargets(snapSessionSourceObj, tgtSnapSession, project, snapshotURIs, uriInfo);
}
/**
* {@inheritDoc}
*/
@Override
public void relinkTargetVolumesToSnapshotSession(BlockObject snapSessionSourceObj, BlockSnapshotSession tgtSnapSession,
List<URI> snapshotURIs, String taskId) {
BlockSnapshotSessionApi snapSessionImpl = getImplementationForBackendSystem(snapSessionSourceObj.getStorageController());
snapSessionImpl.relinkTargetVolumesToSnapshotSession(snapSessionSourceObj, tgtSnapSession, snapshotURIs, taskId);
}
/**
* {@inheritDoc}
*/
@Override
public void validateUnlinkSnapshotSessionTargets(BlockSnapshotSession snapSession, BlockObject snapSessionSourceObj, Project project,
Map<URI, Boolean> targetMap, UriInfo uriInfo) {
BlockSnapshotSessionApi snapSessionImpl = getImplementationForBackendSystem(snapSessionSourceObj.getStorageController());
snapSessionImpl.validateUnlinkSnapshotSessionTargets(snapSession, snapSessionSourceObj, project, targetMap, uriInfo);
}
/**
* {@inheritDoc}
*/
@Override
public void unlinkTargetVolumesFromSnapshotSession(BlockObject snapSessionSourceObj, BlockSnapshotSession snapSession,
Map<URI, Boolean> snapshotDeletionMap, OperationTypeEnum opType, String taskId) {
BlockSnapshotSessionApi snapSessionImpl = getImplementationForBackendSystem(snapSessionSourceObj.getStorageController());
snapSessionImpl.unlinkTargetVolumesFromSnapshotSession(snapSessionSourceObj, snapSession, snapshotDeletionMap, opType, taskId);
}
/**
* {@inheritDoc}
*/
@Override
public void validateRestoreSnapshotSession(List<BlockObject> snapSessionSourceObjs, Project project) {
BlockSnapshotSessionApi snapSessionImpl = getImplementationForBackendSystem(snapSessionSourceObjs.get(0).getStorageController());
snapSessionImpl.validateRestoreSnapshotSession(snapSessionSourceObjs, project);
}
/**
* {@inheritDoc}
*/
@Override
public void restoreSnapshotSession(BlockSnapshotSession snapSession, BlockObject snapSessionSourceObj, String taskId) {
BlockSnapshotSessionApi snapSessionImpl = getImplementationForBackendSystem(snapSessionSourceObj.getStorageController());
snapSessionImpl.restoreSnapshotSession(snapSession, snapSessionSourceObj, taskId);
}
/**
* {@inheritDoc}
*/
@Override
public void validateDeleteSnapshotSession(BlockSnapshotSession snapSession, BlockObject snapSessionSourceObj, Project project) {
BlockSnapshotSessionApi snapSessionImpl = getImplementationForBackendSystem(snapSessionSourceObj.getStorageController());
snapSessionImpl.validateDeleteSnapshotSession(snapSession, snapSessionSourceObj, project);
}
/**
* {@inheritDoc}
*/
@Override
public void deleteSnapshotSession(BlockSnapshotSession snapSession, BlockObject snapSessionSourceObj, String taskId,
String deleteType) {
BlockSnapshotSessionApi snapSessionImpl = getImplementationForBackendSystem(snapSessionSourceObj.getStorageController());
snapSessionImpl.deleteSnapshotSession(snapSession, snapSessionSourceObj, taskId, deleteType);
}
/**
* {@inheritDoc}
*/
@Override
public List<BlockSnapshotSession> getSnapshotSessionsForSource(BlockObject sourceObj) {
BlockSnapshotSessionApi snapSessionImpl = getImplementationForBackendSystem(sourceObj.getStorageController());
return snapSessionImpl.getSnapshotSessionsForSource(sourceObj);
}
/**
* {@inheritDoc}
*/
@Override
public BlockSnapshotSession prepareSnapshotSessionFromSource(BlockObject sourceObj, String snapSessionLabel, String instanceLabel,
String taskId, boolean inApplication) {
BlockSnapshotSessionApi snapSessionImpl = getImplementationForBackendSystem(sourceObj.getStorageController());
BlockSnapshotSession snapSession = snapSessionImpl.prepareSnapshotSessionFromSource(sourceObj, snapSessionLabel,
instanceLabel, taskId, inApplication);
return snapSession;
}
/**
* {@inheritDoc}
*/
@Override
public BlockSnapshot prepareSnapshotForSession(BlockObject sourceObj, String snapsetLabel, String instanceLabel) {
// Important: that the only difference between these snapshots and snapshots created with the
// create snapshot APIs is that the parent and project NamedURIs for those snapshots use the
// snapshot label rather than the source label. This is an inconsistency between non-RP snaps
// and other snaps and should probably be fixed.
BlockSnapshotSessionApi snapSessionImpl = getImplementationForBackendSystem(sourceObj.getStorageController());
BlockSnapshot snapshot = snapSessionImpl.prepareSnapshotForSession(sourceObj, snapsetLabel, instanceLabel);
// This is a native snapshot so do not set the consistency group, otherwise
// the SMIS code/array will get confused trying to look for a consistency
// group that only exists in RecoverPoint.
snapshot.setConsistencyGroup(null);
_dbClient.updateObject(snapshot);
return snapshot;
}
/**
* {@inheritDoc}
*/
@Override
public List<Map<URI, BlockSnapshot>> prepareSnapshotsForSession(List<BlockObject> sourceObjList, int sessionCount, int newTargetCount,
String newTargetsName, boolean inApplication) {
// Important: that the only difference between these snapshots and snapshots created with the
// create snapshot APIs is that the parent and project NamedURIs for those snapshots use the
// snapshot label rather than the source label. This is an inconsistency between non-RP snaps
// and other snaps and should probably be fixed.
BlockObject sourceObj = sourceObjList.get(0);
BlockSnapshotSessionApi snapSessionImpl = getImplementationForBackendSystem(sourceObj.getStorageController());
List<Map<URI, BlockSnapshot>> snapshotMap = snapSessionImpl.prepareSnapshotsForSession(sourceObjList, sessionCount, newTargetCount,
newTargetsName, inApplication);
for (Map<URI, BlockSnapshot> map : snapshotMap) {
for (BlockSnapshot snapshot : map.values()) {
// This is a native snapshot so do not set the consistency group, otherwise
// the SMIS code/array will get confused trying to look for a consistency
// group that only exists in RecoverPoint.
snapshot.setConsistencyGroup(null);
_dbClient.updateObject(snapshot);
}
}
return snapshotMap;
}
/**
* {@inheritDoc}
*/
@Override
public void verifyActiveMirrors(Volume sourceVolume) {
BlockSnapshotSessionApi snapSessionImpl = getImplementationForBackendSystem(sourceVolume.getStorageController());
snapSessionImpl.verifyActiveMirrors(sourceVolume);
}
}