Search in sources :

Example 36 with ExportMask

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

the class VolumeIngestionUtil method createExportMask.

/**
 * Creates an ExportMask for the given arguments and returns the BlockObject.
 *
 * @param eligibleMask an UnManagedExportMask to base the ExportMask on
 * @param unManagedVolume the UnManagedVolume being ingested
 * @param exportGroup the ExportGroup for the ExportMask
 * @param volume the Volume object for the ExportMask
 * @param dbClient a reference to the database client
 * @param hosts a List of Hosts for the ExportMask
 * @param cluster a Cluster for the ExportMask
 * @param exportMaskLabel the name of the ExportMask
 * @throws Exception
 */
public static <T extends BlockObject> ExportMask createExportMask(UnManagedExportMask eligibleMask, UnManagedVolume unManagedVolume, ExportGroup exportGroup, T volume, DbClient dbClient, List<Host> hosts, Cluster cluster, String exportMaskLabel) throws Exception {
    _logger.info("Creating ExportMask for unManaged Mask {}", eligibleMask.getMaskName());
    List<URI> initiatorUris = new ArrayList<URI>(Collections2.transform(eligibleMask.getKnownInitiatorUris(), CommonTransformerFunctions.FCTN_STRING_TO_URI));
    List<Initiator> allInitiators = dbClient.queryObject(Initiator.class, initiatorUris);
    List<Initiator> userAddedInis = VolumeIngestionUtil.findUserAddedInisFromExistingIniListInMask(allInitiators, eligibleMask.getId(), dbClient);
    List<URI> storagePortUris = new ArrayList<URI>(Collections2.transform(eligibleMask.getKnownStoragePortUris(), CommonTransformerFunctions.FCTN_STRING_TO_URI));
    Map<String, Integer> wwnToHluMap = extractWwnToHluMap(eligibleMask, dbClient);
    ExportMask exportMask = ExportMaskUtils.initializeExportMaskWithVolumes(eligibleMask.getStorageSystemUri(), exportGroup, eligibleMask.getMaskName(), exportMaskLabel, allInitiators, null, storagePortUris, eligibleMask.getZoningMap(), volume, eligibleMask.getUnmanagedInitiatorNetworkIds(), eligibleMask.getNativeId(), userAddedInis, dbClient, wwnToHluMap);
    // remove unmanaged mask if created if the block object is not marked as internal
    if (!volume.checkInternalFlags(Flag.PARTIALLY_INGESTED)) {
        _logger.info("breaking relationship between UnManagedExportMask {} and UnManagedVolume {}", eligibleMask.getMaskName(), unManagedVolume.getLabel());
        unManagedVolume.getUnmanagedExportMasks().remove(eligibleMask.getId().toString());
        eligibleMask.getUnmanagedVolumeUris().remove(unManagedVolume.getId().toString());
    }
    updateExportGroup(exportGroup, volume, wwnToHluMap, dbClient, allInitiators, hosts, cluster);
    return exportMask;
}
Also used : BigInteger(java.math.BigInteger) Initiator(com.emc.storageos.db.client.model.Initiator) UnManagedExportMask(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask) ExportMask(com.emc.storageos.db.client.model.ExportMask) ArrayList(java.util.ArrayList) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI)

Example 37 with ExportMask

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

the class BlockDeviceController method rollBackCreateVolumes.

/**
 * {@inheritDoc} NOTE: The signature here MUST match the Workflow.Method rollbackCreateVolumesMethod just above
 * (except opId).
 */
