Search in sources :

Example 31 with WorkflowException

use of com.emc.storageos.workflow.WorkflowException in project coprhd-controller by CoprHD.

the class AbstractConsistencyGroupManager method removeVolumesFromCG.

/**
 * The method called by the workflow to remove VPLEX volumes from a VPLEX
 * consistency group.
 *
 * @param vplexURI The URI of the VPLEX storage system.
 * @param cgURI The URI of the consistency group.
 * @param vplexVolumeURIs The URIs of the volumes to be removed from the
 *            consistency group.
 * @param stepId The workflow step id.
 *
 * @throws WorkflowException When an error occurs updating the workflow step
 *             state.
 */
public void removeVolumesFromCG(URI vplexURI, URI cgURI, List<URI> vplexVolumeURIs, String stepId) throws WorkflowException {
    try {
        // Update workflow step.
        WorkflowStepCompleter.stepExecuting(stepId);
        log.info("Updated workflow step state to execute for remove volumes from consistency group.");
        ServiceCoded codedError = removeVolumesFromCGInternal(vplexURI, cgURI, vplexVolumeURIs);
        if (codedError != null) {
            WorkflowStepCompleter.stepFailed(stepId, codedError);
        } else {
            WorkflowStepCompleter.stepSucceded(stepId);
        }
    } catch (Exception ex) {
        log.error("Exception removing volumes from consistency group: " + ex.getMessage(), ex);
        String opName = ResourceOperationTypeEnum.DELETE_CG_VOLUME.getName();
        ServiceError serviceError = VPlexApiException.errors.removeVolumesFromCGFailed(opName, ex);
        WorkflowStepCompleter.stepFailed(stepId, serviceError);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) ServiceCoded(com.emc.storageos.svcs.errorhandling.model.ServiceCoded) 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)

Example 32 with WorkflowException

use of com.emc.storageos.workflow.WorkflowException in project coprhd-controller by CoprHD.

the class RPVplexConsistencyGroupManager method createCG.

/**
 * Called by the workflow to create a new VPLEX consistency group.
 *
 * @param vplexURI The URI of the VPLEX storage system.
 * @param cgURI The URI of the Bourne consistency group
 * @param vplexVolumeURIs The list of URIs of the VPLEX volumes being
 *            added to the vplex CG
 * @param stepId The workflow step id.
 *
 * @throws WorkflowException When an error occurs updating the workflow step
 *             state.
 */
