Search in sources :

Example 16 with VplexMirror

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

the class VPlexDeviceController method createMirrors.

/**
 * Do the creation of a VPlex Mirror device and attach it as a mirror to the Virtual Volume.
 * This is called as a Workflow Step.
 * NOTE: The parameters here must match createMirrorsMethod above (except stepId).
 *
 * @param vplexURI
 *            URI of the VPlex StorageSystem
 * @param vplexMirrorURIs
 *            URI of the mirrors to be created.
 * @param workflowTaskId
 *            The workflow taskId.
 * @param stepId
 *            The stepId used for completion.
 *
 * @throws WorkflowException
 *             When an error occurs updating the workflow step
 *             state.
 */
public void createMirrors(URI vplexURI, List<URI> vplexMirrorURIs, String workflowTaskId, String stepId) throws WorkflowException {
    List<VolumeInfo> rollbackData = new ArrayList<VolumeInfo>();
    List<URI> createdVplexMirrorURIs = new ArrayList<URI>();
    VplexMirrorTaskCompleter completer = new VplexMirrorTaskCompleter(VplexMirror.class, vplexMirrorURIs, workflowTaskId);
    try {
        WorkflowStepCompleter.stepExecuting(stepId);
        // Get the API client.
        StorageSystem vplex = getDataObject(StorageSystem.class, vplexURI, _dbClient);
        VPlexApiClient client = getVPlexAPIClient(_vplexApiFactory, vplex, _dbClient);
        // Make a map of StorageSystem ids to Storage System
        Map<URI, StorageSystem> storageMap = new HashMap<URI, StorageSystem>();
        // Make a map of Mirrors to Storage Volumes.
        Map<VplexMirror, Volume> mirrorMap = new HashMap<VplexMirror, Volume>();
        for (URI vplexMirrorURI : vplexMirrorURIs) {
            VplexMirror vplexMirror = getDataObject(VplexMirror.class, vplexMirrorURI, _dbClient);
            // Find the underlying Storage Volume, there will be only one associated storage volume
            for (String associatedVolume : vplexMirror.getAssociatedVolumes()) {
                Volume storageVolume = getDataObject(Volume.class, new URI(associatedVolume), _dbClient);
                URI storageSystemId = storageVolume.getStorageController();
                if (storageMap.containsKey(storageSystemId) == false) {
                    StorageSystem storage = _dbClient.queryObject(StorageSystem.class, storageSystemId);
                    storageMap.put(storageSystemId, storage);
                }
                mirrorMap.put(vplexMirror, storageVolume);
            }
        }
        // Now make a call to the VPlexAPIClient.createDeviceAndAttachAsMirror for each vplex mirror.
        StringBuilder buf = new StringBuilder();
        buf.append("Vplex: " + vplexURI + " created mirror(s): ");
        for (VplexMirror vplexMirror : mirrorMap.keySet()) {
            URI vplexMirrorId = vplexMirror.getId();
            Volume sourceVplexVolume = getDataObject(Volume.class, vplexMirror.getSource().getURI(), _dbClient);
            VPlexVirtualVolumeInfo vplexVolumeInfo = new VPlexVirtualVolumeInfo();
            vplexVolumeInfo.setName(sourceVplexVolume.getDeviceLabel());
            vplexVolumeInfo.setPath(sourceVplexVolume.getNativeId());
            if (null == sourceVplexVolume.getAssociatedVolumes() || sourceVplexVolume.getAssociatedVolumes().isEmpty()) {
                _log.error("VPLEX volume {} has no backend volumes.", sourceVplexVolume.forDisplay());
                throw InternalServerErrorException.internalServerErrors.noAssociatedVolumesForVPLEXVolume(sourceVplexVolume.forDisplay());
            }
            if (sourceVplexVolume.getAssociatedVolumes().size() > 1) {
                vplexVolumeInfo.setLocality(VPlexApiConstants.DISTRIBUTED_VIRTUAL_VOLUME);
            } else {
                vplexVolumeInfo.setLocality(VPlexApiConstants.LOCAL_VIRTUAL_VOLUME);
            }
            _log.info(String.format("Creating mirror: %s (%s)", vplexMirror.getLabel(), vplexMirrorId));
            Volume storageVolume = mirrorMap.get(vplexMirror);
            long totalProvisioned = storageVolume.getProvisionedCapacity();
            StorageSystem storage = storageMap.get(storageVolume.getStorageController());
            List<String> itls = VPlexControllerUtils.getVolumeITLs(storageVolume);
            VolumeInfo vinfo = new VolumeInfo(storage.getNativeGuid(), storage.getSystemType(), storageVolume.getWWN().toUpperCase().replaceAll(":", ""), storageVolume.getNativeId(), storageVolume.getThinlyProvisioned().booleanValue(), itls);
            // Update rollback information.
            rollbackData.add(vinfo);
            List<VolumeInfo> vinfos = new ArrayList<VolumeInfo>();
            vinfos.add(vinfo);
            _workflowService.storeStepData(stepId, rollbackData);
            // Make the call to create device and attach it as mirror to the source virtual volume device.
            VPlexDeviceInfo vInfo = client.createDeviceAndAttachAsMirror(vplexVolumeInfo, vinfos, true, false);
            buf.append(vInfo.getName() + " ");
            _log.info(String.format("Created mirror : %s path: %s : for virtual volume %s device label %s", vInfo.getName(), vInfo.getPath(), sourceVplexVolume.getLabel(), sourceVplexVolume.getDeviceLabel()));
            vplexMirror.setNativeId(vInfo.getPath());
            vplexMirror.setDeviceLabel(vInfo.getName());
            // For Vplex virtual volumes set allocated capacity to 0 (cop-18608)
            vplexMirror.setAllocatedCapacity(0L);
            vplexMirror.setProvisionedCapacity(totalProvisioned);
            if (vplexVolumeInfo.isThinEnabled() != sourceVplexVolume.getThinlyProvisioned()) {
                _log.info("Thin provisioned setting changed after mirror operation to " + vplexVolumeInfo.isThinEnabled());
                sourceVplexVolume.setThinlyProvisioned(vplexVolumeInfo.isThinEnabled());
                _dbClient.updateObject(sourceVplexVolume);
            }
            vplexMirror.setThinlyProvisioned(vplexVolumeInfo.isThinEnabled());
            _dbClient.updateObject(vplexMirror);
            // Record VPLEX volume created event.
            createdVplexMirrorURIs.add(vplexMirrorId);
            recordBourneVplexMirrorEvent(vplexMirrorId, OperationTypeEnum.CREATE_VOLUME_MIRROR.getEvType(true), Operation.Status.ready, OperationTypeEnum.CREATE_VOLUME_MIRROR.getDescription());
        }
        completer.ready(_dbClient);
        WorkflowStepCompleter.stepSucceded(stepId);
    } catch (VPlexApiException vae) {
        _log.error("Exception creating Mirror for the Virtual Volume: " + vae.getMessage(), vae);
        // not created.
        for (URI vplexMirrorURI : vplexMirrorURIs) {
            if (!createdVplexMirrorURIs.contains(vplexMirrorURI)) {
                recordBourneVplexMirrorEvent(vplexMirrorURI, OperationTypeEnum.CREATE_VOLUME_MIRROR.getEvType(false), Operation.Status.error, OperationTypeEnum.CREATE_VOLUME_MIRROR.getDescription());
            }
        }
        failStep(completer, stepId, vae);
    } catch (Exception ex) {
        _log.error("Exception creating Mirror for the Virtual Volume: " + ex.getMessage(), ex);
        // not created.
        for (URI vplexMirrorURI : vplexMirrorURIs) {
            if (!createdVplexMirrorURIs.contains(vplexMirrorURI)) {
                recordBourneVplexMirrorEvent(vplexMirrorURI, OperationTypeEnum.CREATE_VOLUME_MIRROR.getEvType(false), Operation.Status.error, OperationTypeEnum.CREATE_VOLUME_MIRROR.getDescription());
            }
        }
        ServiceError serviceError = VPlexApiException.errors.createMirrorsFailed(ex);
        failStep(completer, stepId, serviceError);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) VolumeInfo(com.emc.storageos.vplex.api.clientdata.VolumeInfo) VPlexVirtualVolumeInfo(com.emc.storageos.vplex.api.VPlexVirtualVolumeInfo) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) VPlexVirtualVolumeInfo(com.emc.storageos.vplex.api.VPlexVirtualVolumeInfo) VplexMirrorTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VplexMirrorTaskCompleter) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) InternalServerErrorException(com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) WorkflowException(com.emc.storageos.workflow.WorkflowException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) Volume(com.emc.storageos.db.client.model.Volume) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient) VPlexDeviceInfo(com.emc.storageos.vplex.api.VPlexDeviceInfo) VplexMirror(com.emc.storageos.db.client.model.VplexMirror) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 17 with VplexMirror

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

