Search in sources :

Example 26 with StoragePortGroup

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

the class PortMetricsProcessor method computePortGroupMetrics.

/**
 * Compute port group metrics (portMetric and volume counts) for vmax
 *
 * @param systemURI
 *            - storage system URI
 */
public void computePortGroupMetrics(URI systemURI) {
    StorageSystem system = _dbClient.queryObject(StorageSystem.class, systemURI);
    DiscoveredDataObject.Type type = DiscoveredDataObject.Type.valueOf(system.getSystemType());
    if (type != DiscoveredDataObject.Type.vmax) {
        return;
    }
    _log.info("Calculating port group metrics");
    URIQueryResultList portGroupURIs = new URIQueryResultList();
    _dbClient.queryByConstraint(ContainmentConstraint.Factory.getStorageDevicePortGroupConstraint(systemURI), portGroupURIs);
    Iterator<URI> portGroupIter = portGroupURIs.iterator();
    while (portGroupIter.hasNext()) {
        URI pgURI = portGroupIter.next();
        StoragePortGroup portGroup = _dbClient.queryObject(StoragePortGroup.class, pgURI);
        if (portGroup != null && !portGroup.getInactive() && !portGroup.checkInternalFlags(Flag.INTERNAL_OBJECT)) {
            StringSet ports = portGroup.getStoragePorts();
            List<StoragePort> portMembers = _dbClient.queryObject(StoragePort.class, StringSetUtil.stringSetToUriList(ports));
            Double portMetricTotal = 0.0;
            StringMap dbMetrics = portGroup.getMetrics();
            boolean isMetricsSet = true;
            for (StoragePort port : portMembers) {
                StringMap portMetrics = port.getMetrics();
                if (portMetrics == null) {
                    isMetricsSet = false;
                    break;
                }
                Double portMetric = MetricsKeys.getDouble(MetricsKeys.portMetric, portMetrics);
                if (portMetric == null) {
                    isMetricsSet = false;
                    break;
                }
                portMetricTotal += portMetric;
            }
            if (isMetricsSet && portMetricTotal != null) {
                _log.info(String.format("port group %s portMetric %s", portGroup.getNativeGuid(), portMetricTotal.toString()));
                MetricsKeys.putDouble(MetricsKeys.portMetric, portMetricTotal / portMembers.size(), dbMetrics);
            }
            computePortGroupVolumeCounts(portGroup, dbMetrics, _dbClient);
            portGroup.setMetrics(dbMetrics);
            _dbClient.updateObject(portGroup);
        }
    }
}
Also used : StoragePortGroup(com.emc.storageos.db.client.model.StoragePortGroup) StringMap(com.emc.storageos.db.client.model.StringMap) StoragePort(com.emc.storageos.db.client.model.StoragePort) DiscoveredDataObject(com.emc.storageos.db.client.model.DiscoveredDataObject) URI(java.net.URI) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) StringSet(com.emc.storageos.db.client.model.StringSet) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 27 with StoragePortGroup

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

the class ExportGroupService method validatePortGroupWhenAddVolumesForExportGroup.

/**
 * Validate port group, if the volumes to be exported are from VMAX, and the
 * port group setting is on.
 *
 * @param addVolumes
 *            - Volume params to be exported
 * @param portGroup
 *            - Port group URI
 * @param exportGroup
 *            - export group that is being used
 */