public void createCG(URI vplexURI, URI cgURI, Collection<URI> vplexVolumeURIs, String stepId) throws WorkflowException {
    try {
        // Update workflow step.
        WorkflowStepCompleter.stepExecuting(stepId);
        log.info("Updated step state for consistency group creation to execute.");
        if (vplexVolumeURIs == null || vplexVolumeURIs.isEmpty()) {
            log.info("empty volume list; no CG will be created");
            // Update workflow step state to success.
            WorkflowStepCompleter.stepSucceded(stepId);
            log.info("Updated workflow step for consistency group creation to success.");
            return;
        }
        // Get the API client.
        StorageSystem vplexSystem = getDataObject(StorageSystem.class, vplexURI, dbClient);
        VPlexApiClient client = getVPlexAPIClient(vplexApiFactory, vplexSystem, dbClient);
        log.debug("Got VPLEX API client.");
        // For the following cases we need special steps for the CG to choose the HA side/leg on the VPLEX to be the winner:
        // 1. In an RP+VPLEX distributed setup, the user can choose to protect only the HA side.
        // 2. In a MetroPoint setup, the user can choose the HA side as the Active side.
        // Get the first source volume
        Volume firstVplexVolume = null;
        for (URI volURI : vplexVolumeURIs) {
            Volume vol = dbClient.queryObject(Volume.class, volURI);
            if (vol != null && PersonalityTypes.SOURCE.name().equalsIgnoreCase(vol.getPersonality())) {
                // found the first source volume so break
                firstVplexVolume = vol;
                break;
            }
        }
        if (firstVplexVolume != null && NullColumnValueGetter.isNotNullValue(firstVplexVolume.getPersonality()) && firstVplexVolume.getPersonality().equals(PersonalityTypes.SOURCE.toString())) {
            VirtualPool vpool = getDataObject(VirtualPool.class, firstVplexVolume.getVirtualPool(), dbClient);
            boolean haIsWinningCluster = VirtualPool.isRPVPlexProtectHASide(vpool) || (vpool.getMetroPoint() && NullColumnValueGetter.isNotNullValue(vpool.getHaVarrayConnectedToRp()));
            if (haIsWinningCluster) {
                log.info("Force HA side as winning cluster for VPLEX CG.");
                // Temporarily change the varray to the HA varray.
                // NOTE: Do not persist!
                firstVplexVolume.setLabel("DO NOT PERSIST THIS VOLUME");
                firstVplexVolume.setVirtualArray(URI.create(vpool.getHaVarrayConnectedToRp()));
            }
        }
        // acquire a lock to serialize create cg requests to the VPLEX
        List<String> lockKeys = new ArrayList<String>();
        lockKeys.add(ControllerLockingUtil.getConsistencyGroupStorageKey(dbClient, cgURI, vplexURI));
        workflowService.acquireWorkflowStepLocks(stepId, lockKeys, LockTimeoutValue.get(LockType.RP_VPLEX_CG));
        // Get the consistency group
        BlockConsistencyGroup cg = getDataObject(BlockConsistencyGroup.class, cgURI, dbClient);
        // group the volumes by the cluster/CG that they will go in
        Map<String, List<URI>> cgToVolListMap = new HashMap<String, List<URI>>();
        for (URI vplexVolumeURI : vplexVolumeURIs) {
            Volume vplexVolume = getDataObject(Volume.class, vplexVolumeURI, dbClient);
            // Lets determine the VPlex consistency group that need to be created for this volume.
            ClusterConsistencyGroupWrapper clusterConsistencyGroup = getClusterConsistencyGroup(vplexVolume, cg);
            String cgName = clusterConsistencyGroup.getCgName();
            String clusterName = clusterConsistencyGroup.getClusterName();
            boolean isDistributed = clusterConsistencyGroup.isDistributed();
            String cgKey = String.format("%s:%s:%s", cgName, clusterName, (isDistributed ? "dist" : "local"));
            if (!cgToVolListMap.containsKey(cgKey)) {
                cgToVolListMap.put(cgKey, new ArrayList<URI>());
            }
            cgToVolListMap.get(cgKey).add(vplexVolumeURI);
        }
        // loop through each cluster/CG; create the CG and add the volumes
        for (Entry<String, List<URI>> entry : cgToVolListMap.entrySet()) {
            String[] elems = StringUtils.delimitedListToStringArray(entry.getKey(), ":");
            if (elems.length != 3) {
                // serious coding error see above loop which creates the key
                log.error("Error in vplex cg mapping key. Expect <cgname>:<clustername>:<dist|local>; got: " + entry.getKey());
                continue;
            }
            String cgName = elems[0];
            String clusterName = elems[1];
            boolean isDistributed = elems[2].equals("dist");
            // Verify that the VPlex CG has been created for this VPlex system and cluster.
            if (!BlockConsistencyGroupUtils.isVplexCgCreated(cg, vplexURI.toString(), clusterName, cgName, isDistributed)) {
                createVplexCG(vplexSystem, client, cg, firstVplexVolume, cgName, clusterName, isDistributed);
            } else {
                modifyCGSettings(client, cgName, clusterName, isDistributed);
            }
            addVolumesToCG(cgURI, entry.getValue(), cgName, clusterName, client);
        }
        // Update workflow step state to success.
        WorkflowStepCompleter.stepSucceded(stepId);
        log.info("Updated workflow step for consistency group creation to success.");
    } catch (Exception ex) {
        log.error("Exception creating consistency group: " + ex.getMessage(), ex);
        ServiceError serviceError = VPlexApiException.errors.jobFailed(ex);
        WorkflowStepCompleter.stepFailed(stepId, serviceError);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) ClusterConsistencyGroupWrapper(com.emc.storageos.volumecontroller.impl.utils.ClusterConsistencyGroupWrapper) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) URI(java.net.URI) WorkflowException(com.emc.storageos.workflow.WorkflowException) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) Volume(com.emc.storageos.db.client.model.Volume) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient) ArrayList(java.util.ArrayList) List(java.util.List) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 33 with WorkflowException