the class VPlexDeviceController method addStepsForDetachAndDeleteMirror.

/**
 * Here we detach the mentioned mirror device from the source device and
 * dismantle mirror device.
 *
 * @param workflow
 *            The workflow to which the steps are added.
 * @param waitFor
 *            The previous workflow step for which these steps will wait
 * @param vplexURI
 *            The vplex storage system URI
 * @param mirrorURI
 *            The URI of the mirror that needs to be detached
 * @param taskId
 *            The workflow taskId
 */
public String addStepsForDetachAndDeleteMirror(Workflow workflow, String waitFor, URI vplexURI, URI mirrorURI, String taskId) throws ControllerException {
    try {
        // Add a step to detach mirror device
        String detachStep = workflow.createStepId();
        waitFor = workflow.createStep(VPLEX_STEP, String.format("VPlex %s detaching mirror:%n%s", vplexURI, mirrorURI), waitFor, vplexURI, DiscoveredDataObject.Type.vplex.name(), this.getClass(), detachMirrorDeviceMethod(vplexURI, mirrorURI, null, true), rollbackMethodNullMethod(), detachStep);
        // Add a step to delete mirror device
        String deleteMirrorStep = workflow.createStepId();
        waitFor = workflow.createStep(VPLEX_STEP, String.format("VPlex %s deleting mirror:%n%s", vplexURI, mirrorURI), waitFor, vplexURI, DiscoveredDataObject.Type.vplex.name(), this.getClass(), deleteMirrorDeviceMethod(vplexURI, mirrorURI), rollbackDeleteMirrorDeviceMethod(vplexURI, mirrorURI), deleteMirrorStep);
        // Make a list of ExportGroups that is used.
        List<URI> exportGroupList = new ArrayList<URI>();
        // Create a series of steps to remove the volume from the Export Groups.
        // This list will contain only one backend volume uri for the vplex mirror
        List<URI> backendVolURIs = new ArrayList<URI>();
        boolean unexportStepsAdded = false;
        VplexMirror mirror = _dbClient.queryObject(VplexMirror.class, mirrorURI);
        if (mirror.getAssociatedVolumes() != null) {
            for (String volumeId : mirror.getAssociatedVolumes()) {
                URI volumeURI = new URI(volumeId);
                Volume volume = _dbClient.queryObject(Volume.class, volumeURI);
                // reference when user attempts to cleanup this failed mirror.
                if (volume == null || volume.getInactive() == true || volume.getNativeId() == null) {
                    continue;
                }
                backendVolURIs.add(volume.getId());
            }
            if (!backendVolURIs.isEmpty()) {
                unexportStepsAdded = vplexAddUnexportVolumeWfSteps(workflow, VPLEX_STEP, backendVolURIs, exportGroupList);
            }
        }
        // If we unexported a backend volume, add a step to forget those volumes.
        if (unexportStepsAdded) {
            waitFor = UNEXPORT_STEP;
            // Add a step to forget the backend volumes for the deleted
            // VPLEX volumes on this VPLEX system.
            addStepToForgetVolumes(workflow, vplexURI, backendVolURIs, waitFor);
        } else {
            waitFor = VPLEX_STEP;
        }
        return waitFor;
    } catch (Exception ex) {
        throw VPlexApiException.exceptions.addStepsForDetachAndDeleteMirror(ex);
    }
}
Also used : Volume(com.emc.storageos.db.client.model.Volume) ArrayList(java.util.ArrayList) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) VplexMirror(com.emc.storageos.db.client.model.VplexMirror) 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)