@Override
public void rollBackCreateVolumes(URI systemURI, List<URI> volumeURIs, String opId) throws ControllerException {
    MultiVolumeTaskCompleter completer = new MultiVolumeTaskCompleter(volumeURIs, opId);
    List<Volume> volumes = new ArrayList<>(volumeURIs.size());
    completer.setRollingBack(true);
    try {
        String logMsg = String.format("rollbackCreateVolume start - Array:%s, Volume:%s", systemURI.toString(), Joiner.on(',').join(volumeURIs));
        _log.info(logMsg.toString());
        WorkflowStepCompleter.stepExecuting(opId);
        volumes.addAll(_dbClient.queryObject(Volume.class, volumeURIs));
        for (Volume volume : volumes) {
            // CTRL-5597 clean volumes which have failed only in a multi-volume request
            if (null != volume.getNativeGuid()) {
                StorageSystem system = _dbClient.queryObject(StorageSystem.class, volume.getStorageController());
                if (Type.xtremio.toString().equalsIgnoreCase(system.getSystemType())) {
                    continue;
                }
            }
            // then we need to clear srdfTargets and personality fields for source
            if (null != volume.getSrdfTargets()) {
                _log.info("Clearing targets for existing source");
                volume.getSrdfTargets().clear();
                _dbClient.updateObject(volume);
                // Clearing Source CG
                URI sourceCgUri = volume.getConsistencyGroup();
                if (null != sourceCgUri) {
                    BlockConsistencyGroup sourceCG = _dbClient.queryObject(BlockConsistencyGroup.class, sourceCgUri);
                    if (null != sourceCG && (null == sourceCG.getTypes() || NullColumnValueGetter.isNullURI(sourceCG.getStorageController()))) {
                        sourceCG.getRequestedTypes().remove(Types.SRDF.name());
                        _dbClient.updateObject(sourceCG);
                    }
                }
            }
            // for change Virtual Pool, if failed, clear targets and personality field for source and also
            if (!NullColumnValueGetter.isNullNamedURI(volume.getSrdfParent())) {
                URI sourceUri = volume.getSrdfParent().getURI();
                Volume sourceVolume = _dbClient.queryObject(Volume.class, sourceUri);
                sourceVolume.setPersonality(NullColumnValueGetter.getNullStr());
                if (null != sourceVolume.getSrdfTargets()) {
                    sourceVolume.getSrdfTargets().clear();
                    _dbClient.updateObject(sourceVolume);
                }
                // Clearing target CG
                URI cgUri = volume.getConsistencyGroup();
                if (null != cgUri) {
                    BlockConsistencyGroup targetCG = _dbClient.queryObject(BlockConsistencyGroup.class, cgUri);
                    if (null != targetCG && (null == targetCG.getTypes() || NullColumnValueGetter.isNullURI(targetCG.getStorageController()))) {
                        _log.info("Set target CG {} inactive", targetCG.getLabel());
                        targetCG.setInactive(true);
                        _dbClient.updateObject(targetCG);
                    }
                    // clear association between target volume and target cg
                    volume.setConsistencyGroup(NullColumnValueGetter.getNullURI());
                    _dbClient.updateAndReindexObject(volume);
                }
            }
            // Check for loose export groups associated with this rolled-back volume
            URIQueryResultList exportGroupURIs = new URIQueryResultList();
            _dbClient.queryByConstraint(ContainmentConstraint.Factory.getVolumeExportGroupConstraint(volume.getId()), exportGroupURIs);
            while (exportGroupURIs.iterator().hasNext()) {
                URI exportGroupURI = exportGroupURIs.iterator().next();
                ExportGroup exportGroup = _dbClient.queryObject(ExportGroup.class, exportGroupURI);
                if (!exportGroup.getInactive()) {
                    exportGroup.removeVolume(volume.getId());
                    boolean canRemoveGroup = false;
                    List<ExportMask> exportMasks = ExportMaskUtils.getExportMasks(_dbClient, exportGroup);
                    // Make sure the volume is not in an export mask
                    for (ExportMask exportMask : exportMasks) {
                        exportMask.removeVolume(volume.getId());
                        exportMask.removeFromUserCreatedVolumes(volume);
                        exportMask.removeFromExistingVolumes(volume);
                        if (!exportMask.getCreatedBySystem() && !exportMask.hasAnyVolumes() && exportMask.emptyVolumes()) {
                            canRemoveGroup = true;
                            _dbClient.removeObject(exportMask);
                        } else {
                            _dbClient.updateObject(exportMask);
                        }
                    }
                    // If we didn't find that volume in a mask, it's OK to remove it.
                    if (canRemoveGroup && exportMasks.size() == 1 && exportGroup.getVolumes().isEmpty()) {
                        _dbClient.removeObject(exportGroup);
                    } else {
                        _dbClient.updateObject(exportGroup);
                    }
                }
            }
        }
        InvokeTestFailure.internalOnlyInvokeTestFailure(InvokeTestFailure.ARTIFICIAL_FAILURE_013);
        deleteVolumesWithCompleter(systemURI, volumeURIs, completer);
        InvokeTestFailure.internalOnlyInvokeTestFailure(InvokeTestFailure.ARTIFICIAL_FAILURE_014);
        logMsg = String.format("rollbackCreateVolume end - Array:%s, Volume:%s", systemURI.toString(), Joiner.on(',').join(volumeURIs));
        _log.info(logMsg.toString());
    } catch (Exception e) {
        _log.error(String.format("rollbackCreateVolume Failed - Array:%s, Volume:%s", systemURI.toString(), Joiner.on(',').join(volumeURIs)));
        handleException(e, completer);
    }
}
Also used : ExportMask(com.emc.storageos.db.client.model.ExportMask) ArrayList(java.util.ArrayList) MultiVolumeTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.MultiVolumeTaskCompleter) NamedURI(com.emc.storageos.db.client.model.NamedURI) FCTN_MIRROR_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_MIRROR_TO_URI) URI(java.net.URI) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) BaseCollectionException(com.emc.storageos.plugins.BaseCollectionException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) WorkflowException(com.emc.storageos.workflow.WorkflowException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) DataBindingException(javax.xml.bind.DataBindingException) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) Volume(com.emc.storageos.db.client.model.Volume) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 38 with ExportMask

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

