Search in sources :

Example 91 with ExportGroup

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

the class ExportChangePortGroupCompleter method complete.

@Override
protected void complete(DbClient dbClient, Operation.Status status, ServiceCoded coded) throws DeviceControllerException {
    try {
        String eventMessage = null;
        log.info("Change port group completer:" + status.name());
        ExportGroup exportGroup = dbClient.queryObject(ExportGroup.class, getId());
        Operation operation = new Operation();
        switch(status) {
            case error:
                operation.error(coded);
                eventMessage = String.format(EXPORT_CHANGE_PORT_GROUP_FAILED_MSG, exportGroup.getLabel());
                break;
            case ready:
                operation.ready();
                updateVolumeExportPathParam(dbClient);
                eventMessage = String.format(EXPORT_CHANGE_PORT_GROUP_MSG, exportGroup.getLabel());
                break;
            case suspended_no_error:
                operation.suspendedNoError();
                eventMessage = String.format(EXPORT_CHANGE_PORT_GROUP_SUSPENDED_MSG, exportGroup.getLabel());
                break;
            case suspended_error:
                operation.suspendedError(coded);
                eventMessage = String.format(EXPORT_CHANGE_PORT_GROUP_SUSPENDED_MSG, exportGroup.getLabel());
                break;
            default:
                break;
        }
        exportGroup.getOpStatus().updateTaskStatus(getOpId(), operation);
        dbClient.updateObject(exportGroup);
        log.info(String.format("Done Export change port group - Id: %s, OpId: %s, status: %s", getId().toString(), getOpId(), status.name()));
        recordBlockExportOperation(dbClient, OperationTypeEnum.EXPORT_CHANGE_PORT_GROUP, status, eventMessage, exportGroup);
    } catch (Exception e) {
        log.error(String.format("Failed updating status for Export change port group - Id: %s, OpId: %s", getId().toString(), getOpId()), e);
    } finally {
        super.complete(dbClient, status, coded);
    }
}
Also used : ExportGroup(com.emc.storageos.db.client.model.ExportGroup) Operation(com.emc.storageos.db.client.model.Operation) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException)

Example 92 with ExportGroup

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

the class SmisStorageDevice method rollbackChangePortGroupRemovePaths.

/**
 * Check if the masking view is still exist. If not, then set the step error so that it won't continue to roll back
 * If exists,  set the step ready, then it would continue the roll back.
 */
@Override
public void rollbackChangePortGroupRemovePaths(StorageSystem storage, URI exportGroupURI, URI oldMaskURI, TaskCompleter completer) {
    try {
        ExportMask exportMask = _dbClient.queryObject(ExportMask.class, oldMaskURI);
        if (exportMask != null) {
            String maskName = exportMask.getMaskName();
            CIMObjectPath maskingViewPath = _cimPath.getMaskingViewPath(storage, maskName);
            if (_helper.checkExists(storage, maskingViewPath, false, false) != null) {
                // The masking view still exist, then continue the roll back
                completer.ready(_dbClient);
                return;
            }
        }
        // if export mask is null, or masking view does not exist, then it has been deleted. mark the completer error so that it won't continue to roll back
        if (exportMask != null && !exportMask.getInactive()) {
            _dbClient.markForDeletion(exportMask);
        }
        List<ExportGroup> exportGroups = ExportMaskUtils.getExportGroups(_dbClient, oldMaskURI);
        if (exportGroups != null) {
            // Remove the mask references in the export group
            for (ExportGroup exportGroup : exportGroups) {
                // Remove this mask from the export group
                exportGroup.removeExportMask(exportMask.getId().toString());
            }
            // Update all of the export groups in the DB
            _dbClient.updateObject(exportGroups);
        }
        String msg = String.format("The export mask %s has been deleted, stop roll back.", oldMaskURI.toString());
        _log.info(msg);
        completer.error(_dbClient, DeviceControllerException.errors.jobFailedOpMsg("Rollback change port group delete export mask", msg));
    } catch (Exception e) {
        completer.error(_dbClient, DeviceControllerException.errors.jobFailed(e));
    }
}
Also used : ExportGroup(com.emc.storageos.db.client.model.ExportGroup) ExportMask(com.emc.storageos.db.client.model.ExportMask) CIMObjectPath(javax.cim.CIMObjectPath) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) WBEMException(javax.wbem.WBEMException)

