Search in sources :

Example 1 with VirtualPoolChangeOperationEnum

use of com.emc.storageos.model.vpool.VirtualPoolChangeOperationEnum 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 2 with VirtualPoolChangeOperationEnum

use of com.emc.storageos.model.vpool.VirtualPoolChangeOperationEnum in project coprhd-controller by CoprHD.

the class VPlexBlockServiceApiImpl method changeVolumeVirtualPool.

/**
 * {@inheritDoc}
 */
@Override
public TaskList changeVolumeVirtualPool(List<Volume> volumes, VirtualPool vpool, VirtualPoolChangeParam vpoolChangeParam, String taskId) throws InternalException {
    TaskList taskList = new TaskList();
    StringBuffer notSuppReasonBuff = new StringBuffer();
    VirtualPool volumeVirtualPool = _dbClient.queryObject(VirtualPool.class, volumes.get(0).getVirtualPool());
    if (VirtualPoolChangeAnalyzer.isSupportedPathParamsChange(volumes.get(0), volumeVirtualPool, vpool, _dbClient, notSuppReasonBuff) || VirtualPoolChangeAnalyzer.isSupportedAutoTieringPolicyAndLimitsChange(volumes.get(0), volumeVirtualPool, vpool, _dbClient, notSuppReasonBuff)) {
        taskList = createTasksForVolumes(vpool, volumes, taskId);
        checkCommonVpoolUpdates(volumes, vpool, taskId);
        return taskList;
    }
    // Check if any of the volumes passed is a VPLEX volume
    // in a VPLEX CG with corresponding local consistency
    // group(s) for the backend volumes.
    Volume changeVPoolVolume = isVPlexVolumeInCgWithLocalType(volumes);
    if (changeVPoolVolume != null) {
        s_logger.info("Change vpool request has volumes in VPLEX CG with backing local CGs");
        // If any of the volumes is a CG and if this is a data
        // migration of the volumes, then the volumes passed must
        // contain all the volumes in that CG.
        VirtualPool currentVPool = _dbClient.queryObject(VirtualPool.class, changeVPoolVolume.getVirtualPool());
        VirtualPoolChangeOperationEnum vpoolChange = VirtualPoolChangeAnalyzer.getSupportedVPlexVolumeVirtualPoolChangeOperation(changeVPoolVolume, currentVPool, vpool, _dbClient, new StringBuffer());
        if ((vpoolChange != null) && (vpoolChange == VirtualPoolChangeOperationEnum.VPLEX_DATA_MIGRATION)) {
            s_logger.info("Vpool change is a data migration");
            ControllerOperationValuesWrapper operationsWrapper = new ControllerOperationValuesWrapper();
            operationsWrapper.put(ControllerOperationValuesWrapper.MIGRATION_SUSPEND_BEFORE_COMMIT, vpoolChangeParam.getMigrationSuspendBeforeCommit());
            operationsWrapper.put(ControllerOperationValuesWrapper.MIGRATION_SUSPEND_BEFORE_DELETE_SOURCE, vpoolChangeParam.getMigrationSuspendBeforeDeleteSource());
            List<Volume> volumesNotInRG = new ArrayList<Volume>();
            taskList = migrateVolumesInReplicationGroup(volumes, vpool, volumesNotInRG, null, operationsWrapper);
            // Migrate volumes not in Replication Group as single volumes
            if (!volumesNotInRG.isEmpty()) {
                // Get the migration descriptors
                List<VolumeDescriptor> descriptors = new ArrayList<VolumeDescriptor>();
                for (Volume volume : volumesNotInRG) {
                    StorageSystem vplexStorageSystem = _dbClient.queryObject(StorageSystem.class, volume.getStorageController());
                    descriptors.addAll(createChangeVirtualPoolDescriptors(vplexStorageSystem, volume, vpool, taskId, null, null, operationsWrapper, true));
                }
                // Create the tasks
                taskList.getTaskList().addAll(createTasksForVolumes(vpool, volumesNotInRG, taskId).getTaskList());
                // Now we get the Orchestration controller and use it to migrate all the volumes not in a RG.
                orchestrateVPoolChanges(volumesNotInRG, descriptors, taskId);
            }
            return taskList;
        }
    }
    // Otherwise proceed as we normally would performing
    // individual vpool changes for each volume.
    String nextTaskId = taskId;
    for (Volume volume : volumes) {
        taskList.getTaskList().addAll(changeVolumeVirtualPool(volume.getStorageController(), volume, vpool, vpoolChangeParam, nextTaskId).getTaskList());
        // Create a unique task id.
        nextTaskId = UUID.randomUUID().toString();
    }
    return taskList;
}
Also used : VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) Volume(com.emc.storageos.db.client.model.Volume) TaskList(com.emc.storageos.model.TaskList) VirtualPoolChangeOperationEnum(com.emc.storageos.model.vpool.VirtualPoolChangeOperationEnum) ArrayList(java.util.ArrayList) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) ControllerOperationValuesWrapper(com.emc.storageos.volumecontroller.impl.utils.ControllerOperationValuesWrapper) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 3 with VirtualPoolChangeOperationEnum