use of com.emc.storageos.workflow.WorkflowException in project coprhd-controller by CoprHD.

the class VPlexConsistencyGroupManager method createCG.

/**
 * Called by the workflow to create a new VPLEX consistency group.
 *
 * @param vplexURI The URI of the VPLEX storage system.
 * @param cgURI The URI of the Bourne consistency group
 * @param vplexVolumeURIs The URI of the VPLEX used to determine the VPlex
 *            cluster/distributed information.
 * @param stepId The workflow step id.
 *
 * @throws WorkflowException When an error occurs updating the workflow step
 *             state.
 */
public void createCG(URI vplexURI, URI cgURI, List<URI> vplexVolumeURIs, String stepId) throws WorkflowException {
    try {
        // Update workflow step.
        WorkflowStepCompleter.stepExecuting(stepId);
        log.info("Updated step state for consistency group creation to execute.");
        // Lock the CG for the step duration.
        List<String> lockKeys = new ArrayList<String>();
        lockKeys.add(ControllerLockingUtil.getConsistencyGroupStorageKey(dbClient, cgURI, vplexURI));
        workflowService.acquireWorkflowStepLocks(stepId, lockKeys, LockTimeoutValue.get(LockType.RP_VPLEX_CG));
        // 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 consistency group
        BlockConsistencyGroup cg = getDataObject(BlockConsistencyGroup.class, cgURI, dbClient);
        // Check to see if it was created since we defined the workflow.
        if (cg.created(vplexURI)) {
            StringSet cgNames = cg.getSystemConsistencyGroups().get(vplexURI.toString());
            log.info("Consistency group(s) already created: " + cgNames.toString());
            if (!cg.getTypes().contains(Types.VPLEX.name())) {
                // SRDF will reset the CG types. If the CG was existing on VPLEX need to make sure it is in types.
                cg.addConsistencyGroupTypes(Types.VPLEX.name());
                dbClient.updateObject(cg);
            }
            WorkflowStepCompleter.stepSucceded(stepId);
            return;
        }
        // We need to know on what cluster to create the consistency group.
        // The cluster would be determined by the virtual array specified in
        // a volume creation request, which is the virtual array of the
        // passed virtual volumes. Get the virtual array for one of the
        // vplex volumes.
        Volume firstVPlexVolume = getDataObject(Volume.class, vplexVolumeURIs.get(0), dbClient);
        // Lets determine the VPlex consistency group that need to be created for this volume.
        ClusterConsistencyGroupWrapper clusterConsistencyGroup = getClusterConsistencyGroup(firstVPlexVolume, cg);
        String cgName = clusterConsistencyGroup.getCgName();
        String clusterName = clusterConsistencyGroup.getClusterName();
        boolean isDistributed = clusterConsistencyGroup.isDistributed();
        URI vaURI = firstVPlexVolume.getVirtualArray();
        log.info("Got virtual array for VPLEX volume.");
        // Now we can create the consistency group.
        client.createConsistencyGroup(cgName, clusterName, isDistributed);
        log.info("Created VPLEX consistency group.");
        // Create the rollback data in case this needs to be deleted.
        VPlexCGRollbackData rbData = new VPlexCGRollbackData();
        rbData.setVplexSystemURI(vplexURI);
        rbData.setCgName(cgName);
        rbData.setClusterName(clusterName);
        rbData.setIsDistributed(new Boolean(getIsCGDistributed(client, cgName, clusterName)));
        workflowService.storeStepData(stepId, rbData);
        // Now update the CG in the DB.
        cg.setVirtualArray(vaURI);
        cg.setStorageController(vplexURI);
        cg.addSystemConsistencyGroup(vplexSystem.getId().toString(), BlockConsistencyGroupUtils.buildClusterCgName(clusterName, cgName));
        cg.addConsistencyGroupTypes(Types.VPLEX.name());
        dbClient.persistObject(cg);
        log.info("Updated consistency group in DB.");
        // Update workflow step state to success.
        WorkflowStepCompleter.stepSucceded(stepId);
        log.info("Updated workflow step for consistency group creation to success.");
    } catch (VPlexApiException vex) {
        log.error("Exception creating consistency group: " + vex.getMessage(), vex);
        WorkflowStepCompleter.stepFailed(stepId, vex);
    } catch (Exception ex) {
        log.error("Exception creating consistency group: " + ex.getMessage(), ex);
        String opName = ResourceOperationTypeEnum.CREATE_CONSISTENCY_GROUP.getName();
        ServiceError serviceError = VPlexApiException.errors.createConsistencyGroupFailed(opName, ex);
        WorkflowStepCompleter.stepFailed(stepId, serviceError);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) ClusterConsistencyGroupWrapper(com.emc.storageos.volumecontroller.impl.utils.ClusterConsistencyGroupWrapper) ArrayList(java.util.ArrayList) URI(java.net.URI) 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) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) 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) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 34 with WorkflowException

