Search in sources :

Example 11 with RecoverPointClient

use of com.emc.storageos.recoverpoint.impl.RecoverPointClient in project coprhd-controller by CoprHD.

the class RPHelper method getRPBookmarks.

/**
 * For an RP configuration, get all RP bookmarks for the CGs provided
 *
 * @param system RP system
 * @param cgIDs IDs of the consistency groups to get the bookmarks
 * @return command result object, object list [0] has GetBookmarksResponse
 * @throws RecoverPointException
 */
private static BiosCommandResult getRPBookmarks(ProtectionSystem system, Set<Integer> cgIDs) throws RecoverPointException {
    _log.info("getRPBookmarks {} - start", system.getId());
    RecoverPointClient rp = RPHelper.getRecoverPointClient(system);
    GetBookmarksResponse bookmarkResponse = rp.getRPBookmarks(cgIDs);
    _log.info("getRPBookmarks {} - complete", system.getId());
    BiosCommandResult result = BiosCommandResult.createSuccessfulResult();
    List<Object> returnList = new ArrayList<Object>();
    returnList.add(bookmarkResponse);
    result.setObjectList(returnList);
    return result;
}
Also used : GetBookmarksResponse(com.emc.storageos.recoverpoint.responses.GetBookmarksResponse) BiosCommandResult(com.emc.storageos.volumecontroller.impl.BiosCommandResult) RecoverPointClient(com.emc.storageos.recoverpoint.impl.RecoverPointClient) ArrayList(java.util.ArrayList)

Example 12 with RecoverPointClient

use of com.emc.storageos.recoverpoint.impl.RecoverPointClient in project coprhd-controller by CoprHD.

the class RPUnManagedObjectDiscoverer method discoverUnManagedObjects.

/**
 * Discovers the RP CGs and all the volumes therein. It updates/creates the UnManagedProtectionSet
 * objects and updates (if it exists) the UnManagedVolume objects with RP information needed for
 * ingestion
 *
 * @param accessProfile access profile
 * @param dbClient db client
 * @param partitionManager partition manager
 * @throws Exception
 */
