Search in sources :

Example 91 with VirtualPool

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

the class VirtualPoolService method getVirtualPoolList.

protected VirtualPoolList getVirtualPoolList(VirtualPool.Type type, String shortVdcId, String tenantId) {
    URIQueryResultList vpoolList = new URIQueryResultList();
    VirtualPoolList list = new VirtualPoolList();
    TenantOrg tenant_input = null;
    // if input tenant is not empty, but user have no access to it, return empty list.
    if (!StringUtils.isEmpty(tenantId)) {
        tenant_input = getTenantIfHaveAccess(tenantId);
        if (tenant_input == null) {
            return list;
        }
    }
    StorageOSUser user = getUserFromContext();
    List<VirtualPool> vpoolObjects = null;
    if (_geoHelper.isLocalVdcId(shortVdcId)) {
        _log.debug("retrieving virtual pools via the dbclient");
        _dbClient.queryByConstraint(AlternateIdConstraint.Factory.getVpoolTypeVpoolConstraint(type), vpoolList);
        List<URI> allowed = new ArrayList<URI>();
        for (URI vpool : vpoolList) {
            allowed.add(vpool);
        }
        vpoolObjects = _dbClient.queryObject(VirtualPool.class, allowed);
    } else {
        _log.debug("retrieving virtual pools via the geoclient");
        GeoServiceClient geoClient = _geoHelper.getClient(shortVdcId);
        try {
            // TODO: query by constraint isn't working on the geosvc
            // List<URI> resultList = geoClient.queryByConstraint(AlternateIdConstraint.Factory.getVpoolTypeVpoolConstraint(type),
            // URIQueryResultList.class);
            Iterator<URI> uriIter = geoClient.queryByType(VirtualPool.class, true);
            List<URI> resultList = Lists.newArrayList(uriIter);
            Iterator<VirtualPool> iter = geoClient.queryObjects(VirtualPool.class, resultList);
            // iter);
            vpoolObjects = Lists.newArrayList();
            while (iter.hasNext()) {
                VirtualPool p = iter.next();
                if (type.toString().equals(p.getType())) {
                    vpoolObjects.add(p);
                }
            }
        } catch (Exception ex) {
            // TODO: revisit this exception
            _log.error("error retrieving virtual pools from vdc " + shortVdcId, ex);
            throw APIException.internalServerErrors.genericApisvcError("error retrieving remote pools", ex);
        }
    }
    // else only return the list, which input tenant has access.
    if (_permissionsHelper.userHasGivenRole(user, null, Role.SYSTEM_ADMIN, Role.SYSTEM_MONITOR)) {
        for (VirtualPool virtualPool : vpoolObjects) {
            if (tenant_input == null || _permissionsHelper.tenantHasUsageACL(tenant_input.getId(), virtualPool)) {
                list.getVirtualPool().add(toVirtualPoolResource(virtualPool));
            }
        }
    } else {
        // otherwise, filter by only authorized to use
        URI tenant = null;
        if (tenant_input == null) {
            tenant = URI.create(user.getTenantId());
        } else {
            tenant = tenant_input.getId();
        }
        Set<VirtualPool> vpoolSet = new HashSet<VirtualPool>();
        for (VirtualPool virtualPool : vpoolObjects) {
            if (_permissionsHelper.tenantHasUsageACL(tenant, virtualPool)) {
                vpoolSet.add(virtualPool);
            }
        }
        // if no tenant specified in request, also adding vpools which sub-tenants of the user have access to.
        if (tenant_input == null) {
            List<URI> subtenants = _permissionsHelper.getSubtenantsWithRoles(user);
            for (VirtualPool virtualPool : vpoolObjects) {
                if (_permissionsHelper.tenantHasUsageACL(subtenants, virtualPool)) {
                    vpoolSet.add(virtualPool);
                }
            }
        }
        for (VirtualPool virtualPool : vpoolSet) {
            list.getVirtualPool().add(toVirtualPoolResource(virtualPool));
        }
    }
    return list;
}
Also used : ArrayList(java.util.ArrayList) GeoServiceClient(com.emc.storageos.security.geo.GeoServiceClient) VirtualPoolList(com.emc.storageos.model.vpool.VirtualPoolList) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) URI(java.net.URI) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) APIException(com.emc.storageos.svcs.errorhandling.resources.APIException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) StorageOSUser(com.emc.storageos.security.authentication.StorageOSUser) TenantOrg(com.emc.storageos.db.client.model.TenantOrg) HashSet(java.util.HashSet)