use of com.emc.storageos.workflow.WorkflowException in project coprhd-controller by CoprHD.

the class VPlexConsistencyGroupManager method setCGProperties.

/**
 * Called by the workflow to set the properties for an existing VPLEX
 * consistency group with no volumes.
 *
 * @param vplexURI The URI of the VPLEX storage system.
 * @param cgURI The URI of the Bourne consistency group.
 * @param vplexVolumeURIs The URIs of the VPLEX volumes to be added to the
 *            consistency group.
 * @param stepId The workflow step id.
 *
 * @throws WorkflowException When an error occurs updating the workflow step
 *             state.
 */
public void setCGProperties(URI vplexURI, URI cgURI, List<URI> vplexVolumeURIs, String stepId) throws WorkflowException {
    try {
        // Update workflow step.
        WorkflowStepCompleter.stepExecuting(stepId);
        log.info("Updated step state for consistency group properties to execute.");
        // Lock the CG for the step duration.
        List<String> lockKeys = new ArrayList<String>();
        lockKeys.add(ControllerLockingUtil.getConsistencyGroupStorageKey(dbClient, cgURI, vplexURI));
        workflowService.acquireWorkflowStepLocks(stepId, lockKeys, LockTimeoutValue.get(LockType.RP_VPLEX_CG));
        // 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 consistency group
        BlockConsistencyGroup cg = getDataObject(BlockConsistencyGroup.class, cgURI, dbClient);
        // We need to know on what cluster to find the consistency group.
        // The cluster would be determined by the virtual array specified in
        // a volume creation request, which is the virtual array of the
        // passed virtual volumes. Get the virtual array for one of the
        // vplex volumes.
        Volume firstVPlexVolume = getDataObject(Volume.class, vplexVolumeURIs.get(0), dbClient);
        ClusterConsistencyGroupWrapper clusterConsistencyGroup = getClusterConsistencyGroup(firstVPlexVolume, cg);
        String cgName = clusterConsistencyGroup.getCgName();
        String clusterName = clusterConsistencyGroup.getClusterName();
        boolean isDistributed = clusterConsistencyGroup.isDistributed();
        // Now we can update the consistency group properties.
        client.updateConsistencyGroupProperties(cgName, clusterName, isDistributed);
        log.info("Updated VPLEX consistency group properties.");
        // Update workflow step state to success.
        WorkflowStepCompleter.stepSucceded(stepId);
        log.info("Updated workflow step for consistency group properties to success.");
    } catch (VPlexApiException vae) {
        log.error("Exception updating consistency group properties: " + vae.getMessage(), vae);
        WorkflowStepCompleter.stepFailed(stepId, vae);
    } catch (Exception ex) {
        log.error("Exception updating consistency group properties: " + ex.getMessage(), ex);
        ServiceError serviceError = VPlexApiException.errors.jobFailed(ex);
        WorkflowStepCompleter.stepFailed(stepId, serviceError);
    }
}
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) 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) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup)

Example 35 with WorkflowException

use of com.emc.storageos.workflow.WorkflowException in project coprhd-controller by CoprHD.

the class VPlexConsistencyGroupManager method addVplexVolumesToSRDFTargetCG.

