Search in sources :

Example 56 with VPlexApiClient

use of com.emc.storageos.vplex.api.VPlexApiClient 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)

Example 57 with VPlexApiClient

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

the class VPlexDeviceController method getVPlexAPIClient.

private static VPlexApiClient getVPlexAPIClient(VPlexApiFactory vplexApiFactory, URI vplexUri, DbClient dbClient) throws URISyntaxException {
    VPlexApiClient client = VPlexControllerUtils.getVPlexAPIClient(vplexApiFactory, vplexUri, dbClient);
    updateTimeoutValues();
    return client;
}
Also used : VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient)

Example 58 with VPlexApiClient

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

the class VPlexDeviceController method promoteMirror.

/**
 * This method creates the virtual volume from the detached mirror device.
 *
 * @param vplexURI
 *            The vplex storage system URI
 * @param vplexMirrorURI
 *            The URI of the vplex mirror that needs to be promoted to the virtual volume
 * @param promoteVolumeURI
 *            The URI of the volume will be used as a promoted vplex volume
 * @param stepId
 *            The worflow stepId
 *
 * @throws WorkflowException
 *             When an error occurs updating the workflow step
 *             state.
 */
public void promoteMirror(URI vplexURI, URI vplexMirrorURI, URI promoteVolumeURI, 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);
        Volume promoteVolume = _dbClient.queryObject(Volume.class, promoteVolumeURI);
        // Find virtual volume that should have been created when we did detach mirror.
        // Virtual volume is created with the same name as the device name.
        VPlexVirtualVolumeInfo vvInfo = client.findVirtualVolume(vplexMirror.getDeviceLabel(), null);
        // Get the backend volume for this promoted VPLEX volume.
        StringSet assocVolumes = vplexMirror.getAssociatedVolumes();
        // Get the ViPR label for the promoted VPLEX volume.
        String promotedLabel = String.format("%s-%s", sourceVplexVolume.getLabel(), vplexMirror.getLabel());
        // Rename the vplex volume created using device detach mirror. If custom naming is enabled
        // generate the custom name, else the name follows the default naming convention and must
        // be renamed to append the "_vol" suffix.
        String newVolumeName = null;
        try {
            if (CustomVolumeNamingUtils.isCustomVolumeNamingEnabled(customConfigHandler, DiscoveredDataObject.Type.vplex.name())) {
                String customConfigName = CustomConfigConstants.CUSTOM_VOLUME_NAME;
                Project project = _dbClient.queryObject(Project.class, promoteVolume.getProject().getURI());
                TenantOrg tenant = _dbClient.queryObject(TenantOrg.class, promoteVolume.getTenant().getURI());
                DataSource customNameDataSource = CustomVolumeNamingUtils.getCustomConfigDataSource(project, tenant, promotedLabel, vvInfo.getWwn(), null, dataSourceFactory, customConfigName, _dbClient);
                if (customNameDataSource != null) {
                    newVolumeName = CustomVolumeNamingUtils.getCustomName(customConfigHandler, customConfigName, customNameDataSource, DiscoveredDataObject.Type.vplex.name());
                }
                // Rename the vplex volume created using device detach mirror,
                vvInfo = CustomVolumeNamingUtils.renameVolumeOnVPlex(vvInfo, newVolumeName, client);
                promotedLabel = newVolumeName;
            } else {
                // Build the name for volume so as to rename the vplex volume that is created
                // with the same name as the device name to follow the name pattern _vol
                // as the suffix for the vplex volumes
                StringBuilder volumeNameBuilder = new StringBuilder();
                volumeNameBuilder.append(vplexMirror.getDeviceLabel());
                volumeNameBuilder.append(VPlexApiConstants.VIRTUAL_VOLUME_SUFFIX);
                newVolumeName = volumeNameBuilder.toString();
                // Rename the vplex volume created using device detach mirror,
                vvInfo = CustomVolumeNamingUtils.renameVolumeOnVPlex(vvInfo, newVolumeName, client);
            }
        } catch (Exception e) {
            _log.warn(String.format("Error renaming promoted VPLEX volume %s", promoteVolumeURI), e);
        }
        _log.info(String.format("Renamed promoted virtual volume: %s path: %s", vvInfo.getName(), vvInfo.getPath()));
        // Fill in the details for the promoted vplex volume
        promoteVolume.setLabel(promotedLabel);
        promoteVolume.setNativeId(vvInfo.getPath());
        promoteVolume.setNativeGuid(vvInfo.getPath());
        promoteVolume.setDeviceLabel(vvInfo.getName());
        promoteVolume.setThinlyProvisioned(vvInfo.isThinEnabled());
        promoteVolume.setWWN(vvInfo.getWwn());
        // For Vplex virtual volumes set allocated capacity to 0 (cop-18608)
        promoteVolume.setAllocatedCapacity(0L);
        promoteVolume.setCapacity(vplexMirror.getCapacity());
        promoteVolume.setProvisionedCapacity(vplexMirror.getProvisionedCapacity());
        promoteVolume.setVirtualPool(vplexMirror.getVirtualPool());
        promoteVolume.setVirtualArray(vplexMirror.getVirtualArray());
        promoteVolume.setStorageController(vplexMirror.getStorageController());
        promoteVolume.setSystemType(DiscoveredDataObject.Type.vplex.name());
        promoteVolume.setPool(NullColumnValueGetter.getNullURI());
        promoteVolume.setAssociatedVolumes(new StringSet(assocVolumes));
        promoteVolume.setThinlyProvisioned(vplexMirror.getThinlyProvisioned());
        promoteVolume.setThinVolumePreAllocationSize(vplexMirror.getThinPreAllocationSize());
        // VPLEX volumes created by VIPR have syncActive set to true hence setting same value for promoted vplex
        // volumes
        promoteVolume.setSyncActive(true);
        // Also, we update the name portion of the project and tenant URIs
        // to reflect the new name. This is necessary because the API
        // to search for volumes by project, extracts the name portion of the
        // project URI to get the volume name.
        NamedURI namedURI = promoteVolume.getProject();
        namedURI.setName(promotedLabel);
        promoteVolume.setProject(namedURI);
        namedURI = promoteVolume.getTenant();
        namedURI.setName(promotedLabel);
        promoteVolume.setTenant(namedURI);
        // Remove mirror from the source VPLEX volume
        sourceVplexVolume.getMirrors().remove(vplexMirror.getId().toString());
        _dbClient.updateObject(sourceVplexVolume);
        // Delete the mirror object
        _dbClient.removeObject(vplexMirror);
        // Persist changes for the newly promoted volume
        _dbClient.updateObject(promoteVolume);
        WorkflowStepCompleter.stepSucceded(stepId);
    } catch (VPlexApiException vae) {
        _log.error("Exception promoting mirror volume: " + vae.getMessage(), vae);
        WorkflowStepCompleter.stepFailed(stepId, vae);
    } catch (Exception ex) {
        _log.error("Exception promoting mirror volume: " + ex.getMessage(), ex);
        ServiceError serviceError = VPlexApiException.errors.promoteMirrorFailed(ex);
        WorkflowStepCompleter.stepFailed(stepId, serviceError);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) NamedURI(com.emc.storageos.db.client.model.NamedURI) 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) DataSource(com.emc.storageos.customconfigcontroller.DataSource) Project(com.emc.storageos.db.client.model.Project) Volume(com.emc.storageos.db.client.model.Volume) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient) StringSet(com.emc.storageos.db.client.model.StringSet) TenantOrg(com.emc.storageos.db.client.model.TenantOrg) VplexMirror(com.emc.storageos.db.client.model.VplexMirror)