Example 92 with VirtualPool

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

the class SnapshotService method createSnapshot.

/**
 * The snapshot of a volume in Block Store is a point in time copy of the
 * volume. This API allows the user to create snapshot of a volume
 * NOTE: This is an asynchronous operation.
 *
 * @prereq none
 *
 * @param param
 *            POST data containing the snapshot creation information.
 *
 * @brief Create snapshot
 * @return Details of the newly created snapshot
 * @throws InternalException
 */
@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response createSnapshot(@PathParam("tenant_id") String openstack_tenant_id, SnapshotCreateRequestGen param, @Context HttpHeaders header, @HeaderParam("X-Cinder-V1-Call") String isV1Call) throws InternalException {
    // Step 1: Parameter validation
    String snapshotName = null;
    String snapshotDescription = null;
    if (isV1Call != null) {
        snapshotName = param.snapshot.display_name;
        snapshotDescription = param.snapshot.display_description;
    } else {
        snapshotName = param.snapshot.name;
        snapshotDescription = param.snapshot.description;
    }
    // if snapshot name is empty create random name
    if (snapshotName == null) {
        snapshotName = "snapshot-" + RandomStringUtils.random(10);
    }
    if (snapshotName == null || (snapshotName.length() <= 2)) {
        throw APIException.badRequests.parameterIsNotValid(param.snapshot.name);
    }
    URI volumeUri = null;
    Volume volume = null;
    volumeUri = URI.create(param.snapshot.volume_id);
    volume = queryVolumeResource(volumeUri, openstack_tenant_id);
    if (volume == null) {
        _log.error("Invalid source volume id to create snapshot ={} ", param.snapshot.volume_id);
        return CinderApiUtils.createErrorResponse(404, "Not Found : Invalid source volume id " + param.snapshot.volume_id);
    }
    VirtualPool pool = _dbClient.queryObject(VirtualPool.class, volume.getVirtualPool());
    if (pool == null) {
        _log.info("Virtual Pool corresponding to the volume does not exist.");
        throw APIException.badRequests.parameterIsNotValid(volume.getVirtualPool().toString());
    }
    if (!validateSnapshotCreate(openstack_tenant_id, pool, volume.getProvisionedCapacity())) {
        _log.info("The volume can not be created because of insufficient quota for virtual pool.");
        throw APIException.badRequests.insufficientQuotaForVirtualPool(pool.getLabel(), "virtual pool");
    }
    if (!validateSnapshotCreate(openstack_tenant_id, null, volume.getProvisionedCapacity())) {
        _log.info("The volume can not be created because of insufficient quota for Project.");
        throw APIException.badRequests.insufficientQuotaForProject(pool.getLabel(), "project");
    }
    BlockFullCopyManager fcManager = new BlockFullCopyManager(_dbClient, _permissionsHelper, _auditMgr, _coordinator, _placementManager, sc, uriInfo, _request, _tenantsService);
    VolumeIngestionUtil.checkOperationSupportedOnIngestedVolume(volume, ResourceOperationTypeEnum.CREATE_VOLUME_SNAPSHOT, _dbClient);
    // Don't operate on VPLEX backend volumes or RP journal volumes.
    BlockServiceUtils.validateNotAnInternalBlockObject(volume, false);
    validateSourceVolumeHasExported(volume);
    String snapshotType = TechnologyType.NATIVE.toString();
    Boolean createInactive = Boolean.FALSE;
    Boolean readOnly = Boolean.FALSE;
    BlockServiceApi api = getBlockServiceImpl(pool, _dbClient);
    List<Volume> volumesToSnap = new ArrayList<Volume>();
    volumesToSnap.addAll(api.getVolumesToSnap(volume, snapshotType));
    api.validateCreateSnapshot(volume, volumesToSnap, snapshotType, snapshotName, readOnly, fcManager);
    String taskId = UUID.randomUUID().toString();
    List<URI> snapshotURIs = new ArrayList<URI>();
    List<BlockSnapshot> snapshots = api.prepareSnapshots(volumesToSnap, snapshotType, snapshotName, snapshotURIs, taskId);
    TaskList response = new TaskList();
    for (BlockSnapshot snapshot : snapshots) {
        response.getTaskList().add(toTask(snapshot, taskId));
    }
    // Update the task status for the volumes task.
    _dbClient.createTaskOpStatus(Volume.class, volume.getId(), taskId, ResourceOperationTypeEnum.CREATE_VOLUME_SNAPSHOT);
    // Invoke the block service API implementation to create the snapshot
    api.createSnapshot(volume, snapshotURIs, snapshotType, createInactive, readOnly, taskId);
    SnapshotCreateResponse snapCreateResp = new SnapshotCreateResponse();
    for (TaskResourceRep rep : response.getTaskList()) {
        URI snapshotUri = rep.getResource().getId();
        BlockSnapshot snap = _dbClient.queryObject(BlockSnapshot.class, snapshotUri);
        if (snap != null) {
            StringMap extensions = snap.getExtensions();
            if (extensions == null)
                extensions = new StringMap();
            extensions.put("display_description", (snapshotDescription == null) ? "" : snapshotDescription);
            extensions.put("taskid", rep.getId().toString());
            _log.debug("Create snapshot : stored description");
            snap.setExtensions(extensions);
            ScopedLabelSet tagSet = new ScopedLabelSet();
            snap.setTag(tagSet);
            String[] splits = snapshotUri.toString().split(":");
            String tagName = splits[3];
            // this check will verify whether  retrieved data is not corrupted
            if (tagName == null || tagName.isEmpty() || tagName.length() < 2) {
                throw APIException.badRequests.parameterTooShortOrEmpty("Tag", 2);
            }
            Volume parentVol = _permissionsHelper.getObjectById(snap.getParent(), Volume.class);
            URI tenantOwner = parentVol.getTenant().getURI();
            ScopedLabel tagLabel = new ScopedLabel(tenantOwner.toString(), tagName);
            tagSet.add(tagLabel);
            _dbClient.updateObject(snap);
            if (isV1Call != null) {
                _log.debug("Inside V1 call");
                return CinderApiUtils.getCinderResponse(getSnapshotDetail(snap, isV1Call, openstack_tenant_id), header, true, CinderConstants.STATUS_OK);
            } else {
                return CinderApiUtils.getCinderResponse(getSnapshotDetail(snap, isV1Call, openstack_tenant_id), header, true, CinderConstants.STATUS_ACCEPT);
            }
        }
    }
    return CinderApiUtils.getCinderResponse(new CinderSnapshot(), header, true, CinderConstants.STATUS_ACCEPT);
}
Also used : SnapshotCreateResponse(com.emc.storageos.cinder.model.SnapshotCreateResponse) StringMap(com.emc.storageos.db.client.model.StringMap) TaskList(com.emc.storageos.model.TaskList) ArrayList(java.util.ArrayList) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) TaskResourceRep(com.emc.storageos.model.TaskResourceRep) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) URI(java.net.URI) BlockServiceApi(com.emc.storageos.api.service.impl.resource.BlockServiceApi) ScopedLabelSet(com.emc.storageos.db.client.model.ScopedLabelSet) BlockFullCopyManager(com.emc.storageos.api.service.impl.resource.fullcopy.BlockFullCopyManager) CinderSnapshot(com.emc.storageos.cinder.model.CinderSnapshot) Volume(com.emc.storageos.db.client.model.Volume) ScopedLabel(com.emc.storageos.db.client.model.ScopedLabel) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces)