Example 93 with ExportGroup

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

the class ExportMaskUtils method getExportGroups.

/**
 * Find all export groups that are referencing the export mask URI
 *
 * @param dbClient db client
 * @param exportMask export mask URi
 * @return list of export groups referring to the export mask URI
 */
public static List<ExportGroup> getExportGroups(DbClient dbClient, URI exportMaskURI) {
    URIQueryResultList exportGroupURIs = new URIQueryResultList();
    dbClient.queryByConstraint(ContainmentConstraint.Factory.getExportMaskExportGroupConstraint(exportMaskURI), exportGroupURIs);
    List<ExportGroup> exportGroups = new ArrayList<ExportGroup>();
    for (URI egURI : exportGroupURIs) {
        ExportGroup exportGroup = dbClient.queryObject(ExportGroup.class, egURI);
        if (exportGroup == null || exportGroup.getInactive() == true) {
            continue;
        }
        exportGroups.add(exportGroup);
    }
    return exportGroups;
}
Also used : ExportGroup(com.emc.storageos.db.client.model.ExportGroup) ArrayList(java.util.ArrayList) URI(java.net.URI) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList)

Example 94 with ExportGroup

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

the class VPlexDeviceController method assembleExportMasksWorkflow.

/**
 * Method to assemble the find or create VPLEX storage views (export masks) workflow for the given
 * ExportGroup, Initiators, and the block object Map.
 *
 * @param vplexURI
 *            the URI of the VPLEX StorageSystem object
 * @param export
 *            the ExportGroup in question
 * @param varrayUri
 *            -- NOTE! The varrayURI may NOT be the same as the exportGroup varray!.
 * @param initiators
 *            if initiators is null, the method will use all initiators from the ExportGroup
 * @param blockObjectMap
 *            the key (URI) of this map can reference either the volume itself or a snapshot.
 * @param zoningStepNeeded - Determines whether zone step is needed
 * @param workflow
 *            the controller workflow
 * @param waitFor
 *            -- If non-null, will wait on previous workflow step
 * @param opId
 *            the workflow step id
 * @return the last Workflow Step id
 * @throws Exception
 */
