Search in sources :

Example 96 with ProtectionSystem

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

the class RPCommunicationInterface method isNetworkConnected.

/**
 * Check the connectivity of a storage system to the RP cluster
 *
 * @param serialNumber serial number of the storage system
 * @param siteArray RPSiteArray object
 * @return true if the storage array has network connectivity to the RP cluster
 */
private boolean isNetworkConnected(String serialNumber, RPSiteArray siteArray) {
    // Get the storage system object associated with the serial number sent in.
    URI foundStorageSystemURI = ConnectivityUtil.findStorageSystemBySerialNumber(serialNumber, _dbClient, StorageSystemType.BLOCK);
    if (foundStorageSystemURI == null) {
        _log.info(String.format("Could not find a registered storage system associated with serial number %s", serialNumber));
        _log.info(String.format("No registered network connectivity found between storage system %s and RP site %s", serialNumber, siteArray.getRpInternalSiteName()));
        return false;
    }
    // Find all of the initiators associated with the RP Cluster in the site array object
    ProtectionSystem rpSystem = _dbClient.queryObject(ProtectionSystem.class, siteArray.getRpProtectionSystem());
    if (rpSystem == null) {
        _log.error(String.format("Could not find a registered protection system associated with URI %s", siteArray.getRpProtectionSystem()));
        _log.info(String.format("No registered network connectivity found between storage system %s and RP site %s", serialNumber, siteArray.getRpInternalSiteName()));
        return false;
    }
    // Make sure initiators are loaded for the entire protection system
    if (rpSystem.getSiteInitiators() == null) {
        _log.error(String.format("Could not find initiators associated with protection system %s", rpSystem.getLabel()));
        _log.info(String.format("No registered network connectivity found between storage system %s and RP site %s", serialNumber, siteArray.getRpInternalSiteName()));
        return false;
    }
    // Make sure initiators are loaded for the RP cluster
    if (rpSystem.getSiteInitiators().get(siteArray.getRpInternalSiteName()) == null) {
        _log.error(String.format("Could not find initiators associated with protection system %s on RP cluster %s", rpSystem.getLabel(), siteArray.getRpInternalSiteName()));
        _log.info(String.format("No registered network connectivity found between storage system %s and RP site %s", serialNumber, siteArray.getRpInternalSiteName()));
        return false;
    }
    // For each initiator associated with the RP cluster in this RPSiteArray, see if we can find a route to the storage system
    for (String portWwn : rpSystem.getSiteInitiators().get(siteArray.getRpInternalSiteName())) {
        Initiator initiator = ExportUtils.getInitiator(portWwn, _dbClient);
        if (initiator == null) {
            // This is a database inconsistency issue. Report an error and continue.
            _log.error(String.format("Could not find initiator %s in the database, even though ProtectionSystem %s references it.", portWwn, rpSystem.getLabel()));
        }
        StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, foundStorageSystemURI);
        if (storageSystem == null) {
            // This is a database inconsistency issue. Report an error and continue.
            _log.error(String.format("Could not find storage system %s in the database, even though ProtectionSystem %s references it.", foundStorageSystemURI, rpSystem.getLabel()));
        }
        // If we can at least find one initiator that is connected to the storage system, we can return true.
        if (ConnectivityUtil.isInitiatorConnectedToStorageSystem(initiator, storageSystem, null, _dbClient)) {
            _log.info(String.format("Found initiator %s can be connected to storage system %s", initiator.getInitiatorPort(), serialNumber));
            return true;
        }
    }
    return false;
}
Also used : Initiator(com.emc.storageos.db.client.model.Initiator) URI(java.net.URI) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 97 with ProtectionSystem

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

the class RPCommunicationInterface method discover.

@Override
public void discover(AccessProfile accessProfile) throws BaseCollectionException {
    URI storageSystemId = null;
    ProtectionSystem protectionSystem = null;
    boolean discoverySuccess = true;
    StringBuffer errMsgBuilder = new StringBuffer();
    String detailedStatusMessage = "Unknown Status";
    boolean isNewlyCreated = false;
    try {
        _log.info("Access Profile Details :  IpAddress : {}, PortNumber : {}", accessProfile.getIpAddress(), accessProfile.getPortNumber());
        storageSystemId = accessProfile.getSystemId();
        protectionSystem = _dbClient.queryObject(ProtectionSystem.class, storageSystemId);
        if (protectionSystem.getDiscoveryStatus().equals(DiscoveredDataObject.DataCollectionJobStatus.CREATED.toString())) {
            isNewlyCreated = true;
        }
        if (StorageSystem.Discovery_Namespaces.UNMANAGED_CGS.toString().equalsIgnoreCase(accessProfile.getnamespace())) {
            try {
                unManagedCGDiscoverer.discoverUnManagedObjects(accessProfile, _dbClient, _partitionManager);
            } catch (RecoverPointException rpe) {
                discoverySuccess = false;
                String msg = "Discover RecoverPoint Unmanaged CGs failed. Protection system: " + storageSystemId;
                buildErrMsg(errMsgBuilder, rpe, msg);
            }
        } else {
            try {
                discoverCluster(protectionSystem);
            } catch (RecoverPointException rpe) {
                discoverySuccess = false;
                String msg = "Discover RecoverPoint cluster failed. Protection system: " + storageSystemId;
                buildErrMsg(errMsgBuilder, rpe, msg);
            }
            // get RP array mappings
            try {
                if (discoverySuccess) {
                    discoverRPSiteArrays(protectionSystem);
                    _dbClient.persistObject(protectionSystem);
                }
            } catch (Exception rpe) {
                discoverySuccess = false;
                String msg = "Discover RecoverPoint site/cluster failed. Protection system: " + storageSystemId;
                buildErrMsg(errMsgBuilder, rpe, msg);
            }
            try {
                if (discoverySuccess) {
                    discoverConnectivity(protectionSystem);
                }
            } catch (Exception rpe) {
                discoverySuccess = false;
                String msg = "Discover RecoverPoint connectivity failed. Protection system: " + storageSystemId;
                buildErrMsg(errMsgBuilder, rpe, msg);
            }
            // Perform maintenance on the RP bookmarks; some may no longer be valid
            try {
                if (discoverySuccess) {
                    RPHelper.cleanupSnapshots(_dbClient, protectionSystem);
                }
            } catch (Exception rpe) {
                discoverySuccess = false;
                String msg = "Snapshot maintenance failed. Protection system: " + storageSystemId;
                buildErrMsg(errMsgBuilder, rpe, msg);
            }
            // Rematch storage pools for RP virtual pools
            try {
                if (discoverySuccess && isNewlyCreated) {
                    matchVPools(protectionSystem.getId());
                }
            } catch (Exception rpe) {
                discoverySuccess = false;
                String msg = "Virtual Pool matching failed. Protection system: " + storageSystemId;
                buildErrMsg(errMsgBuilder, rpe, msg);
            }
            // Discover the Connected-via-RP-itself Storage Systems
            try {
                if (discoverySuccess) {
                    discoverVisibleStorageSystems(protectionSystem);
                }
            } catch (Exception rpe) {
                discoverySuccess = false;
                String msg = "RP-visible storage system discovery failed. Protection system: " + storageSystemId;
                buildErrMsg(errMsgBuilder, rpe, msg);
            }
            // Discover the Connected-via-NetworkStorage Systems
            try {
                if (discoverySuccess) {
                    discoverAssociatedStorageSystems(protectionSystem);
                }
            } catch (Exception rpe) {
                discoverySuccess = false;
                String msg = "Storage system discovery failed. Protection system: " + storageSystemId;
                buildErrMsg(errMsgBuilder, rpe, msg);
            }
            // Discover the protection sets
            try {
                if (discoverySuccess) {
                    discoverProtectionSets(protectionSystem);
                }
            } catch (Exception rpe) {
                discoverySuccess = false;
                String msg = "Discovery of protection sets failed. Protection system: " + storageSystemId;
                buildErrMsg(errMsgBuilder, rpe, msg);
            }
            // Discover the protection system cluster connectivity topology information
            try {
                if (discoverySuccess) {
                    discoverTopology(protectionSystem);
                }
            } catch (Exception rpe) {
                discoverySuccess = false;
                String msg = "Discovery of topology failed. Protection system: " + storageSystemId;
                buildErrMsg(errMsgBuilder, rpe, msg);
            }
        }
        if (!discoverySuccess) {
            throw DeviceControllerExceptions.recoverpoint.discoveryFailure(errMsgBuilder.toString());
        } else {
            detailedStatusMessage = String.format("Discovery completed successfully for Protection System: %s", storageSystemId.toString());
        }
    } catch (Exception e) {
        detailedStatusMessage = String.format("Discovery failed for Protection System %s because %s", storageSystemId.toString(), e.getLocalizedMessage());
        _log.error(detailedStatusMessage, e);
        throw DeviceControllerExceptions.recoverpoint.discoveryFailure(detailedStatusMessage);
    } finally {
        releaseResources();
        if (null != protectionSystem) {
            try {
                // set detailed message
                protectionSystem.setLastDiscoveryStatusMessage(detailedStatusMessage);
                _dbClient.persistObject(protectionSystem);
            } catch (DatabaseException ex) {
                _log.error("Error while persisting object to DB", ex);
            }
        }
    }
}
Also used : RecoverPointException(com.emc.storageos.recoverpoint.exceptions.RecoverPointException) URI(java.net.URI) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) URISyntaxException(java.net.URISyntaxException) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) BaseCollectionException(com.emc.storageos.plugins.BaseCollectionException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) RecoverPointException(com.emc.storageos.recoverpoint.exceptions.RecoverPointException) RecoverPointCollectionException(com.emc.storageos.plugins.metering.recoverpoint.RecoverPointCollectionException)