Example 93 with VirtualPool

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

the class TypeService method getVolumeTypes.

/**
 * Get volume types
 *
 * @prereq none
 *
 * @param tenant_id the URN of the tenant
 *
 * @brief List volume types
 * @return Volume types list
 */
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response getVolumeTypes(@PathParam("tenant_id") URI openstack_tenant_id, @Context HttpHeaders header) {
    // Here we ignore the openstack tenant id
    _log.info("START get list of volume types");
    VolumeTypesRestResp types = new VolumeTypesRestResp();
    StorageOSUser user = getUserFromContext();
    URI tenantId = URI.create(user.getTenantId());
    List<URI> vpools = _dbClient.queryByType(VirtualPool.class, true);
    for (URI vpool : vpools) {
        VirtualPool pool = _dbClient.queryObject(VirtualPool.class, vpool);
        _log.debug("Looking up vpool {}", pool.getLabel());
        if (pool != null && pool.getType().equalsIgnoreCase(VirtualPool.Type.block.name())) {
            if (_permissionsHelper.tenantHasUsageACL(tenantId, pool)) {
                _log.debug("Adding vpool {}", pool.getLabel());
                VolumeType type = new VolumeType();
                type.id = pool.getId().toString();
                type.name = pool.getLabel();
                type.extra_specs = new HashMap<String, String>();
                types.getVolume_types().add(type);
            }
        }
    }
    _log.info("END get list of volume types");
    return CinderApiUtils.getCinderResponse(types, header, false, CinderConstants.STATUS_OK);
}
Also used : VolumeType(com.emc.storageos.cinder.model.VolumeType) VolumeTypesRestResp(com.emc.storageos.cinder.model.VolumeTypesRestResp) StorageOSUser(com.emc.storageos.security.authentication.StorageOSUser) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) URI(java.net.URI) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET)

