Search in sources :

Example 46 with VPlexApiException

use of com.emc.storageos.vplex.api.VPlexApiException in project coprhd-controller by CoprHD.

the class VPlexDeviceController method exportGroupAddInitiators.

/*
     * (non-Javadoc)
     *
     * @see com.emc.storageos.volumecontroller.impl.vplex.VplexController#exportAddInitiator(java.net.URI, java.net.URI,
     * java.net.URI,
     * java.lang.String)
     */
@Override
public void exportGroupAddInitiators(URI vplexURI, URI exportURI, List<URI> initiatorURIs, String opId) throws ControllerException {
    try {
        WorkflowStepCompleter.stepExecuting(opId);
        StorageSystem vplex = getDataObject(StorageSystem.class, vplexURI, _dbClient);
        ExportGroup exportGroup = getDataObject(ExportGroup.class, exportURI, _dbClient);
        ExportAddInitiatorCompleter completer = new ExportAddInitiatorCompleter(exportURI, initiatorURIs, opId);
        Workflow workflow = _workflowService.getNewWorkflow(this, "exportAddInitiator", true, opId);
        boolean isRecoverPointExport = ExportUtils.checkIfInitiatorsForRP(_dbClient, exportGroup.getInitiators());
        initiatorURIs = VPlexUtil.filterInitiatorsForVplex(_dbClient, initiatorURIs);
        // get a map of host URI to a list of Initiators in that Host
        Map<URI, List<Initiator>> hostInitiatorsMap = VPlexUtil.makeHostInitiatorsMap(initiatorURIs, _dbClient);
        // Get the varrays involved.
        List<URI> varrayList = new ArrayList<URI>();
        varrayList.add(exportGroup.getVirtualArray());
        // if already present, or create an altVirtualArray if there are distributed volumes.
        if (!isRecoverPointExport) {
            if ((exportGroup.getAltVirtualArrays() != null) && (exportGroup.getAltVirtualArrays().get(vplexURI.toString()) != null)) {
                // If there is an alternate Varray entry for this Vplex, it indicates we have HA volumes.
                varrayList.add(URI.create(exportGroup.getAltVirtualArrays().get(vplexURI.toString())));
            } else {
                // Check to see if there are distributed volumes. If so, maybe we
                // could export to both varrays.
                Map<URI, Integer> volumeMap = ExportUtils.getExportGroupVolumeMap(_dbClient, vplex, exportGroup);
                Map<URI, Set<URI>> varrayToVolumes = VPlexUtil.mapBlockObjectsToVarrays(_dbClient, volumeMap.keySet(), vplexURI, exportGroup);
                // Remove the local volumes
                varrayToVolumes.remove(exportGroup.getVirtualArray());
                if (!varrayToVolumes.isEmpty()) {
                    URI haVarray = VPlexUtil.pickHAVarray(varrayToVolumes);
                    exportGroup.putAltVirtualArray(vplex.toString(), haVarray.toString());
                    _dbClient.updateObject(exportGroup);
                }
            }
        }
        // Process each host separately.
        String previousStep = null;
        for (URI hostURI : hostInitiatorsMap.keySet()) {
            List<URI> initURIs = new ArrayList<URI>();
            for (Initiator initiator : hostInitiatorsMap.get(hostURI)) {
                initURIs.add(initiator.getId());
            }
            // Partition the Initiators by Varray. We may need to do two different ExportMasks,
            // one for each of the varrays.
            Map<URI, List<URI>> varraysToInitiators = VPlexUtil.partitionInitiatorsByVarray(_dbClient, initURIs, varrayList, vplex);
            if (varraysToInitiators.isEmpty()) {
                throw VPlexApiException.exceptions.exportCreateNoinitiatorsHaveCorrectConnectivity(exportGroup.getInitiators().toString(), varrayList.toString());
            }
            // Now process the Initiators for a host and a given varray.
            for (URI varrayURI : varraysToInitiators.keySet()) {
                initURIs = varraysToInitiators.get(varrayURI);
                List<Initiator> initiators = new ArrayList<Initiator>();
                for (Initiator initiator : hostInitiatorsMap.get(hostURI)) {
                    if (initURIs.contains(initiator.getId())) {
                        initiators.add(initiator);
                    }
                }
                if (!initiators.isEmpty()) {
                    previousStep = addStepsForAddInitiators(workflow, vplex, exportGroup, varrayURI, initURIs, initiators, hostURI, previousStep, opId);
                }
            }
        }
        // Fire off the Workflow
        String message = String.format("Successfully added initiators %s to ExportGroup %s", initiatorURIs.toString(), exportGroup.getLabel());
        workflow.executePlan(completer, "Successfully added initiators: " + message);
    } catch (VPlexApiException vae) {
        _log.error("Exception adding initiators to Storage View: " + vae.getMessage(), vae);
        WorkflowStepCompleter.stepFailed(opId, vae);
    } catch (Exception ex) {
        _log.error("Exception adding initiators to Storage View: " + ex.getMessage(), ex);
        String opName = ResourceOperationTypeEnum.ADD_EXPORT_INITIATOR.getName();
        ServiceError serviceError = VPlexApiException.errors.exportGroupAddInitiatorsFailed(opName, ex);
        WorkflowStepCompleter.stepFailed(opId, serviceError);
    }
}
Also used : ExportAddInitiatorCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportAddInitiatorCompleter) ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) Set(java.util.Set) HashSet(java.util.HashSet) StringSet(com.emc.storageos.db.client.model.StringSet) ArrayList(java.util.ArrayList) Workflow(com.emc.storageos.workflow.Workflow) 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) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) Initiator(com.emc.storageos.db.client.model.Initiator) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) ApplicationAddVolumeList(com.emc.storageos.volumecontroller.ApplicationAddVolumeList) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) List(java.util.List) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 47 with VPlexApiException

