use of com.emc.storageos.db.client.model.StringMap in project coprhd-controller by CoprHD.
the class CustomConfigHandler method createSystemConfig.
private CustomConfig createSystemConfig(CustomConfigType template, String scopeType, String scopevalue, String value) {
// create one
CustomConfig curConfig = new CustomConfig();
curConfig.setConfigType(template.getName());
curConfig.setSystemDefault(true);
curConfig.setValue(value);
StringMap scope = new StringMap();
scope.put(scopeType, scopevalue);
curConfig.setScope(scope);
curConfig.setLabel(CustomConfigHandler.constructConfigName(template.getName(), scope));
curConfig.setRegistered(true);
return curConfig;
}
use of com.emc.storageos.db.client.model.StringMap in project coprhd-controller by CoprHD.
the class RPHelper method getMetropointStandbyCopies.
/**
* Returns the list of copies residing on the standby varray given the active production volume in a
* Metropoint environment
*
* @param volume the active production volume
* @param dbClient DbClient ref
* @return returns the list of copies on the standby varray
*/
public static List<Volume> getMetropointStandbyCopies(Volume volume, DbClient dbClient) {
List<Volume> standbyCopies = new ArrayList<Volume>();
if (volume.getProtectionSet() == null) {
return standbyCopies;
}
ProtectionSet protectionSet = dbClient.queryObject(ProtectionSet.class, volume.getProtectionSet());
if (protectionSet.getVolumes() == null) {
return standbyCopies;
}
// look for the standby varray in the volume's vpool
VirtualPool vpool = dbClient.queryObject(VirtualPool.class, volume.getVirtualPool());
if (vpool == null) {
return standbyCopies;
}
StringMap varrayVpoolMap = vpool.getHaVarrayVpoolMap();
if (varrayVpoolMap != null && !varrayVpoolMap.isEmpty()) {
URI standbyVarrayId = URI.create(varrayVpoolMap.keySet().iterator().next());
// now loop through the replication set volumes and look for any copies from the standby varray
for (String rsetVolId : protectionSet.getVolumes()) {
Volume rsetVol = dbClient.queryObject(Volume.class, URI.create(rsetVolId));
if (rsetVol != null && !rsetVol.getInactive() && rsetVol.getRpTargets() != null) {
for (String targetVolId : rsetVol.getRpTargets()) {
Volume targetVol = dbClient.queryObject(Volume.class, URI.create(targetVolId));
if (targetVol.getVirtualArray().equals(standbyVarrayId)) {
standbyCopies.add(targetVol);
}
}
}
}
}
return standbyCopies;
}
use of com.emc.storageos.db.client.model.StringMap in project coprhd-controller by CoprHD.
the class VPlexHDSMaskingOrchestrator method deleteOrRemoveVolumesFromExportMask.
@Override
public void deleteOrRemoveVolumesFromExportMask(URI arrayURI, URI exportGroupURI, URI exportMaskURI, List<URI> volumes, List<URI> initiatorURIs, String stepId) {
ExportTaskCompleter completer = null;
try {
completer = new ExportMaskOnlyRemoveVolumeCompleter(exportGroupURI, exportMaskURI, volumes, stepId);
WorkflowStepCompleter.stepExecuting(stepId);
StorageSystem array = _dbClient.queryObject(StorageSystem.class, arrayURI);
BlockStorageDevice device = _blockController.getDevice(array.getSystemType());
ExportMask exportMask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
// If the exportMask isn't found, or has been deleted, nothing to do.
if (exportMask == null || exportMask.getInactive()) {
_log.info(String.format("ExportMask %s inactive, returning success", exportMaskURI));
completer.ready(_dbClient);
return;
}
// Protect concurrent operations by locking {host, array} dupple.
// Lock will be released when workflow step completes.
List<String> lockKeys = ControllerLockingUtil.getHostStorageLockKeys(_dbClient, ExportGroupType.Host, StringSetUtil.stringSetToUriList(exportMask.getInitiators()), arrayURI);
getWorkflowService().acquireWorkflowStepLocks(stepId, lockKeys, LockTimeoutValue.get(LockType.VPLEX_BACKEND_EXPORT));
// Refresh the ExportMask
exportMask = refreshExportMask(array, device, exportMask);
// Determine if we're deleting the last volume in the mask.
StringMap maskVolumesMap = exportMask.getVolumes();
Set<String> remainingVolumes = new HashSet<String>();
List<URI> passedVolumesInMask = new ArrayList<>(volumes);
if (maskVolumesMap != null) {
remainingVolumes.addAll(maskVolumesMap.keySet());
}
for (URI volume : volumes) {
remainingVolumes.remove(volume.toString());
// are not in the mask to handle this condition.
if ((maskVolumesMap != null) && (!maskVolumesMap.keySet().contains(volume.toString()))) {
passedVolumesInMask.remove(volume);
}
}
_log.info("passedVolumesInMask : {}", passedVolumesInMask);
_log.info("remainingVolumes : {}", remainingVolumes);
// None of the volumes is in the export mask, so we are done.
if (passedVolumesInMask.isEmpty()) {
_log.info("None of these volumes {} are in export mask {}", volumes, exportMask.forDisplay());
completer.ready(_dbClient);
return;
}
// If it is last volume and there are no existing volumes, delete the ExportMask.
if (remainingVolumes.isEmpty() && !exportMask.hasAnyExistingVolumes()) {
device.doExportDelete(array, exportMask, passedVolumesInMask, initiatorURIs, completer);
} else {
List<Initiator> initiators = null;
if (initiatorURIs != null && !initiatorURIs.isEmpty()) {
initiators = _dbClient.queryObject(Initiator.class, initiatorURIs);
}
device.doExportRemoveVolumes(array, exportMask, passedVolumesInMask, initiators, completer);
}
} catch (Exception ex) {
_log.error("Failed to delete or remove volumes to export mask for hds: ", ex);
VPlexApiException vplexex = DeviceControllerExceptions.vplex.addStepsForCreateVolumesFailed(ex);
completer.error(_dbClient, vplexex);
}
}
use of com.emc.storageos.db.client.model.StringMap in project coprhd-controller by CoprHD.
the class HDSMaskingOrchestrator method determineExportGroupCreateSteps.
/**
* Routine contains logic to create an export mask on the array
*
* @param workflow
* - Workflow object to create steps against
* @param previousStep
* - [optional] Identifier of workflow step to wait for
* @param device
* - BlockStorageDevice implementation
* @param storage
* - StorageSystem object representing the underlying array
* @param exportGroup
* - ExportGroup object representing Bourne-level masking
* @param initiatorURIs
* - List of Initiator URIs
* @param volumeMap
* - Map of Volume URIs to requested Integer HLUs
* @param zoningStepNeeded
* - Not required ofr HDS
* @param token
* - Identifier for the operation
*
* @throws Exception
*/
@Override
public boolean determineExportGroupCreateSteps(Workflow workflow, String previousStep, BlockStorageDevice device, StorageSystem storage, ExportGroup exportGroup, List<URI> initiatorURIs, Map<URI, Integer> volumeMap, boolean zoningStepNeeded, String token) throws Exception {
Map<String, URI> portNameToInitiatorURI = new HashMap<String, URI>();
List<URI> volumeURIs = new ArrayList<URI>();
volumeURIs.addAll(volumeMap.keySet());
Map<URI, URI> hostToExistingExportMaskMap = new HashMap<URI, URI>();
List<URI> hostURIs = new ArrayList<URI>();
List<String> portNames = new ArrayList<String>();
// Only update the ports of a mask that we created.
// TODO COP-22395:
// Make sure the caller to this method (the caller that assembles the steps) adds the initiator list to
// send down here. (then remove the log)
List<Initiator> initiators = null;
if (initiatorURIs != null && !initiatorURIs.isEmpty()) {
initiators = _dbClient.queryObject(Initiator.class, initiatorURIs);
} else {
_log.warn("Internal warning: Need to add the initiatorURIs to the call that assembles this step for validation to occur.");
}
// Populate the port WWN/IQNs (portNames) and the
// mapping of the WWN/IQNs to Initiator URIs
processInitiators(exportGroup, initiatorURIs, portNames, portNameToInitiatorURI, hostURIs);
// We always want to have the full list of initiators for the hosts involved in
// this export. This will allow the export operation to always find any
// existing exports for a given host.
queryHostInitiatorsAndAddToList(portNames, portNameToInitiatorURI, initiatorURIs, hostURIs);
// Find the export masks that are associated with any or all the ports in
// portNames. We will have to do processing differently based on whether
// or there is an existing ExportMasks.
Map<String, Set<URI>> matchingExportMaskURIs = device.findExportMasks(storage, portNames, false);
boolean masksWithStoragePortFromVArrayFound = false;
Set<String> storagePortURIsAssociatedWithVArrayAndStorageArray = ExportMaskUtils.getStoragePortUrisAssociatedWithVarrayAndStorageArray(storage.getId(), exportGroup.getVirtualArray(), _dbClient);
Set<String> checkMasks = mergeWithExportGroupMaskURIs(exportGroup, matchingExportMaskURIs.values());
for (String maskURIStr : checkMasks) {
ExportMask exportMask = _dbClient.queryObject(ExportMask.class, URI.create(maskURIStr));
// Check if there are any storage ports in the mask which are part of varray, if not found discard this mask
if (Sets.intersection(storagePortURIsAssociatedWithVArrayAndStorageArray, exportMask.getStoragePorts()).isEmpty()) {
for (Map.Entry<String, Set<URI>> entry : matchingExportMaskURIs.entrySet()) {
entry.getValue().remove(exportMask.getId());
}
continue;
} else {
masksWithStoragePortFromVArrayFound = true;
}
}
if (matchingExportMaskURIs.isEmpty() || !masksWithStoragePortFromVArrayFound) {
_log.info(String.format("No existing mask found w/ initiators { %s }", Joiner.on(",").join(portNames)));
createNewExportMaskWorkflowForInitiators(initiatorURIs, exportGroup, workflow, volumeMap, storage, token, previousStep);
} else {
_log.info(String.format("Mask(s) found w/ initiators {%s}. " + "MatchingExportMaskURIs {%s}, portNameToInitiators {%s}", Joiner.on(",").join(portNames), Joiner.on(",").join(matchingExportMaskURIs.values()), Joiner.on(",").join(portNameToInitiatorURI.entrySet())));
// There are some initiators that already exist. We need to create a
// workflow that create new masking containers or updates masking
// containers as necessary.
// These data structures will be used to track new initiators - ones
// that don't already exist on the array
List<URI> initiatorURIsCopy = new ArrayList<URI>();
initiatorURIsCopy.addAll(initiatorURIs);
// This loop will determine a list of volumes to update per export mask
Map<URI, Map<URI, Integer>> existingMasksToUpdateWithNewVolumes = new HashMap<URI, Map<URI, Integer>>();
Map<URI, Set<Initiator>> existingMasksToUpdateWithNewInitiators = new HashMap<URI, Set<Initiator>>();
for (Map.Entry<String, Set<URI>> entry : matchingExportMaskURIs.entrySet()) {
URI initiatorURI = portNameToInitiatorURI.get(entry.getKey());
Initiator initiator = _dbClient.queryObject(Initiator.class, initiatorURI);
// Keep track of those initiators that have been found to exist already
// in some export mask on the array
initiatorURIsCopy.remove(initiatorURI);
// Get a list of the ExportMasks that were matched to the initiator
List<URI> exportMaskURIs = new ArrayList<URI>();
exportMaskURIs.addAll(entry.getValue());
List<ExportMask> masks = _dbClient.queryObject(ExportMask.class, exportMaskURIs);
_log.info(String.format("initiator %s masks {%s}", initiator.getInitiatorPort(), Joiner.on(',').join(exportMaskURIs)));
for (ExportMask mask : masks) {
// Check if there are any storage ports in the mask which are part of varray, if not found discard this mask
if (Sets.intersection(storagePortURIsAssociatedWithVArrayAndStorageArray, mask.getStoragePorts()).isEmpty())
continue;
if (null == mask.getMaskName()) {
String maskName = ExportMaskUtils.getMaskName(_dbClient, initiators, exportGroup, storage);
_log.info("Generated mask name: {}", maskName);
mask.setMaskName(maskName);
}
_log.info(String.format("mask %s has initiator %s", mask.getMaskName(), initiator.getInitiatorPort()));
if (mask.getCreatedBySystem()) {
_log.info(String.format("initiator %s is in persisted mask %s", initiator.getInitiatorPort(), mask.getMaskName()));
// in our export group, because we would simply add to them.
if (mask.getInitiators() != null) {
for (String existingMaskInitiatorStr : mask.getInitiators()) {
// Now look at it from a different angle. Which one of our export group initiators
// are NOT in the current mask? And if so, if it belongs to the same host as an existing
// one,
// we should add it to this mask.
Iterator<URI> initiatorIter = initiatorURIsCopy.iterator();
while (initiatorIter.hasNext()) {
Initiator initiatorCopy = _dbClient.queryObject(Initiator.class, initiatorIter.next());
if (initiatorCopy != null && initiatorCopy.getId() != null && !mask.hasInitiator(initiatorCopy.getId().toString())) {
Initiator existingMaskInitiator = _dbClient.queryObject(Initiator.class, URI.create(existingMaskInitiatorStr));
if (existingMaskInitiator != null && initiatorCopy.getHost() != null && initiatorCopy.getHost().equals(existingMaskInitiator.getHost())) {
// Add to the list of initiators we need to add to this mask
Set<Initiator> existingMaskInitiators = existingMasksToUpdateWithNewInitiators.get(mask.getId());
if (existingMaskInitiators == null) {
existingMaskInitiators = new HashSet<Initiator>();
existingMasksToUpdateWithNewInitiators.put(mask.getId(), existingMaskInitiators);
}
existingMaskInitiators.add(initiatorCopy);
// remove this from the list of initiators we'll
initiatorIter.remove();
// make a new mask from
}
}
}
}
}
} else {
// Insert this initiator into the mask's list of initiators managed by the system.
// This will get persisted below.
mask.addInitiator(initiator);
if (!NullColumnValueGetter.isNullURI(initiator.getHost())) {
hostToExistingExportMaskMap.put(initiator.getHost(), mask.getId());
}
}
// if it doesn't then we'll add it to the list of volumes to add.
for (URI boURI : volumeURIs) {
BlockObject bo = BlockObject.fetch(_dbClient, boURI);
if (!mask.hasExistingVolume(bo)) {
_log.info(String.format("volume %s is not in mask %s", bo.getNativeGuid(), mask.getMaskName()));
// The volume doesn't exist, so we have to add it to
// the masking container.
Map<URI, Integer> newVolumes = existingMasksToUpdateWithNewVolumes.get(mask.getId());
if (newVolumes == null) {
newVolumes = new HashMap<URI, Integer>();
existingMasksToUpdateWithNewVolumes.put(mask.getId(), newVolumes);
}
// Check if the requested HLU for the volume is
// already taken by a pre-existing volume.
Integer requestedHLU = volumeMap.get(bo.getId());
StringMap existingVolumesInMask = mask.getExistingVolumes();
if (existingVolumesInMask != null && requestedHLU.intValue() != ExportGroup.LUN_UNASSIGNED && !ExportGroup.LUN_UNASSIGNED_DECIMAL_STR.equals(requestedHLU.toString()) && existingVolumesInMask.containsValue(requestedHLU.toString())) {
ExportOrchestrationTask completer = new ExportOrchestrationTask(exportGroup.getId(), token);
ServiceError serviceError = DeviceControllerException.errors.exportHasExistingVolumeWithRequestedHLU(boURI.toString(), requestedHLU.toString());
completer.error(_dbClient, serviceError);
return false;
}
newVolumes.put(bo.getId(), requestedHLU);
mask.addToUserCreatedVolumes(bo);
}
}
// Update the list of volumes and initiators for the mask
Map<URI, Integer> volumeMapForExistingMask = existingMasksToUpdateWithNewVolumes.get(mask.getId());
if (volumeMapForExistingMask != null && !volumeMapForExistingMask.isEmpty()) {
mask.addVolumes(volumeMapForExistingMask);
}
Set<Initiator> initiatorSetForExistingMask = existingMasksToUpdateWithNewInitiators.get(mask.getId());
if (initiatorSetForExistingMask != null && initiatorSetForExistingMask.isEmpty()) {
mask.addInitiators(initiatorSetForExistingMask);
}
updateZoningMap(exportGroup, mask);
_dbClient.updateObject(mask);
// TODO: All export group modifications should be moved to completers
exportGroup.addExportMask(mask.getId());
_dbClient.updateObject(exportGroup);
}
}
// The initiatorURIsCopy was used in the foreach initiator loop to see
// which initiators already exist in a mask. If it is non-empty,
// then it means there are initiators that are new,
// so let's add them to the main tracker
Map<URI, List<URI>> hostInitiatorMap = new HashMap<URI, List<URI>>();
if (!initiatorURIsCopy.isEmpty()) {
for (URI newExportMaskInitiator : initiatorURIsCopy) {
Initiator initiator = _dbClient.queryObject(Initiator.class, newExportMaskInitiator);
List<URI> initiatorSet = hostInitiatorMap.get(initiator.getHost());
if (initiatorSet == null) {
initiatorSet = new ArrayList<URI>();
hostInitiatorMap.put(initiator.getHost(), initiatorSet);
}
initiatorSet.add(initiator.getId());
_log.info(String.format("host = %s, " + "initiators to add: %d, " + "existingMasksToUpdateWithNewVolumes.size = %d", initiator.getHost(), hostInitiatorMap.get(initiator.getHost()).size(), existingMasksToUpdateWithNewVolumes.size()));
}
}
_log.info(String.format("existingMasksToUpdateWithNewVolumes.size = %d", existingMasksToUpdateWithNewVolumes.size()));
// and/or add volumes to existing masks.
if (!hostInitiatorMap.isEmpty()) {
for (URI hostID : hostInitiatorMap.keySet()) {
// associated with that host to the list
if (hostToExistingExportMaskMap.containsKey(hostID)) {
URI existingExportMaskURI = hostToExistingExportMaskMap.get(hostID);
Set<Initiator> toAddInits = new HashSet<Initiator>();
List<URI> hostInitaitorList = hostInitiatorMap.get(hostID);
for (URI initURI : hostInitaitorList) {
Initiator initiator = _dbClient.queryObject(Initiator.class, initURI);
if (!initiator.getInactive()) {
toAddInits.add(initiator);
}
}
_log.info(String.format("Need to add new initiators to existing mask %s, %s", existingExportMaskURI.toString(), Joiner.on(',').join(hostInitaitorList)));
existingMasksToUpdateWithNewInitiators.put(existingExportMaskURI, toAddInits);
continue;
}
// We have some brand new initiators, let's add them to new masks
_log.info(String.format("new export masks %s", Joiner.on(",").join(hostInitiatorMap.get(hostID))));
generateExportMaskCreateWorkflow(workflow, previousStep, storage, exportGroup, hostInitiatorMap.get(hostID), volumeMap, token);
}
}
Map<URI, String> stepMap = new HashMap<URI, String>();
for (Map.Entry<URI, Map<URI, Integer>> entry : existingMasksToUpdateWithNewVolumes.entrySet()) {
ExportMask mask = _dbClient.queryObject(ExportMask.class, entry.getKey());
Map<URI, Integer> volumesToAdd = entry.getValue();
_log.info(String.format("adding these volumes %s to mask %s", Joiner.on(",").join(volumesToAdd.keySet()), mask.getMaskName()));
stepMap.put(entry.getKey(), generateExportMaskAddVolumesWorkflow(workflow, null, storage, exportGroup, mask, volumesToAdd, null));
}
for (Entry<URI, Set<Initiator>> entry : existingMasksToUpdateWithNewInitiators.entrySet()) {
ExportMask mask = _dbClient.queryObject(ExportMask.class, entry.getKey());
Set<Initiator> initiatorsToAdd = entry.getValue();
List<URI> initiatorsURIs = new ArrayList<URI>();
for (Initiator initiator : initiatorsToAdd) {
initiatorsURIs.add(initiator.getId());
}
_log.info(String.format("adding these initiators %s to mask %s", Joiner.on(",").join(initiatorsURIs), mask.getMaskName()));
previousStep = stepMap.get(entry.getKey()) == null ? previousStep : stepMap.get(entry.getKey());
generateExportMaskAddInitiatorsWorkflow(workflow, previousStep, storage, exportGroup, mask, initiatorsURIs, null, token);
}
}
return true;
}
use of com.emc.storageos.db.client.model.StringMap in project coprhd-controller by CoprHD.
the class VPlexVmaxMaskingOrchestrator method deleteOrRemoveVolumesFromExportMask.
@Override
public void deleteOrRemoveVolumesFromExportMask(URI arrayURI, URI exportGroupURI, URI exportMaskURI, List<URI> volumes, List<URI> initiatorURIs, String stepId) {
ExportTaskCompleter completer = null;
try {
completer = new ExportMaskOnlyRemoveVolumeCompleter(exportGroupURI, exportMaskURI, volumes, stepId);
WorkflowStepCompleter.stepExecuting(stepId);
StorageSystem array = _dbClient.queryObject(StorageSystem.class, arrayURI);
BlockStorageDevice device = _blockController.getDevice(array.getSystemType());
ExportMask exportMask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
// If the exportMask isn't found, or has been deleted, nothing to do.
if (exportMask == null || exportMask.getInactive()) {
_log.info(String.format("ExportMask %s inactive, returning success", exportMaskURI));
completer.ready(_dbClient);
return;
}
// Protect concurrent operations by locking {host, array} dupple.
// Lock will be released when workflow step completes.
List<String> lockKeys = ControllerLockingUtil.getHostStorageLockKeys(_dbClient, ExportGroupType.Host, StringSetUtil.stringSetToUriList(exportMask.getInitiators()), arrayURI);
getWorkflowService().acquireWorkflowStepLocks(stepId, lockKeys, LockTimeoutValue.get(LockType.VPLEX_BACKEND_EXPORT));
// Refresh the ExportMask
exportMask = refreshExportMask(array, device, exportMask);
// Determine if we're deleting the last volume in the mask.
StringMap maskVolumesMap = exportMask.getVolumes();
Set<String> remainingVolumes = new HashSet<String>();
List<URI> passedVolumesInMask = new ArrayList<>(volumes);
if (maskVolumesMap != null) {
remainingVolumes.addAll(maskVolumesMap.keySet());
}
for (URI volume : volumes) {
remainingVolumes.remove(volume.toString());
// are not in the mask to handle this condition.
if ((maskVolumesMap != null) && (!maskVolumesMap.keySet().contains(volume.toString()))) {
passedVolumesInMask.remove(volume);
}
}
InvokeTestFailure.internalOnlyInvokeTestFailure(InvokeTestFailure.ARTIFICIAL_FAILURE_043);
// None of the volumes is in the export mask, so we are done.
if (passedVolumesInMask.isEmpty()) {
_log.info("None of these volumes {} are in export mask {}", volumes, exportMask.forDisplay());
completer.ready(_dbClient);
return;
}
// If it is last volume and there are no existing volumes, delete the ExportMask.
if (remainingVolumes.isEmpty() && !exportMask.hasAnyExistingVolumes()) {
device.doExportDelete(array, exportMask, passedVolumesInMask, initiatorURIs, completer);
} else {
List<Initiator> initiators = null;
if (initiatorURIs != null && !initiatorURIs.isEmpty()) {
initiators = _dbClient.queryObject(Initiator.class, initiatorURIs);
}
device.doExportRemoveVolumes(array, exportMask, passedVolumesInMask, initiators, completer);
}
} catch (Exception ex) {
_log.error("Failed to delete or remove volumes to export mask for vmax: ", ex);
VPlexApiException vplexex = DeviceControllerExceptions.vplex.addStepsForCreateVolumesFailed(ex);
completer.error(_dbClient, vplexex);
}
}
Aggregations