the class BlockDeviceExportController method updateVolumePathParams.

@Override
public void updateVolumePathParams(URI volumeURI, URI newVpoolURI, String opId) throws ControllerException {
    _log.info("Received request to update Volume path parameters. Creating master workflow.");
    VolumeVpoolChangeTaskCompleter taskCompleter = null;
    Volume volume = null;
    try {
        // Read volume from database, update the Vpool to the new completer, and create task completer.
        volume = _dbClient.queryObject(Volume.class, volumeURI);
        URI oldVpoolURI = volume.getVirtualPool();
        List<URI> rollbackList = new ArrayList<URI>();
        List<Volume> updatedVolumes = new ArrayList<Volume>();
        rollbackList.add(volumeURI);
        // Check if it is a VPlex volume, and get backend volumes
        Volume backendSrc = VPlexUtil.getVPLEXBackendVolume(volume, true, _dbClient, false);
        if (backendSrc != null) {
            // Change the back end volume's vpool too
            backendSrc.setVirtualPool(newVpoolURI);
            rollbackList.add(backendSrc.getId());
            updatedVolumes.add(backendSrc);
            // VPlex volume, check if it is distributed
            Volume backendHa = VPlexUtil.getVPLEXBackendVolume(volume, false, _dbClient, false);
            if (backendHa != null && backendHa.getVirtualPool() != null && backendHa.getVirtualPool().toString().equals(oldVpoolURI.toString())) {
                backendHa.setVirtualPool(newVpoolURI);
                rollbackList.add(backendHa.getId());
                updatedVolumes.add(backendHa);
            }
        }
        // The VolumeVpoolChangeTaskCompleter will restore the old Virtual Pool in event of error.
        taskCompleter = new VolumeVpoolChangeTaskCompleter(rollbackList, oldVpoolURI, opId);
        volume.setVirtualPool(newVpoolURI);
        updatedVolumes.add(volume);
        _log.info(String.format("Changing VirtualPool PathParams for volume %s (%s) from %s to %s", volume.getLabel(), volume.getId(), oldVpoolURI, newVpoolURI));
        _dbClient.updateObject(updatedVolumes);
    } catch (Exception ex) {
        _log.error("Unexpected exception reading volume or generating taskCompleter: ", ex);
        ServiceError serviceError = DeviceControllerException.errors.jobFailed(ex);
        VolumeWorkflowCompleter completer = new VolumeWorkflowCompleter(volumeURI, opId);
        completer.error(_dbClient, serviceError);
    }
    try {
        Workflow workflow = _wfUtils.newWorkflow("updateVolumePathParams", false, opId);
        // Locate all the ExportMasks containing the given volume, and their Export Group.
        Map<ExportMask, ExportGroup> maskToGroupMap = ExportUtils.getExportMasks(volume, _dbClient);
        Map<URI, StringSetMap> maskToZoningMap = new HashMap<URI, StringSetMap>();
        // Store the original zoning maps of the export masks to be used to restore in case of a failure
        for (ExportMask mask : maskToGroupMap.keySet()) {
            maskToZoningMap.put(mask.getId(), mask.getZoningMap());
        }
        taskCompleter.setMaskToZoningMap(maskToZoningMap);
        // Acquire all necessary locks for the workflow:
        // For each export group lock initiator's hosts and storage array keys.
        List<URI> initiatorURIs = new ArrayList<URI>();
        for (ExportGroup exportGroup : maskToGroupMap.values()) {
            initiatorURIs.addAll(StringSetUtil.stringSetToUriList(exportGroup.getInitiators()));
            List<String> lockKeys = ControllerLockingUtil.getHostStorageLockKeys(_dbClient, ExportGroup.ExportGroupType.valueOf(exportGroup.getType()), initiatorURIs, volume.getStorageController());
            initiatorURIs.clear();
            boolean acquiredLocks = _wfUtils.getWorkflowService().acquireWorkflowLocks(workflow, lockKeys, LockTimeoutValue.get(LockType.EXPORT_GROUP_OPS));
            if (!acquiredLocks) {
                throw DeviceControllerException.exceptions.failedToAcquireLock(lockKeys.toString(), "UpdateVolumePathParams: " + volume.getLabel());
            }
        }
        // These steps are serialized, which is required in case an ExportMask appears
        // in multiple Export Groups.
        String stepId = null;
        for (ExportGroup exportGroup : maskToGroupMap.values()) {
            stepId = _wfUtils.generateExportChangePathParams(workflow, "changePathParams", stepId, volume.getStorageController(), exportGroup.getId(), volumeURI);
        }
        if (!workflow.getAllStepStatus().isEmpty()) {
            _log.info("The updateVolumePathParams workflow has {} steps. Starting the workflow.", workflow.getAllStepStatus().size());
            workflow.executePlan(taskCompleter, "Update the export group on all storage systems successfully.");
        } else {
            taskCompleter.ready(_dbClient);
        }
    } catch (Exception ex) {
        _log.error("Unexpected exception: ", ex);
        ServiceError serviceError = DeviceControllerException.errors.jobFailed(ex);
        taskCompleter.error(_dbClient, serviceError);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) HashMap(java.util.HashMap) VolumeWorkflowCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeWorkflowCompleter) ExportMask(com.emc.storageos.db.client.model.ExportMask) ArrayList(java.util.ArrayList) Workflow(com.emc.storageos.workflow.Workflow) URI(java.net.URI) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) IOException(java.io.IOException) LockRetryException(com.emc.storageos.locking.LockRetryException) VolumeVpoolChangeTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeVpoolChangeTaskCompleter) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) Volume(com.emc.storageos.db.client.model.Volume)

