Search in sources :

Example 16 with BlockObject

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

the class BlockConsistencyGroupService method updateConsistencyGroup.

/**
 * Update the specified consistency group
 *
 * @prereq none
 *
 * @param id the URN of a ViPR Consistency group
 *
 * @brief Update consistency group
 * @return TaskResourceRep
 */
@PUT
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}")
@CheckPermission(roles = { Role.TENANT_ADMIN }, acls = { ACL.OWN, ACL.ALL })
public TaskResourceRep updateConsistencyGroup(@PathParam("id") final URI id, final BlockConsistencyGroupUpdate param) {
    // Get the consistency group.
    BlockConsistencyGroup consistencyGroup = (BlockConsistencyGroup) queryResource(id);
    StorageDriverManager storageDriverManager = (StorageDriverManager) StorageDriverManager.getApplicationContext().getBean(StorageDriverManager.STORAGE_DRIVER_MANAGER);
    // Verify a volume was specified to be added or removed.
    if (!param.hasEitherAddOrRemoveVolumes()) {
        throw APIException.badRequests.noVolumesToBeAddedRemovedFromCG();
    }
    // TODO require a check if requested list contains all volumes/replicas?
    // For replicas, check replica count with volume count in CG
    StorageSystem cgStorageSystem = null;
    // Throw exception if the operation is attempted on volumes that are in RP CG.
    if (consistencyGroup.isRPProtectedCG()) {
        throw APIException.badRequests.operationNotAllowedOnRPVolumes();
    }
    // This method also supports adding volumes or replicas to CG (VMAX - SMIS 8.0.x)
    if ((!consistencyGroup.created() || NullColumnValueGetter.isNullURI(consistencyGroup.getStorageController())) && param.hasVolumesToAdd()) {
        // we just need to check the case of add volumes in this case
        BlockObject bo = BlockObject.fetch(_dbClient, param.getAddVolumesList().getVolumes().get(0));
        cgStorageSystem = _permissionsHelper.getObjectById(bo.getStorageController(), StorageSystem.class);
    } else {
        cgStorageSystem = _permissionsHelper.getObjectById(consistencyGroup.getStorageController(), StorageSystem.class);
    }
    // IBMXIV, XtremIO, VPlex, VNX, ScaleIO, and VMax volumes only
    String systemType = cgStorageSystem.getSystemType();
    if (!storageDriverManager.isDriverManaged(cgStorageSystem.getSystemType())) {
        if (!systemType.equals(DiscoveredDataObject.Type.vplex.name()) && !systemType.equals(DiscoveredDataObject.Type.vnxblock.name()) && !systemType.equals(DiscoveredDataObject.Type.vmax.name()) && !systemType.equals(DiscoveredDataObject.Type.vnxe.name()) && !systemType.equals(DiscoveredDataObject.Type.unity.name()) && !systemType.equals(DiscoveredDataObject.Type.ibmxiv.name()) && !systemType.equals(DiscoveredDataObject.Type.scaleio.name()) && !systemType.equals(DiscoveredDataObject.Type.xtremio.name())) {
            throw APIException.methodNotAllowed.notSupported();
        }
    }
    // Get the specific BlockServiceApiImpl based on the storage system type.
    BlockServiceApi blockServiceApiImpl = getBlockServiceImpl(cgStorageSystem);
    List<URI> volIds = null;
    Set<URI> addSet = new HashSet<URI>();
    boolean isReplica = true;
    if (param.hasVolumesToAdd()) {
        volIds = param.getAddVolumesList().getVolumes();
        addSet.addAll(volIds);
        URI volId = volIds.get(0);
        if (URIUtil.isType(volId, Volume.class)) {
            Volume volume = _permissionsHelper.getObjectById(volId, Volume.class);
            ArgValidator.checkEntity(volume, volId, false);
            if (!BlockFullCopyUtils.isVolumeFullCopy(volume, _dbClient)) {
                isReplica = false;
            }
        }
    }
    List<Volume> cgVolumes = blockServiceApiImpl.getActiveCGVolumes(consistencyGroup);
    // check if add volume list is same as existing volumes in CG
    boolean volsAlreadyInCG = false;
    if (!isReplica && cgVolumes != null && !cgVolumes.isEmpty()) {
        Collection<URI> cgVolIds = transform(cgVolumes, fctnDataObjectToID());
        if (addSet.size() == cgVolIds.size()) {
            volsAlreadyInCG = addSet.containsAll(cgVolIds);
        }
    }
    // Verify that the add and remove lists do not contain the same volume.
    if (param.hasBothAddAndRemoveVolumes()) {
        /*
             * Make sure the add and remove lists are unique by getting the intersection and
             * verifying the size is 0.
             */
        Set<URI> removeSet = new HashSet<URI>(param.getRemoveVolumesList().getVolumes());
        addSet.retainAll(removeSet);
        if (!addSet.isEmpty()) {
            throw APIException.badRequests.sameVolumesInAddRemoveList();
        }
    }
    if (cgStorageSystem.getUsingSmis80() && cgStorageSystem.deviceIsType(Type.vmax)) {
        // CG can have replicas
        if (_log.isDebugEnabled()) {
            _log.debug("CG can have replicas for VMAX with SMI-S 8.x");
        }
    } else if (param.hasVolumesToRemove() || (!isReplica && !volsAlreadyInCG)) {
        // CG cannot have replicas when adding/removing volumes to/from CG
        // Check snapshots
        // Adding/removing volumes to/from a consistency group
        // is not supported when the consistency group has active
        // snapshots.
        URIQueryResultList cgSnapshotsResults = new URIQueryResultList();
        _dbClient.queryByConstraint(getBlockSnapshotByConsistencyGroup(id), cgSnapshotsResults);
        Iterator<URI> cgSnapshotsIter = cgSnapshotsResults.iterator();
        while (cgSnapshotsIter.hasNext()) {
            BlockSnapshot cgSnapshot = _dbClient.queryObject(BlockSnapshot.class, cgSnapshotsIter.next());
            if ((cgSnapshot != null) && (!cgSnapshot.getInactive())) {
                throw APIException.badRequests.notAllowedWhenCGHasSnapshots();
            }
        }
        // VNX group clones and mirrors are just list of replicas, no corresponding group on array side
        if (!cgStorageSystem.deviceIsType(Type.vnxblock)) {
            // is not supported when existing volumes in CG have mirrors.
            if (cgVolumes != null && !cgVolumes.isEmpty()) {
                Volume firstVolume = cgVolumes.get(0);
                StringSet mirrors = firstVolume.getMirrors();
                if (mirrors != null && !mirrors.isEmpty()) {
                    throw APIException.badRequests.notAllowedWhenCGHasMirrors();
                }
            }
            // Check clones
            // Adding/removing volumes to/from a consistency group
            // is not supported when the consistency group has
            // volumes with full copies to which they are still
            // attached or has volumes that are full copies that
            // are still attached to their source volumes.
            getFullCopyManager().verifyConsistencyGroupCanBeUpdated(consistencyGroup, cgVolumes);
        }
    }
    // Verify the volumes to be removed.
    List<URI> removeVolumesList = new ArrayList<URI>();
    if (param.hasVolumesToRemove()) {
        for (URI volumeURI : param.getRemoveVolumesList().getVolumes()) {
            // Validate the volume to be removed exists.
            if (URIUtil.isType(volumeURI, Volume.class)) {
                Volume volume = _permissionsHelper.getObjectById(volumeURI, Volume.class);
                ArgValidator.checkEntity(volume, volumeURI, false);
                /**
                 * Remove SRDF volume from CG is not supported.
                 */
                if (volume.checkForSRDF()) {
                    throw APIException.badRequests.notAllowedOnSRDFConsistencyGroups();
                }
                if (!BlockFullCopyUtils.isVolumeFullCopy(volume, _dbClient)) {
                    blockServiceApiImpl.verifyRemoveVolumeFromCG(volume, cgVolumes);
                }
            }
            removeVolumesList.add(volumeURI);
        }
    }
    URI xivPoolURI = null;
    if (systemType.equals(DiscoveredDataObject.Type.ibmxiv.name()) && !cgVolumes.isEmpty()) {
        Volume firstVolume = cgVolumes.get(0);
        xivPoolURI = firstVolume.getPool();
    }
    // Verify the volumes to be added.
    List<URI> addVolumesList = new ArrayList<URI>();
    List<Volume> volumes = new ArrayList<Volume>();
    if (param.hasVolumesToAdd()) {
        for (URI volumeURI : param.getAddVolumesList().getVolumes()) {
            // Validate the volume to be added exists.
            Volume volume = null;
            if (!isReplica) {
                volume = _permissionsHelper.getObjectById(volumeURI, Volume.class);
                ArgValidator.checkEntity(volume, volumeURI, false);
                blockServiceApiImpl.verifyAddVolumeToCG(volume, consistencyGroup, cgVolumes, cgStorageSystem);
                volumes.add(volume);
            } else {
                verifyAddReplicaToCG(volumeURI, consistencyGroup, cgStorageSystem);
            }
            // IBM XIV specific checking
            if (systemType.equals(DiscoveredDataObject.Type.ibmxiv.name())) {
                // all volumes should be on the same storage pool
                if (xivPoolURI == null) {
                    xivPoolURI = volume.getPool();
                } else {
                    if (!xivPoolURI.equals(volume.getPool())) {
                        throw APIException.badRequests.invalidParameterIBMXIVConsistencyGroupVolumeNotInPool(volumeURI, xivPoolURI);
                    }
                }
            }
            // Add the volume to list.
            addVolumesList.add(volumeURI);
        }
        if (!volumes.isEmpty()) {
            blockServiceApiImpl.verifyReplicaCount(volumes, cgVolumes, volsAlreadyInCG);
        }
    }
    // Create the task id;
    String taskId = UUID.randomUUID().toString();
    // Call the block service API to update the consistency group.
    return blockServiceApiImpl.updateConsistencyGroup(cgStorageSystem, cgVolumes, consistencyGroup, addVolumesList, removeVolumesList, taskId);
}
Also used : BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) ArrayList(java.util.ArrayList) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) MapBlockConsistencyGroup(com.emc.storageos.api.mapper.functions.MapBlockConsistencyGroup) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) StorageDriverManager(com.emc.storageos.services.util.StorageDriverManager) Volume(com.emc.storageos.db.client.model.Volume) Iterator(java.util.Iterator) StringSet(com.emc.storageos.db.client.model.StringSet) BlockObject(com.emc.storageos.db.client.model.BlockObject) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) HashSet(java.util.HashSet) Path(javax.ws.rs.Path) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) PUT(javax.ws.rs.PUT) CheckPermission(com.emc.storageos.security.authorization.CheckPermission)