Example 98 with ProtectionSystem

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

the class BlockRecoverPointIngestOrchestrator method getRPIngestionStatus.

/**
 * This method will assemble a status printout of the ingestion progress for this protection set.
 *
 * @param volumeContext context information
 *
 * @return String status (multi-line, formatted)
 */
private String getRPIngestionStatus(RecoverPointVolumeIngestionContext volumeContext) {
    StringBuffer sb = new StringBuffer();
    UnManagedProtectionSet umpset = volumeContext.getUnManagedProtectionSet();
    sb.append("\nRecoverPoint Ingestion Progress Report\n");
    sb.append("--------------------------------------\n");
    sb.append("RP CG Name:        " + umpset.getCgName() + "\n");
    if (umpset.getProtectionSystemUri() != null) {
        ProtectionSystem ps = _dbClient.queryObject(ProtectionSystem.class, umpset.getProtectionSystemUri());
        sb.append("Protection System: " + ps.getLabel() + " [" + ps.getIpAddress() + "]");
    }
    // Keep track of the column widths
    Map<Integer, Integer> columnWidthMap = new HashMap<Integer, Integer>();
    for (int column = 0; column < ColumnEnum.map.keySet().size(); column++) {
        columnWidthMap.put(column, ColumnEnum.valueOf(column).toString().length());
    }
    if (!umpset.getManagedVolumeIds().isEmpty()) {
        List<Volume> volumes = new ArrayList<Volume>();
        sb.append("\n\nIngested Volumes:\n");
        for (URI volumeId : URIUtil.toURIList(umpset.getManagedVolumeIds())) {
            Volume volume = null;
            BlockObject bo = volumeContext.getRootIngestionRequestContext().findCreatedBlockObject(volumeId);
            if (bo != null && bo instanceof Volume) {
                volume = (Volume) bo;
            }
            if (volume != null) {
                volumes.add(volume);
            } else {
                continue;
            }
            // Name, ID, Personality, copy name, rset name, varray name, vpool name
            if (volume.getLabel() != null && columnWidthMap.get(ColumnEnum.NAME.getColumnNum()) < volume.getLabel().length()) {
                columnWidthMap.put(ColumnEnum.NAME.getColumnNum(), volume.getLabel().length());
            }
            if (volume.getId() != null && columnWidthMap.get(ColumnEnum.ID.getColumnNum()) < volume.getId().toString().length()) {
                columnWidthMap.put(ColumnEnum.ID.getColumnNum(), volume.getId().toString().length());
            }
            if (volume.getPersonality() != null && columnWidthMap.get(ColumnEnum.PERSONALITY.getColumnNum()) < volume.getPersonality().length()) {
                columnWidthMap.put(ColumnEnum.PERSONALITY.getColumnNum(), volume.getPersonality().length());
            }
            if (volume.getRpCopyName() != null && columnWidthMap.get(ColumnEnum.COPY_NAME.getColumnNum()) < volume.getRpCopyName().length()) {
                columnWidthMap.put(ColumnEnum.COPY_NAME.getColumnNum(), volume.getRpCopyName().length());
            }
            if (volume.getRSetName() != null && columnWidthMap.get(ColumnEnum.RSET_NAME.getColumnNum()) < volume.getRSetName().length()) {
                columnWidthMap.put(ColumnEnum.RSET_NAME.getColumnNum(), volume.getRSetName().length());
            }
            if (volume.getVirtualArray() != null) {
                VirtualArray vArray = _dbClient.queryObject(VirtualArray.class, volume.getVirtualArray());
                if (vArray != null && vArray.getLabel() != null && columnWidthMap.get(ColumnEnum.RSET_NAME.getColumnNum()) < vArray.getLabel().length()) {
                    columnWidthMap.put(ColumnEnum.VARRAY.getColumnNum(), vArray.getLabel().length());
                }
            }
            if (volume.getVirtualPool() != null) {
                VirtualPool vPool = _dbClient.queryObject(VirtualPool.class, volume.getVirtualPool());
                if (vPool != null && vPool.getLabel() != null && columnWidthMap.get(ColumnEnum.RSET_NAME.getColumnNum()) < vPool.getLabel().length()) {
                    columnWidthMap.put(ColumnEnum.VPOOL.getColumnNum(), vPool.getLabel().length());
                }
            }
        }
        StringBuffer widthFormat = new StringBuffer();
        for (int column = 0; column < ColumnEnum.map.keySet().size(); column++) {
            StringBuffer formatBuf = new StringBuffer();
            formatBuf.append("%");
            formatBuf.append(String.format("%d", columnWidthMap.get(column)));
            formatBuf.append("s ");
            sb.append(String.format(formatBuf.toString(), ColumnEnum.valueOf(column).name()));
            widthFormat.append(formatBuf.toString());
        }
        sb.append("\n");
        widthFormat.append("\n");
        // Now actually print the values
        for (Volume volume : volumes) {
            String vArrayLabel = LABEL_NA;
            String vPoolLabel = LABEL_NA;
            if (volume.getVirtualArray() != null) {
                VirtualArray vArray = _dbClient.queryObject(VirtualArray.class, volume.getVirtualArray());
                vArrayLabel = vArray.getLabel();
            }
            if (volume.getVirtualPool() != null) {
                VirtualPool vPool = _dbClient.queryObject(VirtualPool.class, volume.getVirtualPool());
                vPoolLabel = vPool.getLabel();
            }
            sb.append(String.format(widthFormat.toString(), volume.getLabel() != null ? volume.getLabel() : LABEL_NA, volume.getId() != null ? volume.getId() : LABEL_NA, volume.getPersonality() != null ? volume.getPersonality() : LABEL_NA, volume.getRpCopyName() != null ? volume.getRpCopyName() : LABEL_NA, volume.getRSetName() != null ? volume.getRSetName() : LABEL_NA, vArrayLabel, vPoolLabel));
        }
    }
    // Keep track of the column widths
    columnWidthMap.clear();
    for (int column = 0; column < ColumnEnum.map.keySet().size(); column++) {
        columnWidthMap.put(column, ColumnEnum.valueOf(column).toString().length());
    }
    if (!umpset.getUnManagedVolumeIds().isEmpty()) {
        sb.append("\nUningested Volumes:\n");
        List<UnManagedVolume> volumes = _dbClient.queryObject(UnManagedVolume.class, URIUtil.toURIList(umpset.getUnManagedVolumeIds()));
        for (UnManagedVolume volume : volumes) {
            // Name, ID, Personality, copy name, rset name, varray name, vpool name
            if (volume.getLabel() != null && columnWidthMap.get(ColumnEnum.NAME.getColumnNum()) < volume.getLabel().length()) {
                columnWidthMap.put(ColumnEnum.NAME.getColumnNum(), volume.getLabel().length());
            }
            if (volume.getId() != null && columnWidthMap.get(ColumnEnum.ID.getColumnNum()) < volume.getId().toString().length()) {
                columnWidthMap.put(ColumnEnum.ID.getColumnNum(), volume.getId().toString().length());
            }
            String personality = PropertySetterUtil.extractValueFromStringSet(SupportedVolumeInformation.RP_PERSONALITY.toString(), volume.getVolumeInformation());
            if (personality != null && columnWidthMap.get(ColumnEnum.PERSONALITY.getColumnNum()) < personality.length()) {
                columnWidthMap.put(ColumnEnum.PERSONALITY.getColumnNum(), personality.length());
            }
            String rpCopyName = PropertySetterUtil.extractValueFromStringSet(SupportedVolumeInformation.RP_COPY_NAME.toString(), volume.getVolumeInformation());
            if (rpCopyName != null && columnWidthMap.get(ColumnEnum.COPY_NAME.getColumnNum()) < rpCopyName.length()) {
                columnWidthMap.put(ColumnEnum.COPY_NAME.getColumnNum(), rpCopyName.length());
            }
            String rsetName = PropertySetterUtil.extractValueFromStringSet(SupportedVolumeInformation.RP_RSET_NAME.toString(), volume.getVolumeInformation());
            if (rsetName != null && columnWidthMap.get(ColumnEnum.RSET_NAME.getColumnNum()) < rsetName.length()) {
                columnWidthMap.put(ColumnEnum.RSET_NAME.getColumnNum(), rsetName.length());
            }
            columnWidthMap.put(ColumnEnum.VARRAY.getColumnNum(), ColumnEnum.VARRAY.name().length());
            columnWidthMap.put(ColumnEnum.VPOOL.getColumnNum(), ColumnEnum.VPOOL.name().length());
        }
        StringBuffer widthFormat = new StringBuffer();
        for (int column = 0; column < ColumnEnum.map.keySet().size(); column++) {
            StringBuffer formatBuf = new StringBuffer();
            formatBuf.append("%");
            formatBuf.append(String.format("%d", columnWidthMap.get(column)));
            formatBuf.append("s ");
            sb.append(String.format(formatBuf.toString(), ColumnEnum.valueOf(column).name()));
            widthFormat.append(formatBuf.toString());
        }
        sb.append("\n");
        widthFormat.append("\n");
        // Now actually print the values
        for (UnManagedVolume volume : volumes) {
            String vArrayLabel = LABEL_NA;
            String vPoolLabel = LABEL_NA;
            String personality = PropertySetterUtil.extractValueFromStringSet(SupportedVolumeInformation.RP_PERSONALITY.toString(), volume.getVolumeInformation());
            String rpCopyName = PropertySetterUtil.extractValueFromStringSet(SupportedVolumeInformation.RP_COPY_NAME.toString(), volume.getVolumeInformation());
            String rsetName = PropertySetterUtil.extractValueFromStringSet(SupportedVolumeInformation.RP_RSET_NAME.toString(), volume.getVolumeInformation());
            sb.append(String.format(widthFormat.toString(), volume.getLabel() != null ? volume.getLabel() : LABEL_NA, volume.getId() != null ? volume.getId() : LABEL_NA, personality != null ? personality : LABEL_NA, rpCopyName != null ? rpCopyName : LABEL_NA, rsetName != null ? rsetName : LABEL_NA, vArrayLabel, vPoolLabel));
        }
    }
    return sb.toString();
}
Also used : VirtualArray(com.emc.storageos.db.client.model.VirtualArray) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) UnManagedProtectionSet(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedProtectionSet) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem) URI(java.net.URI) UnManagedVolume(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume) Volume(com.emc.storageos.db.client.model.Volume) UnManagedVolume(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume) BlockObject(com.emc.storageos.db.client.model.BlockObject)

