Search in sources :

Example 41 with VirtualPool

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

the class BlockService method verifyVPlexVolumeForDataMigration.

/**
 * Performs verification on the VPLEX volume to ensure it is a candidate for migration.
 *
 * @param volume VPLEX volume to check
 * @param currentVpool The current vpool where the volume is placed
 * @param newVpool The target vpool where the volume will be placed after migration
 */
public static void verifyVPlexVolumeForDataMigration(Volume volume, VirtualPool currentVpool, VirtualPool newVpool, DbClient _dbClient) {
    _log.info(String.format("Verifying that the VPlex volume[%s](%s) qualifies for Data Migration" + " moving from current vpool [%s](%s) to new vpool [%s](%s).", volume.getLabel(), volume.getId(), currentVpool.getLabel(), currentVpool.getId(), newVpool.getLabel(), newVpool.getId()));
    // Determine if source side will be migrated.
    boolean migrateSourceVolume = VirtualPoolChangeAnalyzer.vpoolChangeRequiresMigration(currentVpool, newVpool);
    // Determine if HA side will be migrated.
    boolean migrateHAVolume = false;
    VirtualPool currentHaVpool = VirtualPoolChangeAnalyzer.getHaVpool(currentVpool, _dbClient);
    if (currentHaVpool != null) {
        VirtualPool newHaVpool = VirtualPoolChangeAnalyzer.getNewHaVpool(currentVpool, newVpool, _dbClient);
        migrateHAVolume = VirtualPoolChangeAnalyzer.vpoolChangeRequiresMigration(currentHaVpool, newHaVpool);
    }
    // Verify the VPLEX volume structure. Ingested volumes
    // can only be migrated if the component structure of
    // the volume is supported by ViPR.
    verifyVPlexVolumeStructureForDataMigration(volume, currentVpool, migrateSourceVolume, migrateHAVolume, _dbClient);
    // Check for snaps, mirrors, and full copies
    if (migrateSourceVolume) {
        // The vpool change is a data migration and the source
        // side backend volume will be migrated. If the volume
        // has snapshots, then the vpool change will not be
        // allowed because VPLEX snapshots are just snapshots
        // of this backend volume. The user would lose all
        // snapshots if we allowed the vpool change. The user
        // must explicitly go and delete their snapshots first.
        // the same is true for volumes that have full copies
        // from which they are not detached and also full copy
        // volumes that are not detached from their source. If
        // not detached a full copy session still exists between
        // this backend volume and some other volume.
        // 
        // Note: We make this validation here instead of in the
        // verification VirtualPoolChangeAnalyzer method
        // "getSupportedVPlexVolumeVirtualPoolChangeOperation"
        // because this method is called from not only the API
        // to change the volume virtual pool, but also the API
        // that determines the virtual pools to which a volume
        // can be changed. The latter API is used by the UI to
        // populate the list of volumes. We want volumes with
        // snaps to appear in the list, so that the user will
        // know that if they remove the snapshots, they can
        // perform the vpool change.
        Volume srcVolume = VPlexUtil.getVPLEXBackendVolume(volume, true, _dbClient, false);
        if (srcVolume != null) {
            // Has a source volume, so not ingested.
            List<BlockSnapshot> snapshots = CustomQueryUtility.queryActiveResourcesByConstraint(_dbClient, BlockSnapshot.class, ContainmentConstraint.Factory.getVolumeSnapshotConstraint(srcVolume.getId()));
            if (!snapshots.isEmpty()) {
                throw APIException.badRequests.volumeForVpoolChangeHasSnaps(volume.getId().toString());
            }
            // Check for snapshot sessions for the volume.
            if (BlockSnapshotSessionUtils.volumeHasSnapshotSession(srcVolume, _dbClient)) {
                throw APIException.badRequests.volumeForVpoolChangeHasSnaps(volume.getLabel());
            }
            // has full copy sessions.
            if (BlockFullCopyUtils.volumeHasFullCopySession(srcVolume, _dbClient)) {
                throw APIException.badRequests.volumeForVpoolChangeHasFullCopies(volume.getLabel());
            }
        }
        // If the volume has mirrors then Vpool change will not
        // be allowed. User needs to explicitly delete mirrors first.
        // This is applicable for both Local and Distributed volumes.
        // For distributed volume getMirrors will get mirror if any
        // on source or HA side.
        StringSet mirrorURIs = volume.getMirrors();
        if (mirrorURIs != null && !mirrorURIs.isEmpty()) {
            List<VplexMirror> mirrors = _dbClient.queryObject(VplexMirror.class, StringSetUtil.stringSetToUriList(mirrorURIs));
            if (mirrors != null && !mirrors.isEmpty()) {
                throw APIException.badRequests.volumeForVpoolChangeHasMirrors(volume.getId().toString(), volume.getLabel());
            }
        }
    }
}
Also used : MapVolume(com.emc.storageos.api.mapper.functions.MapVolume) Volume(com.emc.storageos.db.client.model.Volume) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) StringSet(com.emc.storageos.db.client.model.StringSet) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) VplexMirror(com.emc.storageos.db.client.model.VplexMirror)