public void discoverUnManagedObjects(AccessProfile accessProfile, DbClient dbClient, PartitionManager partitionManager) throws Exception {
    this.partitionManager = partitionManager;
    log.info("Started discovery of UnManagedVolumes for system {}", accessProfile.getSystemId());
    ProtectionSystem protectionSystem = dbClient.queryObject(ProtectionSystem.class, accessProfile.getSystemId());
    if (protectionSystem == null) {
        log.error("Discovery is not run!  Protection System not found: " + accessProfile.getSystemId());
        return;
    }
    RecoverPointClient rp = RPHelper.getRecoverPointClient(protectionSystem);
    unManagedCGsInsert = new ArrayList<UnManagedProtectionSet>();
    unManagedCGsUpdate = new ArrayList<UnManagedProtectionSet>();
    unManagedVolumesToDelete = new ArrayList<UnManagedVolume>();
    unManagedVolumesToUpdateByWwn = new HashMap<String, UnManagedVolume>();
    unManagedCGsReturnedFromProvider = new HashSet<URI>();
    // Get all of the consistency groups (and their volumes) from RP
    Set<GetCGsResponse> cgs = rp.getAllCGs();
    if (cgs == null) {
        log.warn("No CGs were found on protection system: " + protectionSystem.getLabel());
        return;
    }
    // This section of code allows us to cache XIO native GUID to workaround an issue
    // with RP's understanding of XIO volume WWNs (128-bit) and the rest of the world's
    // understanding of the XIO volume WWN once it's exported (64-bit)
    Map<String, String> rpWwnToNativeWwn = new HashMap<String, String>();
    List<URI> storageSystemIds = dbClient.queryByType(StorageSystem.class, true);
    List<String> storageNativeIdPrefixes = new ArrayList<String>();
    if (storageSystemIds != null) {
        Iterator<StorageSystem> storageSystemsItr = dbClient.queryIterativeObjects(StorageSystem.class, storageSystemIds);
        while (storageSystemsItr.hasNext()) {
            StorageSystem storageSystem = storageSystemsItr.next();
            if (storageSystem.getSystemType().equalsIgnoreCase(Type.xtremio.name())) {
                storageNativeIdPrefixes.add(storageSystem.getNativeGuid());
            }
        }
    }
    for (GetCGsResponse cg : cgs) {
        try {
            log.info("Processing returned CG: " + cg.getCgName());
            boolean newCG = false;
            // UnManagedProtectionSet native GUID is protection system GUID + consistency group ID
            String nativeGuid = protectionSystem.getNativeGuid() + Constants.PLUS + cg.getCgId();
            // First check to see if this protection set is already part of our managed DB
            if (null != DiscoveryUtils.checkProtectionSetExistsInDB(dbClient, nativeGuid)) {
                log.info("Protection Set " + nativeGuid + " already is managed by ViPR, skipping unmanaged discovery");
                continue;
            }
            // Now check to see if the unmanaged CG exists in the database
            UnManagedProtectionSet unManagedProtectionSet = DiscoveryUtils.checkUnManagedProtectionSetExistsInDB(dbClient, nativeGuid);
            if (null == unManagedProtectionSet) {
                log.info("Creating new unmanaged protection set for CG: " + cg.getCgName());
                unManagedProtectionSet = new UnManagedProtectionSet();
                unManagedProtectionSet.setId(URIUtil.createId(UnManagedProtectionSet.class));
                unManagedProtectionSet.setNativeGuid(nativeGuid);
                unManagedProtectionSet.setProtectionSystemUri(protectionSystem.getId());
                StringSet protectionId = new StringSet();
                protectionId.add("" + cg.getCgId());
                unManagedProtectionSet.putCGInfo(SupportedCGInformation.PROTECTION_ID.toString(), protectionId);
                // Default MP to false until proven otherwise
                unManagedProtectionSet.getCGCharacteristics().put(UnManagedProtectionSet.SupportedCGCharacteristics.IS_MP.name(), Boolean.FALSE.toString());
                newCG = true;
            } else {
                log.info("Found existing unmanaged protection set for CG: " + cg.getCgName() + ", using " + unManagedProtectionSet.getId().toString());
            }
            unManagedCGsReturnedFromProvider.add(unManagedProtectionSet.getId());
            // Update the fields for the CG
            unManagedProtectionSet.setCgName(cg.getCgName());
            unManagedProtectionSet.setLabel(cg.getCgName());
            // Indicate whether the CG is in a healthy state or not to ingest.
            unManagedProtectionSet.getCGCharacteristics().put(UnManagedProtectionSet.SupportedCGCharacteristics.IS_HEALTHY.name(), cg.getCgState().equals(GetCGStateResponse.HEALTHY) ? Boolean.TRUE.toString() : Boolean.FALSE.toString());
            // Indicate whether the CG is sync or async
            unManagedProtectionSet.getCGCharacteristics().put(UnManagedProtectionSet.SupportedCGCharacteristics.IS_SYNC.name(), cg.getCgPolicy().synchronous ? Boolean.TRUE.toString() : Boolean.FALSE.toString());
            // Fill in RPO type and value information
            StringSet rpoType = new StringSet();
            rpoType.add(cg.getCgPolicy().rpoType);
            unManagedProtectionSet.putCGInfo(SupportedCGInformation.RPO_TYPE.toString(), rpoType);
            StringSet rpoValue = new StringSet();
            rpoValue.add(cg.getCgPolicy().rpoValue.toString());
            unManagedProtectionSet.putCGInfo(SupportedCGInformation.RPO_VALUE.toString(), rpoValue);
            if (null == cg.getCopies()) {
                log.info("Protection Set " + nativeGuid + " does not contain any copies.  Skipping...");
                continue;
            }
            if (null == cg.getRsets()) {
                log.info("Protection Set " + nativeGuid + " does not contain any replication sets.  Skipping...");
                continue;
            }
            // clean up the existing journal and replicationsets info in the unmanaged protection set, so that updated info is populated
            if (!newCG) {
                cleanUpUnManagedResources(unManagedProtectionSet, unManagedVolumesToUpdateByWwn, dbClient);
            }
            // Now map UnManagedVolume objects to the journal and rset (sources/targets) and put RP fields in them
            Map<String, String> rpCopyAccessStateMap = new HashMap<String, String>();
            mapCgJournals(unManagedProtectionSet, cg, rpCopyAccessStateMap, rpWwnToNativeWwn, storageNativeIdPrefixes, dbClient);
            mapCgSourceAndTargets(unManagedProtectionSet, cg, rpCopyAccessStateMap, rpWwnToNativeWwn, storageNativeIdPrefixes, dbClient);
            if (newCG) {
                unManagedCGsInsert.add(unManagedProtectionSet);
            } else {
                unManagedCGsUpdate.add(unManagedProtectionSet);
            }
        } catch (Exception ex) {
            log.error("Error processing RP CG {}", cg.getCgName(), ex);
        }
    }
    handlePersistence(dbClient, false);
    cleanUp(protectionSystem, dbClient);
}
Also used : GetCGsResponse(com.emc.storageos.recoverpoint.responses.GetCGsResponse) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem) UnManagedProtectionSet(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedProtectionSet) URI(java.net.URI) UnManagedVolume(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume) RecoverPointClient(com.emc.storageos.recoverpoint.impl.RecoverPointClient) StringSet(com.emc.storageos.db.client.model.StringSet) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 13 with RecoverPointClient

use of com.emc.storageos.recoverpoint.impl.RecoverPointClient 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 14 with RecoverPointClient

