Search in sources :

Example 1 with VPlexApiClient

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

the class VPlexCommunicationInterface method discover.

/**
 * Implementation for discovery of VPLEX storage systems.
 *
 * @param accessProfile providing context for this discovery session
 *
 * @throws BaseCollectionException
 */
@Override
public void discover(AccessProfile accessProfile) throws BaseCollectionException {
    s_logger.info("initiating discovery of VPLEX system {}", accessProfile.getProfileName());
    if ((null != accessProfile.getnamespace()) && (accessProfile.getnamespace().equals(StorageSystem.Discovery_Namespaces.UNMANAGED_VOLUMES.toString()))) {
        try {
            VPlexApiClient client = getVPlexAPIClient(accessProfile);
            long timer = System.currentTimeMillis();
            UnmanagedDiscoveryPerformanceTracker tracker = new UnmanagedDiscoveryPerformanceTracker();
            tracker.discoveryMode = ControllerUtils.getPropertyValueFromCoordinator(_coordinator, VplexBackendIngestionContext.DISCOVERY_MODE);
            // get all the detailed virtual volume info from the VPLEX API
            Map<String, VPlexVirtualVolumeInfo> vvolMap = client.getVirtualVolumes(true);
            tracker.virtualVolumeFetch = System.currentTimeMillis() - timer;
            tracker.totalVolumesFetched = vvolMap.size();
            // discover unmanaged storage views
            timer = System.currentTimeMillis();
            Map<String, Set<UnManagedExportMask>> volumeToExportMasksMap = new HashMap<String, Set<UnManagedExportMask>>();
            Map<String, Set<VPlexStorageViewInfo>> volumeToStorageViewMap = new HashMap<String, Set<VPlexStorageViewInfo>>();
            Set<String> recoverPointExportMasks = new HashSet<String>();
            discoverUnmanagedStorageViews(accessProfile, client, vvolMap, volumeToExportMasksMap, volumeToStorageViewMap, recoverPointExportMasks);
            tracker.storageViewFetch = System.currentTimeMillis() - timer;
            // discover unmanaged volumes
            timer = System.currentTimeMillis();
            discoverUnmanagedVolumes(accessProfile, client, vvolMap, volumeToExportMasksMap, volumeToStorageViewMap, recoverPointExportMasks, tracker);
            tracker.unmanagedVolumeProcessing = System.currentTimeMillis() - timer;
            // re-run vpool matching for all vpools so that backend volumes will
            // be updated after vvol discovery to match their parent's matched vpools
            timer = System.currentTimeMillis();
            List<URI> vpoolURIs = _dbClient.queryByType(VirtualPool.class, true);
            List<VirtualPool> vpoolList = _dbClient.queryObject(VirtualPool.class, vpoolURIs);
            Set<URI> srdfEnabledTargetVPools = SRDFUtils.fetchSRDFTargetVirtualPools(_dbClient);
            Set<URI> rpEnabledTargetVPools = RPHelper.fetchRPTargetVirtualPools(_dbClient);
            for (VirtualPool vpool : vpoolList) {
                ImplicitUnManagedObjectsMatcher.matchVirtualPoolsWithUnManagedVolumes(vpool, srdfEnabledTargetVPools, rpEnabledTargetVPools, _dbClient, true);
            }
            tracker.vpoolMatching = System.currentTimeMillis() - timer;
            s_logger.info(tracker.getPerformanceReport());
        } catch (URISyntaxException ex) {
            s_logger.error(ex.getLocalizedMessage());
            throw VPlexCollectionException.exceptions.vplexUnmanagedVolumeDiscoveryFailed(accessProfile.getSystemId().toString(), ex.getLocalizedMessage());
        }
    } else {
        discoverAll(accessProfile);
    }
}
Also used : VPlexStorageViewInfo(com.emc.storageos.vplex.api.VPlexStorageViewInfo) Set(java.util.Set) HashSet(java.util.HashSet) StringSet(com.emc.storageos.db.client.model.StringSet) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) URISyntaxException(java.net.URISyntaxException) VPlexVirtualVolumeInfo(com.emc.storageos.vplex.api.VPlexVirtualVolumeInfo) URI(java.net.URI) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient) UnManagedExportMask(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask) HashSet(java.util.HashSet)

