Search in sources :

Example 1 with VPlexController

use of com.emc.storageos.vplexcontroller.VPlexController in project coprhd-controller by CoprHD.

the class MigrationService method deleteMigration.

/**
 * Delete a migration that has been committed or cancelled
 *
 * @param id the URN of a ViPR migration.
 *
 * @brief Delete a committed or cancelled migration.
 * @return A TaskResourceRep
 */
@POST
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}/deactivate")
@CheckPermission(roles = { Role.SYSTEM_ADMIN, Role.RESTRICTED_SYSTEM_ADMIN })
public TaskResourceRep deleteMigration(@PathParam("id") URI id) {
    ArgValidator.checkFieldUriType(id, Migration.class, "id");
    Migration migration = queryResource(id);
    if (!BulkList.MigrationFilter.isUserAuthorizedForMigration(migration, getUserFromContext(), _permissionsHelper)) {
        StorageOSUser user = getUserFromContext();
        throw APIException.forbidden.insufficientPermissionsForUser(user.getName());
    }
    String status = migration.getMigrationStatus();
    String migrationName = migration.getLabel();
    if (status == null || status.isEmpty() || migrationName == null || migrationName.isEmpty()) {
        throw APIException.badRequests.migrationHasntStarted(id.toString());
    }
    if (!status.equalsIgnoreCase(VPlexMigrationInfo.MigrationStatus.COMMITTED.getStatusValue()) && !status.equalsIgnoreCase(VPlexMigrationInfo.MigrationStatus.CANCELLED.getStatusValue()) && !status.equalsIgnoreCase(VPlexMigrationInfo.MigrationStatus.ERROR.getStatusValue())) {
        throw VPlexApiException.exceptions.cantRemoveMigrationInvalidState(migrationName);
    }
    URI volId = migration.getVolume();
    Volume vplexVol = _dbClient.queryObject(Volume.class, volId);
    // Create a unique task id.
    String taskId = UUID.randomUUID().toString();
    Operation op = _dbClient.createTaskOpStatus(Volume.class, volId, taskId, ResourceOperationTypeEnum.DELETE_MIGRATION);
    TaskResourceRep task = toTask(vplexVol, taskId, op);
    if (migration.getInactive()) {
        s_logger.info("Migration {} has been deleted", id);
        op.ready();
        vplexVol.getOpStatus().createTaskStatus(taskId, op);
        _dbClient.persistObject(vplexVol);
        return task;
    }
    try {
        VPlexController controller = _vplexBlockServiceApi.getController();
        controller.deleteMigration(vplexVol.getStorageController(), id, taskId);
    } catch (InternalException e) {
        s_logger.error("Error", e);
        String errMsg = String.format("Error: %s", e.getMessage());
        task.setState(Operation.Status.error.name());
        task.setMessage(errMsg);
        op.error(e);
        vplexVol.getOpStatus().updateTaskStatus(taskId, op);
        _dbClient.persistObject(vplexVol);
    }
    return task;
}
Also used : VPlexController(com.emc.storageos.vplexcontroller.VPlexController) Volume(com.emc.storageos.db.client.model.Volume) Migration(com.emc.storageos.db.client.model.Migration) StorageOSUser(com.emc.storageos.security.authentication.StorageOSUser) TaskResourceRep(com.emc.storageos.model.TaskResourceRep) Operation(com.emc.storageos.db.client.model.Operation) URI(java.net.URI) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces) CheckPermission(com.emc.storageos.security.authorization.CheckPermission)

Example 2 with VPlexController

use of com.emc.storageos.vplexcontroller.VPlexController in project coprhd-controller by CoprHD.

the class MigrationService method resumeMigration.

/**
 * Resume a migration that was previously paused.
 *
 * @prereq The migration is paused
 *
 * @param id the URN of a ViPR migration.
 *
 * @brief Resume a paused migration.
 * @return A TaskResourceRep
 */