private String assembleExportMasksWorkflow(URI vplexURI, URI export, URI varrayUri, List<URI> initiators, Map<URI, Integer> blockObjectMap, boolean zoningStepNeeded, Workflow workflow, String waitFor, String opId) throws Exception {
    long startAssembly = new Date().getTime();
    VPlexControllerUtils.cleanStaleExportMasks(_dbClient, vplexURI);
    _log.info("TIMER: clean stale export masks took {} ms", new Date().getTime() - startAssembly);
    StorageSystem vplexSystem = getDataObject(StorageSystem.class, vplexURI, _dbClient);
    ExportGroup exportGroup = getDataObject(ExportGroup.class, export, _dbClient);
    // filter volume map just for this VPLEX's virtual volumes
    _log.info("object map before filtering for this VPLEX: " + blockObjectMap);
    Map<URI, Integer> filteredBlockObjectMap = new HashMap<URI, Integer>();
    for (URI boURI : blockObjectMap.keySet()) {
        BlockObject bo = Volume.fetchExportMaskBlockObject(_dbClient, boURI);
        if (bo.getStorageController().equals(vplexURI)) {
            filteredBlockObjectMap.put(bo.getId(), blockObjectMap.get(boURI));
        }
    }
    blockObjectMap = filteredBlockObjectMap;
    _log.info("object map after filtering for this VPLEX: " + blockObjectMap);
    // validate volume to lun map to make sure there aren't any duplicate LUN entries
    ExportUtils.validateExportGroupVolumeMap(exportGroup.getLabel(), blockObjectMap);
    VPlexApiClient client = getVPlexAPIClient(_vplexApiFactory, vplexSystem, _dbClient);
    // we will need lists of new export masks to create and existing export masks to simply update
    List<ExportMask> exportMasksToCreateOnDevice = new ArrayList<ExportMask>();
    List<ExportMask> exportMasksToUpdateOnDevice = new ArrayList<ExportMask>();
    // In case we are just updating the existing export masks we will need this map
    // to add initiators which are not already there.
    Map<URI, List<Initiator>> exportMasksToUpdateOnDeviceWithInitiators = new HashMap<URI, List<Initiator>>();
    // In case we are just updating the existing export masks we will need this map
    // to add storage ports which are not already there.
    Map<URI, List<URI>> exportMasksToUpdateOnDeviceWithStoragePorts = new HashMap<URI, List<URI>>();
    // try to collect initiators, if none supplied by caller
    if (initiators == null) {
        initiators = new ArrayList<URI>();
        if (exportGroup.hasInitiators()) {
            for (String initiator : exportGroup.getInitiators()) {
                initiators.add(URI.create(initiator));
            }
        }
    }
    // sort initiators in a host to initiator map
    Map<URI, List<Initiator>> hostInitiatorMap = VPlexUtil.makeHostInitiatorsMap(initiators, _dbClient);
    // This Set will be used to track shared export mask in database.
    Set<ExportMask> sharedExportMasks = new HashSet<ExportMask>();
    // look at each host
    String lockName = null;
    boolean lockAcquired = false;
    String vplexClusterId = ConnectivityUtil.getVplexClusterForVarray(varrayUri, vplexURI, _dbClient);
    String vplexClusterName = VPlexUtil.getVplexClusterName(varrayUri, vplexURI, client, _dbClient);
    try {
        lockName = _vplexApiLockManager.getLockName(vplexURI, vplexClusterId);
        lockAcquired = _vplexApiLockManager.acquireLock(lockName, LockTimeoutValue.get(LockType.VPLEX_API_LIB));
        if (!lockAcquired) {
            throw VPlexApiException.exceptions.couldNotObtainConcurrencyLock(vplexSystem.getLabel());
        }
        Map<String, String> targetPortToPwwnMap = VPlexControllerUtils.getTargetPortToPwwnMap(client, vplexClusterName);
        Boolean[] doInitiatorRefresh = new Boolean[] { new Boolean(true) };
        /**
         * COP-28674: During Vblock boot volume export, if existing storage views are found then check for existing volumes
         * If found throw exception. This condition is valid only for boot volume vblock export.
         */
        if (exportGroup.forHost() && ExportMaskUtils.isVblockHost(initiators, _dbClient) && ExportMaskUtils.isBootVolume(_dbClient, blockObjectMap)) {
            _log.info("VBlock boot volume Export: Validating the Vplex Cluster {} to find existing storage views", vplexClusterName);
            List<Initiator> initiatorList = _dbClient.queryObject(Initiator.class, initiators);
            List<String> initiatorNames = getInitiatorNames(vplexSystem.getSerialNumber(), vplexClusterName, client, initiatorList.iterator(), doInitiatorRefresh);
            List<VPlexStorageViewInfo> storageViewInfos = client.getStorageViewsContainingInitiators(vplexClusterName, initiatorNames);
            List<String> maskNames = new ArrayList<String>();
            if (!CollectionUtils.isEmpty(storageViewInfos)) {
                for (VPlexStorageViewInfo storageView : storageViewInfos) {
                    if (!CollectionUtils.isEmpty(storageView.getVirtualVolumes())) {
                        maskNames.add(storageView.getName());
                    } else {
                        _log.info("Found Storage View {} for cluster {} with empty volumes", storageView.getName(), vplexClusterName);
                    }
                }
            } else {
                _log.info("No Storage views found for cluster {}", vplexClusterName);
            }
            if (!CollectionUtils.isEmpty(maskNames)) {
                Set<URI> computeResourceSet = hostInitiatorMap.keySet();
                throw VPlexApiException.exceptions.existingMaskFoundDuringBootVolumeExport(Joiner.on(", ").join(maskNames), Joiner.on(", ").join(computeResourceSet), vplexClusterName);
            } else {
                _log.info("VBlock Boot volume Export : Validation passed");
            }
        }
        for (URI hostUri : hostInitiatorMap.keySet()) {
            _log.info("assembling export masks workflow, now looking at host URI: " + hostUri);
            List<Initiator> inits = hostInitiatorMap.get(hostUri);
            _log.info("this host contains these initiators: " + inits);
            boolean foundMatchingStorageView = false;
            boolean allPortsFromMaskMatchForVarray = true;
            _log.info("attempting to locate an existing ExportMask for this host's initiators on VPLEX Cluster " + vplexClusterId);
            Map<URI, ExportMask> vplexExportMasks = new HashMap<URI, ExportMask>();
            allPortsFromMaskMatchForVarray = filterExportMasks(vplexExportMasks, inits, varrayUri, vplexSystem, vplexClusterId);
            ExportMask sharedVplexExportMask = null;
            switch(vplexExportMasks.size()) {
                case FOUND_NO_VIPR_EXPORT_MASKS:
                    // Didn't find any single existing ExportMask for this Host/Initiators.
                    // Check if there is a shared ExportMask in CoprHD with by checking the existing initiators list.
                    sharedVplexExportMask = VPlexUtil.getExportMasksWithExistingInitiators(vplexURI, _dbClient, inits, varrayUri, vplexClusterId);
                    // on the VPLEX and set it up as a new ExportMask.
                    if (null != sharedVplexExportMask) {
                        sharedExportMasks.add(sharedVplexExportMask);
                        // If sharedVplexExportMask is found then that export mask will be used to add any missing
                        // initiators or storage ports as needed, and volumes requested, if not already present.
                        setupExistingExportMaskWithNewHost(blockObjectMap, vplexSystem, exportGroup, varrayUri, exportMasksToUpdateOnDevice, exportMasksToUpdateOnDeviceWithInitiators, exportMasksToUpdateOnDeviceWithStoragePorts, inits, sharedVplexExportMask, opId);
                        VPlexStorageViewInfo storageView = client.getStorageView(vplexClusterName, sharedVplexExportMask.getMaskName());
                        _log.info("Refreshing ExportMask {}", sharedVplexExportMask.getMaskName());
                        VPlexControllerUtils.refreshExportMask(_dbClient, storageView, sharedVplexExportMask, targetPortToPwwnMap, _networkDeviceController);
                        foundMatchingStorageView = true;
                        break;
                    } else {
                        _log.info("could not find an existing matching ExportMask in ViPR, " + "so ViPR will see if there is one already on the VPLEX system");
                        // ViPR will attempt to find a suitable existing storage view
                        // on the VPLEX and set it up as a new ExportMask.
                        long start = new Date().getTime();
                        foundMatchingStorageView = checkForExistingStorageViews(client, targetPortToPwwnMap, vplexSystem, vplexClusterName, inits, exportGroup, varrayUri, blockObjectMap, exportMasksToUpdateOnDevice, exportMasksToUpdateOnDeviceWithInitiators, exportMasksToUpdateOnDeviceWithStoragePorts, doInitiatorRefresh, opId);
                        long elapsed = new Date().getTime() - start;
                        _log.info("TIMER: finding an existing storage view took {} ms and returned {}", elapsed, foundMatchingStorageView);
                        break;
                    }
                case FOUND_ONE_VIPR_EXPORT_MASK:
                    // get the single value in the map
                    ExportMask viprExportMask = vplexExportMasks.values().iterator().next();
                    _log.info("a valid ExportMask matching these initiators exists already in ViPR " + "for this VPLEX device, so ViPR will re-use it: " + viprExportMask.getMaskName());
                    VPlexStorageViewInfo storageView = client.getStorageView(vplexClusterName, viprExportMask.getMaskName());
                    _log.info("Refreshing ExportMask {}", viprExportMask.getMaskName());
                    VPlexControllerUtils.refreshExportMask(_dbClient, storageView, viprExportMask, targetPortToPwwnMap, _networkDeviceController);
                    reuseExistingExportMask(blockObjectMap, vplexSystem, exportGroup, varrayUri, exportMasksToUpdateOnDevice, exportMasksToUpdateOnDeviceWithStoragePorts, inits, allPortsFromMaskMatchForVarray, viprExportMask, opId);
                    foundMatchingStorageView = true;
                    break;
                default:
                    String message = "Invalid Configuration: more than one VPLEX ExportMask " + "in this cluster exists in ViPR for these initiators " + inits;
                    _log.error(message);
                    throw new Exception(message);
            }
            // or set up a brand new ExportMask (to create a storage view on the VPLEX) for the Host.
            if (!foundMatchingStorageView) {
                if (null == sharedVplexExportMask) {
                    // If we reached here, it means there isn't an existing storage view on the VPLEX with the host,
                    // and no other shared ExportMask was found in the database by looking at existingInitiators.
                    // So, ViPR will try to find if there is shared export mask already for the ExportGroup in the database.
                    sharedVplexExportMask = VPlexUtil.getSharedExportMaskInDb(exportGroup, vplexURI, _dbClient, varrayUri, vplexClusterId, hostInitiatorMap);
                }
                if (null != sharedVplexExportMask) {
                    // If a sharedExportMask was found, then the new host will be added to that ExportMask
                    _log.info(String.format("Shared export mask %s %s found for the export group %s %s which will be reused for initiators %s .", sharedVplexExportMask.getMaskName(), sharedVplexExportMask.getId(), exportGroup.getLabel(), exportGroup.getId(), inits.toString()));
                    sharedExportMasks.add(sharedVplexExportMask);
                    VPlexStorageViewInfo storageView = client.getStorageView(vplexClusterName, sharedVplexExportMask.getMaskName());
                    _log.info("Refreshing ExportMask {}", sharedVplexExportMask.getMaskName());
                    VPlexControllerUtils.refreshExportMask(_dbClient, storageView, sharedVplexExportMask, targetPortToPwwnMap, _networkDeviceController);
                    setupExistingExportMaskWithNewHost(blockObjectMap, vplexSystem, exportGroup, varrayUri, exportMasksToUpdateOnDevice, exportMasksToUpdateOnDeviceWithInitiators, exportMasksToUpdateOnDeviceWithStoragePorts, inits, sharedVplexExportMask, opId);
                } else {
                    // Otherwise, create a brand new ExportMask, which will enable the storage view to
                    // be created on the VPLEX device as part of this workflow
                    _log.info("did not find a matching existing storage view anywhere, so ViPR " + "will initialize a new one and push it to the VPLEX device");
                    setupNewExportMask(blockObjectMap, vplexSystem, exportGroup, varrayUri, exportMasksToCreateOnDevice, inits, vplexClusterId, opId);
                }
            }
        }
    } finally {
        if (lockAcquired) {
            _vplexApiLockManager.releaseLock(lockName);
        }
    }
    _log.info("updating zoning if necessary for both new and updated export masks");
    String zoningStepId = waitFor;
    if (zoningStepNeeded) {
        _log.info("Adding step to update zones if required.");
        zoningStepId = addStepsForZoningUpdate(export, initiators, blockObjectMap, workflow, waitFor, exportMasksToCreateOnDevice, exportMasksToUpdateOnDevice);
    } else {
        // If exportMasksToCreateOnDevice list as not empty, new export must be created and zoned on switch .
        if (!exportMasksToCreateOnDevice.isEmpty()) {
            _log.info("Adding zone step to newly created exportMask");
            zoningStepId = addStepsForZoningUpdate(export, initiators, blockObjectMap, workflow, waitFor, exportMasksToCreateOnDevice, new ArrayList<ExportMask>());
        }
        // create the FCZoneReference for new volumes by referencing existing FCZoneReference on same ExportGroup
        if (!exportMasksToUpdateOnDevice.isEmpty()) {
            _log.info("Update ExportGroup: {} will use existing zone and new FCZoneReference will get added", export);
            zoningStepId = addStepsForFCZoneRefCreate(export, blockObjectMap, workflow, zoningStepId, exportMasksToUpdateOnDevice);
        }
    }
    _log.info("set up initiator pre-registration step");
    String storageViewStepId = addStepsForInitiatorRegistration(initiators, vplexSystem, vplexClusterName, workflow, zoningStepId);
    _log.info("processing the export masks to be created");
    for (ExportMask exportMask : exportMasksToCreateOnDevice) {
        storageViewStepId = addStepsForExportMaskCreate(blockObjectMap, workflow, vplexSystem, exportGroup, storageViewStepId, exportMask);
    }
    _log.info("processing the export masks to be updated");
    for (ExportMask exportMask : exportMasksToUpdateOnDevice) {
        boolean shared = false;
        if (sharedExportMasks.contains(exportMask)) {
            shared = true;
        }
        storageViewStepId = addStepsForExportMaskUpdate(export, blockObjectMap, workflow, vplexSystem, exportMasksToUpdateOnDeviceWithInitiators, exportMasksToUpdateOnDeviceWithStoragePorts, storageViewStepId, exportMask, shared);
    }
    long elapsed = new Date().getTime() - startAssembly;
    _log.info("TIMER: export mask assembly took {} ms", elapsed);
    return storageViewStepId;
}
Also used : VPlexStorageViewInfo(com.emc.storageos.vplex.api.VPlexStorageViewInfo) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) Initiator(com.emc.storageos.db.client.model.Initiator) ApplicationAddVolumeList(com.emc.storageos.volumecontroller.ApplicationAddVolumeList) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) List(java.util.List) BlockObject(com.emc.storageos.db.client.model.BlockObject) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) HashSet(java.util.HashSet) ExportMask(com.emc.storageos.db.client.model.ExportMask) Date(java.util.Date) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) InternalServerErrorException(com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException) WorkflowException(com.emc.storageos.workflow.WorkflowException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient)