Example 18 with VplexMirror

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

the class VPlexDeviceController method rollbackCreateMirrors.

/**
 * Rollback any mirror device previously created.
 *
 * @param vplexURI
 *            URI of the VPlex StorageSystem
 * @param vplexMirrorURIs
 *            URI of the mirrors
 * @param executeStepId
 *            step Id of the execute step; used to retrieve rollback data.
 * @param stepId
 *            The stepId used for completion.
 *
 * @throws WorkflowException
 *             When an error occurs updating the workflow step
 *             state.
 */
public void rollbackCreateMirrors(URI vplexURI, List<URI> vplexMirrorURIs, String executeStepId, String stepId) throws WorkflowException {
    try {
        List<VolumeInfo> rollbackData = (List<VolumeInfo>) _workflowService.loadStepData(executeStepId);
        if (rollbackData != null) {
            WorkflowStepCompleter.stepExecuting(stepId);
            // Get the API client.
            StorageSystem vplex = getDataObject(StorageSystem.class, vplexURI, _dbClient);
            VPlexApiClient client = getVPlexAPIClient(_vplexApiFactory, vplex, _dbClient);
            // For each mirror device attempted, try and rollback.
            for (VolumeInfo rollbackInfo : rollbackData) {
                client.deleteLocalDevice(rollbackInfo);
            }
        }
    } catch (Exception ex) {
        _log.error("Exception rolling back: " + ex.getLocalizedMessage());
    } finally {
        // cleanup vplex mirror object in Database
        for (URI uri : vplexMirrorURIs) {
            VplexMirror vplexMirror = _dbClient.queryObject(VplexMirror.class, uri);
            if (vplexMirror != null) {
                Volume sourceVplexVolume = _dbClient.queryObject(Volume.class, vplexMirror.getSource());
                sourceVplexVolume.getMirrors().remove(vplexMirror.getId().toString());
                _dbClient.updateObject(sourceVplexVolume);
                _dbClient.removeObject(vplexMirror);
            }
        }
        WorkflowStepCompleter.stepSucceded(stepId);
    }
}
Also used : Volume(com.emc.storageos.db.client.model.Volume) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient) VolumeInfo(com.emc.storageos.vplex.api.clientdata.VolumeInfo) VPlexVirtualVolumeInfo(com.emc.storageos.vplex.api.VPlexVirtualVolumeInfo) ApplicationAddVolumeList(com.emc.storageos.volumecontroller.ApplicationAddVolumeList) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) List(java.util.List) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) VplexMirror(com.emc.storageos.db.client.model.VplexMirror) 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 19 with VplexMirror

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

