use of com.emc.storageos.db.client.model.ExportPathParams in project coprhd-controller by CoprHD.
the class ExportPortRebalanceCompleter method updateVolumeExportPathParam.
/**
* Update export group pathParameters for the impacted volumes
* @param dbClient
*/
private void updateVolumeExportPathParam(DbClient dbClient) {
log.info("updating path param map.");
if (affectedExportGroups == null || affectedExportGroups.isEmpty()) {
// not export group is affected, return
return;
}
for (URI egURI : affectedExportGroups) {
ExportGroup exportGroup = dbClient.queryObject(ExportGroup.class, egURI);
log.info(String.format("Updating export group %s", exportGroup.getId().toString()));
StringMap volumes = exportGroup.getVolumes();
StringMap existingPathMap = exportGroup.getPathParameters();
List<URI> impactedVolumes = new ArrayList<URI>();
Map<URI, List<URI>> vpoolVolumes = new HashMap<URI, List<URI>>();
Map<URI, List<URI>> volumePath = new HashMap<URI, List<URI>>();
if (volumes == null || volumes.isEmpty()) {
continue;
}
Set<String> volSet = volumes.keySet();
for (String volId : volSet) {
URI volURI = URI.create(volId);
Volume volume = dbClient.queryObject(Volume.class, volURI);
if (volume == null || !volume.getStorageController().equals(systemURI)) {
continue;
}
log.info(String.format("Checking for the volume %s", volume.getLabel()));
// Check if the volume is in the pathMap
String pathParm = existingPathMap.get(volId);
if (pathParm != null) {
URI pathId = URI.create(pathParm);
List<URI> vols = volumePath.get(pathId);
if (vols == null) {
vols = new ArrayList<URI>();
volumePath.put(pathId, vols);
}
vols.add(volURI);
} else {
// check if the volumes' export path parameters are the same
URI vpId = volume.getVirtualPool();
List<URI> vols = vpoolVolumes.get(vpId);
if (vols == null) {
vols = new ArrayList<URI>();
vpoolVolumes.put(vpId, vols);
}
vols.add(volURI);
}
}
if (!vpoolVolumes.isEmpty()) {
log.info("check for vpool");
for (Map.Entry<URI, List<URI>> entry : vpoolVolumes.entrySet()) {
URI vpoolId = entry.getKey();
VirtualPool vpool = dbClient.queryObject(VirtualPool.class, vpoolId);
if (vpool != null) {
log.info(String.format("vpool path param : %d, %d, %d", vpool.getMinPaths(), vpool.getNumPaths(), vpool.getPathsPerInitiator()));
log.info(String.format("New path param %d, %d, %d", newPathParam.getMinPaths(), newPathParam.getMaxPaths(), newPathParam.getPathsPerInitiator()));
if (vpool.getMinPaths() != newPathParam.getMinPaths() || vpool.getNumPaths() != newPathParam.getMaxPaths() || vpool.getPathsPerInitiator() != newPathParam.getPathsPerInitiator()) {
impactedVolumes.addAll(entry.getValue());
}
}
}
}
Map<URI, List<URI>> portGroupVolumesMap = new HashMap<URI, List<URI>>();
if (!volumePath.isEmpty()) {
for (Map.Entry<URI, List<URI>> entry : volumePath.entrySet()) {
URI pathParamURI = entry.getKey();
ExportPathParams pathParam = dbClient.queryObject(ExportPathParams.class, pathParamURI);
if (pathParam == null || pathParam.getMinPaths() != newPathParam.getMinPaths() || pathParam.getMaxPaths() != newPathParam.getMaxPaths() || pathParam.getPathsPerInitiator() != newPathParam.getPathsPerInitiator()) {
// remove the path entry for this volume
for (URI volURI : entry.getValue()) {
exportGroup.removeFromPathParameters(volURI);
}
if (pathParam != null && !NullColumnValueGetter.isNullURI(pathParam.getPortGroup())) {
URI pgURI = pathParam.getPortGroup();
List<URI> pgVols = portGroupVolumesMap.get(pgURI);
if (pgVols == null) {
pgVols = new ArrayList<URI>();
}
pgVols.addAll(entry.getValue());
portGroupVolumesMap.put(pgURI, pgVols);
}
// If there are no more entries for the given ExportPathParam, mark it for deletion
if (!exportGroup.getPathParameters().containsValue(pathParamURI.toString()) && pathParam != null) {
dbClient.markForDeletion(pathParam);
}
impactedVolumes.addAll(entry.getValue());
}
}
}
if (!impactedVolumes.isEmpty()) {
if (portGroupVolumesMap.isEmpty()) {
ExportPathParams pathParam = createExportPathParams(dbClient, exportGroup, null);
for (URI volId : impactedVolumes) {
exportGroup.addToPathParameters(volId, pathParam.getId());
}
} else {
for (Map.Entry<URI, List<URI>> entry : portGroupVolumesMap.entrySet()) {
ExportPathParams pathParam = createExportPathParams(dbClient, exportGroup, entry.getKey());
for (URI volId : entry.getValue()) {
exportGroup.addToPathParameters(volId, pathParam.getId());
}
}
}
}
dbClient.updateObject(exportGroup);
}
}
use of com.emc.storageos.db.client.model.ExportPathParams 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;
}
use of com.emc.storageos.db.client.model.ExportPathParams in project coprhd-controller by CoprHD.
the class AbstractDefaultMaskingOrchestrator method generateExportMaskCreateWorkflow.
/**
* Creates an ExportMask Workflow that generates a new ExportMask in an existing ExportGroup.
*
* @param workflow
* workflow to add steps to
* @param previousStep
* previous step before these steps
* @param storage
* storage system
* @param exportGroup
* export group
* @param initiatorURIs
* initiators impacted by this operation
* @param volumeMap
* volumes
* @param token
* step ID
* @return URI of the new ExportMask
* @throws Exception
*/
public GenExportMaskCreateWorkflowResult generateExportMaskCreateWorkflow(Workflow workflow, String previousStep, StorageSystem storage, ExportGroup exportGroup, List<URI> initiatorURIs, Map<URI, Integer> volumeMap, String token) throws Exception {
URI exportGroupURI = exportGroup.getId();
URI storageURI = storage.getId();
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.");
}
// Create and initialize the Export Mask. This involves assigning and
// allocating the Storage Ports (targets).
ExportPathParams pathParams = _blockScheduler.calculateExportPathParamForVolumes(volumeMap.keySet(), exportGroup.getNumPaths(), storage.getId(), exportGroup.getId());
if (exportGroup.getType() != null) {
pathParams.setExportGroupType(exportGroup.getType());
}
if (exportGroup.getZoneAllInitiators()) {
pathParams.setAllowFewerPorts(true);
}
URI portGroupURI = null;
if (pathParams.getPortGroup() != null) {
portGroupURI = pathParams.getPortGroup();
StoragePortGroup portGroup = _dbClient.queryObject(StoragePortGroup.class, portGroupURI);
_log.info(String.format("port group is %s", portGroup.getLabel()));
List<URI> storagePorts = StringSetUtil.stringSetToUriList(portGroup.getStoragePorts());
if (!CollectionUtils.isEmpty(storagePorts)) {
pathParams.setStoragePorts(StringSetUtil.uriListToStringSet(storagePorts));
} else {
_log.error(String.format("The port group %s does not have any port members", portGroup));
throw DeviceControllerException.exceptions.noPortMembersInPortGroupError(portGroup.getLabel());
}
}
Map<URI, List<URI>> assignments = _blockScheduler.assignStoragePorts(storage, exportGroup, initiators, null, pathParams, volumeMap.keySet(), _networkDeviceController, exportGroup.getVirtualArray(), token);
List<URI> targets = BlockStorageScheduler.getTargetURIsFromAssignments(assignments);
String maskName = useComputedMaskName() ? getComputedExportMaskName(storage, exportGroup, initiators) : null;
// can be done differently
if (exportGroup.checkInternalFlags(Flag.RECOVERPOINT_JOURNAL)) {
maskName += "_journal";
}
ExportMask exportMask = ExportMaskUtils.initializeExportMask(storage, exportGroup, initiators, volumeMap, targets, assignments, maskName, _dbClient);
if (portGroupURI != null) {
exportMask.setPortGroup(portGroupURI);
}
List<BlockObject> vols = new ArrayList<BlockObject>();
for (URI boURI : volumeMap.keySet()) {
BlockObject bo = BlockObject.fetch(_dbClient, boURI);
vols.add(bo);
}
exportMask.addToUserCreatedVolumes(vols);
_dbClient.updateObject(exportMask);
// Make a new TaskCompleter for the exportStep. It has only one subtask.
// This is due to existing requirements in the doExportGroupCreate completion
// logic.
String maskingStep = workflow.createStepId();
ExportTaskCompleter exportTaskCompleter = new ExportMaskCreateCompleter(exportGroupURI, exportMask.getId(), initiatorURIs, volumeMap, maskingStep);
Workflow.Method maskingExecuteMethod = new Workflow.Method("doExportGroupCreate", storageURI, exportGroupURI, exportMask.getId(), volumeMap, initiatorURIs, targets, exportTaskCompleter);
Workflow.Method maskingRollbackMethod = new Workflow.Method("rollbackExportGroupCreate", storageURI, exportGroupURI, exportMask.getId(), maskingStep);
maskingStep = workflow.createStep(EXPORT_GROUP_MASKING_TASK, String.format("Creating mask %s (%s)", exportMask.getMaskName(), exportMask.getId().toString()), previousStep, storageURI, storage.getSystemType(), MaskingWorkflowEntryPoints.class, maskingExecuteMethod, maskingRollbackMethod, maskingStep);
return new GenExportMaskCreateWorkflowResult(exportMask.getId(), maskingStep);
}
use of com.emc.storageos.db.client.model.ExportPathParams in project coprhd-controller by CoprHD.
the class VnxMaskingOrchestrator method generateExportMaskAddInitiatorsWorkflow.
/*
* (non-Javadoc)
*
* @see
* com.emc.storageos.volumecontroller.impl.block.AbstractDefaultMaskingOrchestrator#
* generateExportMaskAddInitiatorsWorkflow(com.emc.
* storageos.workflow.Workflow, java.lang.String, com.emc.storageos.db.client.model.StorageSystem,
* com.emc.storageos.db.client.model.ExportGroup, com.emc.storageos.db.client.model.ExportMask, java.util.List,
* java.util.Set,
* java.lang.String)
*/
@Override
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);
}
// 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));
ExportPathParams pathParams = _blockScheduler.calculateExportPathParamForVolumes(volumeURIs, exportGroup.getNumPaths(), storage.getId(), exportGroup.getId());
if (exportGroup.getType() != null) {
pathParams.setExportGroupType(exportGroup.getType());
}
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;
}
use of com.emc.storageos.db.client.model.ExportPathParams in project coprhd-controller by CoprHD.
the class CreateExportGroupSchedulingThread method run.
@Override
public void run() {
_log.info("Starting scheduling for export group create thread...");
// Call out placementManager to get the recommendation for placement.
try {
// validate clients (initiators, hosts clusters) input and package them
// This call may take a long time.
List<URI> affectedInitiators = this.exportGroupService.validateClientsAndPopulate(exportGroup, project, virtualArray, storageMap.keySet(), clusters, hosts, initiators, volumeMap.keySet(), pathParam);
_log.info("Initiators {} will be used.", affectedInitiators);
// If ExportPathParameter block is present, and volumes are present, capture those arguments.
if (pathParam != null && !volumeMap.keySet().isEmpty()) {
ExportPathParams exportPathParam = exportGroupService.validateAndCreateExportPathParam(pathParam, exportGroup, volumeMap.keySet());
exportGroupService.addBlockObjectsToPathParamMap(volumeMap.keySet(), exportPathParam.getId(), exportGroup);
exportGroupService._dbClient.createObject(exportPathParam);
}
this.exportGroupService._dbClient.updateObject(exportGroup);
// If initiators list is empty or storage map is empty, there's no work to do (yet).
if (storageMap.isEmpty() || affectedInitiators.isEmpty()) {
this.exportGroupService._dbClient.ready(ExportGroup.class, taskRes.getResource().getId(), taskRes.getOpId());
return;
}
// push it to storage devices
BlockExportController exportController = this.exportGroupService.getExportController();
_log.info("createExportGroup request is submitted.");
exportController.exportGroupCreate(exportGroup.getId(), volumeMap, affectedInitiators, task);
} catch (Exception ex) {
if (ex instanceof ServiceCoded) {
this.exportGroupService._dbClient.error(ExportGroup.class, taskRes.getResource().getId(), taskRes.getOpId(), (ServiceCoded) ex);
} else {
this.exportGroupService._dbClient.error(ExportGroup.class, taskRes.getResource().getId(), taskRes.getOpId(), InternalServerErrorException.internalServerErrors.unexpectedErrorExportGroupPlacement(ex));
}
_log.error(ex.getMessage(), ex);
taskRes.setMessage(ex.getMessage());
// Mark the export group to be deleted
this.exportGroupService._dbClient.markForDeletion(exportGroup);
}
_log.info("Ending export group create scheduling thread...");
}
Aggregations