Example 42 with VirtualPool

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

the class BlockService method changeVolumeVirtualPool.

/**
 * Allows the caller to change the virtual pool for the volume identified in
 * the request. Currently, the only virtual pool changes that are supported
 * are as follows:
 *
 * Change the virtual pool for a VPLEX virtual volume. This virtual pool
 * change would allow the caller to change the types of drives, for example,
 * used for the backend volume(s) that are used by the virtual volume.
 *
 * Change the virtual pool for a VPLEX virtual volume, such that a local
 * VPLEX virtual volumes becomes a distributed VPLEX virtual volume.
 *
 * Change the virtual pool of a VMAX or VNX Block volume to make the volume
 * a local or distributed VPLEX virtual volume. Essentially, the volume
 * becomes the backend volume for a VPLEX virtual volume. Similar to
 * creating a virtual volume, but instead of creating a new backend volume,
 * using the volume identified in the request. The VMAX or VNX volume cannot
 * currently be exported for this change.
 *
 * Change the virtual pool of a VMAX or VNX Block volume to make the volume
 * a RecoverPoint protected volume. The volume must be able to stay put, and
 * ViPR will build a protection around it.
 *
 * Change the virtual pool of a VMAX or VNX Block volume to allow native
 * continuous copies to be created for it.
 *
 * Change the virtual pool of a volume to increase the export path parameter max_paths.
 * The number of paths will be upgraded if possible for all Export Groups / Export Masks
 * containing this volume. If the volume is not currently exported, max_paths can be
 * decreased or paths_per_initiator can be changed. Note that changing max_paths does
 * not have any effect on the export of BlockSnapshots that were created from this volume.
 *
 * Change the virtual pool of a VMAX and VNX volume to allow change of Auto-tiering policy
 * associated with it.
 * <p>
 * Since this method has been deprecated use POST /block/volumes/vpool-change
 *
 * @brief Change the virtual pool for a volume.
 *
 * @prereq none
 *
 * @param id
 *            the URN of a ViPR volume.
 * @param param
 *            The parameter specifying the new virtual pool.
 * @return A TaskResourceRep representing the virtual pool change for the
 *         volume.
 * @throws InternalException,
 *             APIException
 */