Example 2 with VPlexApiClient

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

the class AbstractConsistencyGroupManager method deleteCG.

/**
 * Deletes the consistency group with the passed URI on the VPLEX storage
 * system with the passed URU.
 *
 * @param vplexSystemURI The URI of the VPlex system.
 * @param cgUri The URI of the ViPR consistency group.
 * @param cgName The name of the VPlex consistency group to delete.
 * @param clusterName The name of the VPlex cluster.
 * @param setInactive true to mark the CG for deletion.
 * @param stepId The workflow step identifier.
 *
 * @throws WorkflowException When an error occurs updating the work step
 *             state.
 */
public void deleteCG(URI vplexSystemURI, URI cgUri, String cgName, String clusterName, Boolean setInactive, String stepId) throws WorkflowException {
    StorageSystem vplexSystem = null;
    try {
        // Update step state to executing.
        WorkflowStepCompleter.stepExecuting(stepId);
        log.info(String.format("Executing workflow step deleteCG. Storage System: %s, CG Name: %s, Cluster Name: %s", vplexSystemURI, cgName, clusterName));
        vplexSystem = getDataObject(StorageSystem.class, vplexSystemURI, dbClient);
        VPlexApiClient client = getVPlexAPIClient(vplexApiFactory, vplexSystem, dbClient);
        log.info("Got VPlex API client for VPlex system {}", vplexSystemURI);
        InvokeTestFailure.internalOnlyInvokeTestFailure(InvokeTestFailure.ARTIFICIAL_FAILURE_085);
        // Make a call to the VPlex API client to delete the consistency group.
        client.deleteConsistencyGroup(cgName);
        log.info(String.format("Deleted consistency group %s", cgName));
        cleanUpVplexCG(vplexSystemURI, cgUri, cgName, setInactive);
        // Update step status to success.
        WorkflowStepCompleter.stepSucceded(stepId);
    } catch (VPlexApiException vae) {
        if (vae.getServiceCode().getCode() == ServiceCode.VPLEX_CG_NOT_FOUND.getCode()) {
            log.info(String.format("Consistency group %s not found on storage system: %s.  Assumed already deleted.", clusterName + ":" + cgName, (vplexSystem != null && vplexSystem.forDisplay() != null) ? vplexSystem.forDisplay() : vplexSystemURI));
            cleanUpVplexCG(vplexSystemURI, cgUri, cgName, setInactive);
            WorkflowStepCompleter.stepSucceded(stepId);
        } else {
            log.error("Exception deleting consistency group: " + vae.getMessage(), vae);
            WorkflowStepCompleter.stepFailed(stepId, vae);
        }
    } catch (Exception ex) {
        log.error("Exception deleting consistency group: " + ex.getMessage(), ex);
        String opName = ResourceOperationTypeEnum.DELETE_CONSISTENCY_GROUP.getName();
        ServiceError serviceError = VPlexApiException.errors.deleteCGFailed(opName, ex);
        WorkflowStepCompleter.stepFailed(stepId, serviceError);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient) WorkflowException(com.emc.storageos.workflow.WorkflowException) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 3 with VPlexApiClient

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

the class RPVplexConsistencyGroupManager method getClusterConsistencyGroup.

/**
 * Maps a VPlex cluster/consistency group to its volumes.
 *
 * @param vplexVolume The virtual volume from which to obtain the VPlex cluster.
 * @param clusterConsistencyGroupVolumes The map to store cluster/cg/volume relationships.
 * @param cgName The VPlex consistency group name.
 * @throws Exception
 */
@Override
public ClusterConsistencyGroupWrapper getClusterConsistencyGroup(Volume vplexVolume, BlockConsistencyGroup cg) throws Exception {
    ClusterConsistencyGroupWrapper clusterConsistencyGroup = new ClusterConsistencyGroupWrapper();
    String vplexCgName = null;
    // Find the correct VPLEX cluster for this volume
    String vplexCluster = VPlexControllerUtils.getVPlexClusterName(dbClient, vplexVolume);
    // Determine if the volume is distributed
    boolean distributed = false;
    StringSet assocVolumes = vplexVolume.getAssociatedVolumes();
    // Associated volume for the consistency group cannot be null, indicates back-end volumes are not ingested.
    if (vplexVolume.getAssociatedVolumes() != null && !vplexVolume.getAssociatedVolumes().isEmpty()) {
        if (assocVolumes.size() > 1) {
            distributed = true;
        }
    } else {
        String reason = "Associated volume is empty";
        throw VPlexApiException.exceptions.emptyAssociatedVolumes(vplexVolume.getDeviceLabel(), vplexCluster, reason);
    }
    // Keep a reference to the VPLEX
    URI vplexURI = vplexVolume.getStorageController();
    log.info(String.format("Find correct VPLEX CG for VPLEX %s volume [%s](%s) at cluster [%s] on VPLEX (%s)", (distributed ? "distribitued" : "local"), vplexVolume.getLabel(), vplexVolume.getId(), vplexCluster, vplexURI));
    // line up the CG name from the ViPR CG to the VPLEX CGs.
    if (cg.created(vplexURI)) {
        log.info("CG already exists on VPLEX, but we need to figure out the correct one to use...");
        List<String> validVPlexCGsForCluster = new ArrayList<String>();
        // Extract all the CG names for the VPLEX
        // These names are in the format of: cluster-1:cgName or cluster-2:cgName
        StringSet cgNames = cg.getSystemConsistencyGroups().get(vplexURI.toString());
        // Iterate over the names to line up with the cluster
        Iterator<String> cgNamesIter = cgNames.iterator();
        while (cgNamesIter.hasNext()) {
            String clusterCgName = cgNamesIter.next();
            String cluster = BlockConsistencyGroupUtils.fetchClusterName(clusterCgName);
            String cgName = BlockConsistencyGroupUtils.fetchCgName(clusterCgName);
            // We will narrow this down afterwards for distributed.
            if (vplexCluster.equals(cluster) || distributed) {
                validVPlexCGsForCluster.add(cgName);
            }
        }
        // Get the API client.
        StorageSystem vplexSystem = getDataObject(StorageSystem.class, vplexURI, dbClient);
        VPlexApiClient client = getVPlexAPIClient(vplexApiFactory, vplexSystem, dbClient);
        log.info("Got VPLEX API client.");
        // This is not ideal but we need to call the VPlex client to fetch all consistency
        // groups so we can find the exact one we are looking for.
        List<VPlexConsistencyGroupInfo> vplexCGs = client.getConsistencyGroups();
        log.info("Iterating over returned VPLEX CGs to find the one we should use...");
        for (VPlexConsistencyGroupInfo vplexCG : vplexCGs) {
            boolean cgNameFound = validVPlexCGsForCluster.contains(vplexCG.getName());
            boolean volumeFound = vplexCG.getVirtualVolumes().contains(vplexVolume.getDeviceLabel());
            // either way it's valid.
            if (cgNameFound || volumeFound) {
                // Determine if the VPLEX CG is distributed.
                // NOTE: VPlexConsistencyGroupInfo.isDistributed() is not returning
                // the correct information. This is probably due to teh fact that
                // visibleClusters is not being returned in the response.
                // Instead we are checking getStorageAtClusters().size().
                boolean vplexCGIsDistributed = (vplexCG.getStorageAtClusters().size() > 1);
                if ((distributed && vplexCGIsDistributed) || (!distributed && !vplexCGIsDistributed)) {
                    log.info(String.format("Found correct VPLEX CG: %s", vplexCG.getName()));
                    vplexCgName = vplexCG.getName();
                    break;
                }
            }
        }
    }
    // The format for VPLEX local: cgName-vplexCluster
    if (vplexCgName == null) {
        // If we do not have a VPLEX CG name it's time to create one.
        if (distributed) {
            // Add '-dist' to the end of the CG name for distributed consistency groups.
            vplexCgName = cg.getLabel() + "-dist";
        } else {
            vplexCgName = cg.getLabel() + "-" + vplexCluster;
        }
        log.info(String.format("There was no existing VPLEX CG, created CG name: %s", vplexCgName));
    }
    clusterConsistencyGroup.setClusterName(vplexCluster);
    clusterConsistencyGroup.setCgName(vplexCgName);
    clusterConsistencyGroup.setDistributed(distributed);
    return clusterConsistencyGroup;
}
Also used : ClusterConsistencyGroupWrapper(com.emc.storageos.volumecontroller.impl.utils.ClusterConsistencyGroupWrapper) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient) VPlexConsistencyGroupInfo(com.emc.storageos.vplex.api.VPlexConsistencyGroupInfo) StringSet(com.emc.storageos.db.client.model.StringSet) ArrayList(java.util.ArrayList) URI(java.net.URI) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 4 with VPlexApiClient

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