@POST
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}/resume")
@CheckPermission(roles = { Role.SYSTEM_ADMIN, Role.RESTRICTED_SYSTEM_ADMIN })
public TaskResourceRep resumeMigration(@PathParam("id") URI id) {
    ArgValidator.checkFieldUriType(id, Migration.class, "id");
    Migration migration = queryResource(id);
    if (!BulkList.MigrationFilter.isUserAuthorizedForMigration(migration, getUserFromContext(), _permissionsHelper)) {
        StorageOSUser user = getUserFromContext();
        throw APIException.forbidden.insufficientPermissionsForUser(user.getName());
    }
    String status = migration.getMigrationStatus();
    String migrationName = migration.getLabel();
    if (status == null || status.isEmpty() || migrationName == null || migrationName.isEmpty()) {
        throw APIException.badRequests.migrationHasntStarted(id.toString());
    }
    if (!status.equalsIgnoreCase(VPlexMigrationInfo.MigrationStatus.PAUSED.getStatusValue())) {
        throw APIException.badRequests.migrationCantBeResumed(migrationName, status);
    }
    URI volId = migration.getVolume();
    Volume vplexVol = _dbClient.queryObject(Volume.class, volId);
    // Create a unique task id.
    String taskId = UUID.randomUUID().toString();
    // Create a task for the virtual volume being migrated and set the
    // initial task state to pending.
    Operation op = _dbClient.createTaskOpStatus(Volume.class, volId, taskId, ResourceOperationTypeEnum.RESUME_MIGRATION);
    TaskResourceRep task = toTask(vplexVol, taskId, op);
    try {
        VPlexController controller = _vplexBlockServiceApi.getController();
        controller.resumeMigration(vplexVol.getStorageController(), id, taskId);
    } catch (InternalException e) {
        s_logger.error("Error", e);
        String errMsg = String.format("Error: %s", e.getMessage());
        task.setState(Operation.Status.error.name());
        task.setMessage(errMsg);
        op.error(e);
        vplexVol.getOpStatus().updateTaskStatus(taskId, op);
        _dbClient.persistObject(vplexVol);
    }
    return task;
}
Also used : VPlexController(com.emc.storageos.vplexcontroller.VPlexController) Volume(com.emc.storageos.db.client.model.Volume) Migration(com.emc.storageos.db.client.model.Migration) StorageOSUser(com.emc.storageos.security.authentication.StorageOSUser) TaskResourceRep(com.emc.storageos.model.TaskResourceRep) Operation(com.emc.storageos.db.client.model.Operation) URI(java.net.URI) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces) CheckPermission(com.emc.storageos.security.authorization.CheckPermission)

Example 3 with VPlexController

use of com.emc.storageos.vplexcontroller.VPlexController in project coprhd-controller by CoprHD.

the class MigrationService method cancelMigration.

/**
 * Cancel a migration that has yet to be committed.
 *
 * @prereq none
 *
 * @param id the URN of a ViPR migration.
 *
 * @brief Cancel an uncommitted migration.
 * @return A TaskResourceRep
 */
