Search in sources :

Example 1 with RecoverPointException

use of com.emc.storageos.recoverpoint.exceptions.RecoverPointException in project coprhd-controller by CoprHD.

the class RPCommunicationInterface method discoverProtectionSet.

/**
 * Discover a single protection set.
 *
 * @param protectionSystem protection system
 * @param protectionSetId protection set
 * @throws RecoverPointException
 */
private void discoverProtectionSet(ProtectionSystem protectionSystem, URI protectionSetId) throws RecoverPointException {
    ProtectionSet protectionSet = _dbClient.queryObject(ProtectionSet.class, protectionSetId);
    if (protectionSet == null || protectionSet.getInactive()) {
        return;
    }
    List<String> staleVolumes = new ArrayList<String>();
    StringSet protectionVolumes = protectionSet.getVolumes();
    RecoverPointVolumeProtectionInfo protectionVolume = null;
    RecoverPointClient rp = RPHelper.getRecoverPointClient(protectionSystem);
    boolean changed = false;
    _log.info("ProtectionSet discover in the RPDeviceController called for protection set: " + protectionSet.getLabel());
    for (String volume : protectionVolumes) {
        Volume protectionVolumeWWN = _dbClient.queryObject(Volume.class, URI.create(volume));
        if (protectionVolumeWWN == null || protectionVolumeWWN.getInactive()) {
            staleVolumes.add(volume);
            continue;
        }
        try {
            protectionVolume = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(protectionVolumeWWN.getId(), _dbClient));
        } catch (RecoverPointException re) {
            StringBuffer errMsgBuilder = new StringBuffer();
            String msg = "Discovery of protection set failed. Protection system: " + protectionSystem.getId() + ", ";
            errMsgBuilder.append(msg);
            errMsgBuilder.append(re.getMessage());
            _log.warn(errMsgBuilder.toString());
        }
        if (protectionVolume == null) {
            continue;
        }
        // If the volume is a source volume, let's check to see if the personality changed.
        if ((!changed) && (((protectionVolume.getRpVolumeCurrentProtectionStatus() == RecoverPointVolumeProtectionInfo.volumeProtectionStatus.PROTECTED_SOURCE) && (protectionVolumeWWN.getPersonality().equalsIgnoreCase(Volume.PersonalityTypes.TARGET.toString())))) || ((protectionVolume.getRpVolumeCurrentProtectionStatus() == RecoverPointVolumeProtectionInfo.volumeProtectionStatus.PROTECTED_TARGET) && (protectionVolumeWWN.getPersonality().equalsIgnoreCase(Volume.PersonalityTypes.SOURCE.toString())))) {
            _log.info("Changing personality of volume {} due to RP condition on consistency group", protectionVolumeWWN.getLabel());
            updatePostFailoverPersonalities(protectionVolumeWWN);
            changed = true;
        }
        if (protectionVolume.getRpVolumeCurrentProtectionStatus() == RecoverPointVolumeProtectionInfo.volumeProtectionStatus.PROTECTED_SOURCE) {
            switch(rp.getCGState(protectionVolume)) {
                case DELETED:
                    protectionSet.setProtectionStatus(ProtectionStatus.DELETED.toString());
                    break;
                case STOPPED:
                    protectionSet.setProtectionStatus(ProtectionStatus.DISABLED.toString());
                    break;
                case PAUSED:
                    protectionSet.setProtectionStatus(ProtectionStatus.PAUSED.toString());
                    break;
                case MIXED:
                    protectionSet.setProtectionStatus(ProtectionStatus.MIXED.toString());
                    break;
                case READY:
                    protectionSet.setProtectionStatus(ProtectionStatus.ENABLED.toString());
                    break;
            }
            _dbClient.updateObject(protectionSet);
            break;
        }
    }
    // remove stale entries from protection set
    if (!staleVolumes.isEmpty()) {
        _log.info(String.format("ProtectionSet %s references at least one volume id that no longer exist in the database. Removing all stale volume references: %s", protectionSet.getLabel(), String.join(",", staleVolumes)));
        protectionSet.getVolumes().removeAll(staleVolumes);
        _dbClient.updateObject(protectionSet);
    }
}
Also used : RecoverPointVolumeProtectionInfo(com.emc.storageos.recoverpoint.responses.RecoverPointVolumeProtectionInfo) Volume(com.emc.storageos.db.client.model.Volume) RecoverPointClient(com.emc.storageos.recoverpoint.impl.RecoverPointClient) RecoverPointException(com.emc.storageos.recoverpoint.exceptions.RecoverPointException) ProtectionSet(com.emc.storageos.db.client.model.ProtectionSet) ArrayList(java.util.ArrayList) StringSet(com.emc.storageos.db.client.model.StringSet)