public void validatePortGroupWhenAddVolumesForExportGroup(Collection<URI> addVolumes, URI portGroup, ExportGroup exportGroup) {
    if (addVolumes != null && !addVolumes.isEmpty()) {
        Set<URI> systems = new HashSet<URI>();
        for (URI blockURI : addVolumes) {
            BlockObject blockObject = BlockObject.fetch(_dbClient, blockURI);
            systems.add(blockObject.getStorageController());
        }
        boolean isVmax = false;
        StorageSystem storage = null;
        for (URI systemURI : systems) {
            storage = queryObject(StorageSystem.class, systemURI, true);
            if (Type.vmax.name().equals(storage.getSystemType())) {
                isVmax = true;
                break;
            }
        }
        if (isVmax) {
            String value = customConfigHandler.getComputedCustomConfigValue(CustomConfigConstants.VMAX_USE_PORT_GROUP_ENABLED, "vmax", null);
            boolean useExistingPortGroup = Boolean.TRUE.toString().equalsIgnoreCase(value);
            if (!useExistingPortGroup) {
                return;
            }
            if (exportGroup == null && portGroup == null) {
                // create export group case, When use existing port group is on, users should provide a port group
                throw APIException.badRequests.portGroupNotSpecified();
            } else if (exportGroup == null) {
                // port group is specified, check the port group storage system is the same as the volume system
                StoragePortGroup pgObject = queryObject(StoragePortGroup.class, portGroup, true);
                if (!storage.getId().equals(pgObject.getStorageDevice()) || systems.size() > 1) {
                    throw APIException.badRequests.cannotExportVolumesFromDifferentSystems(pgObject.getNativeGuid());
                }
            } else if (exportGroup != null) {
                // update export group. check if export mask exists. if not, need to specify port group if using
                // existing port group
                List<ExportMask> masks = ExportMaskUtils.getExportMasks(_dbClient, exportGroup, storage.getId());
                if (masks.isEmpty() && portGroup == null) {
                    throw APIException.badRequests.portGroupNotSpecified();
                } else if (!masks.isEmpty() && portGroup != null) {
                    StoragePortGroup pgObject = queryObject(StoragePortGroup.class, portGroup, true);
                    if (!storage.getId().equals(pgObject.getStorageDevice()) || systems.size() > 1) {
                        throw APIException.badRequests.cannotExportVolumesFromDifferentSystems(pgObject.getNativeGuid());
                    }
                }
            }
        }
    }
}
Also used : StoragePortGroup(com.emc.storageos.db.client.model.StoragePortGroup) ExportMask(com.emc.storageos.db.client.model.ExportMask) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) BlockObject(com.emc.storageos.db.client.model.BlockObject) HashSet(java.util.HashSet) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 28 with StoragePortGroup

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

the class ExportGroupService method validatePortAssignment.

/**
 * Verifies that StoragePorts can be assigned for a StorageSystem given a set of Initiators.
 * This will verify that the numPaths variable is not too low or too high to allow assignment.
 *
 * @param storageSystem
 * @param varray VirtualArray of ExportGroup
 * @param blockScheduler
 * @param initiators List<Initiators>
 * @param exportPathParameters Optional export path parameters to affect validation
 * @param numPaths
 */
private void validatePortAssignment(StorageSystem storageSystem, URI varray, BlockStorageScheduler blockScheduler, List<Initiator> initiators, Collection<URI> volumes, URI exportGroupURI, ExportPathParameters exportPathParameters) {
    try {
        ExportPathParams pathParams = blockScheduler.calculateExportPathParamForVolumes(volumes, 0, storageSystem.getId(), exportGroupURI);
        if (exportPathParameters != null) {
            // Override the path parameters for the validity check.
            if (exportPathParameters.getMaxPaths() != null) {
                pathParams.setMaxPaths(exportPathParameters.getMaxPaths());
            }
            if (exportPathParameters.getMinPaths() != null) {
                pathParams.setMinPaths(exportPathParameters.getMinPaths());
            }
            if (exportPathParameters.getPathsPerInitiator() != null) {
                pathParams.setPathsPerInitiator(exportPathParameters.getPathsPerInitiator());
            }
            if (!NullColumnValueGetter.isNullURI(exportPathParameters.getPortGroup())) {
                URI pgURI = exportPathParameters.getPortGroup();
                if (!NullColumnValueGetter.isNullURI(pgURI)) {
                    StoragePortGroup portGroup = _dbClient.queryObject(StoragePortGroup.class, pgURI);
                    if (portGroup != null) {
                        pathParams.setStoragePorts(portGroup.getStoragePorts());
                        pathParams.setPortGroup(pgURI);
                    }
                }
            }
        }
        blockScheduler.assignStoragePorts(storageSystem, varray, initiators, pathParams, null, volumes);
    } catch (ControllerException ex) {
        _log.error(ex.getLocalizedMessage());
        throw (ex);
    }
}
Also used : StoragePortGroup(com.emc.storageos.db.client.model.StoragePortGroup) ControllerException(com.emc.storageos.volumecontroller.ControllerException) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) ExportPathParams(com.emc.storageos.db.client.model.ExportPathParams)

