Search in sources :

Example 1 with ProtectionOrchestrationController

use of com.emc.storageos.protectionorchestrationcontroller.ProtectionOrchestrationController in project coprhd-controller by CoprHD.

the class BlockService method performSRDFProtectionAction.

/**
 * perform SRDF Protection APIs
 *
 * @param id
 *            the URN of a ViPR volume associated
 * @param copy
 * @param op
 * @return
 * @throws InternalException
 */
private TaskResourceRep performSRDFProtectionAction(URI id, Copy copy, String op) throws InternalException {
    URI copyID = copy.getCopyID();
    ArgValidator.checkFieldUriType(copyID, Volume.class, "copyID");
    // Get the volume associated with the URI
    Volume volume = queryVolumeResource(id);
    Volume copyVolume = null;
    if (null == copyID) {
        copyVolume = volume;
    } else {
        copyVolume = queryVolumeResource(copyID);
    }
    ArgValidator.checkEntity(volume, id, true);
    ArgValidator.checkEntity(copyVolume, copyID, true);
    // passed in source volume
    if (!copyVolume.getSrdfParent().getURI().equals(id) && !copyVolume.getId().equals(id)) {
        throw APIException.badRequests.protectionVolumeInvalidTargetOfVolume(copyID, id);
    }
    // Make sure that we don't have some pending
    // operation against the volume
    checkForPendingTasks(Arrays.asList(volume.getTenant().getURI()), Arrays.asList(volume));
    if (Volume.isSRDFProtectedVolume(copyVolume)) {
        if (op.equalsIgnoreCase(ProtectionOp.FAILOVER_TEST_CANCEL.getRestOp()) || op.equalsIgnoreCase(ProtectionOp.FAILOVER_TEST.getRestOp())) {
            String task = UUID.randomUUID().toString();
            Operation status = new Operation();
            status.setResourceType(ProtectionOp.getResourceOperationTypeEnum(op));
            _dbClient.createTaskOpStatus(Volume.class, volume.getId(), task, status);
            _dbClient.ready(Volume.class, volume.getId(), task);
            return toTask(volume, task, status);
        }
        if (PersonalityTypes.SOURCE.name().equalsIgnoreCase(copyVolume.getPersonality())) {
            if (op.equalsIgnoreCase(ProtectionOp.FAILOVER_CANCEL.getRestOp()) || op.equalsIgnoreCase(ProtectionOp.FAILOVER.getRestOp()) || op.equalsIgnoreCase(ProtectionOp.SWAP.getRestOp())) {
                throw new ServiceCodeException(ServiceCode.IO_ERROR, "Expected SRDF Target R2 volume, instead R1 {0} is being passed, hence cannot proceed with failover or failback.", new Object[] { copyVolume.getNativeGuid() });
            } else if (copyVolume.getSrdfTargets() == null || copyVolume.getSrdfTargets().isEmpty()) {
                throw new ServiceCodeException(ServiceCode.IO_ERROR, "Target Volume Empty for a given source R1 {0}, hence cannot proceed with failover or failback.", new Object[] { copyVolume.getNativeGuid() });
            } else if (PersonalityTypes.TARGET.name().equalsIgnoreCase(copyVolume.getPersonality()) && RemoteDirectorGroup.SupportedCopyModes.ADAPTIVECOPY.name().equalsIgnoreCase(copyVolume.getSrdfCopyMode())) {
                if (ProtectionOp.CHANGE_COPY_MODE.getRestOp().equalsIgnoreCase(op)) {
                    validateVpoolCopyModeSetting(volume, copy.getCopyMode());
                }
            }
        }
        // COP-25377. We need to block failover and swap operations for SRDF ACTIVE COPY MODE
        if (Mode.ACTIVE.toString().equalsIgnoreCase(copyVolume.getSrdfCopyMode()) && (op.equalsIgnoreCase(ProtectionOp.FAILOVER_CANCEL.getRestOp()) || op.equalsIgnoreCase(ProtectionOp.FAILOVER.getRestOp()) || op.equalsIgnoreCase(ProtectionOp.SWAP.getRestOp()))) {
            throw BadRequestException.badRequests.operationNotPermittedOnSRDFActiveCopyMode(op);
        }
        String task = UUID.randomUUID().toString();
        Operation status = new Operation();
        status.setResourceType(ProtectionOp.getResourceOperationTypeEnum(op));
        _dbClient.createTaskOpStatus(Volume.class, volume.getId(), task, status);
        /*
             * CTRL-6972: In the absence of a /restore API, we re-use /sync with a syncDirection parameter for
             * specifying either SMI-S Resume or Restore:
             * SOURCE_TO_TARGET -> ViPR Resume -> SMI-S Resume -> SRDF Incremental Establish (R1 overwrites R2)
             * TARGET_TO_SOURCE -> ViPR Sync -> SMI-S Restore -> SRDF Full Restore (R2 overwrites R1)
             */
        if (op.equalsIgnoreCase(ProtectionOp.SYNC.getRestOp()) && SOURCE_TO_TARGET.toString().equalsIgnoreCase(copy.getSyncDirection())) {
            op = ProtectionOp.RESUME.getRestOp();
        } else if (isSuspendCopyRequest(op, copy)) {
            op = ProtectionOp.SUSPEND.getRestOp();
        }
        ProtectionOrchestrationController protectionController = getController(ProtectionOrchestrationController.class, ProtectionOrchestrationController.PROTECTION_ORCHESTRATION_DEVICE);
        StorageSystem system = _dbClient.queryObject(StorageSystem.class, copyVolume.getStorageController());
        protectionController.performSRDFProtectionOperation(system.getId(), copy, op, task);
        return toTask(volume, task, status);
    } else {
        throw new ServiceCodeException(ServiceCode.IO_ERROR, "Volume {0} is not SRDF protected", new Object[] { copyVolume.getNativeGuid() });
    }
}
Also used : ProtectionOrchestrationController(com.emc.storageos.protectionorchestrationcontroller.ProtectionOrchestrationController) MapVolume(com.emc.storageos.api.mapper.functions.MapVolume) Volume(com.emc.storageos.db.client.model.Volume) ServiceCodeException(com.emc.storageos.svcs.errorhandling.resources.ServiceCodeException) BlockObject(com.emc.storageos.db.client.model.BlockObject) DiscoveredDataObject(com.emc.storageos.db.client.model.DiscoveredDataObject) DataObject(com.emc.storageos.db.client.model.DataObject) Operation(com.emc.storageos.db.client.model.Operation) URI(java.net.URI) NullColumnValueGetter.isNullURI(com.emc.storageos.db.client.util.NullColumnValueGetter.isNullURI) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 2 with ProtectionOrchestrationController