use of com.emc.storageos.vplex.api.VPlexApiException in project coprhd-controller by CoprHD.

the class VPlexDeviceController method storageViewRemoveVolumes.

/**
 * @param client
 *            -- VPlexApiClient used for communication
 * @param exportGroupURI
 *            -- Export Group
 * @param exportMaskURI
 *            -- ExportMask corresponding to the StorageView
 * @param volumeURIList
 *            -- URI of virtual volumes
 * @param parentStepId
 *            -- Workflow parent step id
 * @param taskCompleter
 *            -- the task completer, used to find the rollback context,
 *               which will be non-null in the case of rollback
 * @param rollbackContextKey
 *            context key for rollback processing
 * @param stepId
 *            -- Workflow step id
 * @throws WorkflowException
 */
public void storageViewRemoveVolumes(URI vplexURI, URI exportGroupURI, URI exportMaskURI, List<URI> volumeURIList, String parentStepId, TaskCompleter taskCompleter, String rollbackContextKey, String stepId) throws WorkflowException {
    ExportMaskRemoveVolumeCompleter completer = null;
    ExportGroup exportGroup = null;
    ExportMask exportMask = null;
    try {
        WorkflowStepCompleter.stepExecuting(stepId);
        List<URI> volumeIdsToProcess = new ArrayList<>(volumeURIList);
        exportGroup = _dbClient.queryObject(ExportGroup.class, exportGroupURI);
        exportMask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
        completer = new ExportMaskRemoveVolumeCompleter(exportGroup.getId(), exportMask.getId(), volumeURIList, stepId);
        // get the context from the task completer, in case this is a rollback.
        if (taskCompleter != null && rollbackContextKey != null) {
            ExportOperationContext context = (ExportOperationContext) WorkflowService.getInstance().loadStepData(rollbackContextKey);
            if (context != null) {
                // a non-null context means this step is running as part of a rollback.
                List<URI> addedVolumes = new ArrayList<>();
                if (context.getOperations() != null) {
                    _log.info("Handling removeVolumes as a result of rollback");
                    ListIterator<ExportOperationContextOperation> li = context.getOperations().listIterator(context.getOperations().size());
                    while (li.hasPrevious()) {
                        ExportOperationContextOperation operation = (ExportOperationContextOperation) li.previous();
                        if (operation != null && VplexExportOperationContext.OPERATION_ADD_VOLUMES_TO_STORAGE_VIEW.equals(operation.getOperation())) {
                            addedVolumes = (List<URI>) operation.getArgs().get(0);
                            _log.info("Removing volumes {} as part of rollback", Joiner.on(',').join(addedVolumes));
                        }
                    }
                    if (addedVolumes == null || addedVolumes.isEmpty()) {
                        _log.info("There was no context found for add volumes. So there is nothing to rollback.");
                        completer.ready(_dbClient);
                        return;
                    }
                }
                // change the list of initiators to process to the
                // list that successfully were added during addInitiators.
                volumeIdsToProcess.clear();
                volumeIdsToProcess.addAll(addedVolumes);
            }
        }
        StorageSystem vplex = getDataObject(StorageSystem.class, vplexURI, _dbClient);
        VPlexApiClient client = getVPlexAPIClient(_vplexApiFactory, vplex, _dbClient);
        // Removes the specified volumes from the storage view
        // and updates the export mask.
        removeVolumesFromStorageViewAndMask(client, exportMask, volumeIdsToProcess, parentStepId);
        completer.ready(_dbClient);
    } catch (VPlexApiException vae) {
        _log.error("Exception removing volumes from Storage View: " + vae.getMessage(), vae);
        failStep(completer, stepId, vae);
    } catch (Exception ex) {
        _log.error("Exception removing volumes from Storage View: " + ex.getMessage(), ex);
        String opName = ResourceOperationTypeEnum.REMOVE_STORAGE_VIEW_VOLUME.getName();
        ServiceError serviceError = VPlexApiException.errors.storageViewRemoveVolumeFailed(exportMask != null ? exportMask.getMaskName() : "none", opName, ex);
        failStep(completer, stepId, serviceError);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) 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) 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) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient) ExportOperationContext(com.emc.storageos.volumecontroller.impl.utils.ExportOperationContext) ExportOperationContextOperation(com.emc.storageos.volumecontroller.impl.utils.ExportOperationContext.ExportOperationContextOperation) ExportMaskRemoveVolumeCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskRemoveVolumeCompleter) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 48 with VPlexApiException