Example 17 with BlockObject

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

the class BlockConsistencyGroupService method verifyAddReplicaToCG.

/**
 * Validates the replicas to be added to Consistency group.
 * - verifies that the replicas are not internal objects,
 * - checks if the given CG is its source volume's CG,
 * - validates that the replica is not in any other CG,
 * - verifies the project for the replicas to be added is same
 * as the project for the consistency group.
 */
private void verifyAddReplicaToCG(URI blockURI, BlockConsistencyGroup cg, StorageSystem cgStorageSystem) {
    BlockObject blockObject = BlockObject.fetch(_dbClient, blockURI);
    // Don't allow partially ingested object to be added to CG.
    BlockServiceUtils.validateNotAnInternalBlockObject(blockObject, false);
    URI sourceVolumeURI = null;
    URI blockProjectURI = null;
    if (blockObject instanceof BlockSnapshot) {
        BlockSnapshot snapshot = (BlockSnapshot) blockObject;
        blockProjectURI = snapshot.getProject().getURI();
        sourceVolumeURI = snapshot.getParent().getURI();
    } else if (blockObject instanceof BlockMirror) {
        BlockMirror mirror = (BlockMirror) blockObject;
        blockProjectURI = mirror.getProject().getURI();
        sourceVolumeURI = mirror.getSource().getURI();
    } else if (blockObject instanceof Volume) {
        Volume volume = (Volume) blockObject;
        blockProjectURI = volume.getProject().getURI();
        sourceVolumeURI = volume.getAssociatedSourceVolume();
    }
    // check if the given CG is its source volume's CG
    Volume sourceVolume = null;
    if (!NullColumnValueGetter.isNullURI(sourceVolumeURI)) {
        sourceVolume = _dbClient.queryObject(Volume.class, sourceVolumeURI);
    }
    if (sourceVolume == null || !cg.getId().equals(sourceVolume.getConsistencyGroup())) {
        throw APIException.badRequests.invalidParameterSourceVolumeNotInGivenConsistencyGroup(sourceVolumeURI, cg.getId());
    }
    // Validate that the replica is not in any other CG.
    if (!NullColumnValueGetter.isNullURI(blockObject.getConsistencyGroup()) && !cg.getId().equals(blockObject.getConsistencyGroup())) {
        throw APIException.badRequests.invalidParameterVolumeAlreadyInAConsistencyGroup(cg.getId(), blockObject.getConsistencyGroup());
    }
    // Verify the project for the replicas to be added is same
    // as the project for the consistency group.
    URI cgProjectURI = cg.getProject().getURI();
    if (!blockProjectURI.equals(cgProjectURI)) {
        List<Project> projects = _dbClient.queryObjectField(Project.class, "label", Arrays.asList(cgProjectURI, blockProjectURI));
        throw APIException.badRequests.consistencyGroupAddVolumeThatIsInDifferentProject(blockObject.getLabel(), projects.get(0).getLabel(), projects.get(1).getLabel());
    }
}
Also used : Project(com.emc.storageos.db.client.model.Project) BlockMirror(com.emc.storageos.db.client.model.BlockMirror) Volume(com.emc.storageos.db.client.model.Volume) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) BlockObject(com.emc.storageos.db.client.model.BlockObject)