Example 2 with RecoverPointException

use of com.emc.storageos.recoverpoint.exceptions.RecoverPointException 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 RecoverPointException

use of com.emc.storageos.recoverpoint.exceptions.RecoverPointException in project coprhd-controller by CoprHD.

the class RecoverPointClient method getRPSystemStatistics.

/**
 * Get RP site statistics for use in collectStatisticsInformation
 *
 * @param RecoverPointVolumeProtectionInfo copyToModify - Volume info for the CG to add a journal volume to
 *
 * @param String journalWWNToDelete - WWN of the journal volume to delete
 *
 * @return RecoverPointStatisticsResponse
 *
 * @throws RecoverPointException
 */
public RecoverPointStatisticsResponse getRPSystemStatistics() throws RecoverPointException {
    logger.info("Collecting RecoverPoint System Statistics.");
    RecoverPointStatisticsResponse response = new RecoverPointStatisticsResponse();
    try {
        Map<Long, Double> siteAvgCPUUsageMap = new HashMap<Long, Double>();
        Map<Long, Long> siteInputAvgThroughput = new HashMap<Long, Long>();
        Map<Long, Long> siteOutputAvgThroughput = new HashMap<Long, Long>();
        Map<Long, Long> siteIncomingAvgWrites = new HashMap<Long, Long>();
        SystemStatistics systemStatistics = functionalAPI.getSystemStatistics();
        Set<ClusterUID> ClusterUIDList = new HashSet<ClusterUID>();
        List<RpaStatistics> rpaStatisticsList = systemStatistics.getRpaStatistics();
        for (RpaStatistics rpaStatistics : rpaStatisticsList) {
            ClusterUID siteID = rpaStatistics.getRpaUID().getClusterUID();
            boolean foundSite = false;
            for (ClusterUID siteListUID : ClusterUIDList) {
                if (siteID.getId() == siteListUID.getId()) {
                    foundSite = true;
                    break;
                }
            }
            if (!foundSite) {
                ClusterUIDList.add(siteID);
            }
        }
        for (ClusterUID ClusterUID : ClusterUIDList) {
            List<Double> rpaCPUList = new LinkedList<Double>();
            List<Long> rpaSiteInputAvgThroughputList = new LinkedList<Long>();
            List<Long> rpaSiteOutputAvgThroughputList = new LinkedList<Long>();
            List<Long> rpaSiteInputAvgIncomingWritesList = new LinkedList<Long>();
            for (RpaStatistics rpaStatistics : rpaStatisticsList) {
                if (rpaStatistics.getRpaUID().getClusterUID().getId() == ClusterUID.getId()) {
                    rpaCPUList.add(Double.valueOf(rpaStatistics.getCpuUsage()));
                    rpaSiteInputAvgThroughputList.add(rpaStatistics.getTraffic().getApplicationThroughputStatistics().getInThroughput());
                    for (ConnectionOutThroughput cot : rpaStatistics.getTraffic().getApplicationThroughputStatistics().getConnectionsOutThroughputs()) {
                        rpaSiteOutputAvgThroughputList.add(cot.getOutThroughput());
                    }
                    rpaSiteInputAvgIncomingWritesList.add(rpaStatistics.getTraffic().getApplicationIncomingWrites());
                }
            }
            Double cpuTotalUsage = 0.0;
            Long incomingWritesTotal = Long.valueOf(0);
            Long inputThoughputTotal = Long.valueOf(0);
            Long outputThoughputTotal = Long.valueOf(0);
            for (Double rpaCPUs : rpaCPUList) {
                cpuTotalUsage += rpaCPUs;
            }
            for (Long siteInputThroughput : rpaSiteInputAvgThroughputList) {
                inputThoughputTotal += siteInputThroughput;
            }
            for (Long siteOutputThroughput : rpaSiteOutputAvgThroughputList) {
                outputThoughputTotal += siteOutputThroughput;
            }
            for (Long incomingWrites : rpaSiteInputAvgIncomingWritesList) {
                incomingWritesTotal += incomingWrites;
            }
            logger.info("Average CPU usage for site: " + ClusterUID.getId() + " is " + cpuTotalUsage / rpaCPUList.size());
            logger.info("Average input throughput for site: " + ClusterUID.getId() + " is " + inputThoughputTotal / rpaCPUList.size() + " kb/s");
            logger.info("Average output throughput for site: " + ClusterUID.getId() + " is " + outputThoughputTotal / rpaCPUList.size() + " kb/s");
            logger.info("Average incoming writes for site: " + ClusterUID.getId() + " is " + incomingWritesTotal / rpaCPUList.size() + " writes/s");
            siteAvgCPUUsageMap.put(ClusterUID.getId(), cpuTotalUsage / rpaCPUList.size());
            siteInputAvgThroughput.put(ClusterUID.getId(), inputThoughputTotal / rpaCPUList.size());
            siteOutputAvgThroughput.put(ClusterUID.getId(), outputThoughputTotal / rpaCPUList.size());
            siteIncomingAvgWrites.put(ClusterUID.getId(), incomingWritesTotal / rpaCPUList.size());
        }
        response.setSiteCPUUsageMap(siteAvgCPUUsageMap);
        response.setSiteInputAvgIncomingWrites(siteIncomingAvgWrites);
        response.setSiteOutputAvgThroughput(siteOutputAvgThroughput);
        response.setSiteInputAvgThroughput(siteInputAvgThroughput);
        List<ProtectionSystemParameters> systemParameterList = new LinkedList<ProtectionSystemParameters>();
        MonitoredParametersStatus monitoredParametersStatus = functionalAPI.getMonitoredParametersStatus();
        List<MonitoredParameter> monitoredParameterList = monitoredParametersStatus.getParameters();
        for (MonitoredParameter monitoredParameter : monitoredParameterList) {
            ProtectionSystemParameters param = response.new ProtectionSystemParameters();
            param.parameterName = monitoredParameter.getKey().getParameterType().value();
            param.parameterLimit = monitoredParameter.getValue().getParameterWaterMarks().getLimit();
            param.currentParameterValue = monitoredParameter.getValue().getValue();
            if (monitoredParameter.getKey().getClusterUID() != null) {
                param.siteID = monitoredParameter.getKey().getClusterUID().getId();
            }
            systemParameterList.add(param);
        }
        response.setParamList(systemParameterList);
        for (ProtectionSystemParameters monitoredParameter : response.getParamList()) {
            logger.info("Key: " + monitoredParameter.parameterName);
            logger.info("Current Value: " + monitoredParameter.currentParameterValue);
            logger.info("Max Value: " + monitoredParameter.parameterLimit);
        }
        return response;
    } catch (FunctionalAPIActionFailedException_Exception e) {
        throw RecoverPointException.exceptions.failedToGetStatistics(e);
    } catch (FunctionalAPIInternalError_Exception e) {
        throw RecoverPointException.exceptions.failedToGetStatistics(e);
    } catch (Exception e) {
        throw RecoverPointException.exceptions.failedToGetStatistics(e);
    }
}
Also used : RpaStatistics(com.emc.fapiclient.ws.RpaStatistics) ProtectionSystemParameters(com.emc.storageos.recoverpoint.responses.RecoverPointStatisticsResponse.ProtectionSystemParameters) HashMap(java.util.HashMap) HashSet(java.util.HashSet) FunctionalAPIActionFailedException_Exception(com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception) ConnectionOutThroughput(com.emc.fapiclient.ws.ConnectionOutThroughput) MonitoredParameter(com.emc.fapiclient.ws.MonitoredParameter) LinkedList(java.util.LinkedList) 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) RecoverPointStatisticsResponse(com.emc.storageos.recoverpoint.responses.RecoverPointStatisticsResponse) ClusterUID(com.emc.fapiclient.ws.ClusterUID) FunctionalAPIInternalError_Exception(com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception) SystemStatistics(com.emc.fapiclient.ws.SystemStatistics) MonitoredParametersStatus(com.emc.fapiclient.ws.MonitoredParametersStatus)