use of com.emc.storageos.vplex.api.VPlexApiException in project coprhd-controller by CoprHD.

the class VPlexDeviceController method storageViewRemoveStoragePorts.

/**
 * Workflow Step to remove storage ports from Storage View.
 * Note arguments (except stepId) must match storageViewRemoveStoragePortsMethod above.
 *
 * @param vplexURI
 *            -- URI of VPlex StorageSystem
 * @param exportURI
 *            -- ExportGroup URI
 * @param maskURI
 *            -- ExportMask URI.
 * @param targetURIs
 *            -- list of targets URIs (VPLEX FE ports) to be removed.
 *            If non null, the targets (VPlex front end ports) indicated by the targetURIs will be removed
 *            from the Storage View.
 * @param rollbackContextKey
 *            -- Context token for rollback processing
 * @param stepId
 *            -- Workflow step id.
 * @throws WorkflowException
 */
public void storageViewRemoveStoragePorts(URI vplexURI, URI exportURI, URI maskURI, List<URI> targetURIs, String rollbackContextKey, String stepId) throws DeviceControllerException {
    ExportMaskRemoveInitiatorCompleter completer = null;
    try {
        WorkflowStepCompleter.stepExecuting(stepId);
        completer = new ExportMaskRemoveInitiatorCompleter(exportURI, maskURI, new ArrayList<URI>(), stepId);
        StorageSystem vplex = getDataObject(StorageSystem.class, vplexURI, _dbClient);
        ExportMask exportMask = _dbClient.queryObject(ExportMask.class, maskURI);
        VPlexApiClient client = getVPlexAPIClient(_vplexApiFactory, vplex, _dbClient);
        String vplexClusterName = VPlexUtil.getVplexClusterName(exportMask, vplexURI, client, _dbClient);
        Map<String, String> targetPortMap = VPlexControllerUtils.getTargetPortToPwwnMap(client, vplexClusterName);
        VPlexStorageViewInfo storageView = client.getStorageView(vplexClusterName, exportMask.getMaskName());
        _log.info("Refreshing ExportMask {}", exportMask.getMaskName());
        VPlexControllerUtils.refreshExportMask(_dbClient, storageView, exportMask, targetPortMap, _networkDeviceController);
        // get the context from the task completer, in case this is a rollback.
        if (rollbackContextKey != null) {
            ExportOperationContext context = (ExportOperationContext) WorkflowService.getInstance().loadStepData(rollbackContextKey);
            if (context != null) {
                // a non-null context means this step is running as part of a rollback.
                List<URI> addedTargets = new ArrayList<>();
                if (context.getOperations() != null) {
                    _log.info("Handling storageViewRemoveStoragePorts as a result of rollback");
                    ListIterator<ExportOperationContextOperation> li = context.getOperations().listIterator(context.getOperations().size());
                    while (li.hasPrevious()) {
                        ExportOperationContextOperation operation = (ExportOperationContextOperation) li.previous();
                        if (operation != null && VplexExportOperationContext.OPERATION_ADD_TARGETS_TO_STORAGE_VIEW.equals(operation.getOperation())) {
                            addedTargets = (List<URI>) operation.getArgs().get(0);
                            _log.info(String.format("Removing target port(s) %s from storage view %s as part of rollback", Joiner.on(',').join(addedTargets), exportMask.getMaskName()));
                        }
                    }
                }
                if (addedTargets == null || addedTargets.isEmpty()) {
                    _log.info("There was no context found for add target. So there is nothing to rollback.");
                    completer.ready(_dbClient);
                    return;
                }
                // Change the list of targets to process to the list
                // that successfully were added during addStoragePorts.
                targetURIs.clear();
                targetURIs.addAll(addedTargets);
            }
        }
        // validate the remove storage port operation against the export mask volumes
        // this is conceptually the same as remove initiators, so will validate with volumes
        List<URI> volumeURIList = (exportMask.getUserAddedVolumes() != null) ? URIUtil.toURIList(exportMask.getUserAddedVolumes().values()) : new ArrayList<URI>();
        if (volumeURIList.isEmpty()) {
            _log.warn("volume URI list for validating remove initiators is empty...");
        }
        // removing all storage ports but leaving the existing initiators and volumes.
        if (!exportMask.hasAnyExistingInitiators() && !exportMask.hasAnyExistingVolumes()) {
            ExportMaskValidationContext ctx = new ExportMaskValidationContext();
            ctx.setStorage(vplex);
            ctx.setExportMask(exportMask);
            ctx.setBlockObjects(volumeURIList, _dbClient);
            ctx.setAllowExceptions(!WorkflowService.getInstance().isStepInRollbackState(stepId));
            validator.removeInitiators(ctx).validate();
            if (targetURIs != null && targetURIs.isEmpty() == false) {
                List<PortInfo> targetPortInfos = new ArrayList<PortInfo>();
                List<URI> targetsToRemoveFromStorageView = new ArrayList<URI>();
                for (URI target : targetURIs) {
                    // Do not try to remove a port twice.
                    if (!exportMask.getStoragePorts().contains(target.toString())) {
                        continue;
                    }
                    // Build the PortInfo structure for the port to be added
                    StoragePort port = getDataObject(StoragePort.class, target, _dbClient);
                    PortInfo pi = new PortInfo(port.getPortNetworkId().toUpperCase().replaceAll(":", ""), null, port.getPortName(), null);
                    targetPortInfos.add(pi);
                    targetsToRemoveFromStorageView.add(target);
                }
                if (!targetPortInfos.isEmpty()) {
                    // Remove the targets from the VPLEX
                    client.removeTargetsFromStorageView(exportMask.getMaskName(), targetPortInfos);
                    // Remove the targets to the database.
                    for (URI target : targetsToRemoveFromStorageView) {
                        exportMask.removeTarget(target);
                    }
                    _dbClient.updateObject(exportMask);
                }
            }
        }
        completer.ready(_dbClient);
    } catch (VPlexApiException vae) {
        _log.error("Exception removing storage ports from Storage View: " + vae.getMessage(), vae);
        failStep(completer, stepId, vae);
    } catch (Exception ex) {
        _log.error("Exception removing storage ports from Storage View: " + ex.getMessage(), ex);
        String opName = ResourceOperationTypeEnum.DELETE_STORAGE_VIEW_STORAGEPORTS.getName();
        ServiceError serviceError = VPlexApiException.errors.storageViewRemoveStoragePortFailed(opName, ex);
        failStep(completer, stepId, serviceError);
    }
}
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) StoragePort(com.emc.storageos.db.client.model.StoragePort) ExportMaskRemoveInitiatorCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskRemoveInitiatorCompleter) 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) PortInfo(com.emc.storageos.vplex.api.clientdata.PortInfo) ExportMaskValidationContext(com.emc.storageos.volumecontroller.impl.validators.contexts.ExportMaskValidationContext) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient) ExportOperationContext(com.emc.storageos.volumecontroller.impl.utils.ExportOperationContext) ExportOperationContextOperation(com.emc.storageos.volumecontroller.impl.utils.ExportOperationContext.ExportOperationContextOperation) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 49 with VPlexApiException