@POST
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}/cancel")
@CheckPermission(roles = { Role.SYSTEM_ADMIN, Role.RESTRICTED_SYSTEM_ADMIN })
public TaskResourceRep cancelMigration(@PathParam("id") URI id) {
    ArgValidator.checkFieldUriType(id, Migration.class, "id");
    Migration migration = queryResource(id);
    if (!BulkList.MigrationFilter.isUserAuthorizedForMigration(migration, getUserFromContext(), _permissionsHelper)) {
        StorageOSUser user = getUserFromContext();
        throw APIException.forbidden.insufficientPermissionsForUser(user.getName());
    }
    if (migration == null || migration.getInactive()) {
        throw APIException.badRequests.cancelMigrationFailed(id.toString(), "The migration is invalid");
    }
    String status = migration.getMigrationStatus();
    String migrationName = migration.getLabel();
    URI volId = migration.getVolume();
    Volume vplexVol = _dbClient.queryObject(Volume.class, volId);
    if (vplexVol == null || vplexVol.getInactive()) {
        throw APIException.badRequests.cancelMigrationFailed(migrationName, "The migrating volume is not valid");
    }
    // Don't allow cancel operation if the vplex volume is in a CG
    URI cgURI = vplexVol.getConsistencyGroup();
    if (!NullColumnValueGetter.isNullURI(cgURI)) {
        throw APIException.badRequests.cancelMigrationFailed(migrationName, "Migration cancellation is not supported for the volumes in consistency group");
    }
    if (status == null || status.isEmpty() || migrationName == null || migrationName.isEmpty()) {
        throw APIException.badRequests.migrationHasntStarted(id.toString());
    }
    if (status.equalsIgnoreCase(VPlexMigrationInfo.MigrationStatus.COMMITTED.getStatusValue())) {
        throw APIException.badRequests.migrationCantBeCancelled(migrationName, status);
    }
    // Create a unique task id.
    String taskId = UUID.randomUUID().toString();
    Operation op = _dbClient.createTaskOpStatus(Volume.class, volId, taskId, ResourceOperationTypeEnum.CANCEL_MIGRATION);
    TaskResourceRep task = toTask(vplexVol, taskId, op);
    if (status.equalsIgnoreCase(VPlexMigrationInfo.MigrationStatus.CANCELLED.getStatusValue()) || status.equalsIgnoreCase(VPlexMigrationInfo.MigrationStatus.PARTIALLY_CANCELLED.getStatusValue())) {
        // it has been cancelled
        s_logger.info("Migration {} has been cancelled", id);
        op.ready();
        vplexVol.getOpStatus().createTaskStatus(taskId, op);
        _dbClient.persistObject(vplexVol);
        return task;
    }
    try {
        VPlexController controller = _vplexBlockServiceApi.getController();
        controller.cancelMigration(vplexVol.getStorageController(), id, taskId);
    } catch (InternalException e) {
        s_logger.error("Controller Error", e);
        String errMsg = String.format("Controller Error: %s", e.getMessage());
        task.setState(Operation.Status.error.name());
        task.setMessage(errMsg);
        op.error(e);
        vplexVol.getOpStatus().updateTaskStatus(taskId, op);
        _dbClient.persistObject(vplexVol);
    }
    return task;
}
Also used : VPlexController(com.emc.storageos.vplexcontroller.VPlexController) Volume(com.emc.storageos.db.client.model.Volume) Migration(com.emc.storageos.db.client.model.Migration) StorageOSUser(com.emc.storageos.security.authentication.StorageOSUser) TaskResourceRep(com.emc.storageos.model.TaskResourceRep) Operation(com.emc.storageos.db.client.model.Operation) URI(java.net.URI) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces) CheckPermission(com.emc.storageos.security.authorization.CheckPermission)

Example 4 with VPlexController

use of com.emc.storageos.vplexcontroller.VPlexController in project coprhd-controller by CoprHD.

the class VPlexBlockServiceApiImpl method importVirtualVolume.

/**
 * Import an existing volume to a VPLEX to make it a Virtual Volume.
 * Outline: 1. Determine the VPLEX(s) that could be used. 2. If this is to
 * become a distributed virtual volume, get a Recommendation for the pool
 * for the haVirtualArray of the Virtual Volume. 3. Create a Virtual Volume
 * and link it to the existing Volume. 4. If this is a distributed virtual
 * volume, create a new Volume and link it to the virtual volume. 5. Format
 * the parameters and call the controller.
 *
 * @param arrayURI -- the URI of the Storage Array holding the existing
 *            Volume.
 * @param importVolume -- An existing Volume that has been provisioned.
 * @param vpool -- The vpool requested on the vpool change request.
 * @param taskId -- The taskId
 * @throws InternalException
 */
