Search in sources :

Example 1 with VplexMirror

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

the class BlockService method getMirror.

/**
 * Show details for a specific continuous copy
 *
 * @prereq none
 *
 * @param id
 *            the URN of a ViPR Source volume
 * @param mid
 *            Continuous copy URI
 *
 * @brief Show continuous copy
 * @return BlockMirrorRestRep
 */
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}/protection/continuous-copies/{mid}")
@CheckPermission(roles = { Role.SYSTEM_MONITOR, Role.TENANT_ADMIN }, acls = { ACL.ANY })
public BlockMirrorRestRep getMirror(@PathParam("id") URI id, @PathParam("mid") URI mid) {
    ArgValidator.checkFieldUriType(id, Volume.class, "id");
    boolean vplexVolume = checkIfVolumeIsForVplex(id);
    BlockMirrorRestRep mirrorRestRep = null;
    if (vplexVolume) {
        ArgValidator.checkFieldUriType(mid, VplexMirror.class, "mid");
        VplexMirror mirror = queryVplexMirror(mid);
        if (!mirror.getSource().getURI().equals(id)) {
            throw APIException.badRequests.invalidParameterVolumeMirrorMismatch(mid, id);
        }
        mirrorRestRep = map(mirror);
    } else {
        queryResource(id);
        ArgValidator.checkFieldUriType(mid, BlockMirror.class, "mid");
        BlockMirror mirror = queryMirror(mid);
        if (!mirror.getSource().getURI().equals(id)) {
            throw APIException.badRequests.invalidParameterVolumeMirrorMismatch(mid, id);
        }
        mirrorRestRep = map(_dbClient, mirror);
    }
    return mirrorRestRep;
}
Also used : BlockMirror(com.emc.storageos.db.client.model.BlockMirror) BlockMirrorRestRep(com.emc.storageos.model.block.BlockMirrorRestRep) VplexMirror(com.emc.storageos.db.client.model.VplexMirror) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) SOURCE_TO_TARGET(com.emc.storageos.model.block.Copy.SyncDirection.SOURCE_TO_TARGET) CheckPermission(com.emc.storageos.security.authorization.CheckPermission)

Example 2 with VplexMirror

use of com.emc.storageos.db.client.model.VplexMirror 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 3 with VplexMirror

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

the class BlockService method queryVplexMirror.

/**
 * Helper method for querying a vplex mirror
 *
 * @param id
 *            the URN of a ViPR mirror to query
 * @return VplexMirror instance
 */
private VplexMirror queryVplexMirror(URI id) {
    ArgValidator.checkUri(id);
    VplexMirror mirror = _permissionsHelper.getObjectById(id, VplexMirror.class);
    ArgValidator.checkEntityNotNull(mirror, id, isIdEmbeddedInURL(id));
    return mirror;
}
Also used : VplexMirror(com.emc.storageos.db.client.model.VplexMirror)

Example 4 with VplexMirror

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

the class BlockService method deactivateMirror.

/**
 * Deactivate continuous copies for given source volume
 *
 * NOTE: This is an asynchronous operation.
 *
 * @prereq none
 *
 * @param id
 *            the URN of a ViPR Source volume
 * @param param
 *            List of copies to deactivate
 * @param type {@link DefaultValue} FULL
 *            Possible type of deletion
 *            <ul>
 *            <li>FULL</li>
 *            <li>VIPR_ONLY</li>
 *            </ul>
 *            if type is FULL, ViPR deletes the continuous copy from storage array and removes from ViPR data base.
 *            if type is VIPR_ONLY, ViPR removes the continuous copy only from ViPR data base and leaves the continuous copy on storage
 *            array as it is.
 *
 * @brief Delete continuous copies
 * @return TaskList
 *
 * @throws ControllerException
 */
