use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskAddInitiatorCompleter in project coprhd-controller by CoprHD.
the class VPlexDeviceController method addStepsForAddInitiators.
/**
* Add workflow steps for adding Initiators to a specific varray for the given VPlex.
*
* @param workflow
* -- Workflow steps go into
* @param vplex
* -- Storage system
* @param exportGroup
* -- ExportGroup operation invoked on
* @param varrayURI
* -- Virtual Array URI that the Initiators are in
* @param hostInitiatorURIs
* -- URIs of the Initiators
* @param initiators
* -- list of Initiator objects
* @param hostURI
* -- The hostURI
* @param previousStepId
* -- wait on this step if non-null
* @param opId
* -- step id for our operation
* @return StepId of last step generated
*/
private String addStepsForAddInitiators(Workflow workflow, StorageSystem vplex, ExportGroup exportGroup, URI varrayURI, List<URI> hostInitiatorURIs, List<Initiator> initiators, URI hostURI, String previousStepId, String opId) throws Exception {
String lastStepId = null;
URI vplexURI = vplex.getId();
URI exportURI = exportGroup.getId();
String initListStr = Joiner.on(',').join(hostInitiatorURIs);
// Find the ExportMask for my host.
ExportMask exportMask = VPlexUtil.getExportMaskForHostInVarray(_dbClient, exportGroup, hostURI, vplexURI, varrayURI);
if (exportMask == null) {
_log.info("No export mask found for hostURI: " + hostURI + " varrayURI: " + varrayURI);
Map<URI, Integer> volumeMap = ExportUtils.getExportGroupVolumeMap(_dbClient, vplex, exportGroup);
// Partition the Volumes by varray.
Map<URI, Set<URI>> varrayToVolumes = VPlexUtil.mapBlockObjectsToVarrays(_dbClient, volumeMap.keySet(), vplexURI, exportGroup);
// Filter the volumes by our Varray.
Map<URI, Integer> varrayVolumeMap = ExportMaskUtils.filterVolumeMap(volumeMap, varrayToVolumes.get(varrayURI));
// Create the ExportMask if there are volumes in this varray.
if (!varrayVolumeMap.isEmpty()) {
lastStepId = assembleExportMasksWorkflow(vplexURI, exportURI, varrayURI, hostInitiatorURIs, varrayVolumeMap, true, workflow, previousStepId, opId);
}
} else {
VPlexApiClient client = getVPlexAPIClient(_vplexApiFactory, vplex, _dbClient);
String vplexClusterName = VPlexUtil.getVplexClusterName(exportMask, vplexURI, client, _dbClient);
VPlexStorageViewInfo storageView = client.getStorageView(vplexClusterName, exportMask.getMaskName());
_log.info("Refreshing ExportMask {}", exportMask.getMaskName());
VPlexControllerUtils.refreshExportMask(_dbClient, storageView, exportMask, VPlexControllerUtils.getTargetPortToPwwnMap(client, vplexClusterName), _networkDeviceController);
if (exportMask.getVolumes() == null) {
// This can occur in Brownfield scenarios where we have not added any volumes yet to the HA side,
// CTRL10760
_log.info(String.format("No volumes in ExportMask %s (%s), so not adding initiators", exportMask.getMaskName(), exportMask.getId()));
return lastStepId;
}
_log.info(String.format("Adding initiators %s for host %s mask %s (%s)", getInitiatorsWwnsString(initiators), hostURI.toString(), exportMask.getMaskName(), exportMask.getId()));
// Calculate the path parameters for the volumes in this ExportMask
Collection<URI> volumeURIs = new HashSet<URI>();
if (exportMask.getVolumes() != null && !exportMask.getVolumes().isEmpty()) {
volumeURIs = (Collections2.transform(exportMask.getVolumes().keySet(), CommonTransformerFunctions.FCTN_STRING_TO_URI));
} else if (exportGroup.getVolumes() != null && !exportGroup.getVolumes().isEmpty()) {
// Hit this condition
// in CTRL-9944
// (unknown why)
_log.info(String.format("No volumes in ExportMask %s, using ExportGroup %s for ExportPathParam", exportMask.getId(), exportGroup.getId()));
Map<URI, Integer> volumeMap = ExportUtils.getExportGroupVolumeMap(_dbClient, vplex, exportGroup);
// Partition the Volumes by varray. Then use only the volumes in the requested varray.
Map<URI, Set<URI>> varrayToVolumes = VPlexUtil.mapBlockObjectsToVarrays(_dbClient, volumeMap.keySet(), vplexURI, exportGroup);
volumeURIs = varrayToVolumes.get(varrayURI);
} else {
_log.info(String.format("No volumes at all- using default path parameters: %s", exportMask.getId()));
}
ExportPathParams pathParams = _blockScheduler.calculateExportPathParamForVolumes(volumeURIs, exportGroup.getNumPaths(), exportMask.getStorageDevice(), exportGroup.getId());
if (exportGroup.getType() != null) {
pathParams.setExportGroupType(exportGroup.getType());
}
// Assign additional StoragePorts if needed.
Map<URI, List<URI>> assignments = _blockScheduler.assignStoragePorts(vplex, exportGroup, initiators, exportMask.getZoningMap(), pathParams, volumeURIs, _networkDeviceController, varrayURI, opId);
List<URI> newTargetURIs = BlockStorageScheduler.getTargetURIsFromAssignments(assignments);
// Build a list of StoragePort targets to remove during rollback. Do not remove existing storage ports during rollback.
List<URI> rollbackTargetURIs = new ArrayList<URI>();
for (URI target : newTargetURIs) {
if (exportMask.getStoragePorts().contains(target.toString())) {
// Skip the target port if it exists in the ViPR ExportMask
continue;
}
rollbackTargetURIs.add(target);
}
exportMask.addZoningMap(BlockStorageScheduler.getZoneMapFromAssignments(assignments));
_dbClient.updateObject(exportMask);
_log.info(String.format("Adding targets %s for host %s", newTargetURIs.toString(), hostURI.toString()));
// Create a Step to add the SAN Zone
String zoningStepId = workflow.createStepId();
Workflow.Method zoningMethod = zoneAddInitiatorStepMethod(vplexURI, exportURI, hostInitiatorURIs, varrayURI);
Workflow.Method zoningRollbackMethod = zoneRollbackMethod(exportURI, zoningStepId);
zoningStepId = workflow.createStep(ZONING_STEP, String.format("Zone initiator %s to ExportGroup %s(%s)", initListStr, exportGroup.getLabel(), exportURI), previousStepId, vplexURI, vplex.getSystemType(), this.getClass(), zoningMethod, zoningRollbackMethod, zoningStepId);
// Create a Step to add the initiator to the Storage View
String message = String.format("initiators %s to StorageView %s", initListStr, exportGroup.getGeneratedName());
ExportMask sharedExportMask = VPlexUtil.getSharedExportMaskInDb(exportGroup, vplexURI, _dbClient, varrayURI, null, null);
boolean shared = false;
if (null != sharedExportMask && sharedExportMask.getId().equals(exportMask.getId())) {
shared = true;
}
String addInitStep = workflow.createStepId();
ExportMaskAddInitiatorCompleter addInitCompleter = new ExportMaskAddInitiatorCompleter(exportURI, exportMask.getId(), hostInitiatorURIs, newTargetURIs, addInitStep);
Workflow.Method addToViewMethod = storageViewAddInitiatorsMethod(vplexURI, exportURI, exportMask.getId(), hostInitiatorURIs, newTargetURIs, shared, addInitCompleter);
Workflow.Method addToViewRollbackMethod = storageViewAddInitiatorsRollbackMethod(vplexURI, exportURI, exportMask.getId(), hostInitiatorURIs, rollbackTargetURIs, addInitStep);
lastStepId = workflow.createStep("storageView", "Add " + message, zoningStepId, vplexURI, vplex.getSystemType(), this.getClass(), addToViewMethod, addToViewRollbackMethod, addInitStep);
}
return lastStepId;
}
use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskAddInitiatorCompleter in project coprhd-controller by CoprHD.
the class VPlexDeviceController method portRebalance.
@Override
public void portRebalance(URI vplex, URI exportGroupURI, URI varray, URI exportMaskURI, Map<URI, List<URI>> adjustedPaths, Map<URI, List<URI>> removedPaths, boolean isAdd, String stepId) throws Exception {
// Retrieve the ExportGroup and ExportMask and validate
ExportGroup exportGroup = _dbClient.queryObject(ExportGroup.class, exportGroupURI);
ExportMask exportMask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
if (exportGroup == null || exportMask == null || exportGroup.getInactive() || exportMask.getInactive() || !exportGroup.hasMask(exportMaskURI)) {
String reason = String.format("Bad exportGroup %s or exportMask %s", exportGroupURI, exportMaskURI);
_log.error(reason);
ServiceCoded coded = WorkflowException.exceptions.workflowConstructionError(reason);
WorkflowStepCompleter.stepFailed(stepId, coded);
return;
}
// Check if the ExportMask is in the desired varray (in cross-coupled ExportGroups)
if (!ExportMaskUtils.exportMaskInVarray(_dbClient, exportMask, varray)) {
_log.info(String.format("ExportMask %s (%s) not in specified varray %s", exportMask.getMaskName(), exportMask.getId(), varray));
WorkflowStepCompleter.stepSucceeded(stepId, String.format("No operation done: Mask not in specified varray %s", varray));
return;
}
// Refresh the ExportMask so we have the latest data.
StorageSystem vplexSystem = getDataObject(StorageSystem.class, vplex, _dbClient);
VPlexApiClient client = getVPlexAPIClient(_vplexApiFactory, vplex, _dbClient);
String vplexClusterName = VPlexUtil.getVplexClusterName(exportMask, vplex, client, _dbClient);
VPlexStorageViewInfo storageView = client.getStorageView(vplexClusterName, exportMask.getMaskName());
_log.info("Processing and Refreshing ExportMask {}", exportMask.getMaskName());
Map<String, String> targetPortToPwwnMap = VPlexControllerUtils.getTargetPortToPwwnMap(client, vplexClusterName);
VPlexControllerUtils.refreshExportMask(_dbClient, storageView, exportMask, targetPortToPwwnMap, _networkDeviceController);
// Determine hosts in ExportMask
Set<URI> hostsInExportMask = new HashSet<URI>();
Set<String> hostNames = ExportMaskUtils.getHostNamesInMask(exportMask, _dbClient);
Set<Initiator> initiatorsInMask = ExportMaskUtils.getInitiatorsForExportMask(_dbClient, exportMask, null);
for (Initiator initiator : initiatorsInMask) {
if (initiator.getHost() != null) {
hostsInExportMask.add(initiator.getHost());
}
}
boolean sharedMask = (hostsInExportMask.size() > 1);
if (isAdd) {
// Processing added paths only
Workflow workflow = _workflowService.getNewWorkflow(this, "portRebalance", false, stepId);
// Determine initiators and targets to be added.
// These are initiators not in mask that are in a host in the mask.
// Earlier versions of the Vplex code may not have had all the initiators in the mask, as
// earlier code only put initiators in the Storage View for which ports were added.
// Targets to be added may be on existing initiators or newly added initiators.
List<URI> initiatorsToAdd = new ArrayList<URI>();
List<URI> targetsToAdd = new ArrayList<URI>();
for (URI initiatorURI : adjustedPaths.keySet()) {
if (!exportMask.hasInitiator(initiatorURI.toString())) {
// Initiator not in ExportMask
Initiator initiator = _dbClient.queryObject(Initiator.class, initiatorURI);
if (initiator != null && !initiator.getInactive()) {
if (hostsInExportMask.contains(initiator.getHost())) {
initiatorsToAdd.add(initiatorURI);
for (URI targetURI : adjustedPaths.get(initiatorURI)) {
if (!exportMask.hasTargets(Arrays.asList(targetURI)) && !targetsToAdd.contains(targetURI)) {
targetsToAdd.add(targetURI);
}
}
}
}
} else {
// Initiator already in ExportMask, look for additional targets
for (URI targetURI : adjustedPaths.get(initiatorURI)) {
if (!exportMask.hasTargets(Arrays.asList(targetURI)) && !targetsToAdd.contains(targetURI)) {
targetsToAdd.add(targetURI);
}
}
}
}
_log.info("Targets to add: " + targetsToAdd.toString());
_log.info("Initiators to add: " + initiatorsToAdd.toString());
// Invoke either storageViewAddInitiators if there are initiators to be added (it will add targets also),
// or storageViewAddStoragePorts if no initiators to be added (which adds only targets).
Workflow.Method addPathsMethod = null;
if (!initiatorsToAdd.isEmpty() || !targetsToAdd.isEmpty()) {
String addInitiatorStepId = workflow.createStepId();
ExportMaskAddInitiatorCompleter completer = new ExportMaskAddInitiatorCompleter(exportGroupURI, exportMaskURI, initiatorsToAdd, targetsToAdd, addInitiatorStepId);
;
if (!initiatorsToAdd.isEmpty()) {
addPathsMethod = storageViewAddInitiatorsMethod(vplex, exportGroupURI, exportMaskURI, initiatorsToAdd, targetsToAdd, sharedMask, completer);
} else if (!targetsToAdd.isEmpty()) {
addPathsMethod = storageViewAddStoragePortsMethod(vplex, exportGroupURI, exportMaskURI, targetsToAdd, completer);
}
String description = String.format("Adding paths to ExportMask %s Hosts %s", exportMask.getMaskName(), hostNames.toString());
workflow.createStep("addPaths", description, null, vplex, vplexSystem.getSystemType(), this.getClass(), addPathsMethod, null, false, addInitiatorStepId);
ExportMaskAddPathsCompleter workflowCompleter = new ExportMaskAddPathsCompleter(exportGroupURI, exportMaskURI, stepId);
workflow.executePlan(workflowCompleter, description + " completed successfully");
return;
}
} else {
// Processing the paths to be removed only, Paths not in the removedPaths map will be retained.
// Note that we only remove ports (targets), never initiators.
Workflow workflow = _workflowService.getNewWorkflow(this, "portRebalance", false, stepId);
// Compute the targets to be removed.
Set<URI> targetsToBeRemoved = ExportMaskUtils.getAllPortsInZoneMap(removedPaths);
Collection<URI> targetsInMask = Collections2.transform(exportMask.getStoragePorts(), CommonTransformerFunctions.FCTN_STRING_TO_URI);
targetsToBeRemoved.retainAll(targetsInMask);
Set<URI> targetsToBeRetained = ExportMaskUtils.getAllPortsInZoneMap(adjustedPaths);
targetsToBeRemoved.removeAll(targetsToBeRetained);
List<URI> portsToBeRemoved = new ArrayList<URI>(targetsToBeRemoved);
_log.info("Targets to be removed: " + portsToBeRemoved.toString());
// Call storageViewRemoveStoragePorts to remove any necessary targets.
Workflow.Method removePathsMethod = null;
if (!portsToBeRemoved.isEmpty()) {
String removeInitiatorStepId = workflow.createStepId();
removePathsMethod = storageViewRemoveStoragePortsMethod(vplex, exportGroupURI, exportMaskURI, portsToBeRemoved, null);
String description = String.format("Removing paths to ExportMask %s Hosts %s", exportMask.getMaskName(), hostNames.toString());
workflow.createStep("removePaths", description, null, vplex, vplexSystem.getSystemType(), this.getClass(), removePathsMethod, null, false, removeInitiatorStepId);
ExportMaskRemovePathsCompleter workflowCompleter = new ExportMaskRemovePathsCompleter(exportGroupURI, exportMaskURI, stepId);
workflowCompleter.setRemovedStoragePorts(portsToBeRemoved);
workflow.executePlan(workflowCompleter, description + " completed successfully");
return;
}
}
// Apparently nothing to do, return success
WorkflowStepCompleter.stepSucceeded(stepId, "No operation performed on VPLEX mask");
}
use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskAddInitiatorCompleter in project coprhd-controller by CoprHD.
the class VPlexDeviceController method addStepsForExportMaskUpdate.
/**
* Handles adding ExportMask updates into the export workflow.
*
* @param exportGroupUri
* the ViPR ExportGroup in question
* @param blockObjectMap
* the map of URIs to block volumes for export
* @param workflow
* the controller Workflow
* @param vplexSystem
* a StorageSystem objet representing the VPLEX
* @param exportMasksToUpdateOnDeviceWithInitiators
* map of ExportMasks to update to initiators
* @param exportMasksToUpdateOnDeviceWithStoragePorts
* map of ExportMasks to update to storage ports
* @param storageViewStepId
* the current workflow step id, to be updated on return
* @param exportMask
* the ExportMask object to be updated
* @param sharedVplexExportMask
* boolean that indicates whether passed exportMask is shared for multiple host
* @return
*/
private String addStepsForExportMaskUpdate(URI exportGroupUri, Map<URI, Integer> blockObjectMap, Workflow workflow, StorageSystem vplexSystem, Map<URI, List<Initiator>> exportMasksToUpdateOnDeviceWithInitiators, Map<URI, List<URI>> exportMasksToUpdateOnDeviceWithStoragePorts, String storageViewStepId, ExportMask exportMask, boolean sharedVplexExportMask) {
_log.info("adding steps to update export mask: " + exportMask.getMaskName());
String addVolumeStepId = workflow.createStepId();
// Add a step to update export mask on the VPlex.
Workflow.Method storageViewExecuteMethod = new Workflow.Method(STORAGE_VIEW_ADD_VOLUMES_METHOD, vplexSystem.getId(), exportGroupUri, exportMask.getId(), blockObjectMap);
Workflow.Method storageViewRollbackMethod = storageViewAddVolumesRollbackMethod(vplexSystem.getId(), exportGroupUri, exportMask.getId(), new ArrayList<URI>(blockObjectMap.keySet()), addVolumeStepId);
storageViewStepId = workflow.createStep("storageView", String.format("Updating VPLEX Storage View for ExportGroup %s Mask %s", exportGroupUri, exportMask.getMaskName()), storageViewStepId, vplexSystem.getId(), vplexSystem.getSystemType(), this.getClass(), storageViewExecuteMethod, storageViewRollbackMethod, addVolumeStepId);
if (exportMasksToUpdateOnDeviceWithInitiators.get(exportMask.getId()) != null) {
List<Initiator> initiatorsToAdd = exportMasksToUpdateOnDeviceWithInitiators.get(exportMask.getId());
List<URI> initiatorURIs = new ArrayList<URI>();
for (Initiator initiator : initiatorsToAdd) {
initiatorURIs.add(initiator.getId());
}
String addInitStep = workflow.createStepId();
ExportMaskAddInitiatorCompleter completer = new ExportMaskAddInitiatorCompleter(exportGroupUri, exportMask.getId(), initiatorURIs, new ArrayList<URI>(), addInitStep);
Workflow.Method addInitiatorMethod = storageViewAddInitiatorsMethod(vplexSystem.getId(), exportGroupUri, exportMask.getId(), initiatorURIs, null, sharedVplexExportMask, completer);
Workflow.Method initiatorRollback = storageViewAddInitiatorsRollbackMethod(vplexSystem.getId(), exportGroupUri, exportMask.getId(), initiatorURIs, null, addInitStep);
storageViewStepId = workflow.createStep("storageView", String.format("Updating VPLEX Storage View Initiators for ExportGroup %s Mask %s", exportGroupUri, exportMask.getMaskName()), storageViewStepId, vplexSystem.getId(), vplexSystem.getSystemType(), this.getClass(), addInitiatorMethod, initiatorRollback, addInitStep);
}
if (exportMasksToUpdateOnDeviceWithStoragePorts.containsKey(exportMask.getId())) {
List<URI> storagePortURIsToAdd = exportMasksToUpdateOnDeviceWithStoragePorts.get(exportMask.getId());
String addPortStep = workflow.createStepId();
ExportMaskAddInitiatorCompleter completer = new ExportMaskAddInitiatorCompleter(exportGroupUri, exportMask.getId(), new ArrayList<URI>(), storagePortURIsToAdd, addPortStep);
// Create a Step to add storage ports to the Storage View
Workflow.Method addPortsToViewMethod = storageViewAddStoragePortsMethod(vplexSystem.getId(), exportGroupUri, exportMask.getId(), storagePortURIsToAdd, completer);
Workflow.Method addToViewRollbackMethod = storageViewAddStoragePortsRollbackMethod(vplexSystem.getId(), exportGroupUri, exportMask.getId(), storagePortURIsToAdd, addPortStep);
storageViewStepId = workflow.createStep("storageView", String.format("Updating VPLEX Storage View StoragePorts for ExportGroup %s Mask %s", exportGroupUri, exportMask.getMaskName()), storageViewStepId, vplexSystem.getId(), vplexSystem.getSystemType(), this.getClass(), addPortsToViewMethod, addToViewRollbackMethod, addPortStep);
}
return storageViewStepId;
}
use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskAddInitiatorCompleter in project coprhd-controller by CoprHD.
the class VPlexDeviceController method increaseMaxPaths.
@Override
public void increaseMaxPaths(Workflow workflow, StorageSystem vplex, ExportGroup exportGroup, ExportMask exportMask, List<URI> newInitiators, String token) throws Exception {
// Allocate any new ports that are required for the initiators
// and update the zoning map in the exportMask.
List<Initiator> initiators = _dbClient.queryObject(Initiator.class, newInitiators);
Collection<URI> volumeURIs = (Collections2.transform(exportMask.getVolumes().keySet(), CommonTransformerFunctions.FCTN_STRING_TO_URI));
ExportPathParams pathParams = _blockScheduler.calculateExportPathParamForVolumes(volumeURIs, exportGroup.getNumPaths(), vplex.getId(), exportGroup.getId());
if (exportGroup.getType() != null) {
pathParams.setExportGroupType(exportGroup.getType());
}
// Determine the Varray for the targets. Default to ExportGroup.virtualArray
URI varrayURI = exportGroup.getVirtualArray();
if (exportGroup.hasAltVirtualArray(vplex.getId().toString())) {
URI altVarrayURI = URI.create(exportGroup.getAltVirtualArrays().get(vplex.getId().toString()));
if (ExportMaskUtils.exportMaskInVarray(_dbClient, exportMask, altVarrayURI)) {
// If the targets match the alternate varray, use that instead.
varrayURI = altVarrayURI;
}
}
// Assign additional storage port(s).
Map<URI, List<URI>> assignments = _blockScheduler.assignStoragePorts(vplex, exportGroup, initiators, exportMask.getZoningMap(), pathParams, volumeURIs, _networkDeviceController, varrayURI, token);
List<URI> newTargets = BlockStorageScheduler.getTargetURIsFromAssignments(assignments);
exportMask.addZoningMap(BlockStorageScheduler.getZoneMapFromAssignments(assignments));
_dbClient.updateObject(exportMask);
if (newTargets.isEmpty() == false) {
// Only include initiators that were assigned ports in the Storage View.
// If we include any inititators that are not assigned and zoned to ports,
// creation or update of the Storage View will fail because we won't be
// able to register those initiators.
List<URI> storageViewInitiators = newInitiators;
// Create a Step to add the initiator to the Storage View
String message = String.format("adding initiators %s to StorageView %s", storageViewInitiators.toString(), exportGroup.getGeneratedName());
ExportMask sharedExportMask = VPlexUtil.getSharedExportMaskInDb(exportGroup, vplex.getId(), _dbClient, varrayURI, null, null);
boolean shared = false;
if (null != sharedExportMask && sharedExportMask.getId().equals(exportMask.getId())) {
shared = true;
}
String addInitStep = workflow.createStepId();
ExportMaskAddInitiatorCompleter completer = new ExportMaskAddInitiatorCompleter(exportGroup.getId(), exportMask.getId(), storageViewInitiators, new ArrayList<URI>(), addInitStep);
Workflow.Method addToViewMethod = storageViewAddInitiatorsMethod(vplex.getId(), exportGroup.getId(), exportMask.getId(), storageViewInitiators, null, shared, completer);
Workflow.Method addToViewRollbackMethod = storageViewAddInitiatorsRollbackMethod(vplex.getId(), exportGroup.getId(), exportMask.getId(), storageViewInitiators, null, addInitStep);
workflow.createStep(STORAGE_VIEW_ADD_INITS_METHOD, message, null, vplex.getId(), vplex.getSystemType(), this.getClass(), addToViewMethod, addToViewRollbackMethod, addInitStep);
// Create a Step to add storage ports to the Storage View
String addPortStep = workflow.createStepId();
ExportMaskAddInitiatorCompleter portCompleter = new ExportMaskAddInitiatorCompleter(exportGroup.getId(), exportMask.getId(), new ArrayList<URI>(), newTargets, addPortStep);
Workflow.Method addPortsToViewMethod = storageViewAddStoragePortsMethod(vplex.getId(), exportGroup.getId(), exportMask.getId(), newTargets, portCompleter);
Workflow.Method addPortsToViewRollbackMethod = storageViewAddStoragePortsRollbackMethod(vplex.getId(), exportGroup.getId(), exportMask.getId(), newTargets, addPortStep);
workflow.createStep(STORAGE_VIEW_ADD_STORAGE_PORTS_METHOD, String.format("Adding storage ports %s to VPLEX storage View %s", Joiner.on(", ").join(newTargets), exportGroup.getGeneratedName()), addInitStep, vplex.getId(), vplex.getSystemType(), this.getClass(), addPortsToViewMethod, addPortsToViewRollbackMethod, addPortStep);
List<ExportMask> exportMasks = ExportMaskUtils.getExportMasks(_dbClient, exportGroup, vplex.getId());
Map<URI, List<URI>> maskToInitiatorsMap = new HashMap<URI, List<URI>>();
Set<URI> zoningInitiators = new HashSet<>();
for (ExportMask mask : exportMasks) {
boolean sharedMask = false;
if (sharedExportMask != null) {
if (sharedExportMask.getId().equals(mask.getId())) {
sharedMask = true;
}
}
maskToInitiatorsMap.put(mask.getId(), new ArrayList<URI>());
Set<URI> exportMaskHosts = VPlexUtil.getExportMaskHosts(_dbClient, mask, sharedMask);
// Only add initiators to this ExportMask that are on the host of the Export Mask
for (Initiator initiator : initiators) {
if (exportMaskHosts.contains(VPlexUtil.getInitiatorHost(initiator))) {
maskToInitiatorsMap.get(mask.getId()).add(initiator.getId());
zoningInitiators.add(initiator.getId());
}
}
}
// Create a Step to add the SAN Zone
String zoningStepId = workflow.createStepId();
Workflow.Method zoningMethod = _networkDeviceController.zoneExportAddInitiatorsMethod(exportGroup.getId(), maskToInitiatorsMap);
List<NetworkZoningParam> zoningParams = NetworkZoningParam.convertExportMaskInitiatorMapsToNetworkZoningParam(exportGroup.getId(), maskToInitiatorsMap, _dbClient);
Workflow.Method zoningRollbackMethod = _networkDeviceController.zoneExportRemoveInitiatorsMethod(zoningParams);
zoningStepId = workflow.createStep(ZONING_STEP, String.format("Zone initiator %s to ExportGroup %s(%s)", Joiner.on(", ").join(zoningInitiators), exportGroup.getLabel(), exportGroup.getId()), addPortStep, vplex.getId(), vplex.getSystemType(), _networkDeviceController.getClass(), zoningMethod, zoningRollbackMethod, zoningStepId);
}
}
use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskAddInitiatorCompleter in project coprhd-controller by CoprHD.
the class AbstractDefaultMaskingOrchestrator method generateExportMaskAddInitiatorsWorkflow.
/**
* Generate workflow steps to add initiators to an export mask
*
* @param workflow
* workflow
* @param previousStep
* previous step ID
* @param storage
* storage device
* @param exportGroup
* export group
* @param exportMask
* export mask
* @param initiatorURIs
* initiator list
* @param newVolumeURIs
* new volume IDs
* @param token
* step ID
* @return step ID
* @throws Exception
*/
public String generateExportMaskAddInitiatorsWorkflow(Workflow workflow, String previousStep, StorageSystem storage, ExportGroup exportGroup, ExportMask exportMask, List<URI> initiatorURIs, Set<URI> newVolumeURIs, String token) throws Exception {
URI exportGroupURI = exportGroup.getId();
URI exportMaskURI = exportMask.getId();
URI storageURI = storage.getId();
List<URI> newTargetURIs = new ArrayList<>();
List<Initiator> initiators = null;
if (initiatorURIs != null && !initiatorURIs.isEmpty()) {
initiators = _dbClient.queryObject(Initiator.class, initiatorURIs);
} else {
_log.error("Internal Error: Need to add the initiatorURIs to the call that assembles this step.");
}
// Allocate any new ports that are required for the initiators
// and update the zoning map in the exportMask.
Collection<URI> volumeURIs = (exportMask.getVolumes() == null) ? newVolumeURIs : (Collection<URI>) (Collections2.transform(exportMask.getVolumes().keySet(), CommonTransformerFunctions.FCTN_STRING_TO_URI));
if (null == volumeURIs) {
volumeURIs = new ArrayList<URI>();
}
ExportPathParams pathParams = _blockScheduler.calculateExportPathParamForVolumes(volumeURIs, exportGroup.getNumPaths(), storageURI, exportGroupURI);
if (exportGroup.getType() != null) {
pathParams.setExportGroupType(exportGroup.getType());
}
URI pgURI = exportMask.getPortGroup();
if (!NullColumnValueGetter.isNullURI(pgURI)) {
StoragePortGroup portGroup = _dbClient.queryObject(StoragePortGroup.class, pgURI);
if (!portGroup.getInactive() && !portGroup.getMutable()) {
_log.info(String.format("Using the port group %s for allocate ports for adding initiators", portGroup.getNativeGuid()));
pathParams.setStoragePorts(portGroup.getStoragePorts());
}
}
Map<URI, List<URI>> assignments = _blockScheduler.assignStoragePorts(storage, exportGroup, initiators, exportMask.getZoningMap(), pathParams, volumeURIs, _networkDeviceController, exportGroup.getVirtualArray(), token);
newTargetURIs = BlockStorageScheduler.getTargetURIsFromAssignments(assignments);
exportMask.addZoningMap(BlockStorageScheduler.getZoneMapFromAssignments(assignments));
_dbClient.updateObject(exportMask);
String maskingStep = workflow.createStepId();
ExportTaskCompleter exportTaskCompleter = new ExportMaskAddInitiatorCompleter(exportGroupURI, exportMask.getId(), initiatorURIs, newTargetURIs, maskingStep);
Workflow.Method maskingExecuteMethod = new Workflow.Method("doExportGroupAddInitiators", storageURI, exportGroupURI, exportMaskURI, new ArrayList<URI>(volumeURIs), initiatorURIs, newTargetURIs, exportTaskCompleter);
Workflow.Method rollbackMethod = new Workflow.Method("rollbackExportGroupAddInitiators", storageURI, exportGroupURI, exportMaskURI, new ArrayList<URI>(volumeURIs), initiatorURIs, maskingStep);
maskingStep = workflow.createStep(EXPORT_GROUP_MASKING_TASK, String.format("Adding initiators to mask %s (%s)", exportMask.getMaskName(), exportMask.getId().toString()), previousStep, storageURI, storage.getSystemType(), MaskingWorkflowEntryPoints.class, maskingExecuteMethod, rollbackMethod, maskingStep);
return maskingStep;
}
Aggregations