Search in sources :

Example 1 with RecoverPointCGResponse

use of com.emc.storageos.recoverpoint.responses.RecoverPointCGResponse in project coprhd-controller by CoprHD.

the class RPDeviceController method cgCreateStep.

/**
 * Workflow step method for creating/updating a consistency group.
 *
 * @param rpSystemId
 *            RP system Id
 * @param recommendation
 *            parameters needed to create the CG
 * @param token
 *            the task
 * @return
 * @throws InternalException
 */
public boolean cgCreateStep(URI rpSystemId, List<VolumeDescriptor> volumeDescriptors, String token) throws InternalException {
    RecoverPointClient rp;
    CGRequestParams cgParams = null;
    boolean metropoint = false;
    boolean lockException = false;
    try {
        // Get only the RP volumes from the descriptors.
        List<VolumeDescriptor> sourceVolumeDescriptors = VolumeDescriptor.filterByType(volumeDescriptors, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.RP_SOURCE, VolumeDescriptor.Type.RP_EXISTING_SOURCE, VolumeDescriptor.Type.RP_VPLEX_VIRT_SOURCE }, new VolumeDescriptor.Type[] {});
        WorkflowStepCompleter.stepExecuting(token);
        ProtectionSystem rpSystem = _dbClient.queryObject(ProtectionSystem.class, rpSystemId);
        URI cgId = volumeDescriptors.iterator().next().getCapabilitiesValues().getBlockConsistencyGroup();
        boolean attachAsClean = true;
        for (VolumeDescriptor sourceVolumedescriptor : sourceVolumeDescriptors) {
            Volume sourceVolume = _dbClient.queryObject(Volume.class, sourceVolumedescriptor.getVolumeURI());
            metropoint = RPHelper.isMetroPointVolume(_dbClient, sourceVolume);
            // if this is a change vpool, attachAsClean should be false so that source and target are synchronized
            if (VolumeDescriptor.Type.RP_EXISTING_SOURCE.equals(sourceVolumedescriptor.getType())) {
                attachAsClean = false;
            }
        }
        // Build the CG Request params
        cgParams = getCGRequestParams(volumeDescriptors, rpSystem);
        updateCGParams(cgParams);
        // Validate the source/target volumes before creating a CG.
        validateCGVolumes(volumeDescriptors);
        rp = RPHelper.getRecoverPointClient(rpSystem);
        // Scan the rp sites for volume visibility
        rp.waitForVolumesToBeVisible(cgParams);
        // Before acquiring a lock on the CG we need to ensure that the
        // CG is created. If it hasn't, then the first CGRequestParams
        // to be allowed to pass through needs to have the journals
        // defined.
        // 
        // NOTE: The CG may not yet be created on the RP protection system and
        // that's OK since this might be the first request going in.
        waitForCGToBeCreated(cgId, cgParams);
        // lock around create and delete operations on the same CG
        List<String> lockKeys = new ArrayList<String>();
        lockKeys.add(ControllerLockingUtil.getConsistencyGroupStorageKey(_dbClient, cgId, rpSystem.getId()));
        boolean lockAcquired = _workflowService.acquireWorkflowStepLocks(token, lockKeys, LockTimeoutValue.get(LockType.RP_CG));
        if (!lockAcquired) {
            lockException = true;
            throw DeviceControllerException.exceptions.failedToAcquireLock(lockKeys.toString(), String.format("Create or add volumes to RP consistency group id: %s", cgId.toString()));
        }
        RecoverPointCGResponse response = null;
        // The CG already exists if it contains volumes and is of type RP
        _log.info("Submitting RP Request: " + cgParams);
        BlockConsistencyGroup cg = _dbClient.queryObject(BlockConsistencyGroup.class, cgId);
        // Check to see if the CG has been created in ViPR and on the RP protection system
        boolean cgAlreadyExists = rpCGExists(cg, rp, cgParams.getCgName(), rpSystem.getId());
        if (cgAlreadyExists) {
            // cg exists in both the ViPR db and on the RP system
            _log.info(String.format("RP CG [%s] already exists, adding replication set(s) to it...", cgParams.getCgName()));
            response = rp.addReplicationSetsToCG(cgParams, metropoint, attachAsClean);
        } else {
            _log.info(String.format("RP CG [%s] does not already exist, creating it now and adding replication set(s) to it...", cgParams.getCgName()));
            response = rp.createCG(cgParams, metropoint, attachAsClean);
            // "Turn-on" the consistency group
            cg = _dbClient.queryObject(BlockConsistencyGroup.class, cgParams.getCgUri());
            cg.addSystemConsistencyGroup(rpSystemId.toString(), cgParams.getCgName());
            cg.addConsistencyGroupTypes(Types.RP.name());
        }
        // At this point, always clear the journal provisioning lock on the
        // CG for any concurrent orders that may come in.
        cg.setJournalProvisioningLock(0L);
        _dbClient.updateObject(cg);
        setVolumeConsistencyGroup(volumeDescriptors, cgParams.getCgUri());
        // If this was a vpool Update, now is a good time to update the vpool and Volume information
        if (VolumeDescriptor.getVirtualPoolChangeVolume(volumeDescriptors) != null) {
            Volume volume = _dbClient.queryObject(Volume.class, VolumeDescriptor.getVirtualPoolChangeVolume(volumeDescriptors));
            URI newVpoolURI = getVirtualPoolChangeNewVirtualPool(volumeDescriptors);
            volume.setVirtualPool(newVpoolURI);
            volume.setPersonality(Volume.PersonalityTypes.SOURCE.toString());
            volume.setAccessState(Volume.VolumeAccessState.READWRITE.name());
            volume.setLinkStatus(Volume.LinkStatus.IN_SYNC.name());
            volume.setProtectionController(rpSystemId);
            _dbClient.updateObject(volume);
            // We might need to update the vpools of the backing volumes if this is an RP+VPLEX
            // or MetroPoint change vpool.
            VPlexUtil.updateVPlexBackingVolumeVpools(volume, newVpoolURI, _dbClient);
            // Record Audit operation. (virtualpool change only)
            AuditBlockUtil.auditBlock(_dbClient, OperationTypeEnum.CHANGE_VOLUME_VPOOL, true, AuditLogManager.AUDITOP_END, token);
        }
        // Create the ProtectionSet to contain the CG UID (which is truly unique to the protection system)
        if (response.getCgId() != null) {
            List<ProtectionSet> protectionSets = CustomQueryUtility.queryActiveResourcesByConstraint(_dbClient, ProtectionSet.class, AlternateIdConstraint.Factory.getConstraint(ProtectionSet.class, "protectionId", response.getCgId().toString()));
            ProtectionSet protectionSet = null;
            if (protectionSets.isEmpty()) {
                // A protection set corresponding to the CG does not exist so we need to create one
                protectionSet = createProtectionSet(rpSystem, cgParams, response.getCgId());
            } else {
                // Update the existing protection set. We will only have 1 protection set
                // get the first one.
                protectionSet = protectionSets.get(0);
                protectionSet = updateProtectionSet(protectionSet, cgParams);
            }
            _dbClient.updateObject(protectionSet);
        }
        // Set the CG last created time to now.
        rpSystem.setCgLastCreatedTime(Calendar.getInstance());
        _dbClient.updateObject(rpSystem);
        // Update the workflow state.
        WorkflowStepCompleter.stepSucceded(token);
        // collect and update the protection system statistics to account for
        // the newly created CG.
        _log.info("Collecting RP statistics post CG create.");
        collectRPStatistics(rpSystem);
    } catch (Exception e) {
        if (lockException) {
            List<URI> volUris = VolumeDescriptor.getVolumeURIs(volumeDescriptors);
            ServiceError serviceError = DeviceControllerException.errors.createVolumesAborted(volUris.toString(), e);
            doFailCgCreateStep(volumeDescriptors, cgParams, rpSystemId, token);
            stepFailed(token, serviceError, "cgCreateStep");
        } else {
            doFailCgCreateStep(volumeDescriptors, cgParams, rpSystemId, token);
            stepFailed(token, e, "cgCreateStep");
        }
        return false;
    }
    return true;
}
Also used : RecoverPointCGResponse(com.emc.storageos.recoverpoint.responses.RecoverPointCGResponse) ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) ArrayList(java.util.ArrayList) ProtectionSet(com.emc.storageos.db.client.model.ProtectionSet) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) InternalServerErrorException(com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) LockRetryException(com.emc.storageos.locking.LockRetryException) FunctionalAPIActionFailedException_Exception(com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception) URISyntaxException(java.net.URISyntaxException) WorkflowException(com.emc.storageos.workflow.WorkflowException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) FunctionalAPIInternalError_Exception(com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception) CoordinatorException(com.emc.storageos.coordinator.exceptions.CoordinatorException) RecoverPointException(com.emc.storageos.recoverpoint.exceptions.RecoverPointException) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) Volume(com.emc.storageos.db.client.model.Volume) RecoverPointClient(com.emc.storageos.recoverpoint.impl.RecoverPointClient) CGRequestParams(com.emc.storageos.recoverpoint.requests.CGRequestParams) ApplicationAddVolumeList(com.emc.storageos.volumecontroller.ApplicationAddVolumeList) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) List(java.util.List)