@PUT
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}/vpool")
@CheckPermission(roles = { Role.TENANT_ADMIN }, acls = { ACL.OWN, ACL.ALL })
@Deprecated
public TaskResourceRep changeVolumeVirtualPool(@PathParam("id") URI id, VirtualPoolChangeParam param) throws InternalException, APIException {
    _log.info("Request to change VirtualPool for volume {}", id);
    // Get the volume.
    ArgValidator.checkFieldUriType(id, Volume.class, "id");
    Volume volume = queryVolumeResource(id);
    _log.info("Found volume");
    // Don't operate on VPLEX backend or RP Journal volumes.
    BlockServiceUtils.validateNotAnInternalBlockObject(volume, false);
    // Don't operate on ingested volumes.
    VolumeIngestionUtil.checkOperationSupportedOnIngestedVolume(volume, ResourceOperationTypeEnum.CHANGE_BLOCK_VOLUME_VPOOL, _dbClient);
    // Get the project.
    URI projectURI = volume.getProject().getURI();
    Project project = _permissionsHelper.getObjectById(projectURI, Project.class);
    ArgValidator.checkEntity(project, projectURI, false);
    _log.info("Found volume project {}", projectURI);
    // Verify the user is authorized for the volume's project.
    BlockServiceUtils.verifyUserIsAuthorizedForRequest(project, getUserFromContext(), _permissionsHelper);
    _log.info("User is authorized for volume's project");
    // Get the VirtualPool for the request and verify that the
    // project's tenant has access to the VirtualPool.
    VirtualPool vpool = getVirtualPoolForRequest(project, param.getVirtualPool(), _dbClient, _permissionsHelper);
    _log.info("Found new VirtualPool {}", vpool.getId());
    // Verify that the VirtualPool change is allowed for the
    // requested volume and VirtualPool.
    verifyVirtualPoolChangeSupportedForVolumeAndVirtualPool(volume, vpool);
    _log.info("VirtualPool change is supported for requested volume and VirtualPool");
    verifyAllVolumesInCGRequirement(Arrays.asList(volume), vpool);
    // verify quota
    if (!CapacityUtils.validateVirtualPoolQuota(_dbClient, vpool, volume.getProvisionedCapacity())) {
        throw APIException.badRequests.insufficientQuotaForVirtualPool(vpool.getLabel(), "volume");
    }
    // Create a unique task id.
    String taskId = UUID.randomUUID().toString();
    Operation op = _dbClient.createTaskOpStatus(Volume.class, id, taskId, ResourceOperationTypeEnum.CHANGE_BLOCK_VOLUME_VPOOL);
    // execute the VirtualPool update on the volume.
    try {
        BlockServiceApi blockServiceAPI = getBlockServiceImplForVirtualPoolChange(volume, vpool);
        _log.info("Got block service implementation for VirtualPool change request");
        blockServiceAPI.changeVolumeVirtualPool(Arrays.asList(volume), vpool, param, taskId);
        _log.info("Executed VirtualPool change for volume.");
    } catch (InternalException | APIException e) {
        String errorMsg = String.format("Volume VirtualPool change error: %s", e.getMessage());
        op = new Operation(Operation.Status.error.name(), errorMsg);
        _dbClient.updateTaskOpStatus(Volume.class, id, taskId, op);
        throw e;
    }
    auditOp(OperationTypeEnum.CHANGE_VOLUME_VPOOL, true, AuditLogManager.AUDITOP_BEGIN, volume.getLabel(), 1, volume.getVirtualArray().toString(), volume.getProject().toString());
    return toTask(volume, taskId, op);
}
Also used : Project(com.emc.storageos.db.client.model.Project) APIException(com.emc.storageos.svcs.errorhandling.resources.APIException) MapVolume(com.emc.storageos.api.mapper.functions.MapVolume) Volume(com.emc.storageos.db.client.model.Volume) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) Operation(com.emc.storageos.db.client.model.Operation) URI(java.net.URI) NullColumnValueGetter.isNullURI(com.emc.storageos.db.client.util.NullColumnValueGetter.isNullURI) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) 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 43 with VirtualPool

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

the class BlockService method verifyVirtualPoolChangeSupportedForVolumeAndVirtualPool.

/**
 * Determines whether or not the passed VirtualPool change for the passed Volume is
 * supported. Throws a ServiceCodeException when the vpool change is not
 * supported.
 *
 * @param volume
 *            A reference to the volume.
 * @param newVpool
 *            A reference to the new VirtualPool.
 */