Example 18 with BlockObject

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

the class BlockSnapshotService method queryResource.

@Override
protected BlockObject queryResource(URI id) {
    ArgValidator.checkUri(id);
    BlockObject blockObj = BlockObject.fetch(_dbClient, id);
    ArgValidator.checkEntityNotNull(blockObj, id, isIdEmbeddedInURL(id));
    return blockObj;
}
Also used : BlockObject(com.emc.storageos.db.client.model.BlockObject)

Example 19 with BlockObject

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

the class ExportGroupService method validateVolumesNotMounted.

/**
 * Verify that none of the volumes in the export group are mounted.
 * Unexporting a mounted volume is dangerous and should be avoided.
 *
 * @param exportGroup
 *            export group
 * @param boURIList
 *            URI list of block objects
 */
private void validateVolumesNotMounted(ExportGroup exportGroup, List<URI> boURIList) {
    if (exportGroup == null) {
        throw APIException.badRequests.exportGroupContainsMountedVolumesInvalidParam();
    }
    Map<URI, String> boToLabelMap = new HashMap<>();
    // It is valid for there to be no storage volumes in the EG, so only perform the check if there are volumes
    if (boURIList != null) {
        for (URI boID : boURIList) {
            BlockObject bo = BlockObject.fetch(_dbClient, boID);
            if (bo != null && bo.getTag() != null) {
                ScopedLabelSet tagSet = bo.getTag();
                Iterator<ScopedLabel> tagIter = tagSet.iterator();
                while (tagIter.hasNext()) {
                    ScopedLabel sl = tagIter.next();
                    if (sl.getLabel() != null && (sl.getLabel().startsWith(MOUNTPOINT) || sl.getLabel().startsWith(VMFS_DATASTORE))) {
                        if (exportGroup.getClusters() != null) {
                            for (String clusterID : exportGroup.getClusters()) {
                                if (sl.getLabel().contains(clusterID)) {
                                    boToLabelMap.put(boID, bo.forDisplay());
                                }
                            }
                        }
                        if (exportGroup.getHosts() != null) {
                            for (String hostID : exportGroup.getHosts()) {
                                if (sl.getLabel().contains(hostID)) {
                                    boToLabelMap.put(boID, bo.forDisplay());
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    if (!boToLabelMap.isEmpty()) {
        _log.error("Export Group {} has volumes {} that are marked as mounted.  It is recommended to unmount via controller before unexport.  This validation check can be disabled if needed.  Contact EMC Support.", exportGroup.getId(), Joiner.on(",").join(boToLabelMap.values()));
        ValidatorConfig vc = new ValidatorConfig();
        vc.setCoordinator(_coordinator);
        if (vc.isValidationEnabled()) {
            throw APIException.badRequests.exportGroupContainsMountedVolumes(exportGroup.getId(), Joiner.on(",").join(boToLabelMap.values()));
        }
    }
}
Also used : HashMap(java.util.HashMap) ScopedLabel(com.emc.storageos.db.client.model.ScopedLabel) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) BlockObject(com.emc.storageos.db.client.model.BlockObject) ScopedLabelSet(com.emc.storageos.db.client.model.ScopedLabelSet) ValidatorConfig(com.emc.storageos.volumecontroller.impl.validators.ValidatorConfig)

Example 20 with BlockObject

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

the class BlockOrchestrationDeviceController method restoreFromFullCopy.

@Override
public void restoreFromFullCopy(URI storage, List<URI> fullCopyURIs, String taskId) throws InternalException {
    CloneRestoreCompleter completer = new CloneRestoreCompleter(fullCopyURIs, taskId);
    // add the CG to the completer if this is a CG restore
    Iterator<Volume> iter = getDbClient().queryIterativeObjects(Volume.class, fullCopyURIs);
    while (iter.hasNext()) {
        Volume fc = iter.next();
        if (!NullColumnValueGetter.isNullURI(fc.getAssociatedSourceVolume())) {
            BlockObject firstSource = BlockObject.fetch(getDbClient(), fc.getAssociatedSourceVolume());
            if (firstSource != null) {
                if (firstSource instanceof Volume && !NullColumnValueGetter.isNullURI(firstSource.getConsistencyGroup())) {
                    completer.addConsistencyGroupId(firstSource.getConsistencyGroup());
                }
                break;
            }
        }
    }
    s_logger.info("Creating steps for restore from full copy.");
    try {
        // Validate the volume identities before proceeding
        validator.volumeURIs(fullCopyURIs, true, true, ValCk.ID, ValCk.VPLEX);
        // Generate the Workflow.
        Workflow workflow = _workflowService.getNewWorkflow(this, RESTORE_FROM_FULLCOPY_WF_NAME, true, taskId);
        // the wait for key returned by previous call
        String waitFor = null;
        // First, call the RP controller to add RP steps for volume restore
        waitFor = _rpDeviceController.addPreRestoreFromFullcopySteps(workflow, waitFor, storage, fullCopyURIs, taskId);
        // Call the VplexDeviceController to add its steps for restore volume from full copy
        waitFor = _vplexDeviceController.addStepsForRestoreFromFullcopy(workflow, waitFor, storage, fullCopyURIs, taskId, completer);
        // Call the BlockDeviceController to add its steps for restore volume from full copy
        waitFor = _blockDeviceController.addStepsForRestoreFromFullcopy(workflow, waitFor, storage, fullCopyURIs, taskId, completer);
        // Call the RPDeviceController to add its steps for post restore volume from full copy
        waitFor = _rpDeviceController.addPostRestoreFromFullcopySteps(workflow, waitFor, storage, fullCopyURIs, taskId);
        // Finish up and execute the plan.
        // The Workflow will handle the TaskCompleter
        String successMessage = "Restore from full copy completed successfully";
        Object[] callbackArgs = new Object[] { new ArrayList<URI>(fullCopyURIs) };
        workflow.executePlan(completer, successMessage, new WorkflowCallback(), callbackArgs, null, null);
    } catch (Exception ex) {
        s_logger.error("Could not restore volume: ", ex);
        ServiceError serviceError = DeviceControllerException.errors.jobFailed(ex);
        completer.error(s_dbClient, _locker, serviceError);
    }
}
Also used : CloneRestoreCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.CloneRestoreCompleter) ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) Volume(com.emc.storageos.db.client.model.Volume) ArrayList(java.util.ArrayList) Workflow(com.emc.storageos.workflow.Workflow) BlockObject(com.emc.storageos.db.client.model.BlockObject) BlockObject(com.emc.storageos.db.client.model.BlockObject) WorkflowException(com.emc.storageos.workflow.WorkflowException) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) LockRetryException(com.emc.storageos.locking.LockRetryException)

Aggregations

BlockObject (com.emc.storageos.db.client.model.BlockObject)341 URI (java.net.URI)222 ArrayList (java.util.ArrayList)152 Volume (com.emc.storageos.db.client.model.Volume)141 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)109 NamedURI (com.emc.storageos.db.client.model.NamedURI)82 HashMap (java.util.HashMap)82 BlockSnapshot (com.emc.storageos.db.client.model.BlockSnapshot)69 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)65 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)60 ExportMask (com.emc.storageos.db.client.model.ExportMask)56 HashSet (java.util.HashSet)56 ExportGroup (com.emc.storageos.db.client.model.ExportGroup)48 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)45 CIMObjectPath (javax.cim.CIMObjectPath)44 Initiator (com.emc.storageos.db.client.model.Initiator)43 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)43 List (java.util.List)40 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)38 StringSet (com.emc.storageos.db.client.model.StringSet)36