the class VPlexDeviceController method detachMirrorDevice.

/**
 * This method will detach mirror device from the vplex volume source device.
 * If discard is true it will leave the device and the underlying structure on VPlex.
 * True is used when this method is used in the context of deleting mirror.
 * If discarded is false it will convert the detached mirror into virtual volume with
 * the same name as the mirror device. False is used in the context of promoting mirror
 * to a vplex volume.
 *
 * @param vplexURI
 *            URI of the VPlex StorageSystem
 * @param vplexMirrorURI
 *            URI of the mirror to be detached.
 * @param discard
 *            true or false value, whether to discard device or not.
 * @param stepId
 *            The stepId used for completion.
 *
 * @throws WorkflowException
 *             When an error occurs updating the workflow step
 *             state.
 */
public void detachMirrorDevice(URI vplexURI, URI vplexMirrorURI, URI promotedVolumeURI, boolean discard, String stepId) throws WorkflowException {
    try {
        WorkflowStepCompleter.stepExecuting(stepId);
        VPlexApiClient client = getVPlexAPIClient(_vplexApiFactory, vplexURI, _dbClient);
        VplexMirror vplexMirror = getDataObject(VplexMirror.class, vplexMirrorURI, _dbClient);
        Volume sourceVplexVolume = getDataObject(Volume.class, vplexMirror.getSource().getURI(), _dbClient);
        if (vplexMirror.getDeviceLabel() != null) {
            if (null == sourceVplexVolume.getAssociatedVolumes() || sourceVplexVolume.getAssociatedVolumes().isEmpty()) {
                _log.error("VPLEX volume {} has no backend volumes.", sourceVplexVolume.forDisplay());
                throw InternalServerErrorException.internalServerErrors.noAssociatedVolumesForVPLEXVolume(sourceVplexVolume.forDisplay());
            }
            if (sourceVplexVolume.getAssociatedVolumes().size() > 1) {
                // Call to detach mirror device from Distributed Virtual Volume
                client.detachLocalMirrorFromDistributedVirtualVolume(sourceVplexVolume.getDeviceLabel(), vplexMirror.getDeviceLabel(), discard);
            } else {
                // Call to detach mirror device from Local Virtual Volume
                client.detachMirrorFromLocalVirtualVolume(sourceVplexVolume.getDeviceLabel(), vplexMirror.getDeviceLabel(), discard);
            }
            // Record VPLEX mirror detach event.
            recordBourneVplexMirrorEvent(vplexMirrorURI, OperationTypeEnum.DETACH_VOLUME_MIRROR.getEvType(true), Operation.Status.ready, OperationTypeEnum.DETACH_VOLUME_MIRROR.getDescription());
        } else {
            _log.info("It seems vplex mirror {} was never created, so move to the next step for cleanup.", vplexMirror.getLabel());
        }
        WorkflowStepCompleter.stepSucceded(stepId);
    } catch (VPlexApiException vae) {
        _log.error("Exception detaching Vplex Mirror {} ", vplexMirrorURI + vae.getMessage(), vae);
        if (promotedVolumeURI != null) {
            // If we are here due to promote mirror action then
            // delete the volume that was supposed to be promoted volume.
            Volume volume = _dbClient.queryObject(Volume.class, promotedVolumeURI);
            _dbClient.removeObject(volume);
        }
        recordBourneVplexMirrorEvent(vplexMirrorURI, OperationTypeEnum.DETACH_VOLUME_MIRROR.getEvType(true), Operation.Status.error, OperationTypeEnum.DETACH_VOLUME_MIRROR.getDescription());
        WorkflowStepCompleter.stepFailed(stepId, vae);
    } catch (Exception ex) {
        _log.error("Exception detaching Vplex Mirror {} ", vplexMirrorURI + ex.getMessage(), ex);
        if (promotedVolumeURI != null) {
            // If we are here due to promote mirror action then
            // delete the volume that was supposed to be promoted volume.
            Volume volume = _dbClient.queryObject(Volume.class, promotedVolumeURI);
            _dbClient.removeObject(volume);
        }
        String opName = ResourceOperationTypeEnum.DETACH_VPLEX_LOCAL_MIRROR.getName();
        ServiceError serviceError = VPlexApiException.errors.detachMirrorFailed(opName, ex);
        recordBourneVplexMirrorEvent(vplexMirrorURI, OperationTypeEnum.DETACH_VOLUME_MIRROR.getEvType(true), Operation.Status.error, OperationTypeEnum.DETACH_VOLUME_MIRROR.getDescription());
        WorkflowStepCompleter.stepFailed(stepId, serviceError);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) Volume(com.emc.storageos.db.client.model.Volume) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient) VplexMirror(com.emc.storageos.db.client.model.VplexMirror) 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)

