Search in sources :

Example 1 with ExportMaskAddPathsCompleter

use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskAddPathsCompleter in project coprhd-controller by CoprHD.

the class VPlexDeviceController method portRebalance.

@Override
public void portRebalance(URI vplex, URI exportGroupURI, URI varray, URI exportMaskURI, Map<URI, List<URI>> adjustedPaths, Map<URI, List<URI>> removedPaths, boolean isAdd, String stepId) throws Exception {
    // Retrieve the ExportGroup and ExportMask and validate
    ExportGroup exportGroup = _dbClient.queryObject(ExportGroup.class, exportGroupURI);
    ExportMask exportMask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
    if (exportGroup == null || exportMask == null || exportGroup.getInactive() || exportMask.getInactive() || !exportGroup.hasMask(exportMaskURI)) {
        String reason = String.format("Bad exportGroup %s or exportMask %s", exportGroupURI, exportMaskURI);
        _log.error(reason);
        ServiceCoded coded = WorkflowException.exceptions.workflowConstructionError(reason);
        WorkflowStepCompleter.stepFailed(stepId, coded);
        return;
    }
    // Check if the ExportMask is in the desired varray (in cross-coupled ExportGroups)
    if (!ExportMaskUtils.exportMaskInVarray(_dbClient, exportMask, varray)) {
        _log.info(String.format("ExportMask %s (%s) not in specified varray %s", exportMask.getMaskName(), exportMask.getId(), varray));
        WorkflowStepCompleter.stepSucceeded(stepId, String.format("No operation done: Mask not in specified varray %s", varray));
        return;
    }
    // Refresh the ExportMask so we have the latest data.
    StorageSystem vplexSystem = getDataObject(StorageSystem.class, vplex, _dbClient);
    VPlexApiClient client = getVPlexAPIClient(_vplexApiFactory, vplex, _dbClient);
    String vplexClusterName = VPlexUtil.getVplexClusterName(exportMask, vplex, client, _dbClient);
    VPlexStorageViewInfo storageView = client.getStorageView(vplexClusterName, exportMask.getMaskName());
    _log.info("Processing and Refreshing ExportMask {}", exportMask.getMaskName());
    Map<String, String> targetPortToPwwnMap = VPlexControllerUtils.getTargetPortToPwwnMap(client, vplexClusterName);
    VPlexControllerUtils.refreshExportMask(_dbClient, storageView, exportMask, targetPortToPwwnMap, _networkDeviceController);
    // Determine hosts in ExportMask
    Set<URI> hostsInExportMask = new HashSet<URI>();
    Set<String> hostNames = ExportMaskUtils.getHostNamesInMask(exportMask, _dbClient);
    Set<Initiator> initiatorsInMask = ExportMaskUtils.getInitiatorsForExportMask(_dbClient, exportMask, null);
    for (Initiator initiator : initiatorsInMask) {
        if (initiator.getHost() != null) {
            hostsInExportMask.add(initiator.getHost());
        }
    }
    boolean sharedMask = (hostsInExportMask.size() > 1);
    if (isAdd) {
        // Processing added paths only
        Workflow workflow = _workflowService.getNewWorkflow(this, "portRebalance", false, stepId);
        // Determine initiators and targets to be added.
        // These are initiators not in mask that are in a host in the mask.
        // Earlier versions of the Vplex code may not have had all the initiators in the mask, as
        // earlier code only put initiators in the Storage View for which ports were added.
        // Targets to be added may be on existing initiators or newly added initiators.
        List<URI> initiatorsToAdd = new ArrayList<URI>();
        List<URI> targetsToAdd = new ArrayList<URI>();
        for (URI initiatorURI : adjustedPaths.keySet()) {
            if (!exportMask.hasInitiator(initiatorURI.toString())) {
                // Initiator not in ExportMask
                Initiator initiator = _dbClient.queryObject(Initiator.class, initiatorURI);
                if (initiator != null && !initiator.getInactive()) {
                    if (hostsInExportMask.contains(initiator.getHost())) {
                        initiatorsToAdd.add(initiatorURI);
                        for (URI targetURI : adjustedPaths.get(initiatorURI)) {
                            if (!exportMask.hasTargets(Arrays.asList(targetURI)) && !targetsToAdd.contains(targetURI)) {
                                targetsToAdd.add(targetURI);
                            }
                        }
                    }
                }
            } else {
                // Initiator already in ExportMask, look for additional targets
                for (URI targetURI : adjustedPaths.get(initiatorURI)) {
                    if (!exportMask.hasTargets(Arrays.asList(targetURI)) && !targetsToAdd.contains(targetURI)) {
                        targetsToAdd.add(targetURI);
                    }
                }
            }
        }
        _log.info("Targets to add: " + targetsToAdd.toString());
        _log.info("Initiators to add: " + initiatorsToAdd.toString());
        // Invoke either storageViewAddInitiators if there are initiators to be added (it will add targets also),
        // or storageViewAddStoragePorts if no initiators to be added (which adds only targets).
        Workflow.Method addPathsMethod = null;
        if (!initiatorsToAdd.isEmpty() || !targetsToAdd.isEmpty()) {
            String addInitiatorStepId = workflow.createStepId();
            ExportMaskAddInitiatorCompleter completer = new ExportMaskAddInitiatorCompleter(exportGroupURI, exportMaskURI, initiatorsToAdd, targetsToAdd, addInitiatorStepId);
            ;
            if (!initiatorsToAdd.isEmpty()) {
                addPathsMethod = storageViewAddInitiatorsMethod(vplex, exportGroupURI, exportMaskURI, initiatorsToAdd, targetsToAdd, sharedMask, completer);
            } else if (!targetsToAdd.isEmpty()) {
                addPathsMethod = storageViewAddStoragePortsMethod(vplex, exportGroupURI, exportMaskURI, targetsToAdd, completer);
            }
            String description = String.format("Adding paths to ExportMask %s Hosts %s", exportMask.getMaskName(), hostNames.toString());
            workflow.createStep("addPaths", description, null, vplex, vplexSystem.getSystemType(), this.getClass(), addPathsMethod, null, false, addInitiatorStepId);
            ExportMaskAddPathsCompleter workflowCompleter = new ExportMaskAddPathsCompleter(exportGroupURI, exportMaskURI, stepId);
            workflow.executePlan(workflowCompleter, description + " completed successfully");
            return;
        }
    } else {
        // Processing the paths to be removed only, Paths not in the removedPaths map will be retained.
        // Note that we only remove ports (targets), never initiators.
        Workflow workflow = _workflowService.getNewWorkflow(this, "portRebalance", false, stepId);
        // Compute the targets to be removed.
        Set<URI> targetsToBeRemoved = ExportMaskUtils.getAllPortsInZoneMap(removedPaths);
        Collection<URI> targetsInMask = Collections2.transform(exportMask.getStoragePorts(), CommonTransformerFunctions.FCTN_STRING_TO_URI);
        targetsToBeRemoved.retainAll(targetsInMask);
        Set<URI> targetsToBeRetained = ExportMaskUtils.getAllPortsInZoneMap(adjustedPaths);
        targetsToBeRemoved.removeAll(targetsToBeRetained);
        List<URI> portsToBeRemoved = new ArrayList<URI>(targetsToBeRemoved);
        _log.info("Targets to be removed: " + portsToBeRemoved.toString());
        // Call storageViewRemoveStoragePorts to remove any necessary targets.
        Workflow.Method removePathsMethod = null;
        if (!portsToBeRemoved.isEmpty()) {
            String removeInitiatorStepId = workflow.createStepId();
            removePathsMethod = storageViewRemoveStoragePortsMethod(vplex, exportGroupURI, exportMaskURI, portsToBeRemoved, null);
            String description = String.format("Removing paths to ExportMask %s Hosts %s", exportMask.getMaskName(), hostNames.toString());
            workflow.createStep("removePaths", description, null, vplex, vplexSystem.getSystemType(), this.getClass(), removePathsMethod, null, false, removeInitiatorStepId);
            ExportMaskRemovePathsCompleter workflowCompleter = new ExportMaskRemovePathsCompleter(exportGroupURI, exportMaskURI, stepId);
            workflowCompleter.setRemovedStoragePorts(portsToBeRemoved);
            workflow.executePlan(workflowCompleter, description + " completed successfully");
            return;
        }
    }
    // Apparently nothing to do, return success
    WorkflowStepCompleter.stepSucceeded(stepId, "No operation performed on VPLEX mask");
}
Also used : VPlexStorageViewInfo(com.emc.storageos.vplex.api.VPlexStorageViewInfo) ExportMask(com.emc.storageos.db.client.model.ExportMask) ExportMaskAddPathsCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskAddPathsCompleter) ArrayList(java.util.ArrayList) ExportMaskAddInitiatorCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskAddInitiatorCompleter) Workflow(com.emc.storageos.workflow.Workflow) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) Initiator(com.emc.storageos.db.client.model.Initiator) ServiceCoded(com.emc.storageos.svcs.errorhandling.model.ServiceCoded) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient) ExportMaskRemovePathsCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskRemovePathsCompleter) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) HashSet(java.util.HashSet)

