use of com.emc.storageos.db.client.model.StringSetMap in project coprhd-controller by CoprHD.
the class HDSExportOperations method removeVolumes.
@Override
public void removeVolumes(StorageSystem storage, URI exportMaskURI, List<URI> volumes, List<Initiator> initiatorList, TaskCompleter taskCompleter) throws DeviceControllerException {
log.info("{} removeVolumes START...", storage.getSerialNumber());
try {
log.info("removeVolumes: Export mask id: {}", exportMaskURI);
log.info("removeVolumes: volumes: {}", Joiner.on(',').join(volumes));
if (initiatorList != null) {
log.info("removeVolumes: impacted initiators: {}", Joiner.on(",").join(initiatorList));
}
HDSApiClient hdsApiClient = hdsApiFactory.getClient(HDSUtils.getHDSServerManagementServerInfo(storage), storage.getSmisUserName(), storage.getSmisPassword());
HDSApiExportManager exportMgr = hdsApiClient.getHDSApiExportManager();
String systemObjectID = HDSUtils.getSystemObjectID(storage);
ExportMask exportMask = dbClient.queryObject(ExportMask.class, exportMaskURI);
if (CollectionUtils.isEmpty(exportMask.getDeviceDataMap())) {
log.info("HSD's are not found in the exportMask {} device DataMap.", exportMask.getId());
taskCompleter.ready(dbClient);
}
// Get the context from the task completer, in case this is a rollback.
boolean isRollback = WorkflowService.getInstance().isStepInRollbackState(taskCompleter.getOpId());
ExportMaskValidationContext ctx = new ExportMaskValidationContext();
ctx.setStorage(storage);
ctx.setExportMask(exportMask);
ctx.setBlockObjects(volumes, dbClient);
ctx.setInitiators(initiatorList);
// Allow exceptions to be thrown when not rolling back
ctx.setAllowExceptions(!isRollback);
AbstractHDSValidator removeVolumeFromMaskValidator = (AbstractHDSValidator) validator.removeVolumes(ctx);
removeVolumeFromMaskValidator.validate();
StringSetMap deviceDataMap = exportMask.getDeviceDataMap();
Set<String> hsdList = deviceDataMap.keySet();
List<Path> pathObjectIdList = new ArrayList<Path>();
if (null == hsdList || hsdList.isEmpty()) {
throw HDSException.exceptions.notAbleToFindHostStorageDomain(systemObjectID);
}
if (null != exportMask && !exportMask.getInactive()) {
for (String hsdObjectId : hsdList) {
HostStorageDomain hsd = exportMgr.getHostStorageDomain(systemObjectID, hsdObjectId);
if (null == hsd) {
log.warn("Couldn't find the HSD {} to remove volume from ExportMask", hsdObjectId);
continue;
}
if (null != hsd.getPathList() && !hsd.getPathList().isEmpty()) {
pathObjectIdList.addAll(getPathObjectIdsFromHsd(hsd, volumes));
}
}
if (!pathObjectIdList.isEmpty()) {
hdsApiClient.getHDSBatchApiExportManager().deleteLUNPathsFromStorageSystem(systemObjectID, pathObjectIdList, storage.getModel());
} else {
log.info("No volumes found on system: {}", systemObjectID);
}
}
// Update the status after deleting the volume from all HSD's.
taskCompleter.ready(dbClient);
} catch (Exception e) {
log.error(String.format("removeVolume failed - maskURI: %s", exportMaskURI.toString()), e);
ServiceError serviceError = DeviceControllerException.errors.jobFailedMsg(e.getMessage(), e);
taskCompleter.error(dbClient, serviceError);
}
log.info("{} removeVolumes END...", storage.getSerialNumber());
}
use of com.emc.storageos.db.client.model.StringSetMap in project coprhd-controller by CoprHD.
the class HDSExportOperations method addInitiators.
@Override
public void addInitiators(StorageSystem storage, URI exportMaskURI, List<URI> volumeURIs, List<Initiator> initiators, List<URI> targetURIList, TaskCompleter taskCompleter) throws DeviceControllerException {
log.info("{} addInitiator START...", storage.getSerialNumber());
HDSApiClient hdsApiClient = null;
String systemObjectID = null;
List<HostStorageDomain> hsdsToCreate = null;
List<HostStorageDomain> hsdsWithInitiators = null;
try {
log.info("addInitiator: Export mask id: {}", exportMaskURI);
if (volumeURIs != null) {
log.info("addInitiator: volumes : {}", Joiner.on(',').join(volumeURIs));
}
log.info("addInitiator: initiators : {}", Joiner.on(',').join(initiators));
log.info("addInitiator: targets : {}", Joiner.on(",").join(targetURIList));
hdsApiClient = hdsApiFactory.getClient(HDSUtils.getHDSServerManagementServerInfo(storage), storage.getSmisUserName(), storage.getSmisPassword());
HDSApiExportManager exportMgr = hdsApiClient.getHDSApiExportManager();
systemObjectID = HDSUtils.getSystemObjectID(storage);
ExportMask exportMask = dbClient.queryObject(ExportMask.class, exportMaskURI);
List<StoragePort> ports = dbClient.queryObject(StoragePort.class, targetURIList, true);
if (checkIfMixedTargetPortTypeSelected(ports)) {
log.error("Unsupported Host as it has both FC & iSCSI Initiators");
throw HDSException.exceptions.unsupportedConfigurationFoundInHost();
}
// @TODO register new initiators by adding them to host on HiCommand DM.
// Currently, HiCommand is not supporting this. Need to see how we can handle.
String hostName = getHostNameForInitiators(initiators);
String hostMode = null, hostModeOption = null;
Pair<String, String> hostModeInfo = getHostModeInfo(storage, initiators);
if (hostModeInfo != null) {
hostMode = hostModeInfo.first;
hostModeOption = hostModeInfo.second;
}
if (targetURIList != null && !targetURIList.isEmpty()) {
Set<URI> newTargetPorts = new HashSet<>(targetURIList);
Set<URI> existingTargetPortsInMask = new HashSet<>();
if (exportMask.getStoragePorts() != null) {
existingTargetPortsInMask = new HashSet<>(targetURIList);
Collection<URI> targetPorts = Collections2.transform(exportMask.getStoragePorts(), CommonTransformerFunctions.FCTN_STRING_TO_URI);
existingTargetPortsInMask.retainAll(targetPorts);
}
newTargetPorts.removeAll(existingTargetPortsInMask);
log.info("list of new storage target ports {}", newTargetPorts);
log.info("list of existing storage target ports available in export masks {}", existingTargetPortsInMask);
// Case 1 is handled here for the new initiators & new target ports.
if (!newTargetPorts.isEmpty()) {
// If the HLU's are already configured on this target port, then an exception is thrown.
// User should make sure that all volumes should have same HLU across all target HSD's.
VolumeURIHLU[] volumeURIHLUs = getVolumeURIHLUFromExportMask(exportMask);
if (0 < volumeURIHLUs.length) {
List<URI> portList = new ArrayList<>(newTargetPorts);
hsdsToCreate = processTargetPortsToFormHSDs(hdsApiClient, storage, portList, hostName, exportMask, hostModeInfo, systemObjectID);
// Step 1: Create all HSD's using batch operation.
List<HostStorageDomain> hsdResponseList = hdsApiClient.getHDSBatchApiExportManager().addHostStorageDomains(systemObjectID, hsdsToCreate, storage.getModel());
if (null == hsdResponseList || hsdResponseList.isEmpty()) {
log.error("Batch HSD creation failed to add new initiators. Aborting operation...");
throw HDSException.exceptions.notAbleToAddHSD(storage.getSerialNumber());
}
// Step 2: Add initiators to all HSD's.
Iterator<StoragePort> storagePortIterator = dbClient.queryIterativeObjects(StoragePort.class, newTargetPorts);
List<StoragePort> stPortList = new ArrayList<>();
while (storagePortIterator.hasNext()) {
StoragePort stPort = storagePortIterator.next();
if (stPort != null && !stPort.getInactive()) {
stPortList.add(stPort);
}
}
hsdsWithInitiators = executeBatchHSDAddInitiatorsCommand(hdsApiClient, systemObjectID, hsdResponseList, stPortList, initiators, storage.getModel());
// Step 3: Add volumes to all HSD's.
List<Path> allHSDPaths = executeBatchHSDAddVolumesCommand(hdsApiClient, systemObjectID, hsdsWithInitiators, volumeURIHLUs, storage.getModel());
if (null != allHSDPaths && !allHSDPaths.isEmpty()) {
updateExportMaskDetailInDB(hsdsWithInitiators, allHSDPaths, exportMask, storage, volumeURIHLUs);
}
} else {
log.info("There are no volumes on this exportmask: {} to add to new initiator", exportMaskURI);
}
}
// existing HSD to access the volumes already exported in the exportmask.
if (!existingTargetPortsInMask.isEmpty()) {
// Step 1: Collect all HSDs from export mask
StringSetMap deviceDataMap = exportMask.getDeviceDataMap();
if (null != deviceDataMap && !deviceDataMap.isEmpty()) {
List<HostStorageDomain> hsdResponseList = new ArrayList<>();
Set<String> hsdObjectIdSet = deviceDataMap.keySet();
for (String hsdObjectId : hsdObjectIdSet) {
HostStorageDomain hsd = exportMgr.getHostStorageDomain(systemObjectID, hsdObjectId);
if (null == hsd) {
throw HDSException.exceptions.notAbleToFindHostStorageDomain(hsdObjectId);
}
hsdResponseList.add(hsd);
}
// Step 2: Add initiators to all HSD's.
Iterator<StoragePort> storagePortIterator = dbClient.queryIterativeObjects(StoragePort.class, existingTargetPortsInMask, true);
List<StoragePort> stPortList = new ArrayList<>();
while (storagePortIterator.hasNext()) {
StoragePort stPort = storagePortIterator.next();
if (stPort != null) {
stPortList.add(stPort);
}
}
hsdsWithInitiators = executeBatchHSDAddInitiatorsCommand(hdsApiClient, systemObjectID, hsdResponseList, stPortList, initiators, storage.getModel());
} else {
log.info("There are no hsd information in exportMask to add initiators");
}
}
}
taskCompleter.ready(dbClient);
} catch (Exception ex) {
try {
log.info("Exception occurred while adding new initiators: {}", ex.getMessage());
if (null != hsdsWithInitiators && !hsdsWithInitiators.isEmpty()) {
hdsApiClient.getHDSBatchApiExportManager().deleteBatchHostStorageDomains(systemObjectID, hsdsWithInitiators, storage.getModel());
} else {
if (null != hsdsToCreate && !hsdsToCreate.isEmpty()) {
List<HostStorageDomain> allHSDs = hdsApiClient.getHDSApiExportManager().getHostStorageDomains(systemObjectID);
List<HostStorageDomain> partialHSDListToRemove = getPartialHSDListToDelete(allHSDs, hsdsToCreate);
hdsApiClient.getHDSBatchApiExportManager().deleteBatchHostStorageDomains(systemObjectID, partialHSDListToRemove, storage.getModel());
}
}
log.error(String.format("addInitiator failed - maskURI: %s", exportMaskURI.toString()), ex);
} catch (Exception ex1) {
log.error("Exception occurred while deleting unsuccessful HSDs on system: {}", systemObjectID, ex1.getMessage());
} finally {
ServiceError serviceError = DeviceControllerException.errors.jobFailedOpMsg(ResourceOperationTypeEnum.ADD_EXPORT_INITIATOR.getName(), ex.getMessage());
taskCompleter.error(dbClient, serviceError);
}
}
log.info("{} addInitiator END...", storage.getSerialNumber());
}
use of com.emc.storageos.db.client.model.StringSetMap in project coprhd-controller by CoprHD.
the class HDSExportOperations method updateExportMaskDetailInDB.
/**
* Updates ExportMask details like volumes, HSD's & target port details in DB.
*
* @param hsdsWithInitiators
* : HSD's create successfully.
* @param allHSDPaths
* : Volume LunPaths added successfully.
* @param exportMask
* : ExportMask db object.
* @param storage
* : StorageSystem db object.
* @param volumeURIHLUs
* : volume-lun details.
*/
private void updateExportMaskDetailInDB(List<HostStorageDomain> hsdsWithInitiators, List<Path> allHSDPaths, ExportMask exportMask, StorageSystem storage, VolumeURIHLU[] volumeURIHLUs) {
StringSetMap deviceDataMap = new StringSetMap();
for (HostStorageDomain hsd : hsdsWithInitiators) {
StringSet targetPortSet = new StringSet();
List<String> hsdPorts = Arrays.asList(hsd.getPortID());
List<String> targetPortURIs = getStoragePortURIs(hsdPorts, storage);
targetPortSet.addAll(targetPortURIs);
deviceDataMap.put(hsd.getObjectID(), targetPortSet);
}
exportMask.addDeviceDataMap(deviceDataMap);
updateVolumeHLUInfo(volumeURIHLUs, allHSDPaths, exportMask);
dbClient.updateObject(exportMask);
log.info("ExportMask: {} details updated successfully.", exportMask.getId());
}
use of com.emc.storageos.db.client.model.StringSetMap in project coprhd-controller by CoprHD.
the class VplexXtremIOMaskingOrchestrator method configureZoning.
@Override
public StringSetMap configureZoning(Map<URI, List<List<StoragePort>>> portGroup, Map<String, Map<URI, Set<Initiator>>> initiatorGroup, Map<URI, NetworkLite> networkMap, StoragePortsAssigner assigner, Map<URI, String> initiatorSwitchMap, Map<URI, Map<String, List<StoragePort>>> switchStoragePortsMap, Map<URI, String> portSwitchMap) {
StringSetMap zoningMap = new StringSetMap();
// Set up a map to track port usage so that we can use all ports more or less equally.
Map<StoragePort, Integer> portUsage = new HashMap<StoragePort, Integer>();
// Iterate through each of the directors, matching each of its initiators
// with one port. This will ensure not to violate four paths per director.
// select number of paths per VPLEX director
// if X-bricks count is less than director count, choose only 2 initiators from each director
// leaving other initiators for future scale of X-bricks
// default 4 initiators in director
int pathsPerDirector = DEFAULT_NUMBER_OF_PATHS_PER_VPLEX_DIRECTOR;
if (xtremIOXbricksCount < vplexDirectorCount) {
pathsPerDirector = MINIMUM_NUMBER_OF_PATHS_PER_VPLEX_DIRECTOR;
}
_log.info(String.format("VPLEX Directors: %s, X-bricks: %s, Number of paths per VPLEX Director: %s", vplexDirectorCount, xtremIOXbricksCount, pathsPerDirector));
boolean isSwitchAffinity = false;
if (initiatorSwitchMap != null && !initiatorSwitchMap.isEmpty() && switchStoragePortsMap != null && !switchStoragePortsMap.isEmpty()) {
isSwitchAffinity = true;
}
int directorNumber = 1;
for (String director : initiatorGroup.keySet()) {
// split initiators across networks depending on number of paths per director
int numberOfNetworksForDirector = initiatorGroup.get(director).keySet().size();
int initiatorsPerNetworkForDirector = pathsPerDirector / numberOfNetworksForDirector;
_log.info("Number of Initiators that must be chosen per network for a director: {}", initiatorsPerNetworkForDirector);
for (URI networkURI : initiatorGroup.get(director).keySet()) {
int numberOfInitiatorsPerNetwork = 0;
NetworkLite net = networkMap.get(networkURI);
for (Initiator initiator : initiatorGroup.get(director).get(networkURI)) {
// If there are no ports on the initiators network, too bad...
if (portGroup.get(networkURI) == null) {
_log.info(String.format("%s -> no ports in network", initiator.getInitiatorPort()));
continue;
}
// if desired number of initiator paths chosen for network
if (numberOfInitiatorsPerNetwork >= initiatorsPerNetworkForDirector) {
_log.info(String.format("Maximum paths per network %s (%d) reached for Director %s", net.getLabel(), numberOfInitiatorsPerNetwork, director));
break;
}
List<StoragePort> assignablePorts = null;
if (isSwitchAffinity) {
// find the ports with the same switch as the initiator
String switchName = initiatorSwitchMap.get(initiator.getId());
if (!switchName.equals(NullColumnValueGetter.getNullStr())) {
Map<String, List<StoragePort>> switchMap = switchStoragePortsMap.get(networkURI);
if (switchMap != null) {
List<StoragePort> switchPorts = switchMap.get(switchName);
if (switchPorts != null && !switchPorts.isEmpty()) {
_log.info(String.format("Found the same switch ports, switch is %s", switchName));
assignablePorts = switchPorts;
}
}
}
}
List<StoragePort> portList = getStoragePortSetForDirector(portGroup.get(networkURI), directorNumber);
if (assignablePorts != null) {
assignablePorts.retainAll(portList);
}
if (assignablePorts == null || assignablePorts.isEmpty()) {
assignablePorts = portList;
}
// find a port for the initiator
StoragePort storagePort = VPlexBackEndOrchestratorUtil.assignPortToInitiator(assigner, assignablePorts, net, initiator, portUsage, null);
if (storagePort != null) {
_log.info(String.format("%s %s %s %s -> %s %s %s", director, net.getLabel(), initiator.getInitiatorPort(), initiatorSwitchMap.get(initiator.getId()), storagePort.getPortNetworkId(), storagePort.getPortName(), portSwitchMap.get(storagePort.getId())));
StringSet ports = new StringSet();
ports.add(storagePort.getId().toString());
zoningMap.put(initiator.getId().toString(), ports);
numberOfInitiatorsPerNetwork++;
} else {
_log.info(String.format("A port could not be assigned for %s %s %s", director, net.getLabel(), initiator.getInitiatorPort()));
}
}
}
directorNumber++;
}
return zoningMap;
}
use of com.emc.storageos.db.client.model.StringSetMap in project coprhd-controller by CoprHD.
the class HDSExportOperations method updateHSDInfoInExportMask.
/**
* Updates the HSD information in the ExportMask.
*
* @param exportMask
* @param hostInitiators
* @param matchedHSDs
*/
private void updateHSDInfoInExportMask(ExportMask exportMask, Set<URI> hostInitiators, Set<HostStorageDomain> matchedHSDs, StorageSystem storage, Map<String, Set<URI>> matchingMasks) {
StringBuilder builder = new StringBuilder();
if (null != matchedHSDs && !matchedHSDs.isEmpty()) {
StringSetMap deviceDataMapEntries = new StringSetMap();
for (HostStorageDomain matchedHSD : matchedHSDs) {
List<String> initiatorsExistsOnHSD = getInitiatorsExistsOnHSD(matchedHSD.getWwnList(), matchedHSD.getIscsiList());
// volume Map['volume Id'] = lun
Map<String, Integer> volumesExistsOnHSD = getExportedVolumes(matchedHSD.getPathList(), storage);
log.info("Current list of Volumes exists on this HSD: {}", volumesExistsOnHSD);
builder.append(String.format("XM:%s I:{%s} V:{%s}%n", matchedHSD.getObjectID(), Joiner.on(',').join(initiatorsExistsOnHSD), Joiner.on(',').join(volumesExistsOnHSD.keySet())));
// Update deviceDataMap in ExportMask with HSD information.
updateDeviceDataMapInExportMask(exportMask, matchedHSD, storage, deviceDataMapEntries);
List<String> storagePorts = Arrays.asList(matchedHSD.getPortID());
List<String> storagePortURIs = getStoragePortURIs(storagePorts, storage);
if (null != exportMask.getStoragePorts() && !exportMask.getStoragePorts().isEmpty()) {
// Add the storage ports if they already exist on
// exportmask.
exportMask.getStoragePorts().addAll(storagePortURIs);
} else {
exportMask.setStoragePorts(storagePortURIs);
}
String maskName = (null == matchedHSD.getName()) ? matchedHSD.getNickname() : matchedHSD.getName();
exportMask.setMaskName(maskName);
exportMask.addToExistingVolumesIfAbsent(volumesExistsOnHSD);
exportMask.addToExistingInitiatorsIfAbsent(initiatorsExistsOnHSD);
List<Initiator> initiatorList = new ArrayList<>();
if (!CollectionUtils.isEmpty(initiatorsExistsOnHSD)) {
for (String port : initiatorsExistsOnHSD) {
Initiator existingInitiator = ExportUtils.getInitiator(Initiator.toPortNetworkId(port), dbClient);
if (existingInitiator != null && !existingInitiator.getInactive()) {
initiatorList.add(existingInitiator);
}
}
}
exportMask.addInitiators(initiatorList);
String strExistingInitiators = "";
String strExistingVolumes = "";
if (exportMask.getExistingInitiators() != null) {
strExistingInitiators = Joiner.on(',').join(exportMask.getExistingInitiators());
}
if (exportMask.getExistingVolumes() != null) {
strExistingVolumes = Joiner.on(',').join(exportMask.getExistingVolumes().keySet());
}
builder.append(String.format("XM is matching. " + "EI: { %s }, EV: { %s }\n", strExistingInitiators, strExistingVolumes));
}
exportMask.addDeviceDataMap(deviceDataMapEntries);
}
log.info(builder.toString());
}
Aggregations