Example 39 with ExportMask

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

the class BlockDeviceExportController method exportGroupChangePortGroup.

@Override
public void exportGroupChangePortGroup(URI systemURI, URI exportGroupURI, URI newPortGroupURI, List<URI> exportMaskURIs, boolean waitForApproval, String opId) {
    _log.info("Received request for change port group. Creating master workflow.");
    ExportTaskCompleter taskCompleter = new ExportOrchestrationUpdateTaskCompleter(exportGroupURI, opId);
    Workflow workflow = null;
    try {
        workflow = _wfUtils.newWorkflow("exportChangePortGroup", false, opId);
        ExportGroup exportGroup = _dbClient.queryObject(ExportGroup.class, exportGroupURI);
        if (exportGroup == null || exportGroup.getExportMasks() == null) {
            _log.info("No export group or export mask");
            taskCompleter.ready(_dbClient);
            return;
        }
        List<ExportMask> exportMasks = ExportMaskUtils.getExportMasks(_dbClient, exportGroup, systemURI);
        if (exportMasks == null || exportMasks.isEmpty()) {
            _log.info(String.format("No export mask found for this system %s", systemURI));
            taskCompleter.ready(_dbClient);
            return;
        }
        // Acquire all necessary locks for the workflow:
        // For each export group lock initiator's hosts and storage array keys.
        List<String> lockKeys = ControllerLockingUtil.getHostStorageLockKeys(_dbClient, ExportGroup.ExportGroupType.valueOf(exportGroup.getType()), StringSetUtil.stringSetToUriList(exportGroup.getInitiators()), systemURI);
        boolean acquiredLocks = _wfUtils.getWorkflowService().acquireWorkflowLocks(workflow, lockKeys, LockTimeoutValue.get(LockType.EXPORT_GROUP_OPS));
        if (!acquiredLocks) {
            _log.error("Change port group could not acquire locks");
            ServiceError serviceError = DeviceControllerException.errors.jobFailedOpMsg("change port group", "Could not acquire workflow lock");
            taskCompleter.error(_dbClient, serviceError);
            return;
        }
        _wfUtils.generateExportGroupChangePortWorkflow(workflow, "change port group", exportGroupURI, newPortGroupURI, exportMaskURIs, waitForApproval);
        if (!workflow.getAllStepStatus().isEmpty()) {
            _log.info("The updateExportWorkflow has {} steps. Starting the workflow.", workflow.getAllStepStatus().size());
            workflow.executePlan(taskCompleter, "Update the export group on all storage systems successfully.");
        } else {
            taskCompleter.ready(_dbClient);
        }
    } catch (Exception e) {
        _log.error("Unexpected exception: ", e);
        if (workflow != null) {
            _wfUtils.getWorkflowService().releaseAllWorkflowLocks(workflow);
        }
        ServiceError serviceError = DeviceControllerException.errors.jobFailed(e);
        taskCompleter.error(_dbClient, serviceError);
    }
}
Also used : ExportGroup(com.emc.storageos.db.client.model.ExportGroup) ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) ExportTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter) ExportOrchestrationUpdateTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportOrchestrationUpdateTaskCompleter) ExportMask(com.emc.storageos.db.client.model.ExportMask) Workflow(com.emc.storageos.workflow.Workflow) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) IOException(java.io.IOException) LockRetryException(com.emc.storageos.locking.LockRetryException)