Example 20 with VplexMirror

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

the class VPlexDeviceController method validateVPlexVolume.

/**
 * Validates that the backend volumes of the passed VPLEX volumes in the
 * ViPR database are the actual backend volumes used by the VPLEX volume
 * on the VPLEX system.
 *
 * @param vplexSystemURI
 *            The URI of the VPLEX storage system.
 * @param vplexVolumeURI
 *            The URI of the VPLEX volume to validate.
 * @param stepId
 *            The workflow step id.
 */
public void validateVPlexVolume(URI vplexSystemURI, URI vplexVolumeURI, String stepId) {
    Volume vplexVolume = null;
    try {
        // Skip this if validation disabled
        ValidatorConfig validatorConfig = new ValidatorConfig();
        validatorConfig.setCoordinator(coordinator);
        if (!validatorConfig.isValidationEnabled()) {
            WorkflowStepCompleter.stepSucceeded(stepId, "Validations not enabled");
            return;
        }
        // Update step state to executing.
        WorkflowStepCompleter.stepExecuting(stepId);
        // Get the VPLEX API client for the VPLEX system.
        VPlexApiClient client = getVPlexAPIClient(_vplexApiFactory, vplexSystemURI, _dbClient);
        // Get the VPLEX volume
        vplexVolume = getDataObject(Volume.class, vplexVolumeURI, _dbClient);
        // Get a VolumeInfo for each backend volume and any mirrors, mapped by VPLEX cluster name.
        Set<String> volumeIds = new HashSet<>();
        Map<String, List<VolumeInfo>> volumeInfoMap = new HashMap<>();
        StringSet associatedVolumeIds = vplexVolume.getAssociatedVolumes();
        if ((associatedVolumeIds == null) || (associatedVolumeIds.isEmpty())) {
            // Ingested volume w/o backend volume ingestion. We can't verify the backend volumes.
            _log.info("VPLEX volume {}:{} has no backend volumes to validate", vplexVolumeURI, vplexVolume.getLabel());
            WorkflowStepCompleter.stepSucceded(stepId);
            return;
        } else {
            volumeIds.addAll(associatedVolumeIds);
        }
        // Now mirrors.
        StringSet mirrorIds = vplexVolume.getMirrors();
        if ((mirrorIds != null) && (mirrorIds.isEmpty() == false)) {
            for (String mirrorId : mirrorIds) {
                VplexMirror mirror = getDataObject(VplexMirror.class, URI.create(mirrorId), _dbClient);
                StringSet associatedVolumeIdsForMirror = mirror.getAssociatedVolumes();
                if ((associatedVolumeIdsForMirror == null) || (associatedVolumeIdsForMirror.isEmpty())) {
                    _log.info("VPLEX mirror {}:{} has no associated volumes", mirrorId, mirror.getLabel());
                    throw DeviceControllerExceptions.vplex.vplexMirrorDoesNotHaveAssociatedVolumes(vplexVolume.getLabel(), mirror.getLabel());
                } else {
                    volumeIds.addAll(associatedVolumeIdsForMirror);
                }
            }
        }
        // Get the WWNs for these volumes mapped by VPLEX cluster name.
        for (String volumesId : volumeIds) {
            URI volumeURI = URI.create(volumesId);
            Volume volume = getDataObject(Volume.class, volumeURI, _dbClient);
            String clusterName = VPlexUtil.getVplexClusterName(volume.getVirtualArray(), vplexSystemURI, client, _dbClient);
            StorageSystem storageSystem = getDataObject(StorageSystem.class, volume.getStorageController(), _dbClient);
            List<String> itls = VPlexControllerUtils.getVolumeITLs(volume);
            VolumeInfo volumeInfo = new VolumeInfo(storageSystem.getNativeGuid(), storageSystem.getSystemType(), volume.getWWN().toUpperCase().replaceAll(":", ""), volume.getNativeId(), volume.getThinlyProvisioned().booleanValue(), itls);
            _log.info(String.format("Validating backend volume %s on cluster %s", volumeURI, clusterName));
            if (volumeInfoMap.containsKey(clusterName)) {
                List<VolumeInfo> clusterVolumeInfos = volumeInfoMap.get(clusterName);
                clusterVolumeInfos.add(volumeInfo);
            } else {
                List<VolumeInfo> clusterVolumeInfos = new ArrayList<>();
                clusterVolumeInfos.add(volumeInfo);
                volumeInfoMap.put(clusterName, clusterVolumeInfos);
            }
        }
        // Validate the ViPR backend volume WWNs match those on the VPLEX.
        client.validateBackendVolumesForVPlexVolume(vplexVolume.getDeviceLabel(), vplexVolume.getNativeId(), volumeInfoMap);
        WorkflowStepCompleter.stepSucceded(stepId);
    } catch (InternalException ie) {
        _log.info("Exception attempting to validate the backend volumes for VPLEX volume {}", vplexVolumeURI);
        WorkflowStepCompleter.stepFailed(stepId, ie);
    } catch (Exception e) {
        _log.info("Exception attempting to validate the backend volumes for VPLEX volume {}", vplexVolumeURI);
        ServiceCoded sc = DeviceControllerExceptions.vplex.failureValidatingVplexVolume(vplexVolumeURI.toString(), (vplexVolume != null ? vplexVolume.getLabel() : ""), e.getMessage());
        WorkflowStepCompleter.stepFailed(stepId, sc);
    }
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) VolumeInfo(com.emc.storageos.vplex.api.clientdata.VolumeInfo) VPlexVirtualVolumeInfo(com.emc.storageos.vplex.api.VPlexVirtualVolumeInfo) 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) ValidatorConfig(com.emc.storageos.volumecontroller.impl.validators.ValidatorConfig) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) Volume(com.emc.storageos.db.client.model.Volume) ServiceCoded(com.emc.storageos.svcs.errorhandling.model.ServiceCoded) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient) StringSet(com.emc.storageos.db.client.model.StringSet) ApplicationAddVolumeList(com.emc.storageos.volumecontroller.ApplicationAddVolumeList) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) List(java.util.List) VplexMirror(com.emc.storageos.db.client.model.VplexMirror) HashSet(java.util.HashSet) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Aggregations

VplexMirror (com.emc.storageos.db.client.model.VplexMirror)36 Volume (com.emc.storageos.db.client.model.Volume)31 NamedURI (com.emc.storageos.db.client.model.NamedURI)15 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)15 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)15 URI (java.net.URI)15 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)12 InternalServerErrorException (com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException)12 ControllerException (com.emc.storageos.volumecontroller.ControllerException)12 URISyntaxException (java.net.URISyntaxException)12 ArrayList (java.util.ArrayList)12 StringSet (com.emc.storageos.db.client.model.StringSet)11 VPlexApiException (com.emc.storageos.vplex.api.VPlexApiException)11 WorkflowException (com.emc.storageos.workflow.WorkflowException)11 IOException (java.io.IOException)11 VPlexApiClient (com.emc.storageos.vplex.api.VPlexApiClient)10 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)8 VolumeDescriptor (com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor)7 HashMap (java.util.HashMap)6 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)5