Search in sources :

Example 1 with Volume

use of com.emc.storageos.db.client.model.Volume in project coprhd-controller by CoprHD.

the class RPDeviceController method disableImageForSnapshots.

/**
 * Disable image access for RP snapshots.
 *
 * @param protectionDevice
 *            protection system
 * @param snapshotList
 *            list of snapshots to enable
 * @param setSnapshotSyncActive
 *            true if the isSyncActive field on BlockSnapshot should be true, false otherwise.
 * @param opId
 * @throws ControllerException
 */
private void disableImageForSnapshots(URI protectionDevice, List<URI> snapshotList, boolean setSnapshotSyncActive, String opId) throws ControllerException {
    BlockSnapshotDeactivateCompleter completer = null;
    try {
        _log.info("Deactivating a bookmark on the RP CG(s)");
        completer = new BlockSnapshotDeactivateCompleter(snapshotList, setSnapshotSyncActive, opId);
        ProtectionSystem system = null;
        try {
            system = _dbClient.queryObject(ProtectionSystem.class, protectionDevice);
        } catch (DatabaseException e) {
            throw DeviceControllerExceptions.recoverpoint.databaseExceptionDeactivateSnapshot(protectionDevice);
        }
        if (system == null) {
            throw DeviceControllerExceptions.recoverpoint.databaseExceptionDeactivateSnapshot(protectionDevice);
        }
        // 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);
            // Determine if we can actually disable image access to the copy associated with the snapshot first
            if (!doDisableImageCopies(snapshot)) {
                // Skip this snapshot because we cannot disable image access. Likely due to the snapshot
                // being exported to multiple hosts.
                _log.warn(String.format("Cannot disable image access for snapshot %s so it will be skipped.  Likely due to the snapshot being exported to multiple hosts", snapshot.getId()));
                continue;
            }
            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.failedToDeactivateSnapshotEmNameMissing(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 disable image access on the bookmark copies
        RecoverPointClient rp = RPHelper.getRecoverPointClient(system);
        // correponding to each emName.
        for (Map.Entry<String, Set<String>> emNameEntry : emNamesToVolumeWWNs.entrySet()) {
            MultiCopyDisableImageRequestParams request = new MultiCopyDisableImageRequestParams();
            request.setVolumeWWNSet(emNameEntry.getValue());
            request.setEmName(emNameEntry.getKey());
            MultiCopyDisableImageResponse response = rp.disableImageCopies(request);
            if (response == null) {
                throw DeviceControllerExceptions.recoverpoint.failedDisableAccessOnRP();
            }
            // Let the completer know about the deactivated snapshots (ones who's associated copies
            // had image access disabled). This will be used to update the BlockSnapshot fields accordingly.
            // This is done because not all snapshots used when creating the completer will be deactivated.
            // We need to maintain a collection of snapshots so that those exported to multiple hosts to not
            // get deactivated.
            completer.addDeactivatedSnapshots(emNamesToSnapshots.get(emNameEntry.getKey()));
        }
        completer.ready(_dbClient);
    } catch (InternalException e) {
        _log.error("Operation failed with Exception: ", e);
        if (completer != null) {
            completer.error(_dbClient, e);
        }
    } catch (URISyntaxException e) {
        _log.error("Operation failed with Exception: ", e);
        if (completer != null) {
            completer.error(_dbClient, DeviceControllerException.errors.invalidURI(e));
        }
    } catch (Exception e) {
        _log.error("Operation failed with Exception: ", e);
        if (completer != null) {
            completer.error(_dbClient, DeviceControllerException.errors.jobFailed(e));
        }
    }
}
Also used : ProtectionSet(com.emc.storageos.db.client.model.ProtectionSet) Set(java.util.Set) HashSet(java.util.HashSet) StringSet(com.emc.storageos.db.client.model.StringSet) HashMap(java.util.HashMap) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) ProtectionSet(com.emc.storageos.db.client.model.ProtectionSet) URISyntaxException(java.net.URISyntaxException) MultiCopyDisableImageRequestParams(com.emc.storageos.recoverpoint.requests.MultiCopyDisableImageRequestParams) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) InternalServerErrorException(com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) LockRetryException(com.emc.storageos.locking.LockRetryException) FunctionalAPIActionFailedException_Exception(com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception) URISyntaxException(java.net.URISyntaxException) WorkflowException(com.emc.storageos.workflow.WorkflowException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) FunctionalAPIInternalError_Exception(com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception) CoordinatorException(com.emc.storageos.coordinator.exceptions.CoordinatorException) RecoverPointException(com.emc.storageos.recoverpoint.exceptions.RecoverPointException) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) MultiCopyDisableImageResponse(com.emc.storageos.recoverpoint.responses.MultiCopyDisableImageResponse) Volume(com.emc.storageos.db.client.model.Volume) RecoverPointClient(com.emc.storageos.recoverpoint.impl.RecoverPointClient) BlockSnapshotDeactivateCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.BlockSnapshotDeactivateCompleter) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) Map(java.util.Map) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) OpStatusMap(com.emc.storageos.db.client.model.OpStatusMap) HashMap(java.util.HashMap)