Example 2 with RecoverPointCGResponse

use of com.emc.storageos.recoverpoint.responses.RecoverPointCGResponse in project coprhd-controller by CoprHD.

the class RecoverPointClient method addReplicationSetsToCG.

/**
 * Updates an existing CG by adding new replication sets.
 *
 * @param request - contains all the information required to create the consistency group
 *
 * @param attachAsClean attach as clean can be true if source and target are guaranteed to be the same (as in create
 *            new volume). for change vpool, attach as clean should be false
 *
 * @return RecoverPointCGResponse - response as to success or fail of creating the consistency group
 *
 * @throws RecoverPointException
 */
public RecoverPointCGResponse addReplicationSetsToCG(CGRequestParams request, boolean metropoint, boolean attachAsClean) throws RecoverPointException {
    if (null == _endpoint.toASCIIString()) {
        throw RecoverPointException.exceptions.noRecoverPointEndpoint();
    }
    RecoverPointCGResponse response = new RecoverPointCGResponse();
    List<ConsistencyGroupCopySettings> groupCopySettings = null;
    ConsistencyGroupUID cgUID = null;
    try {
        // Make sure the CG name is unique.
        List<ConsistencyGroupUID> allCgs = functionalAPI.getAllConsistencyGroups();
        for (ConsistencyGroupUID cg : allCgs) {
            ConsistencyGroupSettings settings = functionalAPI.getGroupSettings(cg);
            if (settings.getName().toString().equalsIgnoreCase(request.getCgName())) {
                cgUID = settings.getGroupUID();
                groupCopySettings = settings.getGroupCopiesSettings();
                break;
            }
        }
        if (cgUID == null) {
            // The CG does not exist so we cannot add replication sets
            throw RecoverPointException.exceptions.failedToAddReplicationSetCgDoesNotExist(request.getCgName());
        }
        response.setCgId(cgUID.getId());
        // caches site names to cluster id's to reduce calls to fapi for the same information
        Map<String, ClusterUID> clusterIdCache = new HashMap<String, ClusterUID>();
        // prodSites is used for logging and to determine if a non-production copy is local or remote
        List<ClusterUID> prodSites = new ArrayList<ClusterUID>();
        // used to set the copy uid on the rset volume when adding rsets
        Map<Long, ConsistencyGroupCopyUID> productionCopiesUID = new HashMap<Long, ConsistencyGroupCopyUID>();
        Map<Long, ConsistencyGroupCopyUID> nonProductionCopiesUID = new HashMap<Long, ConsistencyGroupCopyUID>();
        // get a list of CG production copies so we can determine which copies are production and which
        // are not.
        List<ConsistencyGroupCopyUID> productionCopiesUIDs = functionalAPI.getGroupSettings(cgUID).getProductionCopiesUIDs();
        for (ConsistencyGroupCopySettings copySettings : groupCopySettings) {
            GlobalCopyUID globalCopyUID = copySettings.getCopyUID().getGlobalCopyUID();
            ConsistencyGroupCopyUID copyUID = copySettings.getCopyUID();
            if (RecoverPointUtils.isProductionCopy(copyUID, productionCopiesUIDs)) {
                productionCopiesUID.put(Long.valueOf(globalCopyUID.getClusterUID().getId()), copySettings.getCopyUID());
                prodSites.add(globalCopyUID.getClusterUID());
            } else {
                nonProductionCopiesUID.put(Long.valueOf(globalCopyUID.getClusterUID().getId()), copySettings.getCopyUID());
            }
        }
        StringBuffer sb = new StringBuffer();
        for (ClusterUID prodSite : prodSites) {
            sb.append(prodSite.getId());
            sb.append(" ");
        }
        logger.info("RecoverPointClient: Adding replication set(s) to consistency group " + request.getCgName() + " for endpoint: " + _endpoint.toASCIIString() + " and production sites: " + sb.toString());
        ConsistencyGroupSettingsChangesParam cgSettingsParam = configureCGSettingsChangeParams(request, cgUID, prodSites, clusterIdCache, productionCopiesUID, nonProductionCopiesUID, attachAsClean);
        logger.info("Adding journals and rsets for CG " + request.getCgName());
        functionalAPI.setConsistencyGroupSettings(cgSettingsParam);
        // Sometimes the CG is still active when we start polling for link state and then
        // starts initializing some time afterwards. Adding this sleep to make sure the CG
        // starts initializing before we check the link states
        waitForRpOperation();
        RecoverPointImageManagementUtils rpiMgmt = new RecoverPointImageManagementUtils();
        logger.info("Waiting for links to become active for CG " + request.getCgName());
        // Wait for the CG link state to be active or paused. We can add replication sets to a CG that has a target
        // copy in DIRECT_ACCESS mode. In this image access mode, the link state is PAUSED and is therefore a valid
        // link state.
        rpiMgmt.waitForCGLinkState(functionalAPI, cgUID, RecoverPointImageManagementUtils.getPipeActiveState(functionalAPI, cgUID), PipeState.PAUSED);
        logger.info(String.format("Replication sets have been added to consistency group %s.", request.getCgName()));
        response.setReturnCode(RecoverPointReturnCode.SUCCESS);
        return response;
    } catch (Exception e) {
        logger.info("Failed to add replication set(s) to CG");
        throw RecoverPointException.exceptions.failedToAddReplicationSetToConsistencyGroup(request.getCgName(), getCause(e));
    }
}
Also used : RecoverPointCGResponse(com.emc.storageos.recoverpoint.responses.RecoverPointCGResponse) ConsistencyGroupSettingsChangesParam(com.emc.fapiclient.ws.ConsistencyGroupSettingsChangesParam) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ConsistencyGroupCopySettings(com.emc.fapiclient.ws.ConsistencyGroupCopySettings) RecoverPointImageManagementUtils(com.emc.storageos.recoverpoint.utils.RecoverPointImageManagementUtils) FunctionalAPIValidationException_Exception(com.emc.fapiclient.ws.FunctionalAPIValidationException_Exception) FunctionalAPIActionFailedException_Exception(com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception) FunctionalAPIInternalError_Exception(com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception) RecoverPointException(com.emc.storageos.recoverpoint.exceptions.RecoverPointException) ConsistencyGroupCopyUID(com.emc.fapiclient.ws.ConsistencyGroupCopyUID) ClusterUID(com.emc.fapiclient.ws.ClusterUID) GlobalCopyUID(com.emc.fapiclient.ws.GlobalCopyUID) ConsistencyGroupUID(com.emc.fapiclient.ws.ConsistencyGroupUID) ConsistencyGroupSettings(com.emc.fapiclient.ws.ConsistencyGroupSettings)