Example 59 with VPlexApiClient

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

the class VPlexDeviceController method deleteMigrationStep.

public void deleteMigrationStep(URI vplexURI, URI migrationURI, String stepId) {
    WorkflowStepCompleter.stepExecuting(stepId);
    try {
        StorageSystem vplex = getDataObject(StorageSystem.class, vplexURI, _dbClient);
        VPlexApiClient client = getVPlexAPIClient(_vplexApiFactory, vplex, _dbClient);
        Migration migration = getDataObject(Migration.class, migrationURI, _dbClient);
        client.removeMigrations(Arrays.asList(migration.getLabel()));
        migration.setInactive(true);
        _dbClient.updateObject(migration);
        WorkflowStepCompleter.stepSucceded(stepId);
    } catch (Exception ex) {
        _log.error("Exception deleting migration:", ex);
        String opName = ResourceOperationTypeEnum.DELETE_MIGRATION.getName();
        ServiceError serviceError = VPlexApiException.errors.operateMigrationFailed(opName, ex);
        WorkflowStepCompleter.stepFailed(stepId, serviceError);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) Migration(com.emc.storageos.db.client.model.Migration) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient) 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 60 with VPlexApiClient

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

the class VPlexDeviceController method deleteMirrorDevice.

/**
 * Do the delete of a VPlex mirror device .
 * This is called as a Workflow Step.
 * NOTE: The parameters here must match deleteMirrorDeviceMethod above (except stepId).
 *
 * @param vplexURI
 *            URI of the VPlex StorageSystem
 * @param vplexMirrorURI
 *            URI of the mirror to be deleted
 * @param stepId
 *            The stepId used for completion.
 *
 * @throws WorkflowException
 *             When an error occurs updating the workflow step
 *             state.
 */