Example 2 with ExportMaskAddPathsCompleter

use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskAddPathsCompleter in project coprhd-controller by CoprHD.

the class AbstractDefaultMaskingOrchestrator method generateExportMaskAddPathsWorkflow.

/**
 * Create add paths to export mask workflow step
 *
 * @param workflow
 * @param storage - storage system
 * @param exportGroupURI - export group uri
 * @param exportMaskURI - export mask uri
 * @param newPaths - new paths to be added
 * @param previousStep - previous step that this step will wait for
 * @return - the created step
 * @throws Exception
 */
public String generateExportMaskAddPathsWorkflow(Workflow workflow, StorageSystem storage, URI exportGroupURI, URI exportMaskURI, Map<URI, List<URI>> newPaths, String previousStep) throws Exception {
    String maskingStep = workflow.createStepId();
    ExportTaskCompleter exportTaskCompleter = new ExportMaskAddPathsCompleter(exportGroupURI, exportMaskURI, maskingStep);
    Workflow.Method executeMethod = new Workflow.Method("doExportMaskAddPaths", storage.getId(), exportGroupURI, exportMaskURI, newPaths, exportTaskCompleter);
    maskingStep = workflow.createStep(EXPORT_MASK_ADD_PATHS_TASK, String.format("Adding paths to export mask %s", exportMaskURI.toString()), previousStep, storage.getId(), storage.getSystemType(), MaskingWorkflowEntryPoints.class, executeMethod, null, maskingStep);
    return maskingStep;
}
Also used : ExportTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter) ExportMaskAddPathsCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskAddPathsCompleter) Workflow(com.emc.storageos.workflow.Workflow)