Example 3 with RecoverPointCGResponse

use of com.emc.storageos.recoverpoint.responses.RecoverPointCGResponse in project coprhd-controller by CoprHD.

the class RecoverPointClient method createCG.

/**
 * Creates a consistency group
 *
 * @param request - contains all the information required to create the consistency group
 *
 * @param attachAsClean attach as clean can be true if source and target are guaranteed to be the same (as in create
 *            new volume). for change vpool, attach as clean should be false
 *
 * @return CreateCGResponse - response as to success or fail of creating the consistency group
 *
 * @throws RecoverPointException
 */
public RecoverPointCGResponse createCG(CGRequestParams request, boolean metropoint, boolean attachAsClean) throws RecoverPointException {
    if (null == _endpoint.toASCIIString()) {
        throw RecoverPointException.exceptions.noRecoverPointEndpoint();
    }
    RecoverPointCGResponse response = new RecoverPointCGResponse();
    ConsistencyGroupUID cgUID = null;
    try {
        // Make sure the CG name is unique.
        int cgSuffix = 0;
        String cgName = request.getCgName();
        while (doesCgExist(request.getCgName())) {
            request.setCgName(String.format("%s-%d", cgName, ++cgSuffix));
        }
        // caches site names to cluster id's to reduce calls to fapi for the same information
        Map<String, ClusterUID> clusterIdCache = new HashMap<String, ClusterUID>();
        // prodSites is used for logging and to determine if a non-production copy is local or remote
        List<ClusterUID> prodSites = getProdSites(request, clusterIdCache);
        StringBuffer sb = new StringBuffer();
        for (ClusterUID prodSite : prodSites) {
            sb.append(prodSite.getId());
            sb.append(" ");
        }
        logger.info("RecoverPointClient: Creating recoverPoint consistency group " + request.getCgName() + " for endpoint: " + _endpoint.toASCIIString() + " and production sites: " + sb.toString());
        // used to set the copy uid on the rset volume when adding rsets
        Map<Long, ConsistencyGroupCopyUID> productionCopiesUID = new HashMap<Long, ConsistencyGroupCopyUID>();
        Map<Long, ConsistencyGroupCopyUID> nonProductionCopiesUID = new HashMap<Long, ConsistencyGroupCopyUID>();
        Map<ConsistencyGroupCopyUID, String> cgCopyNames = new HashMap<ConsistencyGroupCopyUID, String>();
        FullConsistencyGroupPolicy fullConsistencyGroupPolicy = configureCGPolicy(request, prodSites, clusterIdCache, productionCopiesUID, nonProductionCopiesUID, cgCopyNames);
        // create the CG with copies
        logger.info("Adding cg, copies and links for CG: " + request.getCgName());
        functionalAPI.validateAddConsistencyGroupAndCopies(fullConsistencyGroupPolicy);
        cgUID = functionalAPI.addConsistencyGroupAndCopies(fullConsistencyGroupPolicy);
        response.setCgId(cgUID.getId());
        ConsistencyGroupSettingsChangesParam cgSettingsParam = configureCGSettingsChangeParams(request, cgUID, prodSites, clusterIdCache, productionCopiesUID, nonProductionCopiesUID, attachAsClean);
        logger.info("Adding journals and rsets for CG " + request.getCgName());
        functionalAPI.setConsistencyGroupSettings(cgSettingsParam);
        RecoverPointImageManagementUtils rpiMgmt = new RecoverPointImageManagementUtils();
        logger.info("Waiting for links to become active for CG " + request.getCgName());
        rpiMgmt.waitForCGLinkState(functionalAPI, cgUID, RecoverPointImageManagementUtils.getPipeActiveState(functionalAPI, cgUID));
        logger.info(String.format("Consistency group %s has been created.", request.getCgName()));
        response.setReturnCode(RecoverPointReturnCode.SUCCESS);
        return response;
    } catch (Exception e) {
        if (cgUID != null) {
            try {
                RecoverPointUtils.cleanupCG(functionalAPI, cgUID);
            } catch (Exception e1) {
                logger.error("Error removing CG " + request.getCgName() + " after create CG failure");
                logger.error(e1.getMessage(), e1);
            }
        }
        throw RecoverPointException.exceptions.failedToCreateConsistencyGroup(request.getCgName(), getCause(e));
    }
}
Also used : RecoverPointCGResponse(com.emc.storageos.recoverpoint.responses.RecoverPointCGResponse) ConsistencyGroupSettingsChangesParam(com.emc.fapiclient.ws.ConsistencyGroupSettingsChangesParam) HashMap(java.util.HashMap) RecoverPointImageManagementUtils(com.emc.storageos.recoverpoint.utils.RecoverPointImageManagementUtils) FunctionalAPIValidationException_Exception(com.emc.fapiclient.ws.FunctionalAPIValidationException_Exception) FunctionalAPIActionFailedException_Exception(com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception) FunctionalAPIInternalError_Exception(com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception) RecoverPointException(com.emc.storageos.recoverpoint.exceptions.RecoverPointException) ConsistencyGroupCopyUID(com.emc.fapiclient.ws.ConsistencyGroupCopyUID) ClusterUID(com.emc.fapiclient.ws.ClusterUID) FullConsistencyGroupPolicy(com.emc.fapiclient.ws.FullConsistencyGroupPolicy) ConsistencyGroupUID(com.emc.fapiclient.ws.ConsistencyGroupUID)