Example 40 with ExportMask

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

the class BlockDeviceExportController method updatePolicyAndLimits.

@Override
public void updatePolicyAndLimits(List<URI> volumeURIs, URI newVpoolURI, String opId) throws ControllerException {
    _log.info("Received request to update Auto-tiering policy. Creating master workflow.");
    VolumeVpoolAutoTieringPolicyChangeTaskCompleter taskCompleter = null;
    URI oldVpoolURI = null;
    List<Volume> volumes = new ArrayList<Volume>();
    List<Volume> vplexBackendVolumes = new ArrayList<Volume>();
    try {
        // Read volume from database, update the vPool to the new vPool
        // and update new auto tiering policy uri, and create task completer.
        volumes = _dbClient.queryObject(Volume.class, volumeURIs);
        VirtualPool newVpool = _dbClient.queryObject(VirtualPool.class, newVpoolURI);
        Map<URI, URI> oldVolToPolicyMap = new HashMap<URI, URI>();
        for (Volume volume : volumes) {
            oldVpoolURI = volume.getVirtualPool();
            volume.setVirtualPool(newVpoolURI);
            _log.info(String.format("Changing VirtualPool Auto-tiering Policy for volume %s (%s) from %s to %s", volume.getLabel(), volume.getId(), oldVpoolURI, newVpoolURI));
            oldVolToPolicyMap.put(volume.getId(), volume.getAutoTieringPolicyUri());
            updateAutoTieringPolicyUriInVolume(volume, newVpool);
            // Check if it is a VPlex volume, and get backend volumes
            Volume backendSrc = VPlexUtil.getVPLEXBackendVolume(volume, true, _dbClient, false);
            if (backendSrc != null) {
                // Change the back end volume's vPool too
                backendSrc.setVirtualPool(newVpoolURI);
                vplexBackendVolumes.add(backendSrc);
                _log.info(String.format("Changing VirtualPool Auto-tiering Policy for VPLEX backend source volume %s (%s) from %s to %s", backendSrc.getLabel(), backendSrc.getId(), oldVpoolURI, newVpoolURI));
                oldVolToPolicyMap.put(backendSrc.getId(), backendSrc.getAutoTieringPolicyUri());
                updateAutoTieringPolicyUriInVolume(backendSrc, newVpool);
                // VPlex volume, check if it is distributed
                Volume backendHa = VPlexUtil.getVPLEXBackendVolume(volume, false, _dbClient, false);
                if (backendHa != null) {
                    VirtualPool newHAVpool = VirtualPool.getHAVPool(newVpool, _dbClient);
                    if (newHAVpool == null) {
                        // it may not be set
                        newHAVpool = newVpool;
                    }
                    backendHa.setVirtualPool(newHAVpool.getId());
                    vplexBackendVolumes.add(backendHa);
                    _log.info(String.format("Changing VirtualPool Auto-tiering Policy for VPLEX backend distributed volume %s (%s) from %s to %s", backendHa.getLabel(), backendHa.getId(), oldVpoolURI, newHAVpool.getId()));
                    oldVolToPolicyMap.put(backendHa.getId(), backendHa.getAutoTieringPolicyUri());
                    updateAutoTieringPolicyUriInVolume(backendHa, newHAVpool);
                }
            }
        }
        _dbClient.updateObject(volumes);
        _dbClient.updateObject(vplexBackendVolumes);
        // The VolumeVpoolChangeTaskCompleter will restore the old Virtual Pool
        // and old auto tiering policy in event of error.
        // Assume all volumes belong to the same vPool. This should be take care by BlockService API.
        taskCompleter = new VolumeVpoolAutoTieringPolicyChangeTaskCompleter(volumeURIs, oldVpoolURI, oldVolToPolicyMap, opId);
    } catch (Exception ex) {
        _log.error("Unexpected exception reading volume or generating taskCompleter: ", ex);
        ServiceError serviceError = DeviceControllerException.errors.jobFailed(ex);
        VolumeWorkflowCompleter completer = new VolumeWorkflowCompleter(volumeURIs, opId);
        completer.error(_dbClient, serviceError);
    }
    try {
        Workflow workflow = _wfUtils.newWorkflow("updateAutoTieringPolicy", false, opId);
        /**
         * For VMAX:
         * get corresponding export mask for each volume
         * group volumes by export mask
         * create workflow step for each export mask.
         *
         * For VNX Block:
         * Policy is set on volume during its creation.
         * Whether it is exported or not, send all volumes
         * to update StorageTierMethodology property on them.
         * Create workflow step for each storage system.
         */
        // Use backend volumes list if it is VPLEX volume
        List<Volume> volumesToUse = !vplexBackendVolumes.isEmpty() ? vplexBackendVolumes : volumes;
        // move applicable volumes from all volumes list to a separate list.
        Map<URI, List<URI>> systemToVolumeMap = getVolumesToModify(volumesToUse);
        String stepId = null;
        for (URI systemURI : systemToVolumeMap.keySet()) {
            stepId = _wfUtils.generateExportChangePolicyAndLimits(workflow, "updateAutoTieringPolicy", stepId, systemURI, null, null, systemToVolumeMap.get(systemURI), newVpoolURI, oldVpoolURI);
        }
        Map<URI, List<URI>> storageToNotExportedVolumesMap = new HashMap<URI, List<URI>>();
        Map<URI, List<URI>> exportMaskToVolumeMap = new HashMap<URI, List<URI>>();
        Map<URI, URI> maskToGroupURIMap = new HashMap<URI, URI>();
        for (Volume volume : volumesToUse) {
            // Locate all the ExportMasks containing the given volume
            Map<ExportMask, ExportGroup> maskToGroupMap = ExportUtils.getExportMasks(volume, _dbClient);
            if (maskToGroupMap.isEmpty()) {
                URI storageURI = volume.getStorageController();
                StorageSystem storage = _dbClient.queryObject(StorageSystem.class, storageURI);
                if (storage.checkIfVmax3()) {
                    if (!storageToNotExportedVolumesMap.containsKey(storageURI)) {
                        storageToNotExportedVolumesMap.put(storageURI, new ArrayList<URI>());
                    }
                    storageToNotExportedVolumesMap.get(storageURI).add(volume.getId());
                }
            }
            for (ExportMask mask : maskToGroupMap.keySet()) {
                if (!exportMaskToVolumeMap.containsKey(mask.getId())) {
                    exportMaskToVolumeMap.put(mask.getId(), new ArrayList<URI>());
                }
                exportMaskToVolumeMap.get(mask.getId()).add(volume.getId());
                maskToGroupURIMap.put(mask.getId(), maskToGroupMap.get(mask).getId());
            }
        }
        VirtualPool oldVpool = _dbClient.queryObject(VirtualPool.class, oldVpoolURI);
        for (URI exportMaskURI : exportMaskToVolumeMap.keySet()) {
            ExportMask exportMask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
            List<URI> exportMaskVolumes = exportMaskToVolumeMap.get(exportMaskURI);
            URI exportMaskNewVpool = newVpoolURI;
            URI exportMaskOldVpool = oldVpoolURI;
            Volume vol = _dbClient.queryObject(Volume.class, exportMaskVolumes.get(0));
            // all volumes are already updated with respective new vPool
            if (Volume.checkForVplexBackEndVolume(_dbClient, vol) && !newVpoolURI.equals(vol.getVirtualPool())) {
                // backend distributed volume; HA vPool set in Vplex vPool
                exportMaskNewVpool = vol.getVirtualPool();
                VirtualPool oldHAVpool = VirtualPool.getHAVPool(oldVpool, _dbClient);
                if (oldHAVpool == null) {
                    // it may not be set
                    oldHAVpool = oldVpool;
                }
                exportMaskOldVpool = oldHAVpool.getId();
            }
            stepId = _wfUtils.generateExportChangePolicyAndLimits(workflow, "updateAutoTieringPolicy", stepId, exportMask.getStorageDevice(), exportMaskURI, maskToGroupURIMap.get(exportMaskURI), exportMaskVolumes, exportMaskNewVpool, exportMaskOldVpool);
        }
        for (URI storageURI : storageToNotExportedVolumesMap.keySet()) {
            stepId = _wfUtils.generateChangeAutoTieringPolicy(workflow, "updateAutoTieringPolicyForNotExportedVMAX3Volumes", stepId, storageURI, storageToNotExportedVolumesMap.get(storageURI), newVpoolURI, oldVpoolURI);
        }
        if (!workflow.getAllStepStatus().isEmpty()) {
            _log.info("The updateAutoTieringPolicy workflow has {} step(s). Starting the workflow.", workflow.getAllStepStatus().size());
            workflow.executePlan(taskCompleter, "Updated the export group on all storage systems successfully.");
        } else {
            taskCompleter.ready(_dbClient);
        }
    } catch (Exception ex) {
        _log.error("Unexpected exception: ", ex);
        ServiceError serviceError = DeviceControllerException.errors.jobFailed(ex);
        taskCompleter.error(_dbClient, serviceError);
    }
}
Also used : VolumeVpoolAutoTieringPolicyChangeTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeVpoolAutoTieringPolicyChangeTaskCompleter) ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) HashMap(java.util.HashMap) VolumeWorkflowCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeWorkflowCompleter) ExportMask(com.emc.storageos.db.client.model.ExportMask) ArrayList(java.util.ArrayList) Workflow(com.emc.storageos.workflow.Workflow) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) URI(java.net.URI) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) IOException(java.io.IOException) LockRetryException(com.emc.storageos.locking.LockRetryException) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) Volume(com.emc.storageos.db.client.model.Volume) List(java.util.List) ArrayList(java.util.ArrayList) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Aggregations

ExportMask (com.emc.storageos.db.client.model.ExportMask)368 URI (java.net.URI)274 ArrayList (java.util.ArrayList)224 Initiator (com.emc.storageos.db.client.model.Initiator)155 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)140 ExportGroup (com.emc.storageos.db.client.model.ExportGroup)134 HashMap (java.util.HashMap)128 HashSet (java.util.HashSet)121 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)107 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)102 List (java.util.List)79 StringSet (com.emc.storageos.db.client.model.StringSet)68 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)65 Map (java.util.Map)65 StringMap (com.emc.storageos.db.client.model.StringMap)60 BlockObject (com.emc.storageos.db.client.model.BlockObject)56 NamedURI (com.emc.storageos.db.client.model.NamedURI)56 Workflow (com.emc.storageos.workflow.Workflow)54 Set (java.util.Set)51 Volume (com.emc.storageos.db.client.model.Volume)44