private void verifyVirtualPoolChangeSupportedForVolumeAndVirtualPool(Volume volume, VirtualPool newVpool) {
    // Currently, Vpool change is only supported for volumes on
    // VPlex storage systems and volumes (both regular and VPLEX i.e. RP+VPLEX) that are currently
    // unprotected by RP to a Vpool that has RP, as long as the source volume doesn't have to move.
    VirtualPool currentVpool = _dbClient.queryObject(VirtualPool.class, volume.getVirtualPool());
    URI systemURI = volume.getStorageController();
    StorageSystem system = _dbClient.queryObject(StorageSystem.class, systemURI);
    String systemType = system.getSystemType();
    StringBuffer notSuppReasonBuff = new StringBuffer();
    notSuppReasonBuff.setLength(0);
    /**
     * Do not support following vpool change operations for the volume part of application
     * 1. Move into Vplex
     * 2. Add RecoverPoint
     * 3. Remove RecoverPoint
     * 4. Add SRDF
     */
    if (volume.getApplication(_dbClient) != null) {
        // Move into VPLEX
        if (!VirtualPool.vPoolSpecifiesHighAvailability(currentVpool) && VirtualPool.vPoolSpecifiesHighAvailability(newVpool)) {
            notSuppReasonBuff.append("Non VPLEX volumes in applications cannot be moved into VPLEX pools");
            throw APIException.badRequests.changeToVirtualPoolNotSupported(newVpool.getLabel(), notSuppReasonBuff.toString());
        }
        // Add recoverPoint
        if (!VirtualPool.vPoolSpecifiesProtection(currentVpool) && VirtualPool.vPoolSpecifiesProtection(newVpool)) {
            notSuppReasonBuff.append("Non RP volumes in applications cannot be moved into RP pools");
            throw APIException.badRequests.changeToVirtualPoolNotSupported(newVpool.getLabel(), notSuppReasonBuff.toString());
        }
        // Remove RecoverPoint
        if (VirtualPool.vPoolSpecifiesProtection(currentVpool) && !VirtualPool.vPoolSpecifiesProtection(newVpool)) {
            notSuppReasonBuff.append("RP volumes in applications cannot be moved into non RP pools");
            throw APIException.badRequests.changeToVirtualPoolNotSupported(newVpool.getLabel(), notSuppReasonBuff.toString());
        }
        // Add SRDF
        if (!VirtualPool.vPoolSpecifiesSRDF(currentVpool) && VirtualPool.vPoolSpecifiesSRDF(newVpool)) {
            notSuppReasonBuff.append("volumes in applications cannot be moved into SRDF pools");
            throw APIException.badRequests.changeToVirtualPoolNotSupported(newVpool.getLabel(), notSuppReasonBuff.toString());
        }
    }
    // Check if an Export Path Params change.
    if (VirtualPoolChangeAnalyzer.isSupportedPathParamsChange(volume, currentVpool, newVpool, _dbClient, notSuppReasonBuff)) {
        ExportPathUpdater updater = new ExportPathUpdater(_dbClient);
        ExportPathParams newParam = new ExportPathParams(newVpool.getNumPaths(), newVpool.getMinPaths(), newVpool.getPathsPerInitiator());
        updater.validateChangePathParams(volume.getId(), newParam);
        _log.info("New VPool specifies an Export Path Params change");
        return;
    }
    // Check if it is an Auto-tiering policy change.
    notSuppReasonBuff.setLength(0);
    if (VirtualPoolChangeAnalyzer.isSupportedAutoTieringPolicyAndLimitsChange(volume, currentVpool, newVpool, _dbClient, notSuppReasonBuff)) {
        _log.info("New VPool specifies an Auto-tiering policy change");
        return;
    }
    if (VirtualPoolChangeAnalyzer.isSupportedReplicationModeChange(currentVpool, newVpool, notSuppReasonBuff)) {
        _log.info("New VPool specifies a replication mode change");
        return;
    }
    if (DiscoveredDataObject.Type.vplex.name().equals(systemType)) {
        _log.info("Volume is a VPlex virtual volume.");
        // the Vpool specifies a different grade of disk drives.
        if (!VirtualPool.vPoolSpecifiesHighAvailability(newVpool)) {
            _log.info("New VirtualPool does not specify VPlex high availability.");
            throw new ServiceCodeException(ServiceCode.API_VOLUME_VPOOL_CHANGE_DISRUPTIVE, "New VirtualPool {0} does not specify vplex high availability", new Object[] { newVpool.getId() });
        } else {
            notSuppReasonBuff.setLength(0);
            // can be exposed in the Migration Services catalog to support RP+VPLEX Data Migrations.
            if (volume.checkPersonality(Volume.PersonalityTypes.METADATA)) {
                if (VirtualPoolChangeAnalyzer.vpoolChangeRequiresMigration(currentVpool, newVpool)) {
                    verifyVPlexVolumeForDataMigration(volume, currentVpool, newVpool, _dbClient);
                    return;
                }
            }
            // if the request is trying to remove RP protection.
            if (volume.checkForRp() && VirtualPool.vPoolSpecifiesProtection(currentVpool) && !VirtualPool.vPoolSpecifiesProtection(newVpool)) {
                notSuppReasonBuff.setLength(0);
                if (!VirtualPoolChangeAnalyzer.isSupportedRPRemoveProtectionVirtualPoolChange(volume, currentVpool, newVpool, _dbClient, notSuppReasonBuff)) {
                    throw APIException.badRequests.changeToVirtualPoolNotSupported(newVpool.getLabel(), notSuppReasonBuff.toString());
                }
            } else if (VirtualPool.vPoolSpecifiesRPVPlex(newVpool)) {
                notSuppReasonBuff.setLength(0);
                // Check to see if any of the operations for protected vpool to protected vpool changes are supported
                if (VirtualPool.vPoolSpecifiesRPVPlex(currentVpool)) {
                    if (VirtualPoolChangeAnalyzer.isSupportedRPVPlexMigrationVirtualPoolChange(volume, currentVpool, newVpool, _dbClient, notSuppReasonBuff, null)) {
                        verifyVPlexVolumeForDataMigration(volume, currentVpool, newVpool, _dbClient);
                    } else if (!VirtualPoolChangeAnalyzer.isSupportedUpgradeToMetroPointVirtualPoolChange(volume, currentVpool, newVpool, _dbClient, notSuppReasonBuff)) {
                        _log.warn("RP Change Protection VirtualPool change for volume is not supported: {}", notSuppReasonBuff.toString());
                        throw APIException.badRequests.changeToVirtualPoolNotSupported(newVpool.getLabel(), notSuppReasonBuff.toString());
                    }
                } else // Otherwise, check to see if we're trying to protect a VPLEX volume.
                if (!VirtualPoolChangeAnalyzer.isSupportedAddRPProtectionVirtualPoolChange(volume, currentVpool, newVpool, _dbClient, notSuppReasonBuff)) {
                    _log.warn("RP+VPLEX VirtualPool change for volume is not supported: {}", notSuppReasonBuff.toString());
                    throw APIException.badRequests.changeToVirtualPoolNotSupported(newVpool.getLabel(), notSuppReasonBuff.toString());
                } else if (BlockFullCopyUtils.volumeHasFullCopySession(volume, _dbClient)) {
                    // Full copies not supported for RP protected volumes.
                    throw APIException.badRequests.volumeForRPVpoolChangeHasFullCopies(volume.getLabel());
                }
            } else {
                VirtualPoolChangeOperationEnum vplexVpoolChangeOperation = VirtualPoolChangeAnalyzer.getSupportedVPlexVolumeVirtualPoolChangeOperation(volume, currentVpool, newVpool, _dbClient, notSuppReasonBuff);
                if (vplexVpoolChangeOperation == null) {
                    _log.warn("VPlex volume VirtualPool change not supported {}", notSuppReasonBuff.toString());
                    throw APIException.badRequests.changeToVirtualPoolNotSupported(newVpool.getLabel(), notSuppReasonBuff.toString());
                } else if (VPlexUtil.isVolumeBuiltOnBlockSnapshot(_dbClient, volume)) {
                    // created using the target volume of a block snapshot.
                    throw APIException.badRequests.vpoolChangeNotAllowedVolumeIsExposedSnapshot(volume.getId().toString());
                } else if (vplexVpoolChangeOperation == VirtualPoolChangeOperationEnum.VPLEX_DATA_MIGRATION) {
                    verifyVPlexVolumeForDataMigration(volume, currentVpool, newVpool, _dbClient);
                }
            }
        }
    } else if (DiscoveredDataObject.Type.vmax.name().equals(systemType) || DiscoveredDataObject.Type.vnxblock.name().equals(systemType) || DiscoveredDataObject.Type.hds.name().equals(systemType) || DiscoveredDataObject.Type.xtremio.name().equals(systemType) || DiscoveredDataObject.Type.ibmxiv.name().equals(systemType) || DiscoveredDataObject.Type.unity.name().equals(systemType)) {
        if (VirtualPool.vPoolSpecifiesHighAvailability(newVpool)) {
            // VNX/VMAX import to VPLEX cases
            notSuppReasonBuff.setLength(0);
            if (!VirtualPoolChangeAnalyzer.isVPlexImport(volume, currentVpool, newVpool, notSuppReasonBuff) || (!VirtualPoolChangeAnalyzer.doesVplexVpoolContainVolumeStoragePool(volume, newVpool, notSuppReasonBuff))) {
                _log.warn("VNX/VMAX cos change for volume is not supported: {}", notSuppReasonBuff.toString());
                throw APIException.badRequests.changeToVirtualPoolNotSupported(newVpool.getLabel(), notSuppReasonBuff.toString());
            }
            if (volume.isVolumeExported(_dbClient)) {
                throw APIException.badRequests.cannotImportExportedVolumeToVplex(volume.getId());
            } else if (BlockFullCopyUtils.volumeHasFullCopySession(volume, _dbClient)) {
                // The backend would have a full copy, but the VPLEX volume would not.
                throw APIException.badRequests.volumeForVpoolChangeHasFullCopies(volume.getLabel());
            } else {
                // Can't be imported if it has snapshot sessions, because we
                // don't currently support these behind VPLEX.
                List<BlockSnapshotSession> snapSessions = CustomQueryUtility.queryActiveResourcesByConstraint(_dbClient, BlockSnapshotSession.class, ContainmentConstraint.Factory.getParentSnapshotSessionConstraint(volume.getId()));
                if (!snapSessions.isEmpty()) {
                    throw APIException.badRequests.cannotImportVolumeWithSnapshotSessions(volume.getLabel());
                }
            }
        } else if (VirtualPool.vPoolSpecifiesProtection(newVpool)) {
            // VNX/VMAX import to RP cases (currently one)
            notSuppReasonBuff.setLength(0);
            if (!VirtualPoolChangeAnalyzer.isSupportedAddRPProtectionVirtualPoolChange(volume, currentVpool, newVpool, _dbClient, notSuppReasonBuff)) {
                _log.warn("VirtualPool change to Add RP Protection for volume is not supported: {}", notSuppReasonBuff.toString());
                throw APIException.badRequests.changeToVirtualPoolNotSupported(newVpool.getLabel(), notSuppReasonBuff.toString());
            } else if (BlockFullCopyUtils.volumeHasFullCopySession(volume, _dbClient)) {
                // Full copies not supported for RP protected volumes.
                throw APIException.badRequests.volumeForRPVpoolChangeHasFullCopies(volume.getLabel());
            } else {
                // Can't add RP if it has snapshot sessions, because we
                // don't currently support these for RP protected volumes.
                List<BlockSnapshotSession> snapSessions = CustomQueryUtility.queryActiveResourcesByConstraint(_dbClient, BlockSnapshotSession.class, ContainmentConstraint.Factory.getParentSnapshotSessionConstraint(volume.getId()));
                if (!snapSessions.isEmpty()) {
                    throw APIException.badRequests.volumeForRPVpoolChangeHasSnapshotSessions(volume.getLabel());
                }
            }
        } else if (VirtualPool.vPoolSpecifiesProtection(currentVpool) && !VirtualPool.vPoolSpecifiesProtection(newVpool)) {
            notSuppReasonBuff.setLength(0);
            if (!VirtualPoolChangeAnalyzer.isSupportedRPRemoveProtectionVirtualPoolChange(volume, currentVpool, newVpool, _dbClient, notSuppReasonBuff)) {
                throw APIException.badRequests.changeToVirtualPoolNotSupported(newVpool.getLabel(), notSuppReasonBuff.toString());
            }
        } else if (VirtualPool.vPoolSpecifiesSRDF(newVpool)) {
            // VMAX import to SRDF cases (currently one)
            notSuppReasonBuff.setLength(0);
            if (!VirtualPoolChangeAnalyzer.isSupportedSRDFVolumeVirtualPoolChange(volume, currentVpool, newVpool, _dbClient, notSuppReasonBuff)) {
                _log.warn("VMAX VirtualPool change for volume is not supported: {}", notSuppReasonBuff.toString());
                throw APIException.badRequests.changeToVirtualPoolNotSupported(newVpool.getLabel(), notSuppReasonBuff.toString());
            } else if (BlockFullCopyUtils.volumeHasFullCopySession(volume, _dbClient)) {
                // Full copy not supported for volumes with asynchronous copy mode.
                Map<URI, VpoolRemoteCopyProtectionSettings> remoteCopySettingsMap = VirtualPool.getRemoteProtectionSettings(newVpool, _dbClient);
                VpoolRemoteCopyProtectionSettings remoteCopyProtectionSettings = remoteCopySettingsMap.values().iterator().next();
                if (SupportedCopyModes.ASYNCHRONOUS.toString().equalsIgnoreCase(remoteCopyProtectionSettings.getCopyMode())) {
                    throw APIException.badRequests.volumeForSRDFVpoolChangeHasFullCopies(volume.getLabel());
                }
            }
        } else if (!NullColumnValueGetter.isNullNamedURI(volume.getSrdfParent()) || (volume.getSrdfTargets() != null && !volume.getSrdfTargets().isEmpty())) {
            // Cannot move SRDF Volume to non SRDF VPool
            throw APIException.badRequests.srdfVolumeVPoolChangeToNonSRDFVPoolNotSupported(volume.getId());
        } else if (VirtualPool.vPoolSpecifiesMirrors(newVpool, _dbClient)) {
            notSuppReasonBuff.setLength(0);
            if (!VirtualPoolChangeAnalyzer.isSupportedAddMirrorsVirtualPoolChange(volume, currentVpool, newVpool, _dbClient, notSuppReasonBuff)) {
                _log.warn("VirtualPool change to add continuous copies for volume {} is not supported: {}", volume.getId(), notSuppReasonBuff.toString());
                throw APIException.badRequests.changeToVirtualPoolNotSupported(newVpool.getLabel(), notSuppReasonBuff.toString());
            }
        } else {
            String errMsg = "there was an invalid property mismatch between source and target vPools.";
            _log.error(errMsg);
            notSuppReasonBuff.append(errMsg);
            throw APIException.badRequests.changeToVirtualPoolNotSupported(newVpool.getLabel(), notSuppReasonBuff.toString());
        }
    } else {
        _log.info("VirtualPool change volume is not a vplex, vmax or vnxblock volume");
        throw new ServiceCodeException(ServiceCode.API_VOLUME_VPOOL_CHANGE_DISRUPTIVE, "VirtualPool change is not supported for volume {0}", new Object[] { volume.getId() });
    }
}
Also used : ExportPathUpdater(com.emc.storageos.volumecontroller.placement.ExportPathUpdater) VpoolRemoteCopyProtectionSettings(com.emc.storageos.db.client.model.VpoolRemoteCopyProtectionSettings) BlockSnapshotSession(com.emc.storageos.db.client.model.BlockSnapshotSession) VirtualPoolChangeOperationEnum(com.emc.storageos.model.vpool.VirtualPoolChangeOperationEnum) ServiceCodeException(com.emc.storageos.svcs.errorhandling.resources.ServiceCodeException) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) URI(java.net.URI) NullColumnValueGetter.isNullURI(com.emc.storageos.db.client.util.NullColumnValueGetter.isNullURI) ITLRestRepList(com.emc.storageos.model.block.export.ITLRestRepList) VirtualPoolChangeList(com.emc.storageos.model.vpool.VirtualPoolChangeList) BlockSnapshotSessionList(com.emc.storageos.model.block.BlockSnapshotSessionList) ArrayList(java.util.ArrayList) TaskList(com.emc.storageos.model.TaskList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) List(java.util.List) NamedVolumesList(com.emc.storageos.model.block.NamedVolumesList) BulkList(com.emc.storageos.api.service.impl.response.BulkList) MigrationList(com.emc.storageos.model.block.MigrationList) SearchedResRepList(com.emc.storageos.api.service.impl.response.SearchedResRepList) MirrorList(com.emc.storageos.model.block.MirrorList) SnapshotList(com.emc.storageos.model.SnapshotList) BlockObject(com.emc.storageos.db.client.model.BlockObject) DiscoveredDataObject(com.emc.storageos.db.client.model.DiscoveredDataObject) DataObject(com.emc.storageos.db.client.model.DataObject) Map(java.util.Map) HashMap(java.util.HashMap) StringMap(com.emc.storageos.db.client.model.StringMap) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) ExportPathParams(com.emc.storageos.db.client.model.ExportPathParams)