Example 4 with RecoverPointException

use of com.emc.storageos.recoverpoint.exceptions.RecoverPointException in project coprhd-controller by CoprHD.

the class RecoverPointClient method validateRSetsRemoved.

/**
 * Validate that the RSet(s) has been removed from the RP system by calling out
 * to get all RSets for the CG and ensuring the one(s) we are trying to delete is gone.
 *
 * If we still see the RSet(s) being returned, wait and try again until max attempts is
 * reached.
 *
 * @param resetIDsToValidate The RSet IDs to check that they have been removed from RP
 * @param cgToValidate The CG UID to check
 * @param volumeWWNs The WWNs of the source volumes to delete, used for exceptions
 * @throws RecoverPointException RP Exception to throw if we hit it
 */
private void validateRSetsRemoved(List<Long> resetIDsToValidate, ConsistencyGroupUID cgToValidate, List<String> volumeWWNs) throws RecoverPointException {
    try {
        String cgName = functionalAPI.getGroupName(cgToValidate);
        logger.info(String.format("Validating that all requested RSets have been removed from RP CG [%s] (%d)", cgName, cgToValidate.getId()));
        int rsetDeleteAttempt = 0;
        while (rsetDeleteAttempt < MAX_WAIT_FOR_RP_DELETE_ATTEMPTS) {
            boolean allRSetsDeleted = true;
            logger.info(String.format("Validation attempt %d of %d", rsetDeleteAttempt + 1, MAX_WAIT_FOR_RP_DELETE_ATTEMPTS));
            // Get the current RSets from the CG
            ConsistencyGroupSettings groupSettings = functionalAPI.getGroupSettings(cgToValidate);
            List<ReplicationSetSettings> replicationSetSettings = groupSettings.getReplicationSetsSettings();
            // If any are still present, wait and check again.
            for (ReplicationSetSettings rset : replicationSetSettings) {
                if (resetIDsToValidate.contains(rset.getReplicationSetUID().getId())) {
                    logger.info(String.format("RSet [%s] (%d) has not been removed yet. Will wait and check again...", rset.getReplicationSetName(), rset.getReplicationSetUID().getId()));
                    waitForRpOperation();
                    rsetDeleteAttempt++;
                    allRSetsDeleted = false;
                    // to RecoverPoint to ensure we do not have a stale connection.
                    if (rsetDeleteAttempt == (MAX_WAIT_FOR_RP_DELETE_ATTEMPTS / 2)) {
                        this.reconnect();
                    }
                    break;
                }
            }
            if (allRSetsDeleted) {
                // RSets appear to have been removed from RP
                logger.info(String.format("All requested RSets have been removed from RP CG [%s] (%d).", cgName, cgToValidate.getId()));
                break;
            }
        }
        // If we reached max attempts alert the user and continue on with delete operation.
        if (rsetDeleteAttempt >= MAX_WAIT_FOR_RP_DELETE_ATTEMPTS) {
            // Allow the cleanup to continue in ViPR but warn the user
            logger.error(String.format("Max attempts reached waiting for requested RSets to be removed from RP CG. " + "Please check RP System."));
            throw RecoverPointException.exceptions.failedToDeleteReplicationSet(volumeWWNs.toString(), new Exception("Max attempts reached waiting for requested RSets to be removed from RP CG. " + "Please check RP System."));
        }
    } catch (Exception e) {
        logger.error(String.format("Exception hit while waiting for all requested RSets to be removed from RP CG."));
        throw RecoverPointException.exceptions.failedToDeleteReplicationSet(volumeWWNs.toString(), e);
    }
}
Also used : ReplicationSetSettings(com.emc.fapiclient.ws.ReplicationSetSettings) ConsistencyGroupSettings(com.emc.fapiclient.ws.ConsistencyGroupSettings) 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)