Example 3 with ExportMaskAddPathsCompleter

use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskAddPathsCompleter in project coprhd-controller by CoprHD.

the class VmaxExportOperations method addPaths.

@Override
public void addPaths(StorageSystem storage, URI exportMaskURI, Map<URI, List<URI>> newPaths, TaskCompleter taskCompleter) throws DeviceControllerException {
    _log.info("{} addPaths START...", storage.getSerialNumber());
    // Initiators should have been in the export mask, only need to add storage ports to the port group.
    Set<URI> storagePorts = new HashSet<URI>();
    for (List<URI> ports : newPaths.values()) {
        storagePorts.addAll(ports);
    }
    ExportMask exportMask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
    _log.info(String.format("The export mask: %s", exportMask.toString()));
    try {
        // validate if the adding ports are still in the port group if the port group not mutable.
        // validate there is no unmanaged initiators.
        ExportMaskValidationContext ctx = new ExportMaskValidationContext();
        ctx.setStorage(storage);
        ctx.setExportMask(exportMask);
        Collection<URI> inits = StringSetUtil.stringSetToUriList(exportMask.getInitiators());
        Collection<Initiator> initiators = _dbClient.queryObject(Initiator.class, inits);
        ctx.setInitiators(initiators);
        URI portGroupURI = exportMask.getPortGroup();
        if (!NullColumnValueGetter.isNullURI(portGroupURI)) {
            StoragePortGroup portGroup = _dbClient.queryObject(StoragePortGroup.class, portGroupURI);
            if (!portGroup.getMutable()) {
                ctx.setPortGroup(portGroup);
                Collection<StoragePort> ports = _dbClient.queryObject(StoragePort.class, storagePorts);
                ctx.setStoragePorts(ports);
            } else {
                _log.warn(String.format("The port group %s in the export mask %s is mutable", portGroup.getLabel(), exportMask.getNativeId()));
            }
        } else {
            _log.warn(String.format("The exportMask does not have port group set %s", exportMask.getNativeId()));
        }
        validator.exportPathAdjustment(ctx).validate();
        List<URI> ports = addStoragePorts(storage, storagePorts, exportMask);
        if (ports != null && !ports.isEmpty()) {
            ExportMaskAddPathsCompleter completer = (ExportMaskAddPathsCompleter) taskCompleter;
            completer.setNewStoragePorts(ports);
        }
        taskCompleter.ready(_dbClient);
    } catch (Exception e) {
        _log.error(String.format("addPaths failed - maskName: %s", exportMask.getMaskName()), e);
        ServiceError serviceError = DeviceControllerException.errors.jobFailed(e);
        taskCompleter.error(_dbClient, serviceError);
    }
    _log.info("{} addPaths END...", storage == null ? null : storage.getSerialNumber());
}
Also used : StoragePortGroup(com.emc.storageos.db.client.model.StoragePortGroup) ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) ExportMask(com.emc.storageos.db.client.model.ExportMask) ExportMaskAddPathsCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskAddPathsCompleter) StoragePort(com.emc.storageos.db.client.model.StoragePort) URI(java.net.URI) SmisException(com.emc.storageos.volumecontroller.impl.smis.SmisException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) WBEMException(javax.wbem.WBEMException) ExportMaskValidationContext(com.emc.storageos.volumecontroller.impl.validators.contexts.ExportMaskValidationContext) Initiator(com.emc.storageos.db.client.model.Initiator) Sets.newHashSet(com.google.common.collect.Sets.newHashSet) HashSet(java.util.HashSet)