Example 95 with ExportGroup

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

the class VPlexDeviceController method deleteStorageView.

/**
 * A Workflow Step to delete a VPlex Storage View.
 *
 * @param vplexURI vplex
 * @param exportMaskURI export mask
 * @param isRollbackStep is this being run as a rollback step?
 * @param stepId step ID
 * @throws WorkflowException
 */
public void deleteStorageView(URI vplexURI, URI exportGroupURI, URI exportMaskURI, boolean isRollbackStep, String stepId) throws WorkflowException {
    ExportMaskDeleteCompleter completer = null;
    try {
        WorkflowStepCompleter.stepExecuting(stepId);
        completer = new ExportMaskDeleteCompleter(exportGroupURI, exportMaskURI, stepId);
        completer.setRollingBack(isRollbackStep);
        StorageSystem vplex = getDataObject(StorageSystem.class, vplexURI, _dbClient);
        Boolean[] viewFound = new Boolean[] { new Boolean(false) };
        ExportMask exportMask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
        VPlexApiClient client = getVPlexAPIClient(_vplexApiFactory, vplex, _dbClient);
        if (exportMask != null) {
            String vplexClusterName = VPlexUtil.getVplexClusterName(exportMask, vplexURI, client, _dbClient);
            VPlexStorageViewInfo storageView = client.getStorageView(vplexClusterName, exportMask.getMaskName());
            if (storageView != null) {
                // we can ignore this in the case of a missing storage view on the VPLEX, it has already been
                // deleted
                _log.info("Refreshing ExportMask {}", exportMask.getMaskName());
                VPlexControllerUtils.refreshExportMask(_dbClient, storageView, exportMask, VPlexControllerUtils.getTargetPortToPwwnMap(client, vplexClusterName), _networkDeviceController);
            }
            if (exportMask.hasAnyExistingVolumes() || exportMask.hasAnyExistingInitiators()) {
                _log.warn("ExportMask {} still has non-ViPR-created existing volumes or initiators, " + "so ViPR will not remove it from the VPLEX device", exportMask.getMaskName());
            }
            if (exportMask.getInactive()) {
                _log.warn("ExportMask {} is already inactive, so there's " + "no need to delete it off the VPLEX", exportMask.getMaskName());
            } else {
                List<URI> volumeURIs = new ArrayList<URI>();
                if (exportMask.getUserAddedVolumes() != null && !exportMask.getUserAddedVolumes().isEmpty()) {
                    volumeURIs = StringSetUtil.stringSetToUriList(exportMask.getUserAddedVolumes().values());
                }
                List<Initiator> initiators = new ArrayList<>();
                if (exportMask.getUserAddedInitiators() != null && !exportMask.getUserAddedInitiators().isEmpty()) {
                    List<URI> initiatorURIs = StringSetUtil.stringSetToUriList(exportMask.getUserAddedInitiators().values());
                    initiators.addAll(_dbClient.queryObject(Initiator.class, initiatorURIs));
                }
                ExportMaskValidationContext ctx = new ExportMaskValidationContext();
                ctx.setStorage(vplex);
                ctx.setExportMask(exportMask);
                ctx.setBlockObjects(volumeURIs, _dbClient);
                ctx.setInitiators(initiators);
                ctx.setAllowExceptions(!WorkflowService.getInstance().isStepInRollbackState(stepId));
                validator.exportMaskDelete(ctx).validate();
                InvokeTestFailure.internalOnlyInvokeTestFailure(InvokeTestFailure.ARTIFICIAL_FAILURE_084);
                // note: there's a chance if the existing storage view originally had only
                // storage ports configured in it, then it would be deleted by this
                _log.info("removing this export mask from VPLEX: " + exportMask.getMaskName());
                client.deleteStorageView(exportMask.getMaskName(), vplexClusterName, viewFound);
                if (viewFound[0]) {
                    _log.info("as expected, storage view was found for deletion on the VPLEX.");
                } else {
                    _log.info("storage view was not found on the VPLEX during deletion, " + "but no errors were encountered.");
                }
            }
            _log.info("Marking export mask for deletion from Vipr: " + exportMask.getMaskName());
            _dbClient.markForDeletion(exportMask);
            _log.info("updating ExportGroups containing this ExportMask");
            List<ExportGroup> exportGroups = ExportMaskUtils.getExportGroups(_dbClient, exportMask);
            for (ExportGroup exportGroup : exportGroups) {
                _log.info("Removing mask from ExportGroup " + exportGroup.getGeneratedName());
                exportGroup.removeExportMask(exportMaskURI);
                _dbClient.updateObject(exportGroup);
            }
        } else {
            _log.info("ExportMask to delete could not be found in database: " + exportMaskURI);
        }
        completer.ready(_dbClient);
    } catch (VPlexApiException vae) {
        _log.error("Exception deleting ExportMask: " + exportMaskURI, vae);
        failStep(completer, stepId, vae);
    } catch (DeviceControllerException ex) {
        _log.error("Exception deleting ExportMask: " + exportMaskURI, ex);
        failStep(completer, stepId, ex);
    } catch (Exception ex) {
        _log.error("Exception deleting ExportMask: " + exportMaskURI, ex);
        ServiceError svcError = VPlexApiException.errors.deleteStorageViewFailed(ex);
        failStep(completer, stepId, svcError);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) VPlexStorageViewInfo(com.emc.storageos.vplex.api.VPlexStorageViewInfo) ExportMask(com.emc.storageos.db.client.model.ExportMask) ArrayList(java.util.ArrayList) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) InternalServerErrorException(com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException) WorkflowException(com.emc.storageos.workflow.WorkflowException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) ExportMaskDeleteCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskDeleteCompleter) ExportMaskValidationContext(com.emc.storageos.volumecontroller.impl.validators.contexts.ExportMaskValidationContext) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) Initiator(com.emc.storageos.db.client.model.Initiator) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Aggregations

ExportGroup (com.emc.storageos.db.client.model.ExportGroup)278 URI (java.net.URI)206 ArrayList (java.util.ArrayList)139 ExportMask (com.emc.storageos.db.client.model.ExportMask)138 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)111 HashMap (java.util.HashMap)94 Initiator (com.emc.storageos.db.client.model.Initiator)86 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)84 NamedURI (com.emc.storageos.db.client.model.NamedURI)80 HashSet (java.util.HashSet)70 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)63 Workflow (com.emc.storageos.workflow.Workflow)61 List (java.util.List)59 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)55 BlockObject (com.emc.storageos.db.client.model.BlockObject)49 Map (java.util.Map)47 ExportOrchestrationTask (com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportOrchestrationTask)44 ControllerException (com.emc.storageos.volumecontroller.ControllerException)41 StringSet (com.emc.storageos.db.client.model.StringSet)38 StringMap (com.emc.storageos.db.client.model.StringMap)33