Search in sources :

Example 51 with VolumeDescriptor

use of com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor in project coprhd-controller by CoprHD.

the class VPlexDeviceController method addStepsForCreateMirrors.

/**
 * <p>
 * Here we should have already created any underlying volumes. What remains to be done: 1. Export the underlying Storage Volumes from
 * the array to the VPlex. 2. Create the mirror device and attach it as a mirror to the source virtual volume
 *
 * @param workflow
 *            The workflow to which the steps are added.
 * @param waitFor
 *            The previous workflow step for which these steps will wait
 * @param volumes
 *            The volume descriptors representing the mirror and the its associated backend volume.
 * @param taskId
 *            The workflow taskId
 */
public String addStepsForCreateMirrors(Workflow workflow, String waitFor, List<VolumeDescriptor> volumes, String taskId) throws ControllerException {
    try {
        // Get only the VPlex mirrors from the descriptors.
        List<VolumeDescriptor> vplexLocalMirrors = VolumeDescriptor.filterByType(volumes, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.VPLEX_LOCAL_MIRROR }, new VolumeDescriptor.Type[] {});
        // If there are no VPlex mirrors, just return
        if (vplexLocalMirrors.isEmpty()) {
            return waitFor;
        }
        // Build some needed maps to get started.
        Map<URI, StorageSystem> arrayMap = buildArrayMap(volumes, Type.BLOCK_DATA);
        Map<URI, Volume> volumeMap = buildVolumeMap(volumes, Type.BLOCK_DATA);
        // Set the project and tenant to those of an underlying volume.
        // These are used to set the project and tenant of a new ExportGroup if needed.
        Volume firstVolume = volumeMap.values().iterator().next();
        URI projectURI = firstVolume.getProject().getURI();
        URI tenantURI = firstVolume.getTenant().getURI();
        // Segregate the volumes by Device.
        Map<URI, List<VolumeDescriptor>> vplexDescMap = VolumeDescriptor.getDeviceMap(vplexLocalMirrors);
        // For each VPLEX mirror to be provisioned (there will be only one for Vplex Local
        // Volume, Vplex Distributed Volume could have one or two mirrors, two mirrors mean
        // one mirror on each leg)
        String lastStep = VPLEX_STEP;
        for (URI vplexURI : vplexDescMap.keySet()) {
            StorageSystem vplexSystem = getDataObject(StorageSystem.class, vplexURI, _dbClient);
            try {
                // Now we need to do the necessary zoning and export steps to ensure
                // the VPlex can see these new backend volumes.
                createWorkflowStepsForBlockVolumeExport(workflow, vplexSystem, arrayMap, volumeMap, projectURI, tenantURI, waitFor);
            } catch (Exception ex) {
                _log.error("Could not create volumes for vplex: " + vplexURI, ex);
                TaskCompleter completer = new VPlexTaskCompleter(Volume.class, vplexURI, taskId, null);
                ServiceError serviceError = VPlexApiException.errors.jobFailed(ex);
                completer.error(_dbClient, serviceError);
                throw ex;
            }
            // Now create each of the Vplex Mirror Devices that may be necessary.
            List<URI> vplexMirrorURIs = VolumeDescriptor.getVolumeURIs(vplexDescMap.get(vplexURI));
            // Now make a Step to create the Mirror.
            String mirrorStep = workflow.createStepId();
            lastStep = workflow.createStep(VPLEX_STEP, String.format("VPlex %s creating mirrors:%n%s", vplexSystem.getIpAddress(), BlockDeviceController.getVolumesMsg(_dbClient, vplexMirrorURIs)), EXPORT_STEP, vplexURI, vplexSystem.getSystemType(), this.getClass(), createMirrorsMethod(vplexURI, vplexMirrorURIs, taskId), rollbackCreateMirrorsMethod(vplexURI, vplexMirrorURIs, mirrorStep), mirrorStep);
        }
        return lastStep;
    } catch (Exception ex) {
        throw VPlexApiException.exceptions.addStepsForCreateMirrors(ex);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) 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) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) WorkflowException(com.emc.storageos.workflow.WorkflowException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) Volume(com.emc.storageos.db.client.model.Volume) ApplicationAddVolumeList(com.emc.storageos.volumecontroller.ApplicationAddVolumeList) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) List(java.util.List) ExportTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter) MigrationTaskCompleter(com.emc.storageos.vplexcontroller.completers.MigrationTaskCompleter) CloneTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.CloneTaskCompleter) MigrationOperationTaskCompleter(com.emc.storageos.vplexcontroller.completers.MigrationOperationTaskCompleter) CacheStatusTaskCompleter(com.emc.storageos.vplexcontroller.completers.CacheStatusTaskCompleter) VplexMirrorTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VplexMirrorTaskCompleter) VolumeTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeTaskCompleter) VolumeGroupUpdateTaskCompleter(com.emc.storageos.vplexcontroller.completers.VolumeGroupUpdateTaskCompleter) TaskCompleter(com.emc.storageos.volumecontroller.TaskCompleter) WorkflowTaskCompleter(com.emc.storageos.workflow.WorkflowTaskCompleter) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 52 with VolumeDescriptor