Aggregations

ExportMaskAddPathsCompleter (com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskAddPathsCompleter)3 ExportMask (com.emc.storageos.db.client.model.ExportMask)2 Initiator (com.emc.storageos.db.client.model.Initiator)2 Workflow (com.emc.storageos.workflow.Workflow)2 URI (java.net.URI)2 HashSet (java.util.HashSet)2 ExportGroup (com.emc.storageos.db.client.model.ExportGroup)1 NamedURI (com.emc.storageos.db.client.model.NamedURI)1 StoragePort (com.emc.storageos.db.client.model.StoragePort)1 StoragePortGroup (com.emc.storageos.db.client.model.StoragePortGroup)1 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)1 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)1 ServiceCoded (com.emc.storageos.svcs.errorhandling.model.ServiceCoded)1 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)1 ExportMaskAddInitiatorCompleter (com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskAddInitiatorCompleter)1 ExportMaskRemovePathsCompleter (com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskRemovePathsCompleter)1 ExportTaskCompleter (com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter)1 SmisException (com.emc.storageos.volumecontroller.impl.smis.SmisException)1 ExportMaskValidationContext (com.emc.storageos.volumecontroller.impl.validators.contexts.ExportMaskValidationContext)1 VPlexApiClient (com.emc.storageos.vplex.api.VPlexApiClient)1