Example 29 with StoragePortGroup

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

the class ExportGroupService method validateAndCreateExportPathParam.

/**
 * Validate the the optional path parameters are valid for the ExportGroup.
 *
 * @param param -- ExportPathParameters block
 * @param exportGroup -- ExportGroup
 * @param blockObjectURIs -- Collection of block object URIs, used only for validating ports
 * @return ExportPathParam suitable for persistence
 */
ExportPathParams validateAndCreateExportPathParam(ExportPathParameters param, ExportGroup exportGroup, Collection<URI> blockObjectURIs) {
    // If minPaths is specified, or pathsPerInitiator is specified, maxPaths must be specified
    if ((param.getMinPaths() != null || param.getPathsPerInitiator() != null) && param.getMaxPaths() == null) {
        throw APIException.badRequests.maxPathsRequired();
    }
    ExportPathParams pathParam = new ExportPathParams();
    pathParam.setId(URIUtil.createId(ExportPathParams.class));
    if (param.getMaxPaths() != null) {
        ArgValidator.checkFieldMinimum(param.getMaxPaths(), 1, "max_paths");
        if (param.getMinPaths() != null) {
            ArgValidator.checkFieldMinimum(param.getMinPaths(), 1, "min_paths");
        } else {
            // Defaults to one path if not suppiled
            param.setMinPaths(1);
        }
        if (param.getPathsPerInitiator() != null) {
            ArgValidator.checkFieldMinimum(param.getPathsPerInitiator(), 1, "paths_per_initiator");
        } else {
            // Defaults to one path if not supplied
            param.setPathsPerInitiator(1);
        }
        // minPaths must be <= than maxPaths.
        if (param.getMinPaths() > param.getMaxPaths()) {
            throw APIException.badRequests.minPathsGreaterThanMaxPaths();
        }
        // pathsPerInitiator must be <= maxPaths.
        if (param.getPathsPerInitiator() > param.getMaxPaths()) {
            throw APIException.badRequests.pathsPerInitiatorGreaterThanMaxPaths();
        }
        // Collect the list of Storage Systems used by the block objects.
        Set<URI> storageArrays = new HashSet<URI>();
        for (URI blockObjectURI : blockObjectURIs) {
            BlockObject blockObject = BlockObject.fetch(_dbClient, blockObjectURI);
            if (blockObject == null) {
                continue;
            }
            storageArrays.add(blockObject.getStorageController());
        }
        // validate storage ports if they are supplied
        validateExportPathParmPorts(param, exportGroup, storageArrays);
        pathParam.setMaxPaths(param.getMaxPaths());
        pathParam.setMinPaths(param.getMinPaths());
        pathParam.setPathsPerInitiator(param.getPathsPerInitiator());
        if (param.getStoragePorts() != null) {
            pathParam.setStoragePorts(StringSetUtil.uriListToStringSet(param.getStoragePorts()));
        }
        // Validate there are no existing exports for the hosts involved that we could not override.
        validateNoConflictingExports(exportGroup, storageArrays, pathParam);
    }
    if (!NullColumnValueGetter.isNullURI(param.getPortGroup())) {
        // Check if the use port group config setting is on
        String value = customConfigHandler.getComputedCustomConfigValue(CustomConfigConstants.VMAX_USE_PORT_GROUP_ENABLED, Type.vmax.name(), null);
        if (Boolean.FALSE.toString().equalsIgnoreCase(value)) {
            throw APIException.badRequests.portGroupSettingIsOff();
        }
        URI pgURI = param.getPortGroup();
        ArgValidator.checkFieldUriType(pgURI, StoragePortGroup.class, "portGroupId");
        StoragePortGroup portGroup = _dbClient.queryObject(StoragePortGroup.class, pgURI);
        if (portGroup == null || !portGroup.isUsable()) {
            throw APIException.badRequests.portGroupInvalid(pgURI.toString());
        }
        pathParam.setPortGroup(pgURI);
    }
    pathParam.setExplicitlyCreated(false);
    return pathParam;
}
Also used : StoragePortGroup(com.emc.storageos.db.client.model.StoragePortGroup) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) BlockObject(com.emc.storageos.db.client.model.BlockObject) ExportPathParams(com.emc.storageos.db.client.model.ExportPathParams) HashSet(java.util.HashSet)