/**
 * This workflow step will add vplex volumes fronting an SRDF target volume to the SRDF target consistency group.
 * Note that the SRDF target consistency group may not be created until the SRDF Pairing operation has completed.
 * At this time the underlying SRDF Targets will be associated with the correct CG. For this reason, we don't know
 * what consistency group to associate the Vplex volumes with until the SRDF pairing operation has completed, and
 * the workflow is executing.
 *
 * So here we find the appropriate SRDF target volume(s), determine the CG, and then set up code to
 * create the Vplex CG and add the volume to that.
 *
 * @param vplexURI -- URI of VPlex system
 * @param vplexVolumeURIs -- List of VPLEX Volume URIs fronting SRDF Target volumes
 * @param stepId -- The step ID being processed
 * @throws WorkflowException
 */
public void addVplexVolumesToSRDFTargetCG(URI vplexURI, List<URI> vplexVolumeURIs, String stepId) throws WorkflowException {
    try {
        // Make a map of the VPlex volume to corresponding SRDF volume
        Map<Volume, Volume> vplexToSrdfVolumeMap = VPlexSrdfUtil.makeVplexToSrdfVolumeMap(dbClient, vplexVolumeURIs);
        // Make sure that the SRDF volumes have a consistency group and it is the same.
        URI cgURI = null;
        for (Volume srdfVolume : vplexToSrdfVolumeMap.values()) {
            if (srdfVolume.getConsistencyGroup() != null) {
                if (cgURI == null) {
                    cgURI = srdfVolume.getConsistencyGroup();
                } else {
                    if (srdfVolume.getConsistencyGroup() != cgURI) {
                        log.info("Multiple CGs discovered: " + cgURI.toString() + " " + srdfVolume.getConsistencyGroup().toString());
                    }
                }
            }
        }
        // If there is no consistency group, That is not an error.
        if (cgURI == null) {
            WorkflowStepCompleter.stepSucceded(stepId);
            return;
        }
        // Get the consistency group, and make sure it has requested type Vplex. Change the VPlex volumes to point to the CG.
        BlockConsistencyGroup consistencyGroup = dbClient.queryObject(BlockConsistencyGroup.class, cgURI);
        if (!consistencyGroup.getRequestedTypes().contains(Types.VPLEX)) {
            consistencyGroup.addRequestedTypes(Arrays.asList(Types.VPLEX.name()));
            dbClient.updateObject(consistencyGroup);
        }
        Volume protoVolume = null;
        for (Volume vplexVolume : vplexToSrdfVolumeMap.keySet()) {
            protoVolume = vplexVolume;
            break;
        }
        StorageSystem vplexSystem = dbClient.queryObject(StorageSystem.class, protoVolume.getStorageController());
        // and we return.
        if (createVplexCG(vplexSystem, consistencyGroup, protoVolume, stepId) == false) {
            return;
        }
        // Add the Vplex volumes to the CG, and fire off the Step completer.
        addVolumesToCG(vplexSystem, consistencyGroup, vplexToSrdfVolumeMap.keySet(), stepId);
    } catch (Exception ex) {
        log.info("Exception adding Vplex volumes to SRDF Target CG: " + ex.getMessage(), ex);
        ServiceError svcError = VPlexApiException.errors.jobFailed(ex);
        WorkflowStepCompleter.stepFailed(stepId, svcError);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) Volume(com.emc.storageos.db.client.model.Volume) URI(java.net.URI) 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) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Aggregations

WorkflowException (com.emc.storageos.workflow.WorkflowException)38 ControllerException (com.emc.storageos.volumecontroller.ControllerException)36 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)34 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)34 VPlexApiException (com.emc.storageos.vplex.api.VPlexApiException)34 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)31 InternalServerErrorException (com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException)31 VPlexApiClient (com.emc.storageos.vplex.api.VPlexApiClient)29 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)27 IOException (java.io.IOException)27 URISyntaxException (java.net.URISyntaxException)27 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)26 Volume (com.emc.storageos.db.client.model.Volume)24 URI (java.net.URI)21 ArrayList (java.util.ArrayList)18 NamedURI (com.emc.storageos.db.client.model.NamedURI)16 VPlexVirtualVolumeInfo (com.emc.storageos.vplex.api.VPlexVirtualVolumeInfo)10 ExportGroup (com.emc.storageos.db.client.model.ExportGroup)8 VplexMirror (com.emc.storageos.db.client.model.VplexMirror)8 ExportMask (com.emc.storageos.db.client.model.ExportMask)7