Example 2 with Volume

use of com.emc.storageos.db.client.model.Volume in project coprhd-controller by CoprHD.

the class RPDeviceController method addExportRemoveVolumesSteps.

/**
 * Add the steps that will remove the volumes from the export group
 * TODO: This could stand to be refactored to be simpler.
 *
 * @param workflow
 *            workflow object
 * @param waitFor
 *            step that these steps are dependent on
 * @param filteredSourceVolumeDescriptors
 *            volumes to act on
 * @return "waitFor" step that future steps should wait on
 * @throws InternalException
 */
private String addExportRemoveVolumesSteps(Workflow workflow, String waitFor, List<VolumeDescriptor> filteredSourceVolumeDescriptors) throws InternalException {
    _log.info("Adding steps to remove volumes from export groups.");
    String returnStep = waitFor;
    Set<URI> volumeURIs = RPHelper.getVolumesToDelete(VolumeDescriptor.getVolumeURIs(filteredSourceVolumeDescriptors), _dbClient);
    _log.info(String.format("Following volume(s) will be unexported from their RP export groups :  [%s]", Joiner.on("--").join(volumeURIs)));
    Map<URI, RPExport> rpExports = new HashMap<URI, RPExport>();
    for (URI volumeURI : volumeURIs) {
        Volume volume = _dbClient.queryObject(Volume.class, volumeURI);
        if (volume == null) {
            _log.warn("Could not load volume with given URI: " + volumeURI);
            continue;
        }
        // get the protection system for this volume
        URI rpSystemId = volume.getProtectionController();
        ProtectionSystem rpSystem = null;
        if (rpSystemId != null) {
            rpSystem = _dbClient.queryObject(ProtectionSystem.class, rpSystemId);
            if (rpSystem == null || rpSystem.getInactive()) {
                _log.warn("No protection system information found for volume {}. Volume cannot be removed from RP export groups.", volume.getLabel());
                continue;
            }
        }
        // Get the storage controller URI of the volume
        URI storageURI = volume.getStorageController();
        // Get the vpool of the volume
        VirtualPool virtualPool = _dbClient.queryObject(VirtualPool.class, volume.getVirtualPool());
        if (VirtualPool.isRPVPlexProtectHASide(virtualPool)) {
            _log.info(String.format("RP+VPLEX protect HA Source Volume [%s] to be removed from RP export group.", volume.getLabel()));
            // the HA side export group only.
            if (volume.getAssociatedVolumes() != null && volume.getAssociatedVolumes().size() == 2) {
                for (String associatedVolURI : volume.getAssociatedVolumes()) {
                    Volume associatedVolume = _dbClient.queryObject(Volume.class, URI.create(associatedVolURI));
                    if (associatedVolume.getVirtualArray().toString().equals(virtualPool.getHaVarrayConnectedToRp())) {
                        ExportGroup exportGroup = getExportGroup(rpSystem, volume.getId(), associatedVolume.getVirtualArray(), associatedVolume.getInternalSiteName());
                        if (exportGroup != null) {
                            _log.info(String.format("Removing volume [%s] from RP export group [%s].", volume.getLabel(), exportGroup.getGeneratedName()));
                        }
                        // Assuming we've found the correct Export Group for this volume, let's
                        // then add the information we need to the rpExports map.
                        addExportGroup(rpExports, exportGroup, volumeURI, storageURI);
                        break;
                    }
                }
            }
        } else if (volume.getAssociatedVolumes() != null && volume.getAssociatedVolumes().size() == 2) {
            for (String associatedVolURI : volume.getAssociatedVolumes()) {
                _log.info(String.format("VPLEX %s Volume [%s] to be removed from RP export group.", volume.getPersonality(), associatedVolURI));
                Volume associatedVolume = _dbClient.queryObject(Volume.class, URI.create(associatedVolURI));
                String internalSiteName = associatedVolume.getInternalSiteName();
                URI virtualArray = associatedVolume.getVirtualArray();
                if (!VirtualPool.vPoolSpecifiesMetroPoint(virtualPool)) {
                    // Only MetroPoint associated volumes will have the internalSiteName set. For VPlex distributed volumes
                    // the parent (virtual volume) internal site name should be used.
                    internalSiteName = volume.getInternalSiteName();
                    // If we are using the parent volume's internal site name, we also need to use the parent volume's virtual array.
                    // Again, only in the case of MetroPoint volumes would we want to use the associated volume's virtual array.
                    virtualArray = volume.getVirtualArray();
                }
                ExportGroup exportGroup = getExportGroup(rpSystem, volume.getId(), virtualArray, internalSiteName);
                if (exportGroup != null) {
                    _log.info(String.format("Removing volume [%s] from RP export group [%s].", volume.getLabel(), exportGroup.getGeneratedName()));
                }
                // Assuming we've found the correct Export Group for this volume, let's
                // then add the information we need to the rpExports map.
                addExportGroup(rpExports, exportGroup, volumeURI, storageURI);
            }
        } else {
            _log.info(String.format("Volume [%s] to be removed from RP export group.", volume.getLabel()));
            // Find the Export Group for this regular RP volume
            ExportGroup exportGroup = getExportGroup(rpSystem, volume.getId(), volume.getVirtualArray(), volume.getInternalSiteName());
            if (exportGroup != null) {
                _log.info(String.format("Removing volume [%s] from RP export group [%s].", volume.getLabel(), exportGroup.getGeneratedName()));
            }
            // Assuming we've found the correct Export Group for this volume, let's
            // then add the information we need to the rpExports map.
            addExportGroup(rpExports, exportGroup, volumeURI, storageURI);
        }
    }
    // Generate the workflow steps for export volume removal and volume deletion
    for (URI exportURI : rpExports.keySet()) {
        _log.info(String.format("RP export group will have these volumes removed: [%s]", Joiner.on(',').join(rpExports.get(exportURI).getVolumes())));
        RPExport rpExport = rpExports.get(exportURI);
        if (!rpExport.getVolumes().isEmpty()) {
            _exportWfUtils.generateExportGroupRemoveVolumes(workflow, STEP_DV_REMOVE_VOLUME_EXPORT, waitFor, rpExport.getStorageSystem(), exportURI, rpExport.getVolumes());
            returnStep = STEP_DV_REMOVE_VOLUME_EXPORT;
        }
    }
    _log.info("Completed adding steps to remove volumes from RP export groups.");
    return returnStep;
}
Also used : ExportGroup(com.emc.storageos.db.client.model.ExportGroup) HashMap(java.util.HashMap) Volume(com.emc.storageos.db.client.model.Volume) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem)