Example 30 with StoragePortGroup

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

the class ExportGroupService method validatePathAdjustment.

/**
 * Validates the ExportMask configuration for a port allocation preview.
 * Throws bad request exception if any ExportMask for the Storage System has existing initiators
 * or initiators that are not in the ExportGroup. If a set of hosts to be processed is specified
 * for a Cluster, removes any initiators not associated with those hosts.
 * If the port group used in the export mask is not mutable, storage ports that could be allocated have to
 * be from the port group. Those storage ports will be set in storagePorts.
 * @param group -- ExportGroup
 * @param initiators -- List of initiators from the Export Group
 * @param system - Storage System
 * @param varray - Virtual array
 * @param hosts -- if ExportGroup is type CLUSTER, filter initiators by supplied hosts if any
 * @param response - OUT PortAllocationPreviewRestRep used to hold list of other affected Export Groups
 * @param existingPaths -- OUT parameter that is populated with existing paths
 * @param storagePorts - OUT Available storage ports to be allocated. It would only be set if port group
 *                           used in the export mask is not mutable, and it is set to the storage ports
 *                           in the port group.
 */
private void validatePathAdjustment(ExportGroup exportGroup, List<Initiator> initiators, StorageSystem system, URI varray, Set<URI> hosts, ExportPathsAdjustmentPreviewRestRep response, StringSetMap existingPaths, boolean useExistingPaths, StringSet storagePorts) {
    Set<URI> affectedGroupURIs = new HashSet<URI>();
    // Add our Export Group to the affected resources.
    affectedGroupURIs.add(exportGroup.getId());
    response.getAffectedExportGroups().add(toNamedRelatedResource(exportGroup, exportGroup.getLabel()));
    if (!Type.vmax.name().equalsIgnoreCase(system.getSystemType()) && !Type.vplex.name().equalsIgnoreCase(system.getSystemType())) {
        throw APIException.badRequests.exportPathAdjustmentSystemNotSupported(system.getSystemType());
    }
    List<ExportMask> exportMasks = ExportMaskUtils.getExportMasks(_dbClient, exportGroup, system.getId());
    if (exportMasks.isEmpty()) {
        throw APIException.badRequests.exportPathAdjustmentSystemExportGroupNotMatch(exportGroup.getLabel(), system.getNativeGuid());
    }
    // Make a map of Export Group initiator URI to Initiator Object
    Map<URI, Initiator> initiatorMap = new HashMap<URI, Initiator>();
    List<Initiator> initiatorsToRemove = new ArrayList<Initiator>();
    for (Initiator initiator : initiators) {
        if (!exportGroup.getType().equals(ExportGroupType.Cluster.name()) || hosts.isEmpty() || hosts.contains(initiator.getHost())) {
            initiatorMap.put(initiator.getId(), initiator);
        } else {
            // Initiator did not match the specified hosts
            initiatorsToRemove.add(initiator);
        }
    }
    // Remove any initiators not retained because of hosts specification
    initiators.removeAll(initiatorsToRemove);
    // Find the Export Masks for this Storage System
    for (ExportMask exportMask : exportMasks) {
        // For VPLEX, must verify the Export Mask is in the appropriate Varray
        if (system.getSystemType().equalsIgnoreCase(StorageSystem.Type.vplex.name())) {
            if (!ExportMaskUtils.exportMaskInVarray(_dbClient, exportMask, varray)) {
                // Check if storage ports belongs to the other varray
                URI otherVarray = null;
                if (!exportGroup.getVirtualArray().equals(varray)) {
                    otherVarray = exportGroup.getVirtualArray();
                } else {
                    StringMap altVarrays = exportGroup.getAltVirtualArrays();
                    if (altVarrays != null) {
                        String altVarray = altVarrays.get(system.getId().toString());
                        if (NullColumnValueGetter.isNotNullValue(altVarray)) {
                            otherVarray = URI.create(altVarray);
                        }
                    }
                }
                if (otherVarray != null && ExportMaskUtils.exportMaskInVarray(_dbClient, exportMask, otherVarray)) {
                    _log.info(String.format("VPLEX ExportMask %s (%s) not in selected varray %s, skipping", exportMask.getMaskName(), exportMask.getId(), varray));
                    continue;
                } else {
                    throw APIException.badRequests.exportMaskNotInVarray(exportMask.getId().toString());
                }
            }
        } else {
            // For other array types, throw error if ports not in the varray
            List<URI> portsNotInVarray = ExportMaskUtils.getExportMaskStoragePortsNotInVarray(_dbClient, exportMask, varray);
            if (!portsNotInVarray.isEmpty()) {
                String errorPorts = Joiner.on(',').join(portsNotInVarray);
                String error = String.format("The ports : %s are in the exportMask %s, but not in the varray %s", errorPorts, exportMask.getId().toString(), varray.toString());
                _log.error(error);
                throw APIException.badRequests.storagePortsNotInVarray(errorPorts, exportMask.getId().toString(), varray.toString());
            }
        }
        // Now look to see if there are any existing initiators in the ExportMask
        if (exportMask.hasAnyExistingInitiators()) {
            _log.error("ExportMask has existing initiators: " + exportMask.getMaskName());
            throw APIException.badRequests.externallyAddedInitiators(exportMask.getMaskName(), exportMask.getExistingInitiators().toString());
        }
        // If there are eixisting volumes in the ExportMask, useExistingPath has to be true
        if (exportMask.hasAnyExistingVolumes() && !useExistingPaths) {
            _log.error("ExportMask has existing volumes: " + exportMask.getMaskName());
            throw APIException.badRequests.externallyAddedVolumes(exportMask.getMaskName(), exportMask.getExistingVolumes().toString());
        }
        URI currentPGUri = exportMask.getPortGroup();
        if (!NullColumnValueGetter.isNullURI(currentPGUri)) {
            StoragePortGroup currentPG = queryObject(StoragePortGroup.class, currentPGUri, false);
            if (!currentPG.getMutable()) {
                storagePorts.addAll(currentPG.getStoragePorts());
            }
        }
        // Populate the existing paths map.
        StringSetMap zoningMap = exportMask.getZoningMap();
        if (zoningMap != null && !zoningMap.isEmpty()) {
            for (String initiator : zoningMap.keySet()) {
                if (zoningMap.get(initiator).isEmpty()) {
                    // No ports for the initiator, inconsistent
                    continue;
                }
                if (!existingPaths.keySet().contains(initiator)) {
                    existingPaths.put(initiator, new StringSet());
                }
                existingPaths.get(initiator).addAll(zoningMap.get(initiator));
            }
        }
        Set<Initiator> maskInitiators = ExportMaskUtils.getInitiatorsForExportMask(_dbClient, exportMask, null);
        Set<String> additionalInitiators = new HashSet<String>();
        boolean hasMatchingInitiator = false;
        Set<URI> hostURIsForInitiators = new HashSet<URI>();
        for (Initiator maskInitiator : maskInitiators) {
            if (maskInitiator.getHost() != null) {
                hostURIsForInitiators.add(maskInitiator.getHost());
            }
            if (initiatorMap.keySet().contains(maskInitiator.getId())) {
                hasMatchingInitiator = true;
            }
            if (!exportGroup.getInitiators().contains(maskInitiator.getId().toString())) {
                additionalInitiators.add(maskInitiator.getInitiatorPort());
            }
        }
        // hosts and this host wasn't present. If not, we just skip this mask.
        if (!hasMatchingInitiator) {
            continue;
        }
        // Check if this is a mask for a single ComputeResource and if there are additional usable initiators.
        // If so add them to the list of initiators.
        List<Host> hostsForInitiators = _dbClient.queryObject(Host.class, hostURIsForInitiators);
        for (Host host : hostsForInitiators) {
            _log.info(String.format("Checking connected initiators for host %s (%s)", host.getHostName(), host.getId()));
            List<URI> hostConnectedInitiators = getHostConnectedInitiators(host, Arrays.asList(system.getId()), exportGroup);
            for (URI hostConnectedInitiator : hostConnectedInitiators) {
                if (!initiators.contains(hostConnectedInitiator)) {
                    Initiator newInitiator = _dbClient.queryObject(Initiator.class, hostConnectedInitiator);
                    _log.info(String.format("Found connected initiator %s host %s (%s) to add to initiators", newInitiator.getInitiatorPort(), newInitiator.getHostName(), newInitiator.getId()));
                    initiators.add(newInitiator);
                }
            }
            _log.info("Connected Initiators check completed host: " + host.getHostName());
        }
        if (!additionalInitiators.isEmpty()) {
            _log.info("ExportMask has additional initiators: ", exportMask.getMaskName());
            throw APIException.badRequests.additionalInitiators(exportMask.getMaskName(), additionalInitiators.toString());
        }
        // Then look to see if any other ExportGroups are using this ExportMask
        List<ExportGroup> assocExportGroups = ExportMaskUtils.getExportGroups(_dbClient, exportMask);
        for (ExportGroup assocGroup : assocExportGroups) {
            if (!assocGroup.getId().equals(exportGroup.getId()) && !affectedGroupURIs.contains(assocGroup.getId())) {
                affectedGroupURIs.add(assocGroup.getId());
                response.getAffectedExportGroups().add(toNamedRelatedResource(assocGroup, assocGroup.getLabel()));
            }
        }
    }
}
Also used : StoragePortGroup(com.emc.storageos.db.client.model.StoragePortGroup) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) StringMap(com.emc.storageos.db.client.model.StringMap) HashMap(java.util.HashMap) ExportMask(com.emc.storageos.db.client.model.ExportMask) ArrayList(java.util.ArrayList) Host(com.emc.storageos.db.client.model.Host) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) Initiator(com.emc.storageos.db.client.model.Initiator) StringSet(com.emc.storageos.db.client.model.StringSet) HashSet(java.util.HashSet)

Aggregations

StoragePortGroup (com.emc.storageos.db.client.model.StoragePortGroup)37 URI (java.net.URI)25 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)14 ArrayList (java.util.ArrayList)14 ExportMask (com.emc.storageos.db.client.model.ExportMask)12 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)11 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)11 HashSet (java.util.HashSet)9 WBEMException (javax.wbem.WBEMException)9 Produces (javax.ws.rs.Produces)9 MapStoragePortGroup (com.emc.storageos.api.mapper.functions.MapStoragePortGroup)8 StringSet (com.emc.storageos.db.client.model.StringSet)8 CheckPermission (com.emc.storageos.security.authorization.CheckPermission)8 Path (javax.ws.rs.Path)8 Initiator (com.emc.storageos.db.client.model.Initiator)7 ExportPathParams (com.emc.storageos.db.client.model.ExportPathParams)6 NamedURI (com.emc.storageos.db.client.model.NamedURI)6 SmisException (com.emc.storageos.volumecontroller.impl.smis.SmisException)6 CIMInstance (javax.cim.CIMInstance)6 CIMObjectPath (javax.cim.CIMObjectPath)6