Example 94 with VirtualPool

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

the class VolumeService method getVolumeDetail.

// INTERNAL FUNCTIONS
protected VolumeDetail getVolumeDetail(Volume vol, String isV1Call, String openstackTenantId) {
    VolumeDetail detail = new VolumeDetail();
    int sizeInGB = (int) ((vol.getCapacity() + halfGB) / GB);
    detail.size = sizeInGB;
    detail.id = getCinderHelper().trimId(vol.getId().toString());
    detail.host_name = getCinderHelper().trimId(vol.getStorageController().toString());
    detail.tenant_id = openstackTenantId;
    detail.attachments = new ArrayList<Attachment>();
    if (vol.getInactive()) {
        detail.status = "deleted";
    } else {
        if (vol.getExtensions() == null) {
            vol.setExtensions(new StringMap());
        }
        if (vol.getProvisionedCapacity() == ZERO_BYTES) {
            detail.status = CinderConstants.ComponentStatus.CREATING.getStatus().toLowerCase();
        } else if (vol.getExtensions().containsKey("status") && vol.getExtensions().get("status").equals(CinderConstants.ComponentStatus.DELETING.getStatus().toLowerCase())) {
            Task taskObj = null;
            String task = vol.getExtensions().get(DELETE_TASK_ID).toString();
            taskObj = TaskUtils.findTaskForRequestId(_dbClient, vol.getId(), task);
            if (taskObj != null) {
                if (taskObj.getStatus().equals("error")) {
                    _log.info(String.format("Error Deleting volume %s, but moving volume to original state so that it will be usable:  ", detail.name));
                    vol.getExtensions().put("status", CinderConstants.ComponentStatus.AVAILABLE.getStatus().toLowerCase());
                    vol.getExtensions().remove(DELETE_TASK_ID);
                    detail.status = CinderConstants.ComponentStatus.AVAILABLE.getStatus().toLowerCase();
                } else if (taskObj.getStatus().equals("pending")) {
                    detail.status = CinderConstants.ComponentStatus.DELETING.getStatus().toLowerCase();
                }
                _dbClient.updateObject(vol);
            } else {
                detail.status = CinderConstants.ComponentStatus.AVAILABLE.getStatus().toLowerCase();
            }
        } else if (vol.getExtensions().containsKey("status") && vol.getExtensions().get("status").equals(CinderConstants.ComponentStatus.EXTENDING.getStatus().toLowerCase())) {
            _log.info("Extending Volume {}", vol.getId().toString());
            Task taskObj = null;
            String task = vol.getExtensions().get("task_id").toString();
            taskObj = TaskUtils.findTaskForRequestId(_dbClient, vol.getId(), task);
            _log.debug("THE TASKOBJ is {}, task_id {}", taskObj.toString(), task);
            _log.debug("THE TASKOBJ STATUS is {}", taskObj.getStatus().toString());
            if (taskObj != null) {
                if (taskObj.getStatus().equals("ready")) {
                    detail.status = CinderConstants.ComponentStatus.AVAILABLE.getStatus().toLowerCase();
                    _log.debug(" STATUS is {}", detail.status);
                    vol.getExtensions().remove("task_id");
                    vol.getExtensions().put("status", "");
                } else if (taskObj.getStatus().equals("error")) {
                    detail.status = CinderConstants.ComponentStatus.AVAILABLE.getStatus().toLowerCase();
                    _log.info(String.format("Error in Extending volume %s, but moving volume to original state so that it will be usable:  ", detail.name));
                    vol.getExtensions().remove("task_id");
                    vol.getExtensions().put("status", "");
                } else {
                    detail.status = CinderConstants.ComponentStatus.EXTENDING.getStatus().toLowerCase();
                    _log.info("STATUS is {}", detail.status);
                }
            } else {
                detail.status = CinderConstants.ComponentStatus.AVAILABLE.getStatus().toLowerCase();
                _log.info(String.format("Error in Extending volume %s, but moving volume to original state so that it will be usable:  ", detail.name));
                vol.getExtensions().remove("task_id");
                vol.getExtensions().put("status", "");
            }
            _dbClient.updateObject(vol);
        } else if (vol.getExtensions().containsKey("status") && !vol.getExtensions().get("status").equals("")) {
            detail.status = vol.getExtensions().get("status").toString().toLowerCase();
        } else {
            detail.status = CinderConstants.ComponentStatus.AVAILABLE.getStatus().toLowerCase();
        }
    }
    detail.created_at = date(vol.getCreationTime().getTimeInMillis());
    URI vpoolUri = vol.getVirtualPool();
    VirtualPool vpool = _dbClient.queryObject(VirtualPool.class, vpoolUri);
    if (vpool != null) {
        detail.volume_type = vpool.getLabel();
    }
    URI varrayUri = vol.getVirtualArray();
    VirtualArray varray = _dbClient.queryObject(VirtualArray.class, varrayUri);
    if (varray != null) {
        detail.availability_zone = varray.getLabel();
    }
    if (vol.getExtensions().containsKey("bootable") && vol.getExtensions().get("bootable").equals(TRUE)) {
        detail.bootable = true;
        _log.debug("Volumes Bootable Flag is TRUE");
    } else {
        detail.bootable = false;
        _log.debug("Volumes Bootable Flag is False");
    }
    detail.setLink(DbObjectMapper.toLink(vol));
    detail.metadata = new HashMap<String, String>();
    String description = null;
    StringMap extensions = vol.getExtensions();
    if (extensions != null) {
        description = extensions.get("display_description");
    }
    if (isV1Call != null) {
        detail.display_name = vol.getLabel();
        detail.display_description = (description == null) ? "" : description;
        detail.description = null;
        detail.name = null;
    } else {
        detail.name = vol.getLabel();
        detail.description = (description == null) ? "" : description;
        detail.display_name = null;
        detail.display_description = null;
    }
    if (vol.getExtensions().containsKey("readonly") && vol.getExtensions().get("readonly").equals(TRUE)) {
        _log.debug("Volumes Readonly Flag is TRUE");
        detail.metadata.put("readonly", "true");
    } else {
        _log.debug("Volumes Readonly Flag is FALSE");
        detail.metadata.put("readonly", "false");
    }
    if (detail.status.equals("in-use")) {
        if (vol.getExtensions() != null && vol.getExtensions().containsKey("OPENSTACK_NOVA_INSTANCE_ID")) {
            detail.metadata.put("attached_mode", vol.getExtensions().get("OPENSTACK_ATTACH_MODE"));
            detail.attachments = getVolumeAttachments(vol);
        }
    }
    if (vol.getConsistencyGroup() != null) {
        detail.consistencygroup_id = CinderApiUtils.splitString(vol.getConsistencyGroup().toString(), ":", 3);
    }
    return detail;
}
Also used : StringMap(com.emc.storageos.db.client.model.StringMap) TaskMapper.toTask(com.emc.storageos.api.mapper.TaskMapper.toTask) Task(com.emc.storageos.db.client.model.Task) VirtualArray(com.emc.storageos.db.client.model.VirtualArray) VolumeDetail(com.emc.storageos.cinder.model.VolumeDetail) Attachment(com.emc.storageos.cinder.model.Attachment) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) URI(java.net.URI) PrefixConstraint(com.emc.storageos.db.client.constraint.PrefixConstraint) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint) ContainmentConstraint(com.emc.storageos.db.client.constraint.ContainmentConstraint)