Example 99 with ProtectionSystem

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

the class RecoverPointScheduler method createRPProtectionRecommendationForMetroPoint.

/**
 * Creates primary (active) and secondary (standby) cluster recommendations for MetroPoint.
 *
 * We first determine the type of MetroPoint request based on the protection virtual array
 * configuration (single remote, local only, or local and remote). Using this information
 * we determine a possible placement recommendation for the primary cluster. Using the
 * primary cluster recommendation we then figure out a secondary cluster recommendation.
 * The secondary cluster recommendation needs protection attributes that give with the
 * primary cluster recommendation to satisfy the type of MetroPoint configuration requested.
 *
 * @param varray the source virtual array.
 * @param protectionVarrays the RecoverPoint protection virtual arrays.
 * @param vpool the source virtual pool.
 * @param haVarray the HA virtual array - secondary cluster.
 * @param haVpool the HA virtual pool - secondary cluster.
 * @param capabilities parameters.
 * @param candidateActiveSourcePools the candidate primary cluster source pools.
 * @param candidateStandbySourcePools the candidate secondary cluster source pools.
 * @param candidateProtectionPoolsMap pre-populated map for tgt varray to storage pools, use null if not needed
 * @return list of Recommendation objects to satisfy the request
 */
private RPProtectionRecommendation createRPProtectionRecommendationForMetroPoint(VirtualArray varray, List<VirtualArray> protectionVarrays, VirtualPool vpool, VirtualArray haVarray, VirtualPool haVpool, VirtualPoolCapabilityValuesWrapper capabilities, List<StoragePool> candidateActiveSourcePools, List<StoragePool> candidateStandbySourcePools, Map<VirtualArray, List<StoragePool>> candidateProtectionPools, Volume vpoolChangeVolume, Project project) {
    // Initialize a list of recommendations to be returned.
    Set<ProtectionSystem> secondaryProtectionSystems = null;
    placementStatus = new PlacementStatus();
    secondaryPlacementStatus = new PlacementStatus();
    int requestedResourceCount = capabilities.getResourceCount();
    int totalSatisfiedCount = 0;
    List<URI> protectionVarrayURIs = new ArrayList<URI>();
    for (VirtualArray vArray : protectionVarrays) {
        protectionVarrayURIs.add(vArray.getId());
        placementStatus.getProcessedProtectionVArrays().put(vArray.getId(), false);
    }
    // Active journal varray - Either explicitly set by the user or use the default varray.
    VirtualArray activeJournalVarray = (NullColumnValueGetter.isNotNullValue(vpool.getJournalVarray()) ? dbClient.queryObject(VirtualArray.class, URI.create(vpool.getJournalVarray())) : varray);
    // Active journal vpool - Either explicitly set by the user or use the default vpool.
    VirtualPool activeJournalVpool = (NullColumnValueGetter.isNotNullValue(vpool.getJournalVpool()) ? dbClient.queryObject(VirtualPool.class, URI.create(vpool.getJournalVpool())) : vpool);
    // Standby journal varray - Either explicitly set by the user or use the default haVarray.
    VirtualArray standbyJournalVarray = (NullColumnValueGetter.isNotNullValue(vpool.getStandbyJournalVarray()) ? dbClient.queryObject(VirtualArray.class, URI.create(vpool.getStandbyJournalVarray())) : haVarray);
    // Standby journal vpool - Either explicitly set by the user or use the default haVpool.
    VirtualPool standbyJournalVpool = (NullColumnValueGetter.isNotNullValue(vpool.getStandbyJournalVpool()) ? dbClient.queryObject(VirtualPool.class, URI.create(vpool.getStandbyJournalVpool())) : haVpool);
    // Build the list of protection virtual arrays to consider for determining a
    // primary placement solution. Add all virtual arrays from the source virtual
    // pool list of protection virtual arrays, except for the HA/standby virtual array.
    // In the case of local and/or remote protection, the HA virtual array should
    // never be considered as a valid protection target for primary placement.
    List<VirtualArray> activeProtectionVarrays = new ArrayList<VirtualArray>();
    for (VirtualArray protectionVarray : protectionVarrays) {
        if (!protectionVarray.getId().equals(haVarray.getId())) {
            activeProtectionVarrays.add(protectionVarray);
        }
    }
    // Build the list of protection virtual arrays to consider for determining a
    // standby placement solution. Add all virtual arrays from the source virtual
    // pool list of protection virtual arrays, except for the source virtual array.
    // In the case of local and/or remote protection, the source virtual array should
    // never be considered as a valid protection target for standby placement.
    List<VirtualArray> standbyProtectionVarrays = new ArrayList<VirtualArray>();
    for (VirtualArray protectionVarray : protectionVarrays) {
        if (!protectionVarray.getId().equals(varray.getId())) {
            standbyProtectionVarrays.add(protectionVarray);
        }
    }
    // The attributes below will not change throughout the placement process
    placementStatus.setSrcVArray(varray.getLabel());
    placementStatus.setSrcVPool(vpool.getLabel());
    boolean secondaryRecommendationSolution = false;
    int satisfiedSourceVolCount = 0;
    int totalRequestedResourceCount = capabilities.getResourceCount();
    boolean isChangeVpool = (vpoolChangeVolume != null);
    // Top level recommendation object
    RPProtectionRecommendation rpProtectionRecommendation = new RPProtectionRecommendation();
    // Source pool recommendations
    List<Recommendation> sourcePoolRecommendations = new ArrayList<Recommendation>();
    // Map to hold standby storage pools to protection systems
    Map<URI, Set<ProtectionSystem>> standbyStoragePoolsToProtectionSystems = new HashMap<URI, Set<ProtectionSystem>>();
    // Change vpool only: Set values for change vpool. If not a change vpool these values will be null.
    rpProtectionRecommendation.setVpoolChangeVolume(vpoolChangeVolume != null ? vpoolChangeVolume.getId() : null);
    rpProtectionRecommendation.setVpoolChangeNewVpool(vpoolChangeVolume != null ? vpool.getId() : null);
    rpProtectionRecommendation.setVpoolChangeProtectionAlreadyExists(vpoolChangeVolume != null ? vpoolChangeVolume.checkForRp() : false);
    // Change vpool only: Recommendation objects specifically used for change vpool. These will not be populated otherwise.
    Recommendation changeVpoolSourceRecommendation = new Recommendation();
    Recommendation changeVpoolStandbyRecommendation = new Recommendation();
    if (isChangeVpool) {
        // valid pool, the existing ones for active and standby. This is just to used to pass through the placement code.
        if (null == vpoolChangeVolume.getAssociatedVolumes() || vpoolChangeVolume.getAssociatedVolumes().isEmpty()) {
            _log.error("VPLEX volume {} has no backend volumes.", vpoolChangeVolume.forDisplay());
            throw InternalServerErrorException.internalServerErrors.noAssociatedVolumesForVPLEXVolume(vpoolChangeVolume.forDisplay());
        }
        for (String associatedVolume : vpoolChangeVolume.getAssociatedVolumes()) {
            Volume assocVol = dbClient.queryObject(Volume.class, URI.create(associatedVolume));
            if (assocVol.getVirtualArray().equals(varray.getId())) {
                // This is the existing active source backing volume
                changeVpoolSourceRecommendation.setSourceStoragePool(assocVol.getPool());
                StoragePool pool = dbClient.queryObject(StoragePool.class, assocVol.getPool());
                changeVpoolSourceRecommendation.setSourceStorageSystem(pool.getStorageDevice());
                changeVpoolSourceRecommendation.setResourceCount(1);
                sourcePoolRecommendations.add(changeVpoolSourceRecommendation);
                _log.info(String.format("RP Placement : Change Virtual Pool - Active source pool already exists, reuse pool: [%s] [%s].", pool.getLabel().toString(), pool.getId().toString()));
            } else if (assocVol.getVirtualArray().equals(haVarray.getId())) {
                // This is the existing standby source backing volume
                changeVpoolStandbyRecommendation.setSourceStoragePool(assocVol.getPool());
                StoragePool pool = dbClient.queryObject(StoragePool.class, assocVol.getPool());
                changeVpoolStandbyRecommendation.setSourceStorageSystem(pool.getStorageDevice());
                changeVpoolStandbyRecommendation.setResourceCount(1);
                _log.info(String.format("RP Placement : Change Virtual Pool - Standby source pool already exists, reuse pool: [%s] [%s].", pool.getLabel().toString(), pool.getId().toString()));
            }
        }
        satisfiedSourceVolCount = 1;
    } else {
        // If this is not a change vpool, then gather the recommended pools for the source.
        sourcePoolRecommendations = getRecommendedPools(rpProtectionRecommendation, varray, vpool, null, null, capabilities, RPHelper.SOURCE, null);
    }
    // If we have no source pools at this point, throw an exception.
    if (sourcePoolRecommendations == null || sourcePoolRecommendations.isEmpty()) {
        _log.error(String.format("RP Placement : No matching storage pools found for the source varray: [%s. " + "There are no storage pools that match the passed vpool parameters and protocols and/or there are " + "no pools that have enough capacity to hold at least one resource of the requested size.", varray.getLabel()));
        throw APIException.badRequests.noMatchingStoragePoolsForVpoolAndVarray(vpool.getLabel(), varray.getLabel());
    }
    _log.info(String.format("RP Placement : Determining RP placement for the primary (active) MetroPoint cluster for %s resources.", totalRequestedResourceCount));
    // Keep track of the possible pools to use for the source. This will help us determine if we have
    // exhausted all our options.
    int remainingPossiblePrimarySrcPoolSolutions = sourcePoolRecommendations.size();
    // Iterate over the source pools found to find a solution...
    for (Recommendation recommendedPool : sourcePoolRecommendations) {
        StoragePool sourcePool = dbClient.queryObject(StoragePool.class, recommendedPool.getSourceStoragePool());
        --remainingPossiblePrimarySrcPoolSolutions;
        satisfiedSourceVolCount = (recommendedPool.getResourceCount() >= requestedResourceCount) ? requestedResourceCount : recommendedPool.getResourceCount();
        Set<ProtectionSystem> primaryProtectionSystems = new HashSet<ProtectionSystem>();
        ProtectionSystem cgProtectionSystem = getCgProtectionSystem(capabilities.getBlockConsistencyGroup());
        // used by other volumes in it.
        if (cgProtectionSystem != null) {
            BlockConsistencyGroup cg = dbClient.queryObject(BlockConsistencyGroup.class, capabilities.getBlockConsistencyGroup());
            _log.info(String.format("RP Placement : Narrowing down placement to use protection system %s, which is currently used " + "by RecoverPoint consistency group %s.", cgProtectionSystem.getLabel(), cg));
            primaryProtectionSystems.add(cgProtectionSystem);
        } else {
            primaryProtectionSystems = getProtectionSystemsForStoragePool(sourcePool, varray, true);
            if (primaryProtectionSystems.isEmpty()) {
                continue;
            }
        }
        // Sort the ProtectionSystems based on the last time a CG was created. Always use the
        // ProtectionSystem with the oldest cgLastCreated timestamp to support a round-robin
        // style of load balancing.
        List<ProtectionSystem> primaryProtectionSystemsList = sortProtectionSystems(primaryProtectionSystems);
        for (ProtectionSystem primaryProtectionSystem : primaryProtectionSystemsList) {
            Calendar cgLastCreated = primaryProtectionSystem.getCgLastCreatedTime();
            _log.info(String.format("RP Placement : Attempting to use protection system [%s], which was last used to create a CG on [%s].", primaryProtectionSystem.getLabel(), cgLastCreated != null ? cgLastCreated.getTime().toString() : "N/A"));
            // Get a list of associated storage systems for the pool, varray, and the protection system.
            // This will return a list of strings that are in the format of:
            // <storage system serial number>:<rp site name>
            List<String> primaryAssociatedStorageSystems = getCandidateVisibleStorageSystems(sourcePool, primaryProtectionSystem, varray, activeProtectionVarrays, true);
            if (primaryAssociatedStorageSystems.isEmpty()) {
                // In this case no rp sites were connected to this storage system, we should not hit this,
                // but just to be safe we'll catch it.
                _log.info(String.format("RP Placement: Protection System %s does not have an rp site cluster connected to Storage pool %s ", primaryProtectionSystem.getLabel(), sourcePool.getLabel()));
                continue;
            }
            // Iterate over the associated storage systems
            for (String primaryAssociatedStorageSystem : primaryAssociatedStorageSystems) {
                rpProtectionRecommendation.setProtectionDevice(primaryProtectionSystem.getId());
                _log.info(String.format("RP Placement : Build MetroPoint Active Recommendation..."));
                RPRecommendation sourceRec = buildSourceRecommendation(primaryAssociatedStorageSystem, varray, vpool, primaryProtectionSystem, sourcePool, capabilities, satisfiedSourceVolCount, placementStatus, vpoolChangeVolume, false);
                if (sourceRec == null) {
                    // No source placement found for the primaryAssociatedStorageSystem, so continue.
                    _log.warn(String.format("RP Placement : Could not create MetroPoint Active Recommendation using [%s], continuing...", primaryAssociatedStorageSystem));
                    continue;
                }
                URI primarySourceStorageSystemURI = sourceRec.getVirtualVolumeRecommendation().getVPlexStorageSystem();
                if (rpProtectionRecommendation.getSourceJournalRecommendation() == null) {
                    _log.info(String.format("RP Placement : Build MetroPoint Active Journal Recommendation..."));
                    RPRecommendation activeJournalRecommendation = buildJournalRecommendation(rpProtectionRecommendation, sourceRec.getInternalSiteName(), vpool.getJournalSize(), activeJournalVarray, activeJournalVpool, primaryProtectionSystem, capabilities, totalRequestedResourceCount, vpoolChangeVolume, false);
                    if (activeJournalRecommendation == null) {
                        // No source journal placement found, so continue.
                        _log.warn(String.format("RP Placement : Could not create MetroPoint Active Journal Recommendation, continuing..."));
                        continue;
                    }
                    rpProtectionRecommendation.setSourceJournalRecommendation(activeJournalRecommendation);
                }
                rpProtectionRecommendation.getSourceRecommendations().add(sourceRec);
                _log.info("RP Placement : An RP source placement solution has been identified for the MetroPoint primary (active) cluster.");
                // Find a solution, given this vpool, and the target varrays
                if (findSolution(rpProtectionRecommendation, sourceRec, varray, vpool, activeProtectionVarrays, capabilities, satisfiedSourceVolCount, true, null, project)) {
                    _log.info("RP Placement : An RP target placement solution has been identified for the MetroPoint primary (active) cluster.");
                    // We have a primary cluster protection recommendation for the specified metroPointType. We need to now determine if
                    // we can protect the secondary cluster for the given metroPointType.
                    _log.info("RP Placement : Determining RP placement for the secondary (standby) MetroPoint cluster.");
                    secondaryRecommendationSolution = false;
                    // Get the candidate secondary cluster source pools - sets secondarySourcePoolURIs.
                    List<Recommendation> secondaryPoolsRecommendation = new ArrayList<Recommendation>();
                    if (isChangeVpool) {
                        secondaryPoolsRecommendation.add(changeVpoolStandbyRecommendation);
                    } else {
                        secondaryPoolsRecommendation = getRecommendedPools(rpProtectionRecommendation, haVarray, haVpool, null, null, capabilities, RPHelper.TARGET, null);
                    }
                    secondaryPlacementStatus.setSrcVArray(haVarray.getLabel());
                    secondaryPlacementStatus.setSrcVPool(haVpool.getLabel());
                    for (Recommendation secondaryPoolRecommendation : secondaryPoolsRecommendation) {
                        // Start with the top of the list of source pools, find a solution based on that.
                        StoragePool standbySourcePool = dbClient.queryObject(StoragePool.class, secondaryPoolRecommendation.getSourceStoragePool());
                        // Lookup source pool protection systems in the cache first.
                        if (standbyStoragePoolsToProtectionSystems.containsKey(standbySourcePool.getId())) {
                            secondaryProtectionSystems = standbyStoragePoolsToProtectionSystems.get(standbySourcePool.getId());
                        } else {
                            secondaryProtectionSystems = getProtectionSystemsForStoragePool(standbySourcePool, haVarray, true);
                            if (secondaryProtectionSystems.isEmpty()) {
                                continue;
                            }
                            // Cache the result for this pool
                            standbyStoragePoolsToProtectionSystems.put(standbySourcePool.getId(), secondaryProtectionSystems);
                        }
                        ProtectionSystem selectedSecondaryProtectionSystem = null;
                        // Ensure the we have a secondary protection system that matches the primary protection system
                        for (ProtectionSystem secondaryProtectionSystem : secondaryProtectionSystems) {
                            if (secondaryProtectionSystem.getId().equals(rpProtectionRecommendation.getProtectionDevice())) {
                                // We have a protection system match for this pool, continue.
                                selectedSecondaryProtectionSystem = secondaryProtectionSystem;
                                break;
                            }
                        }
                        if (selectedSecondaryProtectionSystem == null) {
                            // There is no protection system for this pool that matches the selected primary
                            // protection system. So lets try another pool.
                            _log.info(String.format("RP Placement: Secondary source storage pool %s " + " does not have connectivity to the selected primary protection system.", standbySourcePool.getLabel()));
                            continue;
                        } else {
                            // List of concatenated strings that contain the RP site + associated storage system.
                            List<String> secondaryAssociatedStorageSystems = getCandidateVisibleStorageSystems(standbySourcePool, selectedSecondaryProtectionSystem, haVarray, activeProtectionVarrays, true);
                            // make sure you check RP topology to see if the sites can protect that many targets
                            if (secondaryAssociatedStorageSystems.isEmpty()) {
                                // no rp site clusters connected to this storage system, should not hit this,
                                // but just to be safe we'll catch it
                                _log.info("RP Placement: Protection System " + selectedSecondaryProtectionSystem.getLabel() + " does not have an rp site cluster connected to Storage pool " + standbySourcePool.getLabel());
                                continue;
                            }
                            Set<String> validSecondaryAssociatedStorageSystems = new LinkedHashSet<String>();
                            // that reference the same storage system as the primary recommendation and has a different RP site.
                            for (String secondaryAssociatedStorageSystem : secondaryAssociatedStorageSystems) {
                                String secondarySourceInternalSiteName = ProtectionSystem.getAssociatedStorageSystemSiteName(secondaryAssociatedStorageSystem);
                                URI secondarySourceStorageSystemURI = ConnectivityUtil.findStorageSystemBySerialNumber(ProtectionSystem.getAssociatedStorageSystemSerialNumber(secondaryAssociatedStorageSystem), dbClient, StorageSystemType.BLOCK);
                                boolean validForStandbyPlacement = false;
                                if (secondarySourceStorageSystemURI.equals(primarySourceStorageSystemURI) && !secondarySourceInternalSiteName.equals(sourceRec.getInternalSiteName())) {
                                    validForStandbyPlacement = true;
                                    validSecondaryAssociatedStorageSystems.add(secondaryAssociatedStorageSystem);
                                }
                                _log.info(String.format("RP Placement: associated storage system entry [%s] " + "%s valid for standby placement.", secondaryAssociatedStorageSystem, (validForStandbyPlacement ? "" : "NOT")));
                            }
                            for (String secondaryAssociatedStorageSystem : validSecondaryAssociatedStorageSystems) {
                                _log.info(String.format("RP Placement : Build MetroPoint Standby Recommendation..."));
                                RPRecommendation secondaryRpRecommendation = buildSourceRecommendation(secondaryAssociatedStorageSystem, haVarray, haVpool, selectedSecondaryProtectionSystem, standbySourcePool, capabilities, satisfiedSourceVolCount, secondaryPlacementStatus, null, true);
                                if (secondaryRpRecommendation == null) {
                                    // No standby placement found for the secondaryAssociatedStorageSystem, so continue.
                                    _log.warn(String.format("RP Placement : Could not create MetroPoint Standby Recommendation using [%s], continuing...", secondaryAssociatedStorageSystem));
                                    continue;
                                }
                                if (rpProtectionRecommendation.getStandbyJournalRecommendation() == null) {
                                    _log.info(String.format("RP Placement : Build MetroPoint Standby Journal Recommendation..."));
                                    RPRecommendation standbyJournalRecommendation = buildJournalRecommendation(rpProtectionRecommendation, secondaryRpRecommendation.getInternalSiteName(), vpool.getJournalSize(), standbyJournalVarray, standbyJournalVpool, primaryProtectionSystem, capabilities, totalRequestedResourceCount, vpoolChangeVolume, true);
                                    if (standbyJournalRecommendation == null) {
                                        // No standby journal placement found, so continue.
                                        _log.warn(String.format("RP Placement : Could not create MetroPoint Standby Journal Recommendation, continuing..."));
                                        continue;
                                    }
                                    rpProtectionRecommendation.setStandbyJournalRecommendation(standbyJournalRecommendation);
                                }
                                sourceRec.setHaRecommendation(secondaryRpRecommendation);
                                // Find a solution, given this vpool, and the target varrays
                                if (findSolution(rpProtectionRecommendation, secondaryRpRecommendation, haVarray, vpool, standbyProtectionVarrays, capabilities, satisfiedSourceVolCount, true, sourceRec, project)) {
                                    _log.info("RP Placement : An RP target placement solution has been identified for the " + "MetroPoint secondary (standby) cluster.");
                                    secondaryRecommendationSolution = true;
                                    break;
                                } else {
                                    _log.info("RP Placement : Unable to find a suitable solution, continuining to find other solutions.");
                                    continue;
                                }
                            }
                            if (secondaryRecommendationSolution) {
                                break;
                            } else {
                                continue;
                            }
                        }
                    }
                    if (!secondaryRecommendationSolution) {
                        _log.info("RP Placement : Unable to find MetroPoint secondary cluster placement recommendation that " + "jives with primary cluster recommendation.  Need to find a new primary recommendation.");
                        // Exhausted all the secondary pool URIs. Need to find another primary solution.
                        break;
                    }
                    // We are done - secondary recommendation found
                    requestedResourceCount = requestedResourceCount - satisfiedSourceVolCount;
                    totalSatisfiedCount += satisfiedSourceVolCount;
                    if (totalSatisfiedCount >= totalRequestedResourceCount) {
                        rpProtectionRecommendation.setResourceCount(totalSatisfiedCount);
                        // Check to ensure the protection system can handle the new resources about to come down
                        if (!verifyPlacement(primaryProtectionSystem, rpProtectionRecommendation, rpProtectionRecommendation.getResourceCount())) {
                            continue;
                        }
                        return rpProtectionRecommendation;
                    } else {
                        // loop back to the next pool
                        break;
                    }
                } else {
                    // Not sure there's anything to do here. Just go to the next candidate protection system or Protection System
                    _log.info(String.format("RP Placement : Could not find a solution against protection system %s and internal " + "cluster name %s", primaryProtectionSystem.getLabel(), sourceRec.getInternalSiteName()));
                    rpProtectionRecommendation = getNewProtectionRecommendation(vpoolChangeVolume, vpool);
                }
            }
            // end of for loop trying to find solution using possible rp cluster sites
            rpProtectionRecommendation = getNewProtectionRecommendation(vpoolChangeVolume, vpool);
        }
    // end of protection systems for loop
    }
    // a solution
    if ((remainingPossiblePrimarySrcPoolSolutions == 0) && totalSatisfiedCount < capabilities.getResourceCount()) {
        _log.error("Could not find a MetroPoint placement solution.  In a MetroPoint consistency group, there can " + "exist at most one remote copy and from zero to two local copies.  If there is no remote copy, " + "there must be two local copies, one at each side of the VPLEX Metro.");
        throw APIException.badRequests.cannotFindSolutionForRP(buildMetroProintPlacementStatusString());
    }
    _log.error("ViPR could not find matching target storage pools that could be protected via RecoverPoint");
    _log.error("Could not find a MetroPoint placement solution.  In a MetroPoint consistency group, there can " + "exist at most one remote copy and from zero to two local copies.  If there is no remote copy, " + "there must be two local copies, one at each side of the VPLEX Metro.");
    throw APIException.badRequests.cannotFindSolutionForRP(buildMetroProintPlacementStatusString());
}
Also used : LinkedHashSet(java.util.LinkedHashSet) VirtualArray(com.emc.storageos.db.client.model.VirtualArray) Set(java.util.Set) HashSet(java.util.HashSet) AbstractChangeTrackingSet(com.emc.storageos.db.client.model.AbstractChangeTrackingSet) LinkedHashSet(java.util.LinkedHashSet) StringSet(com.emc.storageos.db.client.model.StringSet) StoragePool(com.emc.storageos.db.client.model.StoragePool) RPProtectionRecommendation(com.emc.storageos.volumecontroller.RPProtectionRecommendation) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem) URI(java.net.URI) RPRecommendation(com.emc.storageos.volumecontroller.RPRecommendation) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) Calendar(java.util.Calendar) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) Recommendation(com.emc.storageos.volumecontroller.Recommendation) RPRecommendation(com.emc.storageos.volumecontroller.RPRecommendation) RPProtectionRecommendation(com.emc.storageos.volumecontroller.RPProtectionRecommendation) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) Volume(com.emc.storageos.db.client.model.Volume)