use of com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor in project coprhd-controller by CoprHD.

the class VPlexDeviceController method addStepsForImportClonesOfApplicationVolumes.

/**
 * This method will add steps to import the clone of the source backend volumes,
 * create clone VPlex virtual volumes
 * create HA backend volume for clone virtual volume if distributed.
 *
 * @param workflow
 * @param waitFor
 * @param sourceVolumes
 * @param opId
 * @return
 */
public void addStepsForImportClonesOfApplicationVolumes(Workflow workflow, String waitFor, List<URI> sourceVolumes, String opId) {
    _log.info("Creating steps for importing clones");
    for (URI vplexSrcUri : sourceVolumes) {
        Volume vplexSrcVolume = getDataObject(Volume.class, vplexSrcUri, _dbClient);
        Volume backendSrc = VPlexUtil.getVPLEXBackendVolume(vplexSrcVolume, true, _dbClient);
        long size = backendSrc.getProvisionedCapacity();
        Volume backendHASrc = VPlexUtil.getVPLEXBackendVolume(vplexSrcVolume, false, _dbClient);
        StringSet backSrcCopies = backendSrc.getFullCopies();
        if (backSrcCopies != null && !backSrcCopies.isEmpty()) {
            for (String copy : backSrcCopies) {
                List<VolumeDescriptor> vplexVolumeDescriptors = new ArrayList<VolumeDescriptor>();
                List<VolumeDescriptor> blockDescriptors = new ArrayList<VolumeDescriptor>();
                Volume backCopy = getDataObject(Volume.class, URI.create(copy), _dbClient);
                String name = backCopy.getLabel();
                _log.info(String.format("Creating steps for import clone %s.", name));
                VolumeDescriptor vplexCopyVolume = prepareVolumeDescriptor(vplexSrcVolume, name, VolumeDescriptor.Type.VPLEX_VIRT_VOLUME, size, false);
                Volume vplexCopy = getDataObject(Volume.class, vplexCopyVolume.getVolumeURI(), _dbClient);
                vplexCopy.setAssociatedVolumes(new StringSet());
                StringSet assVol = vplexCopy.getAssociatedVolumes();
                if (null == assVol) {
                    assVol = new StringSet();
                    vplexCopy.setAssociatedVolumes(assVol);
                }
                assVol.add(backCopy.getId().toString());
                VirtualPoolCapabilityValuesWrapper capabilities = getCapabilities(backCopy, size);
                VolumeDescriptor backCopyDesc = new VolumeDescriptor(VolumeDescriptor.Type.VPLEX_IMPORT_VOLUME, backCopy.getStorageController(), backCopy.getId(), backCopy.getPool(), capabilities);
                blockDescriptors.add(backCopyDesc);
                if (backendHASrc != null) {
                    // distributed volume
                    name = name + "-ha";
                    VolumeDescriptor haDesc = prepareVolumeDescriptor(backendHASrc, name, VolumeDescriptor.Type.BLOCK_DATA, size, true);
                    blockDescriptors.add(haDesc);
                    assVol.add(haDesc.getVolumeURI().toString());
                }
                vplexCopy.setFullCopySetName(backCopy.getFullCopySetName());
                vplexCopy.setAssociatedSourceVolume(vplexSrcUri);
                StringSet srcClones = vplexSrcVolume.getFullCopies();
                if (srcClones == null) {
                    srcClones = new StringSet();
                }
                srcClones.add(vplexCopy.getId().toString());
                backCopy.setFullCopySetName(NullColumnValueGetter.getNullStr());
                backCopy.addInternalFlags(Flag.INTERNAL_OBJECT);
                _dbClient.updateObject(backCopy);
                _dbClient.updateObject(vplexCopy);
                _dbClient.updateObject(vplexSrcVolume);
                vplexVolumeDescriptors.add(vplexCopyVolume);
                createStepsForFullCopyImport(workflow, vplexSrcVolume.getStorageController(), vplexVolumeDescriptors, blockDescriptors, waitFor);
            }
        }
    }
    _log.info("Created workflow steps to import the backend full copies");
}
Also used : VirtualPoolCapabilityValuesWrapper(com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper) VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) Volume(com.emc.storageos.db.client.model.Volume) StringSet(com.emc.storageos.db.client.model.StringSet) ArrayList(java.util.ArrayList) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI)