the class VPlexConsistencyGroupManager method addVolumesToCG.

/**
 * Adds volumes to a BlockConsistencyGroup.
 * @param vplexSystem - StorageSystem representing the Vplex
 * @param cg -- Block Consistency Group the volumes are to be added to
 * @param vplexVolumes -- Collection of Vplex volumes to be added
 * @param stepId -- String Stepid. WorkflowStepCompleter is called if successful or not.
 * @return true if successful, false if not
 */
private boolean addVolumesToCG(StorageSystem vplexSystem, BlockConsistencyGroup cg, Collection<Volume> vplexVolumes, String stepId) {
    try {
        VPlexApiClient client = getVPlexAPIClient(vplexApiFactory, vplexSystem, dbClient);
        // Get the names of the volumes to be added.
        Volume protoVolume = null;
        List<String> vplexVolumeNames = new ArrayList<String>();
        for (Volume vplexVolume : vplexVolumes) {
            if (protoVolume == null) {
                protoVolume = vplexVolume;
            }
            vplexVolumeNames.add(vplexVolume.getDeviceLabel());
            log.info("VPLEX volume:" + vplexVolume.getDeviceLabel());
        }
        log.info("Got VPLEX volume names.");
        String cgName = getVplexCgName(protoVolume, cg.getId());
        long startTime = System.currentTimeMillis();
        // Add the volumes to the CG.
        client.addVolumesToConsistencyGroup(cgName, vplexVolumeNames);
        long elapsed = System.currentTimeMillis() - startTime;
        log.info(String.format("TIMER: Adding %s virtual volume(s) %s to the consistency group %s took %f seconds", vplexVolumeNames.size(), vplexVolumeNames, cgName, (double) elapsed / (double) 1000));
        // adding volumes to a CG after volume creation.
        for (Volume vplexVolume : vplexVolumes) {
            vplexVolume.setConsistencyGroup(cg.getId());
            dbClient.updateObject(vplexVolume);
        }
        // Update workflow step state to success.
        WorkflowStepCompleter.stepSucceded(stepId);
        log.info("Updated workflow step state to success for add volumes to consistency group.");
        return true;
    } catch (VPlexApiException vae) {
        log.error("Exception adding volumes to consistency group: " + vae.getMessage(), vae);
        WorkflowStepCompleter.stepFailed(stepId, vae);
        return false;
    } catch (Exception ex) {
        log.error("Exception adding volumes to consistency group: " + ex.getMessage(), ex);
        ServiceError svcError = VPlexApiException.errors.jobFailed(ex);
        WorkflowStepCompleter.stepFailed(stepId, svcError);
        return false;
    }
}
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) ArrayList(java.util.ArrayList) WorkflowException(com.emc.storageos.workflow.WorkflowException) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) InternalServerErrorException(com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException)