Example 3 with Volume

use of com.emc.storageos.db.client.model.Volume 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));
        }
    }
}
Also used : HashMap(java.util.HashMap) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) Workflow(com.emc.storageos.workflow.Workflow) BlockSnapshotCreateCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.BlockSnapshotCreateCompleter) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem) Date(java.util.Date) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) InternalServerErrorException(com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) LockRetryException(com.emc.storageos.locking.LockRetryException) FunctionalAPIActionFailedException_Exception(com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception) URISyntaxException(java.net.URISyntaxException) WorkflowException(com.emc.storageos.workflow.WorkflowException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) FunctionalAPIInternalError_Exception(com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception) CoordinatorException(com.emc.storageos.coordinator.exceptions.CoordinatorException) RecoverPointException(com.emc.storageos.recoverpoint.exceptions.RecoverPointException) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) Volume(com.emc.storageos.db.client.model.Volume) VolumeGroupUpdateTaskCompleter(com.emc.storageos.vplexcontroller.completers.VolumeGroupUpdateTaskCompleter) TaskCompleter(com.emc.storageos.volumecontroller.TaskCompleter) VolumeVpoolChangeTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeVpoolChangeTaskCompleter) RPCGProtectionTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.RPCGProtectionTaskCompleter) SimpleDateFormat(java.text.SimpleDateFormat) HashSet(java.util.HashSet)