use of com.emc.storageos.vplex.api.VPlexApiException in project coprhd-controller by CoprHD.

the class VPlexDeviceController method detachMirror.

/**
 * Called to detach the remote mirror for a distributed VPLEX volume prior
 * to restoring a native snapshot of the backend source volume.
 *
 * @param vplexURI
 *            The URI of the VPLEX system.
 * @param vplexVolumeURI
 *            The URI of the distributed VPLEX volume.
 * @param cgURI
 *            The URI of the volume's CG or null.
 * @param stepId
 *            The workflow step identifier.
 */
public void detachMirror(URI vplexURI, URI vplexVolumeURI, URI cgURI, String stepId) {
    _log.info("Executing detach mirror of VPLEX volume {} on VPLEX {}", new Object[] { vplexVolumeURI, vplexURI });
    String detachedDeviceName = "";
    try {
        // Initialize the data that will tell RB what to do in
        // case of failure.
        Map<String, String> stepData = new HashMap<String, String>();
        stepData.put(REATTACH_MIRROR, Boolean.FALSE.toString());
        stepData.put(ADD_BACK_TO_CG, Boolean.FALSE.toString());
        _workflowService.storeStepData(stepId, stepData);
        // Update workflow step.
        WorkflowStepCompleter.stepExecuting(stepId);
        // Get the API client.
        StorageSystem vplexSystem = getDataObject(StorageSystem.class, vplexURI, _dbClient);
        VPlexApiClient client = getVPlexAPIClient(_vplexApiFactory, vplexSystem, _dbClient);
        _log.info("Got VPLEX API client");
        // Get the VPLEX volume.
        Volume vplexVolume = getDataObject(Volume.class, vplexVolumeURI, _dbClient);
        String vplexVolumeName = vplexVolume.getDeviceLabel();
        _log.info("Got VPLEX volume");
        // COP-17337 : If device length is greater than 47 character then VPLEX does
        // not allow reattaching mirror. This is mostly going to be the case for the
        // distributed volume with XIO back-end on both legs. Temporarily rename the
        // device to 47 characters and then detach the mirror. Now when we reattach
        // the device name will not exceed the limit. We must do this before we detach
        // so that the device name is the same for the detach/attach operations. If
        // we try to rename prior to reattaching the mirror, COP-25581 will result.
        VPlexVirtualVolumeInfo vvInfo = client.findVirtualVolume(vplexVolumeName, vplexVolume.getNativeId());
        if (vvInfo != null) {
            String distDeviceName = vvInfo.getSupportingDevice();
            if (distDeviceName.length() > VPlexApiConstants.MAX_DEVICE_NAME_LENGTH_FOR_ATTACH_MIRROR) {
                String modifiedName = distDeviceName.substring(0, VPlexApiConstants.MAX_DEVICE_NAME_LENGTH_FOR_ATTACH_MIRROR);
                _log.info("Temporarily renaming the distributed device from {} to {} as VPLEX expects the name " + " to be 47 characters or less when we reattach the mirror.", distDeviceName, modifiedName);
                client.renameDistributedDevice(distDeviceName, modifiedName);
                stepData.put(RESTORE_DEVICE_NAME, distDeviceName);
            }
        } else {
            _log.error("Can't find volume {}:{} to detach mirror.", vplexVolumeName, vplexVolumeURI);
            throw VPlexApiException.exceptions.cantFindVolumeForDeatchMirror(vplexVolume.forDisplay());
        }
        // detaching the remote mirror.
        if (cgURI != null) {
            ConsistencyGroupManager consistencyGroupManager = getConsistencyGroupManager(vplexVolume);
            consistencyGroupManager.removeVolumeFromCg(cgURI, vplexVolume, client, false);
            stepData.put(ADD_BACK_TO_CG, Boolean.TRUE.toString());
            _workflowService.storeStepData(stepId, stepData);
            _log.info("Removed volumes from consistency group.");
        }
        // Detach the mirror.
        detachedDeviceName = client.detachMirrorFromDistributedVolume(vplexVolumeName, null);
        stepData.put(DETACHED_DEVICE, detachedDeviceName);
        stepData.put(REATTACH_MIRROR, Boolean.TRUE.toString());
        _workflowService.storeStepData(stepId, stepData);
        _log.info("Detached the mirror");
        updateThinProperty(client, vplexSystem, vplexVolume);
        // Update workflow step state to success.
        WorkflowStepCompleter.stepSucceded(stepId);
        _log.info("Updated workflow step state to success");
    } catch (VPlexApiException vae) {
        _log.error("Exception detaching mirror for VPLEX distributed volume: " + vae.getMessage(), vae);
        WorkflowStepCompleter.stepFailed(stepId, vae);
    } catch (Exception e) {
        _log.error("Exception detaching mirror for VPLEX distributed volume: " + e.getMessage(), e);
        WorkflowStepCompleter.stepFailed(stepId, VPlexApiException.exceptions.failedDetachingVPlexVolumeMirror(detachedDeviceName, vplexVolumeURI.toString(), e));
    }
}
Also used : HashMap(java.util.HashMap) Volume(com.emc.storageos.db.client.model.Volume) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient) VPlexVirtualVolumeInfo(com.emc.storageos.vplex.api.VPlexVirtualVolumeInfo) 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) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 50 with VPlexApiException