Example 53 with VolumeDescriptor

use of com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor in project coprhd-controller by CoprHD.

the class VPlexDeviceController method addStepsForChangeVirtualPool.

@Override
public String addStepsForChangeVirtualPool(Workflow workflow, String waitFor, List<VolumeDescriptor> volumes, String taskId) throws InternalException {
    try {
        // Get all the Virtual Volumes.
        List<VolumeDescriptor> vplexVirtualVolumes = VolumeDescriptor.filterByType(volumes, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.VPLEX_VIRT_VOLUME }, new VolumeDescriptor.Type[] {});
        if (vplexVirtualVolumes == null || vplexVirtualVolumes.isEmpty()) {
            return waitFor;
        }
        // Find the original change vpool virtual volumes from the descriptors.
        URI newVpoolURI = null;
        List<URI> changeVpoolVirtualVolumeURIs = new ArrayList<URI>();
        for (VolumeDescriptor vplexVirtualVolume : vplexVirtualVolumes) {
            if (vplexVirtualVolume.getParameters() != null && !vplexVirtualVolume.getParameters().isEmpty()) {
                // Let's check to see if the PARAM_VPOOL_CHANGE_EXISTING_VOLUME_ID was populated
                // in the descriptor params map. This would indicate that the descriptor
                // has information about the existing volume for the change vpool operation.
                Object existingVolumeId = vplexVirtualVolume.getParameters().get(VolumeDescriptor.PARAM_VPOOL_CHANGE_EXISTING_VOLUME_ID);
                if (existingVolumeId != null) {
                    URI virtualVolumeURI = (URI) existingVolumeId;
                    _log.info(String.format("Adding steps for change vpool for vplex volume %s", virtualVolumeURI.toString()));
                    if (newVpoolURI == null) {
                        newVpoolURI = (URI) vplexVirtualVolume.getParameters().get(VolumeDescriptor.PARAM_VPOOL_CHANGE_NEW_VPOOL_ID);
                    }
                    changeVpoolVirtualVolumeURIs.add(virtualVolumeURI);
                }
            }
        }
        // Check to see if this is an RP+VPLEX change vpool request
        List<VolumeDescriptor> rpExistingSourceVolumes = VolumeDescriptor.filterByType(volumes, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.RP_EXISTING_SOURCE }, new VolumeDescriptor.Type[] {});
        // Check to see if this is an RP+VPLEX change vpool request
        List<VolumeDescriptor> rpExistingProtectedSourceVolumes = VolumeDescriptor.filterByType(volumes, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.RP_EXISTING_PROTECTED_SOURCE }, new VolumeDescriptor.Type[] {});
        boolean rpAddProtectionVPoolChange = (rpExistingSourceVolumes != null && !rpExistingSourceVolumes.isEmpty());
        boolean rpUpgradeProtectionVPoolChange = (rpExistingProtectedSourceVolumes != null && !rpExistingProtectedSourceVolumes.isEmpty());
        // RP+VPLEX change vpool request
        if (rpAddProtectionVPoolChange || rpUpgradeProtectionVPoolChange) {
            // First let's make a copy of the all the volume descriptors passed in
            List<VolumeDescriptor> copyOfVolumeDescriptors = new ArrayList<VolumeDescriptor>();
            copyOfVolumeDescriptors.addAll(volumes);
            if (rpAddProtectionVPoolChange) {
                _log.info("Adding VPLEX steps for RP+VPLEX/MetroPoint add protection vpool change...");
                Iterator<VolumeDescriptor> it = copyOfVolumeDescriptors.iterator();
                while (it.hasNext()) {
                    VolumeDescriptor currentVolumeDesc = it.next();
                    if (changeVpoolVirtualVolumeURIs.contains(currentVolumeDesc.getVolumeURI())) {
                        // Remove the RP+VPLEX Source Change Vpool Virtual Volume(s) from the copy of the
                        // descriptors as they do not need to be created (because they already exist!)
                        it.remove();
                        break;
                    }
                }
                // already)
                for (URI virtualVolumeURI : changeVpoolVirtualVolumeURIs) {
                    Volume changeVpoolVolume = getDataObject(Volume.class, virtualVolumeURI, _dbClient);
                    changeVpoolVolume.getConsistencyGroup();
                    // This is a good time to update the vpool on the existing Virtual Volume to the new vpool
                    changeVpoolVolume.setVirtualPool(newVpoolURI);
                    _dbClient.updateObject(changeVpoolVolume);
                    StorageSystem vplex = getDataObject(StorageSystem.class, changeVpoolVolume.getStorageController(), _dbClient);
                    // Get a handle on the RP consistency group manager
                    ConsistencyGroupManager consistencyGroupManager = getConsistencyGroupManager(DiscoveredDataObject.Type.rp.name());
                    // Add step for create CG
                    waitFor = consistencyGroupManager.addStepsForCreateConsistencyGroup(workflow, waitFor, vplex, Arrays.asList(virtualVolumeURI), false);
                    _log.info("Added steps for CG creation for vplex volume {}", virtualVolumeURI);
                }
            } else {
                _log.info("Adding VPLEX steps for RP+VPLEX/MetroPoint upgrade protection vpool change...");
            }
            // Let's now create the virtual volumes for the RP+VPLEX:
            // Source Journal, Target(s), and Target Journal.
            waitFor = addStepsForCreateVolumes(workflow, waitFor, copyOfVolumeDescriptors, taskId);
        }
        // Create steps to migrate the backend volumes.
        String lastStep = waitFor;
        URI cgURI = null;
        // With application support, one VPLEX CG could have multiple replication groups from the same local system.
        // The localSystemToRemoveCG map key is storagesystemUri, value is the list of replication group names to be removed.
        Map<URI, Set<String>> localSystemsToRemoveCG = new HashMap<URI, Set<String>>();
        List<VolumeDescriptor> vplexMigrateVolumes = VolumeDescriptor.filterByType(volumes, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.VPLEX_MIGRATE_VOLUME }, new VolumeDescriptor.Type[] {});
        if (vplexMigrateVolumes != null && !vplexMigrateVolumes.isEmpty()) {
            for (URI virtualVolumeURI : changeVpoolVirtualVolumeURIs) {
                _log.info("Adding migration steps for vplex volume {}", virtualVolumeURI);
                // A list of the volumes satisfying the new VirtualPool to
                // which the data on the current backend volumes
                // will be migrated.
                List<URI> newVolumes = new ArrayList<URI>();
                // A Map containing a migration for each new backend
                // volume
                Map<URI, URI> migrationMap = new HashMap<URI, URI>();
                // A map that specifies the storage pool in which
                // each new volume should be created.
                Map<URI, URI> poolVolumeMap = new HashMap<URI, URI>();
                // The URI of the vplex system
                URI vplexURI = null;
                for (VolumeDescriptor desc : vplexMigrateVolumes) {
                    // Skip migration targets that are not for the VPLEX
                    // volume being processed.
                    Migration migration = getDataObject(Migration.class, desc.getMigrationId(), _dbClient);
                    if (!migration.getVolume().equals(virtualVolumeURI)) {
                        continue;
                    }
                    // migrated when multiple volumes are passed.
                    if (vplexURI == null) {
                        Volume virtualVolume = getDataObject(Volume.class, virtualVolumeURI, _dbClient);
                        vplexURI = virtualVolume.getStorageController();
                        cgURI = virtualVolume.getConsistencyGroup();
                    }
                    // Set data required to add the migration steps.
                    newVolumes.add(desc.getVolumeURI());
                    migrationMap.put(desc.getVolumeURI(), desc.getMigrationId());
                    poolVolumeMap.put(desc.getVolumeURI(), desc.getPoolURI());
                    // If the migration is to a different storage system
                    // we may need to remove the backend CG on the source
                    // system after the migration completes. Note that the
                    // migration source is null for an ingested volume
                    // being migrated to known storage.
                    Volume migSrc = null;
                    URI migSrcURI = migration.getSource();
                    if (!NullColumnValueGetter.isNullURI(migSrcURI)) {
                        migSrc = getDataObject(Volume.class, migSrcURI, _dbClient);
                    }
                    URI migTgtURI = migration.getTarget();
                    Volume migTgt = getDataObject(Volume.class, migTgtURI, _dbClient);
                    if ((migSrc != null) && (!migTgt.getStorageController().equals(migSrc.getStorageController()))) {
                        // If we have a volume to migrate and the RG field is NOT set on the volume,
                        // do not remove the RG on the local system.
                        // 
                        // Volumes that are in RGs that are being migrated are grouped together so otherwise
                        // we're good as the replication instance will be set on those volumes.
                        String rgName = migSrc.getReplicationGroupInstance();
                        if (NullColumnValueGetter.isNotNullValue(rgName)) {
                            URI storageUri = migSrc.getStorageController();
                            Set<String> rgNames = localSystemsToRemoveCG.get(storageUri);
                            if (rgNames == null) {
                                rgNames = new HashSet<String>();
                                localSystemsToRemoveCG.put(storageUri, rgNames);
                            }
                            rgNames.add(rgName);
                            _log.info("Will remove CG {} on local system {}", rgName, storageUri);
                        } else {
                            _log.info("Will not remove CG on local system {}", migSrc.getStorageController());
                        }
                    }
                }
                // Note that the last step here is a step group associated
                // with deleting the migration sources after the migrations
                // have completed and committed. This means that anything
                // that waits on this, will occur after the migrations have
                // completed, been committed, and the migration sources deleted.
                lastStep = addStepsForMigrateVolumes(workflow, vplexURI, virtualVolumeURI, newVolumes, migrationMap, poolVolumeMap, newVpoolURI, null, VolumeDescriptor.getMigrationSuspendBeforeCommit(volumes), VolumeDescriptor.getMigrationSuspendBeforeDeleteSource(volumes), taskId, waitFor);
                _log.info("Add migration steps for vplex volume {}", virtualVolumeURI);
            }
            // systemConsistencyGroup specified for the group.
            if (!NullColumnValueGetter.isNullURI(cgURI)) {
                _log.info("Vpool change volumes are in CG {}", cgURI);
                BlockConsistencyGroup cg = getDataObject(BlockConsistencyGroup.class, cgURI, _dbClient);
                if (cg.checkForType(Types.LOCAL)) {
                    _log.info("CG {} has local type", cgURI);
                    // If any of the VPLEX volumes involved in the vpool change
                    // is in a VPLEX CG with corresponding local CGs for the backend
                    // volumes, then it is required that all VPLEX volumes in the
                    // CG are part of the vpool change. If the backend volumes are being
                    // migrated to a new storage system, then we need to add a step
                    // to delete the local CG.
                    boolean localCGDeleted = false;
                    for (Map.Entry<URI, Set<String>> entry : localSystemsToRemoveCG.entrySet()) {
                        localCGDeleted = true;
                        URI localSystemURI = entry.getKey();
                        StorageSystem localSystem = getDataObject(StorageSystem.class, localSystemURI, _dbClient);
                        Set<String> rgNames = entry.getValue();
                        for (String rgName : rgNames) {
                            _log.info("Adding step to remove CG {} on local system {}", rgName, localSystemURI);
                            Workflow.Method deleteCGMethod = new Workflow.Method("deleteReplicationGroupInConsistencyGroup", localSystemURI, cgURI, rgName, false, false, true);
                            workflow.createStep("deleteLocalCG", String.format("Delete consistency group from storage system: %s", localSystemURI), lastStep, localSystemURI, localSystem.getSystemType(), BlockDeviceController.class, deleteCGMethod, null, null);
                        }
                    }
                    if (localCGDeleted) {
                        lastStep = "deleteLocalCG";
                    }
                }
            }
        }
        // Return the last step
        return lastStep;
    } catch (Exception ex) {
        throw VPlexApiException.exceptions.addStepsForChangeVirtualPoolFailed(ex);
    }
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) StringSet(com.emc.storageos.db.client.model.StringSet) HashMap(java.util.HashMap) Migration(com.emc.storageos.db.client.model.Migration) ArrayList(java.util.ArrayList) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) Workflow(com.emc.storageos.workflow.Workflow) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) InternalServerErrorException(com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) WorkflowException(com.emc.storageos.workflow.WorkflowException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) Volume(com.emc.storageos.db.client.model.Volume) BlockObject(com.emc.storageos.db.client.model.BlockObject) DiscoveredDataObject(com.emc.storageos.db.client.model.DiscoveredDataObject) DataObject(com.emc.storageos.db.client.model.DataObject) VPlexControllerUtils.getDataObject(com.emc.storageos.vplexcontroller.VPlexControllerUtils.getDataObject) Map(java.util.Map) OpStatusMap(com.emc.storageos.db.client.model.OpStatusMap) HashMap(java.util.HashMap) StringMap(com.emc.storageos.db.client.model.StringMap)