Example 100 with ProtectionSystem

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

the class RecoverPointScheduler method buildCgRecommendations.

/**
 * Builds a recommendation from existing CG.
 *
 * This method is called when adding more volumes into an existing CG or change vpool scenario.
 *
 * When adding to an existing CG we can accommodate the request with the recommendations from
 * resources that have already been placed in the existing CG.
 *
 * @param capabilities - Virtual Pool capabilities
 * @param vpool - Virtual Pool
 * @param protectionVarrays - List of target copy virtual arrays
 * @param vpoolChangeVolume - change virtual pool volume
 * @return - List of recommendations
 */
protected List<Recommendation> buildCgRecommendations(VirtualPoolCapabilityValuesWrapper capabilities, VirtualPool vpool, List<VirtualArray> protectionVarrays, Volume vpoolChangeVolume) {
    BlockConsistencyGroup cg = dbClient.queryObject(BlockConsistencyGroup.class, capabilities.getBlockConsistencyGroup());
    _log.info(String.format("Attempting to align placement (protection system, storage pools, internal site names) with " + "existing volumes in RecoverPoint consistency group %s.", cg.getLabel()));
    List<Recommendation> recommendations = new ArrayList<Recommendation>();
    // Find the first existing source volume
    List<Volume> sourceVolumes = RPHelper.getCgSourceVolumes(cg.getId(), dbClient);
    if (sourceVolumes.isEmpty()) {
        _log.info(String.format("Unable to fully align placement with existing volumes in RecoverPoint consistency group %s.  " + "The consistency group currently contains no volumes.", cg.getLabel()));
        return recommendations;
    }
    // Verify that all the underlying protection storage pools used by the existing source volume are available to this request
    if (!verifyExistingSourceProtectionPools(sourceVolumes.get(0), vpool, cg.getLabel())) {
        return recommendations;
    }
    Volume sourceVolume = null;
    boolean createRecommendations = false;
    for (Volume currentSourceVolume : sourceVolumes) {
        // enough capacity, use it to produce the recommendation.
        if (cgPoolsHaveAvailableCapacity(currentSourceVolume, capabilities, vpool, protectionVarrays)) {
            createRecommendations = true;
            sourceVolume = currentSourceVolume;
            break;
        }
    }
    if (!createRecommendations) {
        return recommendations;
    }
    RPProtectionRecommendation recommendation = new RPProtectionRecommendation();
    if (sourceVolume.getProtectionController() != null) {
        ProtectionSystem ps = dbClient.queryObject(ProtectionSystem.class, sourceVolume.getProtectionController());
        if (ps.getInactive()) {
            // be protected so we must fail.
            throw APIException.badRequests.cgReferencesInvalidProtectionSystem(cg.getId(), sourceVolume.getProtectionController());
        }
    } else {
        // be protected so we must fail.
        throw APIException.badRequests.cgReferencesInvalidProtectionSystem(cg.getId(), sourceVolume.getProtectionController());
    }
    recommendation.setProtectionDevice(sourceVolume.getProtectionController());
    recommendation.setVpoolChangeVolume(vpoolChangeVolume != null ? vpoolChangeVolume.getId() : null);
    recommendation.setVpoolChangeNewVpool(vpoolChangeVolume != null ? vpool.getId() : null);
    recommendation.setVpoolChangeProtectionAlreadyExists(vpoolChangeVolume != null ? vpoolChangeVolume.checkForRp() : false);
    recommendation.setResourceCount(capabilities.getResourceCount());
    // Check to see if we need an additional journal for Source
    Map<Integer, Long> additionalJournalForSource = RPHelper.additionalJournalRequiredForRPCopy(vpool.getJournalSize(), cg.getId(), capabilities.getSize(), capabilities.getResourceCount(), sourceVolume.getRpCopyName(), dbClient);
    if (!CollectionUtils.isEmpty(additionalJournalForSource)) {
        // ACTIVE SOURCE JOURNAL Recommendation
        List<Volume> sourceJournals = RPHelper.findExistingJournalsForCopy(dbClient, sourceVolume.getConsistencyGroup(), sourceVolume.getRpCopyName());
        Volume sourceJournal = sourceJournals.get(0);
        if (sourceJournal == null) {
            _log.error(String.format("No existing source journal found in CG [%s] for copy [%s], returning false", sourceVolume.getConsistencyGroup(), sourceVolume.getRpCopyName()));
            throw APIException.badRequests.unableToFindSuitableJournalRecommendation();
        }
        VirtualPool sourceJournalVpool = NullColumnValueGetter.isNotNullValue(vpool.getJournalVpool()) ? dbClient.queryObject(VirtualPool.class, URI.create(vpool.getJournalVpool())) : vpool;
        Long sourceJournalSize = getJournalCapabilities(vpool.getJournalSize(), capabilities, 1).getSize();
        RPRecommendation sourceJournalRecommendation = buildRpRecommendationFromExistingVolume(sourceJournal, sourceJournalVpool, capabilities, sourceJournalSize);
        // Parse out the calculated values
        Map.Entry<Integer, Long> entry = additionalJournalForSource.entrySet().iterator().next();
        Integer journalCount = entry.getKey();
        Long journalSize = entry.getValue();
        // Override values in recommendation with calculated journal count and size
        sourceJournalRecommendation.setResourceCount(journalCount);
        sourceJournalRecommendation.setSize(journalSize);
        recommendation.setSourceJournalRecommendation(sourceJournalRecommendation);
        // STANDBY SOURCE JOURNAL Recommendation
        String standbyCopyName = RPHelper.getStandbyProductionCopyName(dbClient, sourceVolume);
        if (standbyCopyName != null) {
            List<Volume> existingStandbyJournals = RPHelper.findExistingJournalsForCopy(dbClient, sourceVolume.getConsistencyGroup(), standbyCopyName);
            Volume standbyJournal = existingStandbyJournals.get(0);
            if (standbyJournal == null) {
                _log.error(String.format("No existing standby journal found in CG [%s] for copy [%s], returning false", sourceVolume.getConsistencyGroup(), standbyCopyName));
                throw APIException.badRequests.unableToFindSuitableJournalRecommendation();
            }
            VirtualPool haVpool = (null != VirtualPool.getHAVPool(vpool, dbClient)) ? VirtualPool.getHAVPool(vpool, dbClient) : vpool;
            VirtualPool standbyJournalVpool = NullColumnValueGetter.isNotNullValue(vpool.getStandbyJournalVpool()) ? dbClient.queryObject(VirtualPool.class, URI.create(vpool.getStandbyJournalVpool())) : haVpool;
            RPRecommendation standbyJournalRecommendation = buildRpRecommendationFromExistingVolume(standbyJournal, standbyJournalVpool, capabilities, sourceJournalSize);
            // Override values in recommendation with calculated journal count and size
            standbyJournalRecommendation.setResourceCount(journalCount);
            standbyJournalRecommendation.setSize(journalSize);
            recommendation.setStandbyJournalRecommendation(standbyJournalRecommendation);
        }
    }
    // SOURCE Recommendation
    RPRecommendation sourceRecommendation = buildRpRecommendationFromExistingVolume(sourceVolume, vpool, capabilities, null);
    recommendation.getSourceRecommendations().add(sourceRecommendation);
    // TARGET Recommendation(s)
    Map<URI, VpoolProtectionVarraySettings> protectionSettings = VirtualPool.getProtectionSettings(vpool, dbClient);
    for (VirtualArray protectionVarray : protectionVarrays) {
        Volume targetVolume = getTargetVolumeForProtectionVirtualArray(sourceVolume, protectionVarray);
        // if the target vpool is not set, it defaults to the source vpool
        VirtualPool targetVpool = vpool;
        if (protectionSettings.get(protectionVarray.getId()) != null && protectionSettings.get(protectionVarray.getId()).getVirtualPool() != null) {
            targetVpool = dbClient.queryObject(VirtualPool.class, protectionSettings.get(protectionVarray.getId()).getVirtualPool());
        }
        RPRecommendation targetRecommendation = buildRpRecommendationFromExistingVolume(targetVolume, targetVpool, capabilities, null);
        if (sourceRecommendation.getTargetRecommendations() == null) {
            sourceRecommendation.setTargetRecommendations(new ArrayList<RPRecommendation>());
        }
        sourceRecommendation.getTargetRecommendations().add(targetRecommendation);
        // Check to see if we need an additional journal for Target
        Map<Integer, Long> additionalJournalForTarget = RPHelper.additionalJournalRequiredForRPCopy(vpool.getJournalSize(), cg.getId(), capabilities.getSize(), capabilities.getResourceCount(), targetVolume.getRpCopyName(), dbClient);
        if (!CollectionUtils.isEmpty(additionalJournalForTarget)) {
            // TARGET JOURNAL Recommendation
            List<Volume> targetJournals = RPHelper.findExistingJournalsForCopy(dbClient, targetVolume.getConsistencyGroup(), targetVolume.getRpCopyName());
            Volume targetJournal = targetJournals.get(0);
            if (targetJournal == null) {
                _log.error(String.format("No existing target journal found in CG [%s] for copy [%s], returning false", targetVolume.getConsistencyGroup(), targetVolume.getRpCopyName()));
                throw APIException.badRequests.unableToFindSuitableJournalRecommendation();
            }
            VirtualPool targetJournalVpool = protectionSettings.get(protectionVarray.getId()).getJournalVpool() != null ? dbClient.queryObject(VirtualPool.class, protectionSettings.get(protectionVarray.getId()).getJournalVpool()) : targetVpool;
            Long targetJournalSize = getJournalCapabilities(protectionSettings.get(protectionVarray.getId()).getJournalSize(), capabilities, 1).getSize();
            RPRecommendation targetJournalRecommendation = buildRpRecommendationFromExistingVolume(targetJournal, targetJournalVpool, capabilities, targetJournalSize);
            // Parse out the calculated values
            Map.Entry<Integer, Long> entry = additionalJournalForSource.entrySet().iterator().next();
            Integer journalCount = entry.getKey();
            Long journalSize = entry.getValue();
            // Override values in recommendation with calculated journal count and size
            targetJournalRecommendation.setResourceCount(journalCount);
            targetJournalRecommendation.setSize(journalSize);
            if (recommendation.getTargetJournalRecommendations() == null) {
                recommendation.setTargetJournalRecommendations(new ArrayList<RPRecommendation>());
            }
            recommendation.getTargetJournalRecommendations().add(targetJournalRecommendation);
        }
    }
    _log.info(String.format("Produced recommendations based on existing source volume [%s](%s) from " + "RecoverPoint consistency group [%s].", sourceVolume.getLabel(), sourceVolume.getId(), cg.getLabel()));
    recommendations.add(recommendation);
    return recommendations;
}
Also used : VirtualArray(com.emc.storageos.db.client.model.VirtualArray) RPProtectionRecommendation(com.emc.storageos.volumecontroller.RPProtectionRecommendation) ArrayList(java.util.ArrayList) VpoolProtectionVarraySettings(com.emc.storageos.db.client.model.VpoolProtectionVarraySettings) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem) URI(java.net.URI) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) Recommendation(com.emc.storageos.volumecontroller.Recommendation) RPRecommendation(com.emc.storageos.volumecontroller.RPRecommendation) RPProtectionRecommendation(com.emc.storageos.volumecontroller.RPProtectionRecommendation) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) Volume(com.emc.storageos.db.client.model.Volume) RPRecommendation(com.emc.storageos.volumecontroller.RPRecommendation) Map(java.util.Map) HashMap(java.util.HashMap) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) StringMap(com.emc.storageos.db.client.model.StringMap)

Aggregations

ProtectionSystem (com.emc.storageos.db.client.model.ProtectionSystem)120 URI (java.net.URI)57 ArrayList (java.util.ArrayList)52 NamedURI (com.emc.storageos.db.client.model.NamedURI)44 Volume (com.emc.storageos.db.client.model.Volume)44 HashMap (java.util.HashMap)32 StringSet (com.emc.storageos.db.client.model.StringSet)30 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)28 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)25 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)25 ControllerException (com.emc.storageos.volumecontroller.ControllerException)25 RPProtectionRecommendation (com.emc.storageos.volumecontroller.RPProtectionRecommendation)25 URISyntaxException (java.net.URISyntaxException)25 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)24 RecoverPointException (com.emc.storageos.recoverpoint.exceptions.RecoverPointException)24 InternalServerErrorException (com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException)24 WorkflowException (com.emc.storageos.workflow.WorkflowException)24 Test (org.junit.Test)24 FunctionalAPIActionFailedException_Exception (com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception)23 FunctionalAPIInternalError_Exception (com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception)23