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);
}
}
}
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());
}
}
}
}
}
}
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);
}
}
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;
}
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()));
}
}
}
}
Aggregations