use of com.emc.storageos.protectionorchestrationcontroller.ProtectionOrchestrationController in project coprhd-controller by CoprHD.

the class BlockConsistencyGroupService method performSRDFProtectionAction.

/**
 * Performs the SRDF Protection operation.
 *
 * @param consistencyGroupId the URI of the BlockConsistencyGroup to perform the protection action against.
 * @param copy the copy to operate on
 * @param op operation to perform (pause, stop, failover, etc)
 * @return task resource rep
 * @throws InternalException
 */
private TaskResourceRep performSRDFProtectionAction(URI consistencyGroupId, Copy copy, String op) throws InternalException {
    URI targetVarrayId = copy.getCopyID();
    ArgValidator.checkFieldUriType(targetVarrayId, VirtualArray.class, "copyID");
    ArgValidator.checkFieldUriType(consistencyGroupId, BlockConsistencyGroup.class, "id");
    // Get the BlockConsistencyGroup and target VirtualArray associated with the request.
    final BlockConsistencyGroup consistencyGroup = (BlockConsistencyGroup) queryResource(consistencyGroupId);
    final VirtualArray targetVirtualArray = _permissionsHelper.getObjectById(targetVarrayId, VirtualArray.class);
    ArgValidator.checkEntity(consistencyGroup, consistencyGroupId, true);
    ArgValidator.checkEntity(targetVirtualArray, targetVarrayId, true);
    // The consistency group needs to be associated with SRDF in order to perform the operation.
    if (!consistencyGroup.checkForType(Types.SRDF)) {
        // Attempting to perform an SRDF operation on a non-SRDF consistency group
        throw APIException.badRequests.consistencyGroupMustBeSRDFProtected(consistencyGroupId);
    }
    // Get the block service implementation
    BlockServiceApi blockServiceApiImpl = getBlockServiceImpl(consistencyGroup);
    // Get a list of CG volumes.
    List<Volume> volumeList = BlockConsistencyGroupUtils.getActiveVolumesInCG(consistencyGroup, _dbClient, null);
    if (volumeList == null || volumeList.isEmpty()) {
        throw APIException.badRequests.consistencyGroupContainsNoVolumes(consistencyGroup.getId());
    }
    Volume srcVolume = null;
    // Find a source volume in the SRDF local CG
    for (Volume volume : volumeList) {
        if (volume.getPersonality() != null && volume.getPersonality().equals(PersonalityTypes.SOURCE.name())) {
            srcVolume = volume;
            break;
        }
    }
    if (srcVolume == null) {
        // CG contains no source volumes.
        throw APIException.badRequests.srdfCgContainsNoSourceVolumes(consistencyGroup.getId());
    }
    // Find the target volume that corresponds to the source whose Virtual Array matches
    // the specified target Virtual Array. From that, obtain the remote SRDF CG.
    BlockConsistencyGroup targetCg = null;
    if (srcVolume.getSrdfTargets() != null && !srcVolume.getSrdfTargets().isEmpty()) {
        for (String uri : srcVolume.getSrdfTargets()) {
            Volume target = _dbClient.queryObject(Volume.class, URI.create(uri));
            if (target.getVirtualArray().equals(targetVarrayId)) {
                targetCg = _dbClient.queryObject(BlockConsistencyGroup.class, target.getConsistencyGroup());
                break;
            }
        }
    }
    // Get all target CG target volumes for validation
    List<Volume> targetVolumes = getTargetVolumes(targetCg, targetVarrayId);
    for (Volume tgtVolume : targetVolumes) {
        if (!Volume.isSRDFProtectedVolume(tgtVolume)) {
            // protected.
            throw APIException.badRequests.volumeMustBeSRDFProtected(tgtVolume.getId());
        }
    }
    if (targetVolumes == null || targetVolumes.isEmpty()) {
        // The supplied target varray is not referenced by any target volumes in the CG.
        throw APIException.badRequests.targetVirtualArrayDoesNotMatch(targetCg.getId(), targetVarrayId);
    }
    // Get the first volume
    Volume targetVolume = targetVolumes.get(0);
    // COP-25377. We need to block failover and swap operations for SRDF ACTIVE COPY MODE
    if (Mode.ACTIVE.toString().equalsIgnoreCase(targetVolume.getSrdfCopyMode()) && (op.equalsIgnoreCase(ProtectionOp.FAILOVER_CANCEL.getRestOp()) || op.equalsIgnoreCase(ProtectionOp.FAILOVER.getRestOp()) || op.equalsIgnoreCase(ProtectionOp.SWAP.getRestOp()))) {
        throw BadRequestException.badRequests.operationNotPermittedOnSRDFActiveCopyMode(op);
    }
    String task = UUID.randomUUID().toString();
    Operation status = new Operation();
    status.setResourceType(ProtectionOp.getResourceOperationTypeEnum(op));
    _dbClient.createTaskOpStatus(BlockConsistencyGroup.class, targetCg.getId(), task, status);
    if (op.equalsIgnoreCase(ProtectionOp.FAILOVER_TEST_CANCEL.getRestOp()) || op.equalsIgnoreCase(ProtectionOp.FAILOVER_TEST.getRestOp())) {
        _dbClient.ready(BlockConsistencyGroup.class, targetCg.getId(), task);
        return toTask(targetCg, task, status);
    }
    /*
         * CTRL-6972: In the absence of a /restore API, we re-use /sync with a syncDirection parameter for
         * specifying either SMI-S Resume or Restore:
         * SOURCE_TO_TARGET -> ViPR Resume -> SMI-S Resume -> SRDF Incremental Establish (R1 overwrites R2)
         * TARGET_TO_SOURCE -> ViPR Sync -> SMI-S Restore -> SRDF Full Restore (R2 overwrites R1)
         */
    if (op.equalsIgnoreCase(ProtectionOp.SYNC.getRestOp()) && SOURCE_TO_TARGET.toString().equalsIgnoreCase(copy.getSyncDirection())) {
        op = ProtectionOp.RESUME.getRestOp();
    } else if (BlockService.isSuspendCopyRequest(op, copy)) {
        op = ProtectionOp.SUSPEND.getRestOp();
    }
    StorageSystem system = _dbClient.queryObject(StorageSystem.class, targetVolume.getStorageController());
    ProtectionOrchestrationController controller = getController(ProtectionOrchestrationController.class, ProtectionOrchestrationController.PROTECTION_ORCHESTRATION_DEVICE);
    // Create a new duplicate copy of the original copy. Update the copyId field to be the
    // ID of the target volume. Existing SRDF controller logic needs the target volume
    // to operate off of, not the virtual array.
    Copy updatedCopy = new Copy(copy.getType(), copy.getSync(), targetVolume.getId(), copy.getName(), copy.getCount());
    controller.performSRDFProtectionOperation(system.getId(), updatedCopy, op, task);
    return toTask(targetCg, task, status);
}
Also used : VirtualArray(com.emc.storageos.db.client.model.VirtualArray) ProtectionOrchestrationController(com.emc.storageos.protectionorchestrationcontroller.ProtectionOrchestrationController) Volume(com.emc.storageos.db.client.model.Volume) Copy(com.emc.storageos.model.block.Copy) Operation(com.emc.storageos.db.client.model.Operation) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) MapBlockConsistencyGroup(com.emc.storageos.api.mapper.functions.MapBlockConsistencyGroup) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Aggregations

Operation (com.emc.storageos.db.client.model.Operation)2 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)2 Volume (com.emc.storageos.db.client.model.Volume)2 ProtectionOrchestrationController (com.emc.storageos.protectionorchestrationcontroller.ProtectionOrchestrationController)2 URI (java.net.URI)2 MapBlockConsistencyGroup (com.emc.storageos.api.mapper.functions.MapBlockConsistencyGroup)1 MapVolume (com.emc.storageos.api.mapper.functions.MapVolume)1 BlockConsistencyGroup (com.emc.storageos.db.client.model.BlockConsistencyGroup)1 BlockObject (com.emc.storageos.db.client.model.BlockObject)1 DataObject (com.emc.storageos.db.client.model.DataObject)1 DiscoveredDataObject (com.emc.storageos.db.client.model.DiscoveredDataObject)1 NamedURI (com.emc.storageos.db.client.model.NamedURI)1 VirtualArray (com.emc.storageos.db.client.model.VirtualArray)1 NullColumnValueGetter.isNullURI (com.emc.storageos.db.client.util.NullColumnValueGetter.isNullURI)1 Copy (com.emc.storageos.model.block.Copy)1 ServiceCodeException (com.emc.storageos.svcs.errorhandling.resources.ServiceCodeException)1