public void importVirtualVolume(URI arrayURI, Volume importVolume, VirtualPool vpool, String taskId) throws InternalException {
    VirtualArray neighborhood = _dbClient.queryObject(VirtualArray.class, importVolume.getVirtualArray());
    Project project = _dbClient.queryObject(Project.class, importVolume.getProject());
    URI nullPoolURI = NullColumnValueGetter.getNullURI();
    BlockConsistencyGroup consistencyGroup = null;
    if (importVolume.getConsistencyGroup() != null) {
        consistencyGroup = _dbClient.queryObject(BlockConsistencyGroup.class, importVolume.getConsistencyGroup());
    }
    // Determine the VPLEX(s) that could be used.
    Set<URI> vplexes = ConnectivityUtil.getVPlexSystemsAssociatedWithArray(_dbClient, arrayURI);
    Iterator<URI> vplexIter = vplexes.iterator();
    while (vplexIter.hasNext()) {
        StorageSystem vplex = _dbClient.queryObject(StorageSystem.class, vplexIter.next());
        StringSet vplexVarrays = vplex.getVirtualArrays();
        if ((vplexVarrays == null) || (vplexVarrays.isEmpty()) || (!vplexVarrays.contains(neighborhood.getId().toString()))) {
            vplexIter.remove();
        }
    }
    if (vplexes.isEmpty()) {
        throw APIException.badRequests.noVPlexSystemsAssociatedWithStorageSystem(arrayURI);
    }
    // If distributed virtual volume, get a recommendation.
    // Then create the volume.
    List<VolumeDescriptor> descriptors = new ArrayList<VolumeDescriptor>();
    URI vplexURI = null;
    StorageSystem vplexSystem = null;
    Volume createVolume = null;
    Project vplexProject;
    if (vpool.getHighAvailability().equals(VirtualPool.HighAvailabilityType.vplex_distributed.name())) {
        // Determine if the user requested a specific HA VirtualArray and an associated HA VirtualPool.
        VirtualArray requestedHaVarray = null;
        VirtualPool requestedHaVirtualPool = vpool;
        try {
            if (vpool.getHaVarrayVpoolMap() != null && !vpool.getHaVarrayVpoolMap().isEmpty()) {
                for (String haNH : vpool.getHaVarrayVpoolMap().keySet()) {
                    if (haNH.equals(NullColumnValueGetter.getNullURI().toString())) {
                        continue;
                    }
                    requestedHaVarray = _dbClient.queryObject(VirtualArray.class, new URI(haNH));
                    String haVirtualPool = vpool.getHaVarrayVpoolMap().get(haNH);
                    if (haVirtualPool.equals(NullColumnValueGetter.getNullURI().toString())) {
                        continue;
                    }
                    requestedHaVirtualPool = _dbClient.queryObject(VirtualPool.class, new URI(haVirtualPool));
                    break;
                }
            }
        } catch (URISyntaxException ex) {
            s_logger.error("URISyntaxException", ex);
        }
        VirtualPoolCapabilityValuesWrapper cosCapabilities = new VirtualPoolCapabilityValuesWrapper();
        cosCapabilities.put(VirtualPoolCapabilityValuesWrapper.SIZE, getVolumeCapacity(importVolume));
        cosCapabilities.put(VirtualPoolCapabilityValuesWrapper.RESOURCE_COUNT, new Integer(1));
        cosCapabilities.put(VirtualPoolCapabilityValuesWrapper.THIN_PROVISIONING, importVolume.getThinlyProvisioned());
        // Get the recommendations and pick one.
        List<Recommendation> recommendations = getBlockScheduler().scheduleStorageForImport(neighborhood, vplexes, requestedHaVarray, requestedHaVirtualPool, cosCapabilities);
        if (recommendations.isEmpty()) {
            throw APIException.badRequests.noStorageFoundForVolumeMigration(requestedHaVirtualPool.getLabel(), requestedHaVarray.getLabel(), importVolume.getId());
        }
        Recommendation recommendation = recommendations.get(0);
        VPlexRecommendation vplexRecommendation = (VPlexRecommendation) recommendation;
        vplexURI = vplexRecommendation.getVPlexStorageSystem();
        vplexSystem = _dbClient.queryObject(StorageSystem.class, vplexURI);
        vplexProject = getVplexProject(vplexSystem, _dbClient, _tenantsService);
        // Prepare the created volume.
        VirtualArray haVirtualArray = _dbClient.queryObject(VirtualArray.class, vplexRecommendation.getVirtualArray());
        createVolume = prepareVolumeForRequest(getVolumeCapacity(importVolume), vplexProject, haVirtualArray, vpool, vplexRecommendation.getSourceStorageSystem(), vplexRecommendation.getSourceStoragePool(), importVolume.getLabel() + "-1", ResourceOperationTypeEnum.CREATE_BLOCK_VOLUME, taskId, _dbClient);
        createVolume.addInternalFlags(Flag.INTERNAL_OBJECT);
        _dbClient.updateObject(createVolume);
        VolumeDescriptor desc = new VolumeDescriptor(VolumeDescriptor.Type.BLOCK_DATA, createVolume.getStorageController(), createVolume.getId(), createVolume.getPool(), cosCapabilities);
        descriptors.add(desc);
    } else {
        vplexURI = vplexes.toArray(new URI[0])[0];
        vplexSystem = _dbClient.queryObject(StorageSystem.class, vplexURI);
        vplexProject = getVplexProject(vplexSystem, _dbClient, _tenantsService);
    }
    // Prepare the VPLEX Virtual volume.
    Volume vplexVolume = prepareVolumeForRequest(getVolumeCapacity(importVolume), project, neighborhood, vpool, vplexURI, nullPoolURI, importVolume.getLabel(), ResourceOperationTypeEnum.CREATE_BLOCK_VOLUME, taskId, _dbClient);
    vplexVolume.setAssociatedVolumes(new StringSet());
    vplexVolume.getAssociatedVolumes().add(importVolume.getId().toString());
    if (createVolume != null) {
        vplexVolume.getAssociatedVolumes().add(createVolume.getId().toString());
    }
    if (consistencyGroup != null) {
        // If the volume being converted to a virtual volume has a CG, make the virtual
        // volume a member of the CG.
        vplexVolume.setConsistencyGroup(consistencyGroup.getId());
        consistencyGroup.addRequestedTypes(Arrays.asList(BlockConsistencyGroup.Types.VPLEX.name()));
        _dbClient.updateObject(consistencyGroup);
    }
    vplexVolume.setVirtualPool(vpool.getId());
    _dbClient.updateObject(vplexVolume);
    // Add a descriptor for the VPLEX_VIRT_VOLUME
    VolumeDescriptor desc = new VolumeDescriptor(VolumeDescriptor.Type.VPLEX_VIRT_VOLUME, vplexURI, vplexVolume.getId(), null, null);
    descriptors.add(desc);
    // Add a descriptor for the import volume too!
    desc = new VolumeDescriptor(VolumeDescriptor.Type.VPLEX_IMPORT_VOLUME, importVolume.getStorageController(), importVolume.getId(), importVolume.getPool(), null);
    descriptors.add(desc);
    // Now send the command to the controller.
    try {
        s_logger.info("Calling VPlex controller.");
        VPlexController controller = getController();
        controller.importVolume(vplexURI, descriptors, vplexProject.getId(), vplexProject.getTenantOrg().getURI(), vpool.getId(), importVolume.getLabel() + SRC_BACKEND_VOL_LABEL_SUFFIX, null, Boolean.TRUE, taskId);
    } catch (InternalException ex) {
        s_logger.error("ControllerException on importVolume", ex);
        String errMsg = String.format("ControllerException: %s", ex.getMessage());
        Operation statusUpdate = new Operation(Operation.Status.error.name(), errMsg);
        _dbClient.updateTaskOpStatus(Volume.class, vplexVolume.getId(), taskId, statusUpdate);
        _dbClient.markForDeletion(vplexVolume);
        if (createVolume != null) {
            _dbClient.markForDeletion(createVolume);
        }
        throw ex;
    }
}
Also used : VirtualPoolCapabilityValuesWrapper(com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper) VirtualArray(com.emc.storageos.db.client.model.VirtualArray) VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) VPlexController(com.emc.storageos.vplexcontroller.VPlexController) ArrayList(java.util.ArrayList) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) URISyntaxException(java.net.URISyntaxException) Operation(com.emc.storageos.db.client.model.Operation) 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) SRDFCopyRecommendation(com.emc.storageos.volumecontroller.SRDFCopyRecommendation) VolumeRecommendation(com.emc.storageos.api.service.impl.placement.VolumeRecommendation) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) Recommendation(com.emc.storageos.volumecontroller.Recommendation) SRDFRecommendation(com.emc.storageos.volumecontroller.SRDFRecommendation) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) Project(com.emc.storageos.db.client.model.Project) Volume(com.emc.storageos.db.client.model.Volume) StringSet(com.emc.storageos.db.client.model.StringSet) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 5 with VPlexController