Example 95 with VirtualPool

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

the class VolumeService method checkForConsistencyGroup.

/**
 * Method to support consistency group for a volume
 *
 * @param vpool
 * @param consistencyGroup
 * @param project
 * @param blockServiceImpl
 * @param varray
 * @param capabilities
 * @param blkFullCpManager
 */
public void checkForConsistencyGroup(VirtualPool vpool, BlockConsistencyGroup consistencyGroup, Project project, BlockServiceApi blockServiceImpl, VirtualArray varray, VirtualPoolCapabilityValuesWrapper capabilities, BlockFullCopyManager blkFullCpManager) {
    Integer volumeCount = 1;
    final Boolean isMultiVolumeConsistencyOn = vpool.getMultivolumeConsistency() == null ? Boolean.FALSE : vpool.getMultivolumeConsistency();
    _log.info("*********MultiVolumeConsistencyOn************** : " + isMultiVolumeConsistencyOn);
    /*
         * Validate Consistency Group:
         * 1. CG should be active in the database
         * 2. CG project and Volume project should match
         * 3. The storage system that the CG is bonded to is associated to the
         * request virtual array
         */
    ArrayList<String> requestedTypes = new ArrayList<String>();
    final URI actualId = project.getId();
    if (consistencyGroup != null) {
        // Check that the Volume project and the CG project are the same
        final URI expectedId = consistencyGroup.getProject().getURI();
        final boolean condition = actualId.equals(expectedId);
        if (!condition) {
            throw APIException.badRequests.invalidProjectConflict(expectedId);
        }
        // attribute should be true
        if (!isMultiVolumeConsistencyOn) {
            throw APIException.badRequests.invalidParameterConsistencyGroupProvidedButVirtualPoolHasNoMultiVolumeConsistency(consistencyGroup.getId(), URI.create(vpool.toString()));
        }
        // Find all volumes assigned to the group
        final List<Volume> activeCGVolumes = blockServiceImpl.getActiveCGVolumes(consistencyGroup);
        // Validate that the number of volumes in the group plus the number
        // to be added by this request does not exceed the maximum volumes
        // in a CG.
        int cgMaxVolCount = blockServiceImpl.getMaxVolumesForConsistencyGroup(consistencyGroup);
        if ((activeCGVolumes.size() + volumeCount.intValue()) > cgMaxVolCount) {
            throw APIException.badRequests.requestedVolumeCountExceedsLimitsForCG(volumeCount.intValue(), cgMaxVolCount, consistencyGroup.getLabel());
        }
        if (VirtualPool.vPoolSpecifiesProtection(vpool)) {
            requestedTypes.add(Types.RP.name());
        }
        // LOCAL type.
        if (VirtualPool.vPoolSpecifiesHighAvailability(vpool)) {
            requestedTypes.add(Types.VPLEX.name());
        }
        if (VirtualPool.vPoolSpecifiesSRDF(vpool)) {
            requestedTypes.add(Types.SRDF.name());
        }
        if (!VirtualPool.vPoolSpecifiesProtection(vpool) && !VirtualPool.vPoolSpecifiesHighAvailability(vpool) && !VirtualPool.vPoolSpecifiesSRDF(vpool) && vpool.getMultivolumeConsistency()) {
            requestedTypes.add(Types.LOCAL.name());
        }
        // If the consistency group is not yet created, verify the name is OK.
        if (!consistencyGroup.created()) {
            blockServiceImpl.validateConsistencyGroupName(consistencyGroup, requestedTypes);
        }
        // Consistency Group is already a Target, hence cannot be used to create source volume
        if (consistencyGroup.srdfTarget()) {
            throw APIException.badRequests.consistencyGroupBelongsToTarget(consistencyGroup.getId());
        }
        if (VirtualPool.vPoolSpecifiesSRDF(vpool) && (consistencyGroup.getLabel().length() > 8 || !isAlphaNumeric(consistencyGroup.getLabel()))) {
            throw APIException.badRequests.groupNameCannotExceedEightCharactersoronlyAlphaNumericAllowed();
        }
        if (!VirtualPool.vPoolSpecifiesSRDF(vpool) && consistencyGroup.checkForType(Types.SRDF)) {
            throw APIException.badRequests.nonSRDFVolumeCannotbeAddedToSRDFCG();
        }
        // check if CG's storage system is associated to the requested virtual array
        validateCGValidWithVirtualArray(consistencyGroup, varray);
        // the CG's previously requested types.
        if (consistencyGroup.creationInitiated()) {
            if (!consistencyGroup.getRequestedTypes().containsAll(requestedTypes)) {
                throw APIException.badRequests.consistencyGroupIsNotCompatibleWithRequest(consistencyGroup.getId(), consistencyGroup.getTypes().toString(), requestedTypes.toString());
            }
        }
        // RP consistency group validation
        if (VirtualPool.vPoolSpecifiesProtection(vpool)) {
            // If an RP protected vpool is specified, ensure that the CG selected is empty or contains only RP volumes.
            if (activeCGVolumes != null && !activeCGVolumes.isEmpty() && !consistencyGroup.getTypes().contains(BlockConsistencyGroup.Types.RP.toString())) {
                throw APIException.badRequests.consistencyGroupMustBeEmptyOrContainRpVolumes(consistencyGroup.getId());
            }
            if (!activeCGVolumes.isEmpty()) {
                // Find the first existing source volume for source/target varray comparison.
                Volume existingSourceVolume = null;
                for (Volume cgVolume : activeCGVolumes) {
                    if (cgVolume.getPersonality() != null && cgVolume.getPersonality().equals(Volume.PersonalityTypes.SOURCE.toString())) {
                        existingSourceVolume = cgVolume;
                        break;
                    }
                }
                if (existingSourceVolume != null) {
                    VirtualPool existingVpool = _dbClient.queryObject(VirtualPool.class, existingSourceVolume.getVirtualPool());
                    VirtualPool requestedVpool = _dbClient.queryObject(VirtualPool.class, URI.create(vpool.toString()));
                    // The source virtual arrays must much
                    if (existingVpool.getVirtualArrays().size() != requestedVpool.getVirtualArrays().size() || !existingVpool.getVirtualArrays().containsAll(requestedVpool.getVirtualArrays())) {
                        // The source virtual arrays are not compatible with the CG
                        throw APIException.badRequests.vPoolSourceVarraysNotCompatibleForCG(consistencyGroup.getLabel());
                    }
                    // MetroPoint volumes in the same CG.
                    if (VirtualPool.vPoolSpecifiesHighAvailability(existingVpool) && VirtualPool.vPoolSpecifiesHighAvailability(requestedVpool)) {
                        // that we are not trying to mix MetroPoint volumes with Metro volumes.
                        if ((!VirtualPool.vPoolSpecifiesMetroPoint(requestedVpool) && VirtualPool.vPoolSpecifiesMetroPoint(existingVpool)) || (VirtualPool.vPoolSpecifiesMetroPoint(requestedVpool) && !VirtualPool.vPoolSpecifiesMetroPoint(existingVpool))) {
                            throw APIException.badRequests.cannotMixMetroPointAndNonMetroPointVolumes(consistencyGroup.getLabel());
                        }
                    }
                    // Check the target virtual arrays
                    StringMap existingProtectionVarraySettings = existingVpool.getProtectionVarraySettings();
                    if (existingProtectionVarraySettings == null) {
                        // NOTE: This will be supported in the future through Jira CTRL-10129
                        throw APIException.badRequests.cannotAddVolumesToSwappedCG(consistencyGroup.getLabel());
                    }
                    StringMap requestedProtectionVarraySettings = requestedVpool.getProtectionVarraySettings();
                    if (existingProtectionVarraySettings.size() != requestedProtectionVarraySettings.size()) {
                        // The target virtual arrays are not compatible with the CG
                        throw APIException.badRequests.vPoolTargetVarraysNotCompatibleForCG(consistencyGroup.getLabel());
                    }
                    for (String targetVarray : requestedProtectionVarraySettings.keySet()) {
                        if (!existingProtectionVarraySettings.containsKey(targetVarray)) {
                            // The target virtual arrays are not compatible with the CG
                            throw APIException.badRequests.vPoolTargetVarraysNotCompatibleForCG(consistencyGroup.getLabel());
                        }
                    }
                }
            }
        }
        checkCGForSnapshots(consistencyGroup);
        // Creating new volumes in 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.
        blkFullCpManager.verifyNewVolumesCanBeCreatedInConsistencyGroup(consistencyGroup, activeCGVolumes);
        capabilities.put(VirtualPoolCapabilityValuesWrapper.BLOCK_CONSISTENCY_GROUP, consistencyGroup.getId());
        if (consistencyGroup != null) {
            consistencyGroup.addRequestedTypes(requestedTypes);
            _dbClient.updateAndReindexObject(consistencyGroup);
        }
    } else if (VirtualPool.vPoolSpecifiesProtection(vpool)) {
        // protection is specified, a consistency group must be selected.
        throw APIException.badRequests.consistencyGroupMissingForRpProtection();
    }
}
Also used : StringMap(com.emc.storageos.db.client.model.StringMap) CinderVolume(com.emc.storageos.cinder.model.CinderVolume) Volume(com.emc.storageos.db.client.model.Volume) ArrayList(java.util.ArrayList) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) URI(java.net.URI) PrefixConstraint(com.emc.storageos.db.client.constraint.PrefixConstraint) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint) ContainmentConstraint(com.emc.storageos.db.client.constraint.ContainmentConstraint)

Aggregations

VirtualPool (com.emc.storageos.db.client.model.VirtualPool)339 URI (java.net.URI)189 ArrayList (java.util.ArrayList)122 Volume (com.emc.storageos.db.client.model.Volume)103 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)92 NamedURI (com.emc.storageos.db.client.model.NamedURI)88 VirtualArray (com.emc.storageos.db.client.model.VirtualArray)88 StringSet (com.emc.storageos.db.client.model.StringSet)76 Project (com.emc.storageos.db.client.model.Project)65 StoragePool (com.emc.storageos.db.client.model.StoragePool)57 StringMap (com.emc.storageos.db.client.model.StringMap)53 HashMap (java.util.HashMap)52 Produces (javax.ws.rs.Produces)50 CheckPermission (com.emc.storageos.security.authorization.CheckPermission)45 VirtualPoolCapabilityValuesWrapper (com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper)44 List (java.util.List)44 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)42 Path (javax.ws.rs.Path)42 TenantOrg (com.emc.storageos.db.client.model.TenantOrg)37 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)37