Aggregations

FunctionalAPIActionFailedException_Exception (com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception)3 FunctionalAPIInternalError_Exception (com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception)3 RecoverPointException (com.emc.storageos.recoverpoint.exceptions.RecoverPointException)3 RecoverPointCGResponse (com.emc.storageos.recoverpoint.responses.RecoverPointCGResponse)3 ClusterUID (com.emc.fapiclient.ws.ClusterUID)2 ConsistencyGroupCopyUID (com.emc.fapiclient.ws.ConsistencyGroupCopyUID)2 ConsistencyGroupSettingsChangesParam (com.emc.fapiclient.ws.ConsistencyGroupSettingsChangesParam)2 ConsistencyGroupUID (com.emc.fapiclient.ws.ConsistencyGroupUID)2 FunctionalAPIValidationException_Exception (com.emc.fapiclient.ws.FunctionalAPIValidationException_Exception)2 RecoverPointImageManagementUtils (com.emc.storageos.recoverpoint.utils.RecoverPointImageManagementUtils)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 ConsistencyGroupCopySettings (com.emc.fapiclient.ws.ConsistencyGroupCopySettings)1 ConsistencyGroupSettings (com.emc.fapiclient.ws.ConsistencyGroupSettings)1 FullConsistencyGroupPolicy (com.emc.fapiclient.ws.FullConsistencyGroupPolicy)1 GlobalCopyUID (com.emc.fapiclient.ws.GlobalCopyUID)1 VolumeDescriptor (com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor)1 CoordinatorException (com.emc.storageos.coordinator.exceptions.CoordinatorException)1 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)1 BlockConsistencyGroup (com.emc.storageos.db.client.model.BlockConsistencyGroup)1