@POST
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}/protection/continuous-copies/deactivate")
@CheckPermission(roles = { Role.TENANT_ADMIN }, acls = { ACL.OWN, ACL.ALL })
public TaskList deactivateMirror(@PathParam("id") URI id, CopiesParam param, @DefaultValue("FULL") @QueryParam("type") String deleteType) throws ControllerException {
    TaskList taskList = new TaskList();
    // Validate the source volume URI
    ArgValidator.checkFieldUriType(id, Volume.class, "id");
    Volume volume = _dbClient.queryObject(Volume.class, id);
    // Make sure that we don't have some pending
    // operation against the volume
    checkForPendingTasks(Arrays.asList(volume.getTenant().getURI()), Arrays.asList(volume));
    // Validate the list of copies
    ArgValidator.checkFieldNotEmpty(param.getCopies(), "copies");
    boolean vplexVolume = checkIfVolumeIsForVplex(id);
    // Process the list of copies
    for (Copy copy : param.getCopies()) {
        // Validate the copy ID
        URI copyID = copy.getCopyID();
        ArgValidator.checkUri(copyID);
        // Validate a copy type was passed
        ArgValidator.checkFieldNotEmpty(copy.getType(), "type");
        if (TechnologyType.NATIVE.toString().equalsIgnoreCase(copy.getType())) {
            String task = UUID.randomUUID().toString();
            StorageSystem device;
            String mirrorLabel;
            URI mirrorURI;
            BlockServiceApi blockServiceApi;
            if (vplexVolume) {
                VplexMirror mirror = queryVplexMirror(copyID);
                ArgValidator.checkEntity(mirror, mirror.getId(), isIdEmbeddedInURL(copyID));
                if (!mirror.getSource().getURI().equals(id)) {
                    throw APIException.badRequests.mirrorDoesNotBelongToVolume(copyID, id);
                }
                mirrorLabel = mirror.getLabel();
                mirrorURI = mirror.getId();
                device = _dbClient.queryObject(StorageSystem.class, mirror.getStorageController());
                blockServiceApi = getBlockServiceImpl(DiscoveredDataObject.Type.vplex.name());
            } else {
                BlockMirror mirror = queryMirror(copyID);
                ArgValidator.checkEntity(mirror, mirror.getId(), isIdEmbeddedInURL(copyID));
                if (!mirror.getSource().getURI().equals(id)) {
                    throw APIException.badRequests.mirrorDoesNotBelongToVolume(copyID, id);
                }
                mirrorLabel = mirror.getLabel();
                mirrorURI = mirror.getId();
                device = _dbClient.queryObject(StorageSystem.class, mirror.getStorageController());
                blockServiceApi = getBlockServiceImpl("mirror");
            }
            // Deactivate the mirror
            TaskList deactivateTaskList = blockServiceApi.deactivateMirror(device, mirrorURI, task, deleteType);
            // Create the audit log message
            String opStage = VolumeDeleteTypeEnum.VIPR_ONLY.name().equals(deleteType) ? null : AuditLogManager.AUDITOP_BEGIN;
            boolean opStatus = true;
            for (TaskResourceRep resultTask : deactivateTaskList.getTaskList()) {
                if (Operation.Status.error.name().equals(resultTask.getState())) {
                    opStatus = false;
                    break;
                }
            }
            auditOp(OperationTypeEnum.DEACTIVATE_VOLUME_MIRROR, opStatus, opStage, copyID.toString(), mirrorLabel);
            // Add tasks for this copy
            taskList.getTaskList().addAll(deactivateTaskList.getTaskList());
        } else {
            throw APIException.badRequests.invalidCopyType(copy.getType());
        }
    }
    return taskList;
}
Also used : BlockMirror(com.emc.storageos.db.client.model.BlockMirror) MapVolume(com.emc.storageos.api.mapper.functions.MapVolume) Volume(com.emc.storageos.db.client.model.Volume) Copy(com.emc.storageos.model.block.Copy) TaskList(com.emc.storageos.model.TaskList) TaskResourceRep(com.emc.storageos.model.TaskResourceRep) URI(java.net.URI) NullColumnValueGetter.isNullURI(com.emc.storageos.db.client.util.NullColumnValueGetter.isNullURI) VplexMirror(com.emc.storageos.db.client.model.VplexMirror) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces) CheckPermission(com.emc.storageos.security.authorization.CheckPermission)

Example 5 with VplexMirror

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

the class VplexVolumeIngestionContext method createVplexMirrorObjects.

/**
 * Create a VplexMirror database object if a VPLEX native mirror is present.
 * This should be called after the parent virtual volume has already been ingested.
 *
 * @param context the VplexBackendIngestionContext
 * @param virtualVolume the ingested virtual volume's Volume object.
 */