Example 4 with Volume

use of com.emc.storageos.db.client.model.Volume in project coprhd-controller by CoprHD.

the class RPDeviceController method upgradeRPVPlexToMetroPoint.

/**
 * Upgrades a RP+VPLEX CG to MetroPoint by adding a standby journal to the HA side.
 *
 * Prerequisite: All RSets(volumes) in the CG must have had their HA sides already exported to RP in VPLEX.
 *
 * @param sourceVolume
 *            A single source volume from the CG, we only need one.
 * @param rpSystem
 *            The rpSystem we're using
 */
private void upgradeRPVPlexToMetroPoint(Volume sourceVolume, VirtualPool newVpool, VirtualPool oldVpool, ProtectionSystem rpSystem) {
    // Grab the new standby journal from the CG
    String standbyCopyName = RPHelper.getStandbyProductionCopyName(_dbClient, sourceVolume);
    List<Volume> existingStandbyJournals = RPHelper.findExistingJournalsForCopy(_dbClient, sourceVolume.getConsistencyGroup(), standbyCopyName);
    if (existingStandbyJournals.isEmpty()) {
        _log.error(String.format("Could not find standby journal during upgrade to MetroPoint operation. " + "Expected to find a new standby journal for RP copy [%s]", standbyCopyName));
        throw RecoverPointException.exceptions.cannotFindJournal(String.format("for RP copy [%s]", standbyCopyName));
    }
    Volume standbyProdJournal = existingStandbyJournals.get(0);
    // Add new standby journal
    if (standbyProdJournal != null) {
        _log.info(String.format("Upgrade RP+VPLEX CG to MetroPoint by adding new standby journal [%s] to the CG", standbyProdJournal.getLabel()));
        RecoverPointClient rp = RPHelper.getRecoverPointClient(rpSystem);
        RecoverPointVolumeProtectionInfo protectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(sourceVolume.getId(), _dbClient));
        _log.info(String.format("RecoverPointVolumeProtectionInfo [%s] retrieved", protectionInfo.getRpProtectionName()));
        RPCopyRequestParams copyParams = new RPCopyRequestParams();
        copyParams.setCopyVolumeInfo(protectionInfo);
        List<CreateVolumeParams> journaVols = new ArrayList<CreateVolumeParams>();
        CreateVolumeParams journalVolParams = new CreateVolumeParams();
        journalVolParams.setWwn(RPHelper.getRPWWn(standbyProdJournal.getId(), _dbClient));
        journalVolParams.setInternalSiteName(standbyProdJournal.getInternalSiteName());
        journaVols.add(journalVolParams);
        CreateCopyParams standbyProdCopyParams = new CreateCopyParams();
        standbyProdCopyParams.setName(standbyProdJournal.getRpCopyName());
        standbyProdCopyParams.setJournals(journaVols);
        _log.info(String.format("Adding standby journal [%s] to teh RP CG...", standbyProdJournal.getLabel()));
        // TODO BH - Empty, not sure why we need this
        List<CreateRSetParams> rSets = new ArrayList<CreateRSetParams>();
        rp.addStandbyProductionCopy(standbyProdCopyParams, null, rSets, copyParams);
        _log.info("Standby journal added successfully.");
        // TODO Add new Targets if they exist ??
        // Next we need to update the vpool reference of any existing related volumes
        // that were referencing the old vpool.
        // We'll start by getting all source volumes from the ViPR CG
        BlockConsistencyGroup viprCG = _dbClient.queryObject(BlockConsistencyGroup.class, sourceVolume.getConsistencyGroup());
        List<Volume> allSourceVolumesInCG = BlockConsistencyGroupUtils.getActiveVplexVolumesInCG(viprCG, _dbClient, Volume.PersonalityTypes.SOURCE);
        for (Volume sourceVol : allSourceVolumesInCG) {
            // For each source volume, we'll get all the related volumes (Targets, Journals, Backing volumes for
            // VPLEX...etc)
            Set<Volume> allRelatedVolumes = RPHelper.getAllRelatedVolumesForSource(sourceVol.getId(), _dbClient, true, true);
            // If it is, update the reference and persist the change.
            for (Volume rpRelatedVol : allRelatedVolumes) {
                if (rpRelatedVol.getVirtualPool().equals(oldVpool.getId())) {
                    rpRelatedVol.setVirtualPool(newVpool.getId());
                    _dbClient.updateObject(rpRelatedVol);
                    _log.info(String.format("Volume [%s] has had its virtual pool updated to [%s].", rpRelatedVol.getLabel(), newVpool.getLabel()));
                }
            }
        }
    }
}
Also used : CreateRSetParams(com.emc.storageos.recoverpoint.requests.CreateRSetParams) ArrayList(java.util.ArrayList) RPCopyRequestParams(com.emc.storageos.recoverpoint.requests.RPCopyRequestParams) CreateVolumeParams(com.emc.storageos.recoverpoint.requests.CreateVolumeParams) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) RecoverPointVolumeProtectionInfo(com.emc.storageos.recoverpoint.responses.RecoverPointVolumeProtectionInfo) Volume(com.emc.storageos.db.client.model.Volume) RecoverPointClient(com.emc.storageos.recoverpoint.impl.RecoverPointClient) CreateCopyParams(com.emc.storageos.recoverpoint.requests.CreateCopyParams)