Example 54 with VolumeDescriptor

use of com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor in project coprhd-controller by CoprHD.

the class VPlexDeviceController method groupDescriptorsByReplicationGroup.

/**
 * Group the given volume descriptors by backend Array Replication Group.
 *
 * Volume descriptors contains
 * 1. VPLEX v-volume to be copied (source),
 * 2. VPLEX copy v-volume to be created,
 * 3. backend source volume to be created as clone for (1)'s backend volume
 * 4. Empty volume to be created as HA backend volume for (2) in case of Distributed
 *
 * @param volumeDescriptors
 *            the volume descriptors
 * @return the replication group to volume desciptors map
 */
private Map<String, List<VolumeDescriptor>> groupDescriptorsByReplicationGroup(List<VolumeDescriptor> volumeDescriptors) {
    _log.info("Group the given desciptors based on backend Replication Group");
    Map<String, List<VolumeDescriptor>> repGroupToVolumeDescriptors = new HashMap<String, List<VolumeDescriptor>>();
    List<VolumeDescriptor> vplexVolumeDescriptors = VolumeDescriptor.filterByType(volumeDescriptors, new VolumeDescriptor.Type[] { Type.VPLEX_VIRT_VOLUME }, new VolumeDescriptor.Type[] {});
    List<VolumeDescriptor> vplexSrcVolumeDescrs = getDescriptorsForFullCopySrcVolumes(vplexVolumeDescriptors);
    // has only copy v-volumes
    vplexVolumeDescriptors.removeAll(vplexSrcVolumeDescrs);
    List<URI> vplexSrcVolumeURIs = VolumeDescriptor.getVolumeURIs(vplexSrcVolumeDescrs);
    if (!vplexSrcVolumeURIs.isEmpty()) {
        List<Volume> vplexSrcVolumes = ControllerUtils.queryVolumesByIterativeQuery(_dbClient, vplexSrcVolumeURIs);
        // group volumes by Array Group
        Map<String, List<Volume>> arrayGroupToVolumesMap = ControllerUtils.groupVolumesByArrayGroup(vplexSrcVolumes, _dbClient);
        /**
         * If only one entry of array replication group, put all descriptors
         * Else group them according to array group
         */
        if (arrayGroupToVolumesMap.size() == 1) {
            String arrayGroupName = arrayGroupToVolumesMap.keySet().iterator().next();
            _log.info("Single entry: Replication Group {}, Volume descriptors {}", arrayGroupName, Joiner.on(',').join(VolumeDescriptor.getVolumeURIs(volumeDescriptors)));
            repGroupToVolumeDescriptors.put(arrayGroupName, volumeDescriptors);
        } else {
            for (String arrayGroupName : arrayGroupToVolumesMap.keySet()) {
                // AG - Array Replication Group
                _log.debug("Processing Replication Group {}", arrayGroupName);
                List<Volume> vplexSrcVolumesAG = arrayGroupToVolumesMap.get(arrayGroupName);
                List<VolumeDescriptor> descriptorsForAG = new ArrayList<VolumeDescriptor>();
                // add VPLEX src volumes to descriptor list
                Collection<URI> vplexSrcVolumesUrisAG = transform(vplexSrcVolumesAG, fctnDataObjectToID());
                descriptorsForAG.addAll(getDescriptorsForURIsFromGivenList(vplexSrcVolumeDescrs, vplexSrcVolumesUrisAG));
                for (VolumeDescriptor vplexCopyVolumeDesc : vplexVolumeDescriptors) {
                    URI vplexCopyVolumeURI = vplexCopyVolumeDesc.getVolumeURI();
                    Volume vplexCopyVolume = getDataObject(Volume.class, vplexCopyVolumeURI, _dbClient);
                    if (vplexSrcVolumesUrisAG.contains(vplexCopyVolume.getAssociatedSourceVolume())) {
                        _log.debug("Adding VPLEX copy volume descriptor for {}", vplexCopyVolumeURI);
                        // add VPLEX Copy volumes to descriptor list
                        descriptorsForAG.add(vplexCopyVolumeDesc);
                        // add Copy associated volumes to desciptor list
                        List<VolumeDescriptor> assocDescriptors = getDescriptorsForAssociatedVolumes(vplexCopyVolumeURI, volumeDescriptors);
                        descriptorsForAG.addAll(assocDescriptors);
                    }
                }
                _log.info("Entry: Replication Group {}, Volume descriptors {}", arrayGroupName, Joiner.on(',').join(VolumeDescriptor.getVolumeURIs(descriptorsForAG)));
                repGroupToVolumeDescriptors.put(arrayGroupName, descriptorsForAG);
            }
        }
    } else {
        // non-application & clone for Snapshot
        _log.info("Request is not for VPLEX volume, returning all.");
        repGroupToVolumeDescriptors.put("SNAPSHOT_GROUP", volumeDescriptors);
    }
    return repGroupToVolumeDescriptors;
}
Also used : VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) Volume(com.emc.storageos.db.client.model.Volume) ApplicationAddVolumeList(com.emc.storageos.volumecontroller.ApplicationAddVolumeList) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) List(java.util.List)