use of com.emc.storageos.model.vpool.VirtualPoolChangeOperationEnum in project coprhd-controller by CoprHD.

the class VirtualPoolChangeAnalyzer method isSupportedAddRPProtectionVirtualPoolChange.

/**
 * Determines if the volume qualifies for RP protection. (and if not, why not)
 *
 * @param volume A reference to the volume.
 * @param currentVpool A reference to the current volume Vpool.
 * @param newVpool The desired new Vpool.
 * @param dbClient A reference to a DB client.
 * @param notSuppReasonBuff [OUT] Specifies the reason a Vpool change is not
 *            supported between the two Vpool.
 * @return true if the add RP protection operation is allowed, false otherwise.
 */
public static boolean isSupportedAddRPProtectionVirtualPoolChange(Volume volume, VirtualPool currentVpool, VirtualPool newVpool, DbClient dbClient, StringBuffer notSuppReasonBuff) {
    s_logger.info(String.format("Checking isSupportedAddRPProtectionVirtualPoolChange from [%s] to [%s]...", currentVpool.getLabel(), newVpool.getLabel()));
    // Make sure the Vpool are not the same instance.
    if (isSameVirtualPool(currentVpool, newVpool, notSuppReasonBuff)) {
        return false;
    }
    // RP protection already exists
    if (volume.checkForRp() || VirtualPool.vPoolSpecifiesProtection(currentVpool)) {
        notSuppReasonBuff.append("Can't add RecoverPoint Protection since it already exists.");
        return false;
    }
    // Adding RP+VPLEX/MetroPoint protection to a non-VPLEX volume is not supported
    if (!VirtualPool.vPoolSpecifiesHighAvailability(currentVpool) && VirtualPool.vPoolSpecifiesRPVPlex(newVpool)) {
        notSuppReasonBuff.append("Can't add RecoverPoint+VPLEX Protection directly to non-VPLEX volume. Import to VPLEX first.");
        return false;
    }
    // Adding MetroPoint protection to a VPLEX Local volume is not supported
    if (VirtualPool.vPoolSpecifiesHighAvailability(currentVpool) && !VirtualPool.vPoolSpecifiesHighAvailabilityDistributed(currentVpool) && VirtualPool.vPoolSpecifiesMetroPoint(newVpool)) {
        notSuppReasonBuff.append("Can't add MetroPoint Protection directly to VPLEX Local volume. " + "Upgrade from VPLEX Local to VPLEX Distributed first.");
        return false;
    }
    // Throw an exception if any of the following properties are different
    // between the current and new Vpool. The check for continuous and protection-
    // based settings change is below.
    String[] include = new String[] { TYPE, VARRAYS, REF_VPOOL, MIRROR_VPOOL, FAST_EXPANSION, ACLS, INACTIVE, PROTOCOLS, PROVISIONING_TYPE, USE_MATCHED_POOLS, ARRAY_INFO, DRIVE_TYPE, AUTO_TIER_POLICY_NAME, HOST_IO_LIMIT_IOPS, HOST_IO_LIMIT_BANDWIDTH, VMAX_COMPRESSION_ENABLED, IS_THIN_VOLUME_PRE_ALLOCATION_ENABLED, ASSIGNED_STORAGE_POOLS };
    Map<String, Change> changes = analyzeChanges(currentVpool, newVpool, include, null, null);
    if (!changes.isEmpty()) {
        notSuppReasonBuff.append("These target virtual pool differences are invalid: ");
        fillInNotSupportedReasons(changes, notSuppReasonBuff);
        return false;
    }
    // If protection changed, we do support upgrade from
    // non-protected to protected. Make sure that change is there.
    include = new String[] { PROTECTION_VARRAY_SETTINGS };
    changes = analyzeChanges(currentVpool, newVpool, include, null, null);
    if (changes.isEmpty()) {
        notSuppReasonBuff.append("These target virtual pool differences are required: ");
        fillInNotSupportedReasons(changes, notSuppReasonBuff);
        return false;
    }
    // as the new vpool specifies HA and Protection both.
    if (VirtualPool.vPoolSpecifiesHighAvailability(currentVpool) && (VirtualPool.vPoolSpecifiesRPVPlex(newVpool) || VirtualPool.vPoolSpecifiesMetroPoint(newVpool))) {
        VirtualPoolChangeOperationEnum op = vplexCommonChecks(volume, currentVpool, newVpool, dbClient, notSuppReasonBuff, include);
        if (op == null || !op.equals(VirtualPoolChangeOperationEnum.RP_PROTECTED)) {
            return false;
        }
    }
    return true;
}
Also used : VirtualPoolChangeOperationEnum(com.emc.storageos.model.vpool.VirtualPoolChangeOperationEnum)