Example 5 with Volume

use of com.emc.storageos.db.client.model.Volume 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;
    }
}
Also used : ProtectionSet(com.emc.storageos.db.client.model.ProtectionSet) Set(java.util.Set) HashSet(java.util.HashSet) StringSet(com.emc.storageos.db.client.model.StringSet) MultiCopyEnableImageResponse(com.emc.storageos.recoverpoint.responses.MultiCopyEnableImageResponse) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ProtectionSet(com.emc.storageos.db.client.model.ProtectionSet) URISyntaxException(java.net.URISyntaxException) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) RecoverPointClient(com.emc.storageos.recoverpoint.impl.RecoverPointClient) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) InternalServerErrorException(com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) LockRetryException(com.emc.storageos.locking.LockRetryException) FunctionalAPIActionFailedException_Exception(com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception) URISyntaxException(java.net.URISyntaxException) WorkflowException(com.emc.storageos.workflow.WorkflowException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) FunctionalAPIInternalError_Exception(com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception) CoordinatorException(com.emc.storageos.coordinator.exceptions.CoordinatorException) RecoverPointException(com.emc.storageos.recoverpoint.exceptions.RecoverPointException) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) Volume(com.emc.storageos.db.client.model.Volume) VolumeGroupUpdateTaskCompleter(com.emc.storageos.vplexcontroller.completers.VolumeGroupUpdateTaskCompleter) TaskCompleter(com.emc.storageos.volumecontroller.TaskCompleter) VolumeVpoolChangeTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeVpoolChangeTaskCompleter) RPCGProtectionTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.RPCGProtectionTaskCompleter) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) Map(java.util.Map) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) OpStatusMap(com.emc.storageos.db.client.model.OpStatusMap) HashMap(java.util.HashMap) BlockSnapshotActivateCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.BlockSnapshotActivateCompleter) MultiCopyEnableImageRequestParams(com.emc.storageos.recoverpoint.requests.MultiCopyEnableImageRequestParams)

Aggregations

Volume (com.emc.storageos.db.client.model.Volume)1303 URI (java.net.URI)775 ArrayList (java.util.ArrayList)522 NamedURI (com.emc.storageos.db.client.model.NamedURI)412 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)319 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)291 BlockSnapshot (com.emc.storageos.db.client.model.BlockSnapshot)221 StringSet (com.emc.storageos.db.client.model.StringSet)208 HashMap (java.util.HashMap)203 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)202 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)197 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)160 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)152 BlockObject (com.emc.storageos.db.client.model.BlockObject)150 ControllerException (com.emc.storageos.volumecontroller.ControllerException)143 BlockConsistencyGroup (com.emc.storageos.db.client.model.BlockConsistencyGroup)139 WorkflowException (com.emc.storageos.workflow.WorkflowException)126 HashSet (java.util.HashSet)126 CIMObjectPath (javax.cim.CIMObjectPath)107 VirtualPool (com.emc.storageos.db.client.model.VirtualPool)104