use of com.emc.storageos.vplexcontroller.VPlexController in project coprhd-controller by CoprHD.

the class VPlexBlockServiceApiImpl method updateConsistencyGroup.

/**
 * {@inheritDoc}
 */
@Override
public TaskResourceRep updateConsistencyGroup(StorageSystem cgStorageSystem, List<Volume> cgVolumes, BlockConsistencyGroup consistencyGroup, List<URI> addVolumesList, List<URI> removeVolumesList, String taskId) throws ControllerException {
    // addVolumesList could be volumes, or full copies, or snapshots or mirrors.
    List<URI> addVolumes = new ArrayList<URI>();
    List<URI> addSnapshots = new ArrayList<URI>();
    List<URI> addFullcopies = new ArrayList<URI>();
    for (URI volumeURI : addVolumesList) {
        BlockObject blockObject = BlockObject.fetch(_dbClient, volumeURI);
        if (blockObject instanceof BlockMirror) {
            throw APIException.badRequests.actionNotApplicableForVplexVolumeMirrors(ResourceOperationTypeEnum.UPDATE_CONSISTENCY_GROUP.name());
        } else if (blockObject instanceof BlockSnapshot) {
            addSnapshots.add(volumeURI);
        } else if (blockObject instanceof Volume) {
            boolean isFullCopy = ControllerUtils.isVolumeFullCopy((Volume) blockObject, _dbClient);
            if (isFullCopy) {
                addFullcopies.add(volumeURI);
            } else {
                addVolumes.add(volumeURI);
            }
        }
    }
    if ((!addVolumes.isEmpty() && (!addSnapshots.isEmpty() || !addFullcopies.isEmpty())) || (!addSnapshots.isEmpty() && !addFullcopies.isEmpty())) {
        throw APIException.badRequests.cantUpdateCGWithMixedBlockObjects(consistencyGroup.getLabel());
    }
    // group.
    if (!addVolumes.isEmpty()) {
        Iterator<Volume> cgVolumesIter = cgVolumes.iterator();
        if (cgVolumesIter.hasNext()) {
            Volume cgVolume = cgVolumesIter.next();
            VirtualPool cgVPool = _permissionsHelper.getObjectById(cgVolume.getVirtualPool(), VirtualPool.class);
            URI cgVArrayURI = cgVolume.getVirtualArray();
            String cgHAType = cgVPool.getHighAvailability();
            for (URI volumeURI : addVolumes) {
                Volume addVolume = _permissionsHelper.getObjectById(volumeURI, Volume.class);
                VirtualPool addVolumeVPool = _permissionsHelper.getObjectById(addVolume.getVirtualPool(), VirtualPool.class);
                if (!addVolumeVPool.getHighAvailability().equals(cgHAType)) {
                    throw APIException.badRequests.invalidParameterConsistencyGroupVolumeHasIncorrectHighAvailability(cgVolume.getId(), cgHAType);
                } else if (!cgVArrayURI.equals(addVolume.getVirtualArray())) {
                    throw APIException.badRequests.invalidParameterConsistencyGroupVolumeHasIncorrectVArray(cgVolume.getId(), cgVArrayURI);
                }
            }
        }
        // Check if the volumes have been in the CG, and not ingestion case
        if (consistencyGroup.getTypes().contains(Types.LOCAL.toString()) && !cgVolumes.isEmpty()) {
            Set<String> cgVolumesURISet = new HashSet<String>();
            for (Volume cgVolume : cgVolumes) {
                cgVolumesURISet.add(cgVolume.getId().toString());
            }
            Iterator<URI> iter = addVolumes.iterator();
            while (iter.hasNext()) {
                if (cgVolumesURISet.contains(iter.next().toString())) {
                    iter.remove();
                }
            }
            if (addVolumes.isEmpty()) {
                // All volumes in the addVolumes list have been in the CG. return success
                s_logger.info("The volumes have been added to the CG");
                Operation op = new Operation();
                op.setResourceType(ResourceOperationTypeEnum.UPDATE_CONSISTENCY_GROUP);
                op.ready("Volumes have been added to the consistency group");
                _dbClient.createTaskOpStatus(BlockConsistencyGroup.class, consistencyGroup.getId(), taskId, op);
                return toTask(consistencyGroup, taskId, op);
            }
        }
    }
    // Only add snapshot or full copies to CG if backend volumes are from the same storage system.
    if (!addSnapshots.isEmpty() || !addFullcopies.isEmpty()) {
        if (!VPlexUtil.isVPLEXCGBackendVolumesInSameStorage(cgVolumes, _dbClient)) {
            throw APIException.badRequests.cantUpdateCGWithReplicaFromMultipleSystems(consistencyGroup.getLabel());
        }
    }
    Operation op = _dbClient.createTaskOpStatus(BlockConsistencyGroup.class, consistencyGroup.getId(), taskId, ResourceOperationTypeEnum.UPDATE_CONSISTENCY_GROUP);
    // When adding snapshots to CG, just call block implementation.
    if (!addSnapshots.isEmpty()) {
        BlockSnapshot snapshot = _permissionsHelper.getObjectById(addSnapshots.get(0), BlockSnapshot.class);
        URI systemURI = snapshot.getStorageController();
        StorageSystem system = _permissionsHelper.getObjectById(systemURI, StorageSystem.class);
        BlockController controller = getController(BlockController.class, system.getSystemType());
        controller.updateConsistencyGroup(system.getId(), consistencyGroup.getId(), addVolumesList, removeVolumesList, taskId);
        return toTask(consistencyGroup, taskId, op);
    }
    // all the virtual volumes in the CG have to be selected.
    if (!addVolumes.isEmpty()) {
        verifyAddVolumesToIngestedCG(consistencyGroup, addVolumes);
    }
    if (!addFullcopies.isEmpty()) {
        addVolumes.addAll(addFullcopies);
    }
    // Get VPlex controller
    VPlexController controller = getController();
    controller.updateConsistencyGroup(cgStorageSystem.getId(), consistencyGroup.getId(), addVolumes, removeVolumesList, taskId);
    return toTask(consistencyGroup, taskId, op);
}
Also used : BlockMirror(com.emc.storageos.db.client.model.BlockMirror) VPlexController(com.emc.storageos.vplexcontroller.VPlexController) BlockController(com.emc.storageos.volumecontroller.BlockController) ArrayList(java.util.ArrayList) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) Operation(com.emc.storageos.db.client.model.Operation) 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) Volume(com.emc.storageos.db.client.model.Volume) BlockObject(com.emc.storageos.db.client.model.BlockObject) HashSet(java.util.HashSet) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Aggregations

VPlexController (com.emc.storageos.vplexcontroller.VPlexController)20 Volume (com.emc.storageos.db.client.model.Volume)17 URI (java.net.URI)17 Operation (com.emc.storageos.db.client.model.Operation)16 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)13 TaskResourceRep (com.emc.storageos.model.TaskResourceRep)11 ArrayList (java.util.ArrayList)10 NamedURI (com.emc.storageos.db.client.model.NamedURI)9 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)9 FCTN_STRING_TO_URI (com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_STRING_TO_URI)7 FCTN_VPLEX_MIRROR_TO_URI (com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_VPLEX_MIRROR_TO_URI)7 VirtualPool (com.emc.storageos.db.client.model.VirtualPool)6 TaskList (com.emc.storageos.model.TaskList)6 VolumeDescriptor (com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor)5 Migration (com.emc.storageos.db.client.model.Migration)5 VirtualArray (com.emc.storageos.db.client.model.VirtualArray)5 CheckPermission (com.emc.storageos.security.authorization.CheckPermission)5 POST (javax.ws.rs.POST)5 Produces (javax.ws.rs.Produces)5 Project (com.emc.storageos.db.client.model.Project)4