use of com.emc.storageos.recoverpoint.impl.RecoverPointClient in project coprhd-controller by CoprHD.

the class RPCommunicationInterface method discoverVisibleStorageSystems.

/**
 * Discovers the Storage Systems associated to the Protection System.
 *
 * @param protectionSystem A reference to the Protection System
 */
private void discoverVisibleStorageSystems(ProtectionSystem protectionSystem) {
    RecoverPointClient rp = RPHelper.getRecoverPointClient(protectionSystem);
    Map<String, Set<String>> siteStorageSystems = rp.getArraysForClusters();
    if (protectionSystem.getSiteVisibleStorageArrays() != null) {
        protectionSystem.getSiteVisibleStorageArrays().clear();
    } else {
        protectionSystem.setSiteVisibleStorageArrays(new StringSetMap());
    }
    List<URI> storageSystemIDs = _dbClient.queryByType(StorageSystem.class, true);
    if (storageSystemIDs == null) {
        return;
    }
    List<StorageSystem> storageSystems = _dbClient.queryObject(StorageSystem.class, storageSystemIDs);
    if (storageSystems == null) {
        return;
    }
    // (for the arrays ViPR knows about)
    if (siteStorageSystems != null) {
        for (Map.Entry<String, Set<String>> clusterEntry : siteStorageSystems.entrySet()) {
            if (clusterEntry.getValue() == null || clusterEntry.getValue().isEmpty()) {
                continue;
            }
            for (String serialNumber : clusterEntry.getValue()) {
                if (serialNumber == null || serialNumber.isEmpty()) {
                    continue;
                }
                // Find the storage system ID associated with this serial number
                // We have a serial number from the RP appliances, and for the most part, that works
                // with a Constraint Query, but in the case of VPLEX, the serial number object for distributed
                // VPLEX clusters will contain two serial numbers, not just one. So we need a long-form
                // way of finding those VPLEXs as well.
                Iterator<StorageSystem> activeSystemListItr = storageSystems.iterator();
                StorageSystem foundStorageSystem = null;
                while (activeSystemListItr.hasNext() && foundStorageSystem == null) {
                    StorageSystem system = activeSystemListItr.next();
                    if (NullColumnValueGetter.isNotNullValue(system.getSerialNumber()) && system.getSerialNumber().contains(serialNumber)) {
                        foundStorageSystem = system;
                    }
                }
                if (foundStorageSystem != null) {
                    protectionSystem.addSiteVisibleStorageArrayEntry(clusterEntry.getKey(), serialNumber);
                    _log.info(String.format("RP Discovery found RP cluster %s is configured to use a registered storage system: %s, %s", clusterEntry.getKey(), serialNumber, foundStorageSystem.getNativeGuid()));
                } else {
                    _log.info(String.format("RP Discovery found RP cluster %s is configured to use a storage system: %s, but it is not configured for use in ViPR", clusterEntry.getKey(), serialNumber));
                }
            }
        }
    }
    _dbClient.persistObject(protectionSystem);
}
Also used : StringSetMap(com.emc.storageos.db.client.model.StringSetMap) ProtectionSet(com.emc.storageos.db.client.model.ProtectionSet) Set(java.util.Set) HashSet(java.util.HashSet) AbstractChangeTrackingSet(com.emc.storageos.db.client.model.AbstractChangeTrackingSet) StringSet(com.emc.storageos.db.client.model.StringSet) RecoverPointClient(com.emc.storageos.recoverpoint.impl.RecoverPointClient) URI(java.net.URI) Map(java.util.Map) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) StringMap(com.emc.storageos.db.client.model.StringMap) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 15 with RecoverPointClient

use of com.emc.storageos.recoverpoint.impl.RecoverPointClient 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

RecoverPointClient (com.emc.storageos.recoverpoint.impl.RecoverPointClient)31 ArrayList (java.util.ArrayList)18 URI (java.net.URI)17 ProtectionSystem (com.emc.storageos.db.client.model.ProtectionSystem)15 Volume (com.emc.storageos.db.client.model.Volume)15 RecoverPointException (com.emc.storageos.recoverpoint.exceptions.RecoverPointException)15 URISyntaxException (java.net.URISyntaxException)15 FunctionalAPIActionFailedException_Exception (com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception)13 FunctionalAPIInternalError_Exception (com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception)13 CoordinatorException (com.emc.storageos.coordinator.exceptions.CoordinatorException)13 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)13 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)13 LockRetryException (com.emc.storageos.locking.LockRetryException)13 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)13 InternalServerErrorException (com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException)13 ControllerException (com.emc.storageos.volumecontroller.ControllerException)13 WorkflowException (com.emc.storageos.workflow.WorkflowException)13 NamedURI (com.emc.storageos.db.client.model.NamedURI)12 ProtectionSet (com.emc.storageos.db.client.model.ProtectionSet)10 StringSet (com.emc.storageos.db.client.model.StringSet)7