public void deleteMirrorDevice(URI vplexURI, URI vplexMirrorURI, String stepId) throws WorkflowException {
    try {
        WorkflowStepCompleter.stepExecuting(stepId);
        VPlexApiClient client = getVPlexAPIClient(_vplexApiFactory, vplexURI, _dbClient);
        VplexMirror vplexMirror = getDataObject(VplexMirror.class, vplexMirrorURI, _dbClient);
        if (vplexMirror.getDeviceLabel() != null) {
            // Call to delete mirror device
            client.deleteLocalDevice(vplexMirror.getDeviceLabel());
            if (vplexMirror.getSource() != null && vplexMirror.getSource().getURI() != null) {
                Volume vplexVolume = getDataObject(Volume.class, vplexMirror.getSource().getURI(), _dbClient);
                StorageSystem vplexSystem = getDataObject(StorageSystem.class, vplexURI, _dbClient);
                updateThinProperty(client, vplexSystem, vplexVolume);
            }
            // Record VPLEX mirror delete event.
            recordBourneVplexMirrorEvent(vplexMirrorURI, OperationTypeEnum.DELETE_VOLUME_MIRROR.getEvType(true), Operation.Status.ready, OperationTypeEnum.DELETE_VOLUME_MIRROR.getDescription());
        } else {
            _log.info("It seems vplex mirror {} was never created, so just move to the next step.", vplexMirror.getLabel());
        }
        WorkflowStepCompleter.stepSucceded(stepId);
    } catch (VPlexApiException vae) {
        _log.error("Exception deleting VPlex Virtual Volume: " + vae.getMessage(), vae);
        recordBourneVplexMirrorEvent(vplexMirrorURI, OperationTypeEnum.DELETE_VOLUME_MIRROR.getEvType(true), Operation.Status.error, OperationTypeEnum.DELETE_VOLUME_MIRROR.getDescription());
        WorkflowStepCompleter.stepFailed(stepId, vae);
    } catch (Exception ex) {
        _log.error("Exception deleting VPlex Virtual Volume: " + ex.getMessage(), ex);
        String opName = ResourceOperationTypeEnum.DELETE_VPLEX_LOCAL_MIRROR.getName();
        ServiceError serviceError = VPlexApiException.errors.deleteMirrorFailed(opName, ex);
        recordBourneVplexMirrorEvent(vplexMirrorURI, OperationTypeEnum.DELETE_VOLUME_MIRROR.getEvType(true), Operation.Status.error, OperationTypeEnum.DELETE_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) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Aggregations

VPlexApiClient (com.emc.storageos.vplex.api.VPlexApiClient)81 VPlexApiException (com.emc.storageos.vplex.api.VPlexApiException)57 URISyntaxException (java.net.URISyntaxException)57 ControllerException (com.emc.storageos.volumecontroller.ControllerException)55 WorkflowException (com.emc.storageos.workflow.WorkflowException)55 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)54 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)52 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)52 InternalServerErrorException (com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException)52 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)48 IOException (java.io.IOException)47 URI (java.net.URI)41 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)40 Volume (com.emc.storageos.db.client.model.Volume)34 ArrayList (java.util.ArrayList)34 NamedURI (com.emc.storageos.db.client.model.NamedURI)26 HashMap (java.util.HashMap)18 ExportMask (com.emc.storageos.db.client.model.ExportMask)16 VPlexStorageViewInfo (com.emc.storageos.vplex.api.VPlexStorageViewInfo)16 VPlexVirtualVolumeInfo (com.emc.storageos.vplex.api.VPlexVirtualVolumeInfo)16