Example 4 with VirtualPoolChangeOperationEnum

use of com.emc.storageos.model.vpool.VirtualPoolChangeOperationEnum in project coprhd-controller by CoprHD.

the class VPlexBlockServiceApiImpl method getVirtualPoolChangeAllowedOperations.

/**
 * {@inheritDoc}
 */
@Override
protected List<VirtualPoolChangeOperationEnum> getVirtualPoolChangeAllowedOperations(Volume volume, VirtualPool currentVirtualPool, VirtualPool newVirtualPool, StringBuffer notSuppReasonBuff) {
    List<VirtualPoolChangeOperationEnum> allowedOperations = new ArrayList<VirtualPoolChangeOperationEnum>();
    // Get the varray for the volume.
    URI volumeVarrayURI = volume.getVirtualArray();
    StringSet newVirtualPoolVarrays = newVirtualPool.getVirtualArrays();
    if ((newVirtualPoolVarrays != null) && (!newVirtualPoolVarrays.isEmpty()) && (!newVirtualPoolVarrays.contains(volumeVarrayURI.toString()))) {
        // The VirtualPool is not allowed because it is not available in the
        // volume varray.
        notSuppReasonBuff.append("The VirtualPool is not available to the volume's varray");
    } else if (VirtualPool.vPoolSpecifiesRPVPlex(newVirtualPool)) {
        if (VirtualPoolChangeAnalyzer.isSupportedAddRPProtectionVirtualPoolChange(volume, currentVirtualPool, newVirtualPool, _dbClient, notSuppReasonBuff)) {
            if (VirtualPool.vPoolSpecifiesRPVPlex(currentVirtualPool)) {
                allowedOperations.add(VirtualPoolChangeOperationEnum.RP_UPGRADE_TO_METROPOINT);
            } else {
                allowedOperations.add(VirtualPoolChangeOperationEnum.RP_PROTECTED);
            }
        }
    } else if (VirtualPool.vPoolSpecifiesHighAvailability(newVirtualPool)) {
        VirtualPoolChangeOperationEnum allowedOperation = VirtualPoolChangeAnalyzer.getSupportedVPlexVolumeVirtualPoolChangeOperation(volume, currentVirtualPool, newVirtualPool, _dbClient, notSuppReasonBuff);
        if (allowedOperation != null) {
            allowedOperations.add(allowedOperation);
        }
    }
    return allowedOperations;
}
Also used : VirtualPoolChangeOperationEnum(com.emc.storageos.model.vpool.VirtualPoolChangeOperationEnum) ArrayList(java.util.ArrayList) StringSet(com.emc.storageos.db.client.model.StringSet) FCTN_STRING_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_STRING_TO_URI) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) FCTN_VPLEX_MIRROR_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_VPLEX_MIRROR_TO_URI)

Example 5 with VirtualPoolChangeOperationEnum

use of com.emc.storageos.model.vpool.VirtualPoolChangeOperationEnum in project coprhd-controller by CoprHD.

the class RPBlockServiceApiImpl method getVirtualPoolChangeAllowedOperations.