Example 44 with VirtualPool

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

the class BlockVirtualPoolService method getMatchingPoolsForVirtualPoolAttributes.

/**
 * Return the matching pools for a given set of VirtualPool attributes.
 * This API is useful for user to find the matching pools before creating a VirtualPool.
 *
 * @prereq none
 * @param param : VirtualPoolAttributeParam
 * @brief List matching pools for virtual pool properties
 * @return matching pools.
 */
@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/matching-pools")
@CheckPermission(roles = { Role.SYSTEM_ADMIN, Role.RESTRICTED_SYSTEM_ADMIN })
public StoragePoolList getMatchingPoolsForVirtualPoolAttributes(BlockVirtualPoolParam param) {
    StoragePoolList poolList = new StoragePoolList();
    Map<URI, VpoolRemoteCopyProtectionSettings> remoteSettingsMap = new HashMap<URI, VpoolRemoteCopyProtectionSettings>();
    List<VpoolProtectionVarraySettings> protectionSettings = new ArrayList<VpoolProtectionVarraySettings>();
    Map<URI, VpoolProtectionVarraySettings> protectionSettingsMap = new HashMap<URI, VpoolProtectionVarraySettings>();
    VirtualPool vpool = prepareVirtualPool(param, remoteSettingsMap, protectionSettingsMap, protectionSettings);
    List<URI> storagePoolURIs = _dbClient.queryByType(StoragePool.class, true);
    List<StoragePool> allPools = _dbClient.queryObject(StoragePool.class, storagePoolURIs);
    StringBuffer errorMessage = new StringBuffer();
    List<StoragePool> matchedPools = ImplicitPoolMatcher.getMatchedPoolWithStoragePools(vpool, allPools, protectionSettingsMap, remoteSettingsMap, null, _dbClient, _coordinator, AttributeMatcher.VPOOL_MATCHERS, errorMessage);
    for (StoragePool pool : matchedPools) {
        poolList.getPools().add(toNamedRelatedResource(pool, pool.getNativeGuid()));
    }
    return poolList;
}
Also used : StoragePoolList(com.emc.storageos.model.pools.StoragePoolList) VpoolRemoteCopyProtectionSettings(com.emc.storageos.db.client.model.VpoolRemoteCopyProtectionSettings) StoragePool(com.emc.storageos.db.client.model.StoragePool) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) VpoolProtectionVarraySettings(com.emc.storageos.db.client.model.VpoolProtectionVarraySettings) VirtualPoolMapper.toBlockVirtualPool(com.emc.storageos.api.mapper.VirtualPoolMapper.toBlockVirtualPool) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) CheckPermission(com.emc.storageos.security.authorization.CheckPermission)