private void createVplexMirrorObjects() {
    if (!getUnmanagedVplexMirrors().isEmpty()) {
        Volume virtualVolume = (Volume) _parentRequestContext.getProcessedBlockObject(getUnmanagedVirtualVolume().getNativeGuid());
        _logger.info("creating VplexMirror object for virtual volume " + virtualVolume.getLabel());
        for (Entry<UnManagedVolume, String> entry : getUnmanagedVplexMirrors().entrySet()) {
            // find mirror and create a VplexMirror object
            BlockObject mirror = getBlockObjectsToBeCreatedMap().get(entry.getKey().getNativeGuid().replace(VolumeIngestionUtil.UNMANAGEDVOLUME, VolumeIngestionUtil.VOLUME));
            if (null != mirror) {
                _logger.info("processing mirror " + mirror.getLabel());
                if (mirror instanceof Volume) {
                    Volume mirrorVolume = (Volume) mirror;
                    // create VplexMirror set all the basic properties
                    VplexMirror vplexMirror = new VplexMirror();
                    vplexMirror.setId(URIUtil.createId(VplexMirror.class));
                    vplexMirror.setCapacity(mirrorVolume.getCapacity());
                    vplexMirror.setLabel(mirrorVolume.getLabel());
                    vplexMirror.setNativeId(entry.getValue());
                    // For Vplex virtual volumes set allocated capacity to 0 (cop-18608)
                    vplexMirror.setAllocatedCapacity(0L);
                    vplexMirror.setProvisionedCapacity(mirrorVolume.getProvisionedCapacity());
                    vplexMirror.setSource(new NamedURI(virtualVolume.getId(), virtualVolume.getLabel()));
                    vplexMirror.setStorageController(virtualVolume.getStorageController());
                    vplexMirror.setTenant(mirrorVolume.getTenant());
                    vplexMirror.setThinPreAllocationSize(mirrorVolume.getThinVolumePreAllocationSize());
                    vplexMirror.setThinlyProvisioned(mirrorVolume.getThinlyProvisioned());
                    vplexMirror.setVirtualArray(mirrorVolume.getVirtualArray());
                    vplexMirror.setVirtualPool(mirrorVolume.getVirtualPool());
                    // set the associated volume for this VplexMirror
                    StringSet associatedVolumes = new StringSet();
                    associatedVolumes.add(mirrorVolume.getId().toString());
                    vplexMirror.setAssociatedVolumes(associatedVolumes);
                    // VplexMirror will have the same project
                    // as the virtual volume (i.e., the front-end project)
                    // but the mirror backend will have the backend project
                    vplexMirror.setProject(new NamedURI(getFrontendProject().getId(), mirrorVolume.getLabel()));
                    mirrorVolume.setProject(new NamedURI(getBackendProject().getId(), mirrorVolume.getLabel()));
                    // update flags on mirror volume
                    Set<DataObject> updatedObjects = getDataObjectsToBeUpdatedMap().get(mirrorVolume.getNativeGuid());
                    if (updatedObjects == null) {
                        updatedObjects = new HashSet<DataObject>();
                        getDataObjectsToBeUpdatedMap().put(mirrorVolume.getNativeGuid(), updatedObjects);
                    }
                    VolumeIngestionUtil.clearInternalFlags(this, mirrorVolume, updatedObjects, _dbClient);
                    // VPLEX backend volumes should still have the INTERNAL_OBJECT flag
                    mirrorVolume.addInternalFlags(Flag.INTERNAL_OBJECT);
                    // deviceLabel will be the very last part of the native guid
                    String[] devicePathParts = entry.getValue().split("/");
                    String deviceName = devicePathParts[devicePathParts.length - 1];
                    vplexMirror.setDeviceLabel(deviceName);
                    // save the new VplexMirror & persist backend & updated objects
                    getCreatedVplexMirrors().add(vplexMirror);
                    // set mirrors property on the parent virtual volume
                    StringSet mirrors = virtualVolume.getMirrors();
                    if (mirrors == null) {
                        mirrors = new StringSet();
                    }
                    mirrors.add(vplexMirror.getId().toString());
                    virtualVolume.setMirrors(mirrors);
                }
            }
        }
    }
}
Also used : DataObject(com.emc.storageos.db.client.model.DataObject) UnManagedVolume(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume) Volume(com.emc.storageos.db.client.model.Volume) NamedURI(com.emc.storageos.db.client.model.NamedURI) UnManagedVolume(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume) StringSet(com.emc.storageos.db.client.model.StringSet) VplexMirror(com.emc.storageos.db.client.model.VplexMirror) BlockObject(com.emc.storageos.db.client.model.BlockObject)

Aggregations

VplexMirror (com.emc.storageos.db.client.model.VplexMirror)36 Volume (com.emc.storageos.db.client.model.Volume)31 NamedURI (com.emc.storageos.db.client.model.NamedURI)15 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)15 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)15 URI (java.net.URI)15 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)12 InternalServerErrorException (com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException)12 ControllerException (com.emc.storageos.volumecontroller.ControllerException)12 URISyntaxException (java.net.URISyntaxException)12 ArrayList (java.util.ArrayList)12 StringSet (com.emc.storageos.db.client.model.StringSet)11 VPlexApiException (com.emc.storageos.vplex.api.VPlexApiException)11 WorkflowException (com.emc.storageos.workflow.WorkflowException)11 IOException (java.io.IOException)11 VPlexApiClient (com.emc.storageos.vplex.api.VPlexApiClient)10 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)8 VolumeDescriptor (com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor)7 HashMap (java.util.HashMap)6 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)5