@Override
protected List<VirtualPoolChangeOperationEnum> getVirtualPoolChangeAllowedOperations(Volume volume, VirtualPool currentVpool, VirtualPool newVpool, StringBuffer notSuppReasonBuff) {
    List<VirtualPoolChangeOperationEnum> allowedOperations = new ArrayList<VirtualPoolChangeOperationEnum>();
    // can been exposed in the Migration Services catalog to support RP+VPLEX Data Migrations.
    if (volume.checkPersonality(Volume.PersonalityTypes.METADATA)) {
        boolean vplex = RPHelper.isVPlexVolume(volume, _dbClient);
        if (vplex) {
            if (VirtualPoolChangeAnalyzer.vpoolChangeRequiresMigration(currentVpool, newVpool)) {
                // Allow the VPLEX Data Migration operation
                allowedOperations.add(VirtualPoolChangeOperationEnum.VPLEX_DATA_MIGRATION);
            }
        }
    }
    // should it meet the correct criteria.
    if (volume.checkForRp() && VirtualPool.vPoolSpecifiesProtection(currentVpool) && !VirtualPool.vPoolSpecifiesProtection(newVpool)) {
        if (VirtualPoolChangeAnalyzer.isSupportedRPRemoveProtectionVirtualPoolChange(volume, currentVpool, newVpool, _dbClient, notSuppReasonBuff)) {
            allowedOperations.add(VirtualPoolChangeOperationEnum.RP_REMOVE_PROTECTION);
        }
    }
    // specifying RP Protection.
    if (VirtualPool.vPoolSpecifiesProtection(newVpool)) {
        boolean vplex = RPHelper.isVPlexVolume(volume, _dbClient);
        // Check to see if this is a VPLEX volume
        if (vplex) {
            // Get the varray for the volume.
            URI volumeVarrayURI = volume.getVirtualArray();
            StringSet newVirtualPoolVarrays = newVpool.getVirtualArrays();
            if ((newVirtualPoolVarrays != null) && (!newVirtualPoolVarrays.isEmpty()) && (!newVirtualPoolVarrays.contains(volumeVarrayURI.toString()))) {
                // The VirtualPool is not allowed because it is not available in the
                // volume varray.
                notSuppReasonBuff.append("The VirtualPool is not available to the volume's varray");
            } else if (VirtualPool.vPoolSpecifiesRPVPlex(currentVpool) && VirtualPool.vPoolSpecifiesRPVPlex(newVpool)) {
                if (VirtualPoolChangeAnalyzer.isSupportedRPVPlexMigrationVirtualPoolChange(volume, currentVpool, newVpool, _dbClient, notSuppReasonBuff, null)) {
                    // Allow the VPLEX Data Migration operation
                    allowedOperations.add(VirtualPoolChangeOperationEnum.VPLEX_DATA_MIGRATION);
                }
                if (VirtualPoolChangeAnalyzer.isSupportedUpgradeToMetroPointVirtualPoolChange(volume, currentVpool, newVpool, _dbClient, notSuppReasonBuff)) {
                    // Allow the RP change protection operation
                    allowedOperations.add(VirtualPoolChangeOperationEnum.RP_UPGRADE_TO_METROPOINT);
                }
            } else if (VirtualPool.vPoolSpecifiesRPVPlex(newVpool)) {
                if (VirtualPoolChangeAnalyzer.isSupportedAddRPProtectionVirtualPoolChange(volume, currentVpool, newVpool, _dbClient, notSuppReasonBuff)) {
                    // Allow the RP Protection add operation
                    allowedOperations.add(VirtualPoolChangeOperationEnum.RP_PROTECTED);
                }
            }
        } else if (VirtualPoolChangeAnalyzer.isSupportedAddRPProtectionVirtualPoolChange(volume, currentVpool, newVpool, _dbClient, notSuppReasonBuff)) {
            allowedOperations.add(VirtualPoolChangeOperationEnum.RP_PROTECTED);
        }
    }
    return allowedOperations;
}
Also used : VirtualPoolChangeOperationEnum(com.emc.storageos.model.vpool.VirtualPoolChangeOperationEnum) ArrayList(java.util.ArrayList) StringSet(com.emc.storageos.db.client.model.StringSet) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI)

Aggregations

VirtualPoolChangeOperationEnum (com.emc.storageos.model.vpool.VirtualPoolChangeOperationEnum)7 ArrayList (java.util.ArrayList)5 VirtualPool (com.emc.storageos.db.client.model.VirtualPool)4 URI (java.net.URI)4 NamedURI (com.emc.storageos.db.client.model.NamedURI)3 StringSet (com.emc.storageos.db.client.model.StringSet)3 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)2 Volume (com.emc.storageos.db.client.model.Volume)2 VpoolRemoteCopyProtectionSettings (com.emc.storageos.db.client.model.VpoolRemoteCopyProtectionSettings)2 TaskList (com.emc.storageos.model.TaskList)2 VirtualPoolChangeList (com.emc.storageos.model.vpool.VirtualPoolChangeList)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 BulkList (com.emc.storageos.api.service.impl.response.BulkList)1 SearchedResRepList (com.emc.storageos.api.service.impl.response.SearchedResRepList)1 VolumeDescriptor (com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor)1 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)1 BlockObject (com.emc.storageos.db.client.model.BlockObject)1 BlockSnapshotSession (com.emc.storageos.db.client.model.BlockSnapshotSession)1 DataObject (com.emc.storageos.db.client.model.DataObject)1