Example 45 with VirtualPool

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

the class BlockVirtualPoolService method getVirtualPoolForVirtualPoolChange.

/**
 * Returns all potential virtual pools, which supported the given virtual pool change operation
 * for a virtual pool change of the volumes specified in the request
 *
 * @prereq none
 *
 * @param param
 *
 * @brief Show potential virtual pools
 * @return A VirtualPoolChangeList that identifies each potential virtual
 *         pool, whether or not a change is allowed for the virtual pool,
 *         and if not, the reason why.
 */
@POST
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}/vpool-change/vpool")
@CheckPermission(roles = { Role.SYSTEM_MONITOR, Role.TENANT_ADMIN }, acls = { ACL.OWN, ACL.ALL })
public VirtualPoolChangeList getVirtualPoolForVirtualPoolChange(@PathParam("id") URI id, BulkIdParam param) {
    VirtualPool vpool = getVirtualPool(VirtualPool.Type.block, id);
    ArgValidator.checkFieldNotEmpty(param.getIds(), "volume_id");
    // We only need one volume from the current vpool to determine
    // which other vpools we can move to.
    Volume volume = _dbClient.queryObject(Volume.class, param.getIds().get(0));
    VirtualPoolChangeList virtualPoolChangeList = new VirtualPoolChangeList();
    if (volume != null) {
        if (!volume.getVirtualPool().equals(id)) {
            throw APIException.badRequests.volumeNotInVirtualPool(volume.getLabel(), vpool.getLabel());
        }
        // Get the block service implementation for this volume.
        BlockServiceApi blockServiceApi = BlockService.getBlockServiceImpl(volume, _dbClient);
        _log.info("Got BlockServiceApi for volume, now checking for vpool change candidates...");
        // Return the list of candidate VirtualPools for a VirtualPool change for this volume.
        VirtualPoolChangeList volumeVirturalPoolChangeList = blockServiceApi.getVirtualPoolForVirtualPoolChange(volume);
        virtualPoolChangeList.getVirtualPools().addAll(volumeVirturalPoolChangeList.getVirtualPools());
    }
    return virtualPoolChangeList;
}
Also used : Volume(com.emc.storageos.db.client.model.Volume) VirtualPoolChangeList(com.emc.storageos.model.vpool.VirtualPoolChangeList) VirtualPoolMapper.toBlockVirtualPool(com.emc.storageos.api.mapper.VirtualPoolMapper.toBlockVirtualPool) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces) CheckPermission(com.emc.storageos.security.authorization.CheckPermission)

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