Example 5 with RecoverPointException

use of com.emc.storageos.recoverpoint.exceptions.RecoverPointException in project coprhd-controller by CoprHD.

the class RecoverPointClientFactory method getClient.

/**
 * Static method to manage Recover Point connections via the RecoverPointClient class.
 *
 * When a valid connection is created the RecoverPointClient object is kept in a ConcurrentHashMap
 * and referenced by a unique key combination comprised of the endpoint + username + password.
 *
 * If a connection key exists, a handle to an existing RecoverPointClient object will
 * be returned instead of creating a brand new connection. Otherwise, a new connection will be created
 * and stored (if valid).
 *
 * If the connection info is invalid, an exception will be thrown and the object will not be stored.
 *
 * The method can potentially be called by multiple threads, therefore synchronization is required
 * to maintain thread safety. ConcurrentHashMap is, by default, thread safe which is why
 * it is being used to store valid connections.
 *
 * @param protectionSystem for a unique key, if we connect using a secondary address, keep using that address.
 * @param endpoints URI to the RecoverPoint System
 * @param username Username to log into the RecoverPoint System
 * @param password Password to log into the RecoverPoint System
 *
 * @return RecoverPointClient with a connection to the RPA.
 * @throws RecoverPointException
 */
public static synchronized RecoverPointClient getClient(URI protectionSystem, List<URI> endpoints, String username, String password) throws RecoverPointException {
    logger.info("Attempting to get RecoverPointClient connection...");
    // Throw an exception if null credentials are passed in.
    if (endpoints == null || username == null || password == null) {
        throw RecoverPointException.exceptions.invalidCrendentialsPassedIn(username, password);
    }
    // Unique key to identify RP connections for different Protection Systems
    String key = String.valueOf(protectionSystem) + username + password;
    // See if there is an existing valid RecoverPointClient using the protection system key
    RecoverPointClient existingClient = clientMap.get(key);
    if (existingClient != null) {
        logger.info("Existing RecoverPointClient connection found. Re-using connection: " + existingClient.getEndpoint().toString());
        try {
            // Do a ping check. If this fails, try the other IP addresses.
            existingClient.ping();
            return existingClient;
        } catch (Exception e) {
            logger.error("Received " + e.toString() + ".  Failed to ping Mgmt IP: " + existingClient.getEndpoint().toString() + ", Cause: " + RecoverPointClient.getCause(e));
            // remove the protection system's connection from the factory, and the endpoint from the endpoints list
            clientMap.remove(key);
            endpoints.remove(existingClient.getEndpoint());
        }
    }
    // Now go through the endpoints and try to create a new RP client connection.
    Iterator<URI> endpointIter = endpoints.iterator();
    while (endpointIter.hasNext()) {
        URI endpoint = endpointIter.next();
        // Throw an exception if the endpoint can not be resolved to an ASCII string
        String mgmtIPAddress = endpoint.toASCIIString();
        if (mgmtIPAddress == null) {
            throw RecoverPointException.exceptions.noRecoverPointEndpoint();
        }
        logger.info("Creating new RecoverPointClient connection to: " + mgmtIPAddress);
        // If we don't have an existing RecoverPointClient, create a new one and add it to the client map only
        // if the connection is valid.
        RecoverPointClient newRecoverpointClient = new RecoverPointClient(endpoint, username, password);
        FunctionalAPIImpl impl = null;
        try {
            // Create the connection
            impl = new RecoverPointConnection().connect(endpoint, username, password);
            logger.info("New RecoverPointClient connection created to: " + mgmtIPAddress);
            // Add the new RecoverPointConnection to the RecoverPointClient
            newRecoverpointClient.setFunctionalAPI(impl);
            // We just connected but to be safe, lets do a quick ping to confirm that
            // we can reach the new RecoverPoint client
            newRecoverpointClient.ping();
            // Update the client map
            clientMap.put(key, newRecoverpointClient);
            return newRecoverpointClient;
        } catch (Exception e) {
            logger.error("Received " + e.toString() + ". Failed to create new RP connection: " + endpoint.toString() + ", Cause: " + RecoverPointClient.getCause(e));
            // Remove invalid entry
            clientMap.remove(key);
            if (endpointIter.hasNext()) {
                logger.info("Trying a different IP address to contact RP...");
            } else {
                throw RecoverPointException.exceptions.failedToPingMgmtIP(mgmtIPAddress, RecoverPointClient.getCause(e));
            }
        }
    }
    // You'll never get here.
    return null;
}
Also used : RecoverPointClient(com.emc.storageos.recoverpoint.impl.RecoverPointClient) URI(java.net.URI) FunctionalAPIImpl(com.emc.fapiclient.ws.FunctionalAPIImpl) RecoverPointException(com.emc.storageos.recoverpoint.exceptions.RecoverPointException)