Example 55 with VolumeDescriptor

use of com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor in project coprhd-controller by CoprHD.

the class VPlexDeviceController method buildVolumeMap.

/**
 * Build a map of URI to cached Volumes for the underlying Storage Volumes that
 * should be already present (and created).
 *
 * @param vplexSystem
 *            Only return Volume associated with this VPlex
 * @param descriptors
 *            VolumeDescriptors
 * @param VolmeDescriptor.Type
 *            used to filter descriptors
 * @return Map<volumeURI, Volume>
 */
private Map<URI, Volume> buildVolumeMap(StorageSystem vplexSystem, List<VolumeDescriptor> descriptors, VolumeDescriptor.Type type) {
    Map<URI, Volume> volumeMap = new HashMap<URI, Volume>();
    // Get only the descriptors for the type if specified.
    if (type != null) {
        descriptors = VolumeDescriptor.filterByType(descriptors, new VolumeDescriptor.Type[] { type }, new VolumeDescriptor.Type[] {});
    }
    // Loop through all the descriptors / filtered descriptors
    for (VolumeDescriptor desc : descriptors) {
        // Check to see if the volumeMap already contains the volume URI.
        if (volumeMap.containsKey(desc.getVolumeURI()) == false) {
            // Load the volume from the descriptor
            Volume volume = getDataObject(Volume.class, desc.getVolumeURI(), _dbClient);
            if (vplexSystem == null) {
                // If the vplexSystem hasn't been passed in, just add the volume the volumeMap.
                volumeMap.put(desc.getVolumeURI(), volume);
            } else {
                // Check the storage controller of this Virtual Volume
                if (desc.getType().equals(VolumeDescriptor.Type.VPLEX_VIRT_VOLUME) && volume.getStorageController().toString().equals(vplexSystem.getId().toString())) {
                    StringSet backingVolumes = volume.getAssociatedVolumes();
                    if (null == backingVolumes || backingVolumes.isEmpty()) {
                        _log.warn("VPLEX volume {} has no backend volumes.", volume.forDisplay());
                    } else {
                        // Add all backing volumes found to the volumeMap
                        for (String backingVolumeId : backingVolumes) {
                            URI backingVolumeURI = URI.create(backingVolumeId);
                            Volume backingVolume = getDataObject(Volume.class, backingVolumeURI, _dbClient);
                            volumeMap.put(backingVolumeURI, backingVolume);
                        }
                    }
                }
            }
        }
    }
    return volumeMap;
}
Also used : LockType(com.emc.storageos.locking.LockType) Type(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor.Type) TechnologyType(com.emc.storageos.db.client.model.BlockSnapshot.TechnologyType) Initiator_Type(com.emc.storageos.vplex.api.VPlexInitiatorInfo.Initiator_Type) VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) Volume(com.emc.storageos.db.client.model.Volume) HashMap(java.util.HashMap) StringSet(com.emc.storageos.db.client.model.StringSet) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI)

Aggregations

VolumeDescriptor (com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor)117 Volume (com.emc.storageos.db.client.model.Volume)98 URI (java.net.URI)86 NamedURI (com.emc.storageos.db.client.model.NamedURI)77 ArrayList (java.util.ArrayList)77 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)38 HashMap (java.util.HashMap)38 StringSet (com.emc.storageos.db.client.model.StringSet)29 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)27 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)19 FCTN_STRING_TO_URI (com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_STRING_TO_URI)18 Workflow (com.emc.storageos.workflow.Workflow)18 ApplicationAddVolumeList (com.emc.storageos.volumecontroller.ApplicationAddVolumeList)17 ControllerException (com.emc.storageos.volumecontroller.ControllerException)17 List (java.util.List)17 BlockOrchestrationController (com.emc.storageos.blockorchestrationcontroller.BlockOrchestrationController)16 VirtualPool (com.emc.storageos.db.client.model.VirtualPool)16 InternalServerErrorException (com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException)16 URISyntaxException (java.net.URISyntaxException)16 BlockConsistencyGroup (com.emc.storageos.db.client.model.BlockConsistencyGroup)15