use of com.emc.storageos.vplex.api.VPlexApiException in project coprhd-controller by CoprHD.

the class VPlexVmaxMaskingOrchestrator method createOrAddVolumesToExportMask.

/**
 * Create an ExportMask on the VMAX if it does not exist. Otherwise, just add the indicated
 * volumes to the ExportMask.
 */
@Override
public void createOrAddVolumesToExportMask(URI arrayURI, URI exportGroupURI, URI exportMaskURI, Map<URI, Integer> volumeMap, List<URI> initiatorURIs2, TaskCompleter completer, String stepId) {
    try {
        WorkflowStepCompleter.stepExecuting(stepId);
        StorageSystem array = _dbClient.queryObject(StorageSystem.class, arrayURI);
        ExportMask exportMask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
        // If the exportMask isn't found, or has been deleted, fail, ask user to retry.
        if (exportMask == null || exportMask.getInactive()) {
            _log.info(String.format("ExportMask %s deleted or inactive, failing", exportMaskURI));
            ServiceError svcerr = VPlexApiException.errors.createBackendExportMaskDeleted(exportMaskURI.toString(), arrayURI.toString());
            WorkflowStepCompleter.stepFailed(stepId, svcerr);
            return;
        }
        // Protect concurrent operations by locking {host, array} dupple.
        // Lock will be released when workflow step completes.
        List<String> lockKeys = ControllerLockingUtil.getHostStorageLockKeys(_dbClient, ExportGroupType.Host, StringSetUtil.stringSetToUriList(exportMask.getInitiators()), arrayURI);
        getWorkflowService().acquireWorkflowStepLocks(stepId, lockKeys, LockTimeoutValue.get(LockType.VPLEX_BACKEND_EXPORT));
        // Refresh the ExportMask
        BlockStorageDevice device = _blockController.getDevice(array.getSystemType());
        exportMask = refreshExportMask(array, device, exportMask);
        InvokeTestFailure.internalOnlyInvokeTestFailure(InvokeTestFailure.ARTIFICIAL_FAILURE_009);
        if (!exportMask.hasAnyVolumes()) {
            // We are creating this ExportMask on the hardware! (Maybe not the first time though...)
            // Fetch the Initiators
            List<URI> initiatorURIs = new ArrayList<URI>();
            List<Initiator> initiators = new ArrayList<Initiator>();
            for (String initiatorId : exportMask.getInitiators()) {
                Initiator initiator = _dbClient.queryObject(Initiator.class, URI.create(initiatorId));
                if (initiator != null) {
                    initiators.add(initiator);
                    initiatorURIs.add(initiator.getId());
                }
            }
            // Fetch the targets
            List<URI> targets = new ArrayList<URI>();
            for (String targetId : exportMask.getStoragePorts()) {
                targets.add(URI.create(targetId));
            }
            // The default completer passed in is for add volume, create correct one
            completer = new ExportMaskCreateCompleter(exportGroupURI, exportMaskURI, initiatorURIs, volumeMap, stepId);
            // Note that there should not be any code after the call to the device as the completer
            // will be invoked causing the workflow to continue execution with the next step.
            device.doExportCreate(array, exportMask, volumeMap, initiators, targets, completer);
        } else {
            List<URI> initiatorURIs = new ArrayList<URI>();
            List<Initiator> initiators = new ArrayList<Initiator>();
            for (String initiatorId : exportMask.getInitiators()) {
                Initiator initiator = _dbClient.queryObject(Initiator.class, URI.create(initiatorId));
                if (initiator != null) {
                    initiators.add(initiator);
                    initiatorURIs.add(initiator.getId());
                }
            }
            // Note that there should not be any code after the call to the device as the completer
            // will be invoked causing the workflow to continue execution with the next step.
            device.doExportAddVolumes(array, exportMask, initiators, volumeMap, completer);
        }
    } catch (Exception ex) {
        _log.error("Failed to create or add volumes to export mask for vmax: ", ex);
        VPlexApiException vplexex = DeviceControllerExceptions.vplex.addStepsForCreateVolumesFailed(ex);
        WorkflowStepCompleter.stepFailed(stepId, vplexex);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) ExportMask(com.emc.storageos.db.client.model.ExportMask) ArrayList(java.util.ArrayList) URI(java.net.URI) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) ExportMaskCreateCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskCreateCompleter) BlockStorageDevice(com.emc.storageos.volumecontroller.BlockStorageDevice) Initiator(com.emc.storageos.db.client.model.Initiator) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Aggregations

VPlexApiException (com.emc.storageos.vplex.api.VPlexApiException)59 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)53 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)43 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)43 ControllerException (com.emc.storageos.volumecontroller.ControllerException)43 WorkflowException (com.emc.storageos.workflow.WorkflowException)43 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)41 InternalServerErrorException (com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException)41 VPlexApiClient (com.emc.storageos.vplex.api.VPlexApiClient)40 URI (java.net.URI)39 ArrayList (java.util.ArrayList)39 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)34 IOException (java.io.IOException)34 URISyntaxException (java.net.URISyntaxException)34 ExportMask (com.emc.storageos.db.client.model.ExportMask)26 Volume (com.emc.storageos.db.client.model.Volume)25 NamedURI (com.emc.storageos.db.client.model.NamedURI)21 Initiator (com.emc.storageos.db.client.model.Initiator)20 BlockStorageDevice (com.emc.storageos.volumecontroller.BlockStorageDevice)14 VPlexVirtualVolumeInfo (com.emc.storageos.vplex.api.VPlexVirtualVolumeInfo)12