Aggregations

RecoverPointException (com.emc.storageos.recoverpoint.exceptions.RecoverPointException)30 FunctionalAPIActionFailedException_Exception (com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception)12 FunctionalAPIInternalError_Exception (com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception)12 RecoverPointVolumeProtectionInfo (com.emc.storageos.recoverpoint.responses.RecoverPointVolumeProtectionInfo)12 FunctionalAPIValidationException_Exception (com.emc.fapiclient.ws.FunctionalAPIValidationException_Exception)10 HashSet (java.util.HashSet)9 ClusterUID (com.emc.fapiclient.ws.ClusterUID)6 HashMap (java.util.HashMap)6 ConsistencyGroupSettings (com.emc.fapiclient.ws.ConsistencyGroupSettings)5 ConsistencyGroupUID (com.emc.fapiclient.ws.ConsistencyGroupUID)5 URISyntaxException (java.net.URISyntaxException)5 ConsistencyGroupCopyUID (com.emc.fapiclient.ws.ConsistencyGroupCopyUID)4 URI (java.net.URI)4 Test (org.junit.Test)4 ClusterConfiguration (com.emc.fapiclient.ws.ClusterConfiguration)3 ConsistencyGroupSettingsChangesParam (com.emc.fapiclient.ws.ConsistencyGroupSettingsChangesParam)3 ReplicationSetSettings (com.emc.fapiclient.ws.ReplicationSetSettings)3 CreateBookmarkRequestParams (com.emc.storageos.recoverpoint.requests.CreateBookmarkRequestParams)3 RecoverPointImageManagementUtils (com.emc.storageos.recoverpoint.utils.RecoverPointImageManagementUtils)3 ArrayList (java.util.ArrayList)3