Example 5 with VPlexApiClient

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

the class VPlexConsistencyGroupManager method updateConsistencyGroupReadOnlyState.

/**
 * Step to call the VPLEX to update the read-only flag on a consistency group.
 * If the Vplex Api library detects the firmware does not properly handle the flag,
 * a warning message is put in the SUCCESS status.
 * @param vplexVolumeURIs -- List of at least some volumes in the consistency group.
 * @param isReadOnly - if true marks read-only, false read-write
 * @param stepId - Workflow step id
 */
public void updateConsistencyGroupReadOnlyState(List<URI> vplexVolumeURIs, Boolean isReadOnly, String stepId) {
    try {
        WorkflowStepCompleter.stepExecuting(stepId);
        // Get the first virtual volume, as all volumes should be in the same CG
        Volume vplexVolume = dbClient.queryObject(Volume.class, vplexVolumeURIs.get(0));
        // Get the storage system for the Vplex.
        StorageSystem vplexSystem = dbClient.queryObject(StorageSystem.class, vplexVolume.getStorageController());
        // And from that a handle to the VplexApiClient
        VPlexApiClient client = getVPlexAPIClient(vplexApiFactory, vplexSystem, dbClient);
        // From that get the Consistency Group, if there is not one, just return success
        if (NullColumnValueGetter.isNullURI(vplexVolume.getConsistencyGroup())) {
            log.info("Volume has no ConsistencyGroup: " + vplexVolume.getLabel());
            WorkflowStepCompleter.stepSucceded(stepId);
            return;
        }
        BlockConsistencyGroup cg = dbClient.queryObject(BlockConsistencyGroup.class, vplexVolume.getConsistencyGroup());
        // Get the consistency group parameters.
        ClusterConsistencyGroupWrapper clusterConsistencyGroup = getClusterConsistencyGroup(vplexVolume, cg);
        String cgName = clusterConsistencyGroup.getCgName();
        String clusterName = clusterConsistencyGroup.getClusterName();
        boolean isDistributed = clusterConsistencyGroup.isDistributed();
        // Make the call to update the consistency group read-only status
        client.updateConsistencyGroupReadOnly(cgName, clusterName, isDistributed, isReadOnly);
        // Complete the step
        WorkflowStepCompleter.stepSucceded(stepId);
    } catch (VPlexApiException ex) {
        if (ServiceCode.VPLEX_API_FIRMWARE_UPDATE_NEEDED.equals(ex.getServiceCode())) {
            // The firmware doesn't support read-only flag, inform the user, but do not fail.
            WorkflowStepCompleter.stepSucceeded(stepId, ex.getLocalizedMessage());
        } else {
            log.info("Exception setting Consistency Group read-only state: " + ex.getMessage());
            ServiceError svcError = VPlexApiException.errors.jobFailed(ex);
            WorkflowStepCompleter.stepFailed(stepId, svcError);
        }
    } catch (Exception ex) {
        log.info("Exception setting Consistency Group read-only state: " + ex.getMessage());
        ServiceError svcError = VPlexApiException.errors.jobFailed(ex);
        WorkflowStepCompleter.stepFailed(stepId, svcError);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) ClusterConsistencyGroupWrapper(com.emc.storageos.volumecontroller.impl.utils.ClusterConsistencyGroupWrapper) Volume(com.emc.storageos.db.client.model.Volume) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient) WorkflowException(com.emc.storageos.workflow.WorkflowException) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) InternalServerErrorException(com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup)

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