use of com.emc.storageos.volumecontroller.BlockExportController in project coprhd-controller by CoprHD.
the class CreateExportGroupUpdateSchedulingThread method run.
@Override
public void run() {
_log.info("Starting scheduling for export group update thread...");
try {
Map<URI, Integer> newVolumesMap = exportGroupService.getUpdatedVolumesMap(exportUpdateParam, exportGroup);
Map<URI, Map<URI, Integer>> storageMap = exportGroupService.computeAndValidateVolumes(newVolumesMap, exportGroup, exportUpdateParam);
_log.info("Updated volumes belong to storage systems: {}", Joiner.on(',').join(storageMap.keySet()));
// Convert the storageMap to a list of added and removed Block Objects
newVolumesMap.clear();
for (Map.Entry<URI, Map<URI, Integer>> entry : storageMap.entrySet()) {
newVolumesMap.putAll(entry.getValue());
}
Map<URI, Integer> addedBlockObjectsMap = new HashMap<URI, Integer>();
Map<URI, Integer> removedBlockObjectsMap = new HashMap<URI, Integer>();
ExportUtils.getAddedAndRemovedBlockObjects(newVolumesMap, exportGroup, addedBlockObjectsMap, removedBlockObjectsMap);
_log.info("Added volumes: {}", Joiner.on(',').join(addedBlockObjectsMap.keySet()));
_log.info("Removed volumes: {}", Joiner.on(',').join(removedBlockObjectsMap.keySet()));
// If ExportPathParameter block is present, and volumes are added, capture ExportPathParameters arguments.
// This looks weird, but isn't. We use the added volumes from ExportCreateParam instead of addedBlockObjectsMap
// because the user may want to change the parameters for volumes that are already exported. In this way,
// the same volume can have different parameters to different hosts.
Map<URI, Integer> addedVolumeParams = exportGroupService.getChangedVolumes(exportUpdateParam, true);
ExportPathParams exportPathParam = null;
if (exportUpdateParam.getExportPathParameters() != null && !addedVolumeParams.keySet().isEmpty()) {
exportPathParam = exportGroupService.validateAndCreateExportPathParam(exportUpdateParam.getExportPathParameters(), exportGroup, addedVolumeParams.keySet());
exportGroupService.validatePortGroupWhenAddVolumesForExportGroup(addedVolumeParams.keySet(), exportUpdateParam.getExportPathParameters().getPortGroup(), exportGroup);
exportGroupService.addBlockObjectsToPathParamMap(addedVolumeParams.keySet(), exportPathParam.getId(), exportGroup);
} else if (!addedVolumeParams.keySet().isEmpty()) {
// exportPathParam is null
exportGroupService.validatePortGroupWhenAddVolumesForExportGroup(addedVolumeParams.keySet(), null, exportGroup);
}
// Remove the block objects being deleted from any existing path parameters.
exportGroupService.removeBlockObjectsFromPathParamMap(removedBlockObjectsMap.keySet(), exportGroup);
Set<URI> addedClusters = new HashSet<>();
Set<URI> removedClusters = new HashSet<>();
Set<URI> addedHosts = new HashSet<>();
Set<URI> removedHosts = new HashSet<>();
Set<URI> addedInitiators = new HashSet<>();
Set<URI> removedInitiators = new HashSet<>();
// Validate updated entries
List<URI> newInitiators = StringSetUtil.stringSetToUriList(exportGroup.getInitiators());
List<URI> newHosts = StringSetUtil.stringSetToUriList(exportGroup.getHosts());
List<URI> newClusters = StringSetUtil.stringSetToUriList(exportGroup.getClusters());
exportGroupService.validateClientsAndUpdate(exportGroup, project, storageMap.keySet(), exportUpdateParam, newClusters, newHosts, newInitiators, addedClusters, removedClusters, addedHosts, removedHosts, addedInitiators, removedInitiators);
_log.info("All clients were successfully validated");
dbClient.persistObject(exportGroup);
if (exportPathParam != null) {
dbClient.createObject(exportPathParam);
}
// push it to storage devices
BlockExportController exportController = exportGroupService.getExportController();
_log.info("Submitting export group update request.");
exportController.exportGroupUpdate(exportGroup.getId(), addedBlockObjectsMap, removedBlockObjectsMap, addedClusters, removedClusters, addedHosts, removedHosts, addedInitiators, removedInitiators, task);
} catch (Exception ex) {
if (ex instanceof ServiceCoded) {
dbClient.error(ExportGroup.class, taskRes.getResource().getId(), taskRes.getOpId(), (ServiceCoded) ex);
} else {
dbClient.error(ExportGroup.class, taskRes.getResource().getId(), taskRes.getOpId(), InternalServerErrorException.internalServerErrors.unexpectedErrorExportGroupPlacement(ex));
}
_log.error(ex.getMessage(), ex);
taskRes.setMessage(ex.getMessage());
}
_log.info("Ending export group update scheduling thread...");
}
use of com.emc.storageos.volumecontroller.BlockExportController in project coprhd-controller by CoprHD.
the class ExportGroupService method changePortGroup.
@PUT
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}/change-port-group")
@CheckPermission(roles = { Role.TENANT_ADMIN }, acls = { ACL.OWN, ACL.ALL })
public TaskResourceRep changePortGroup(@PathParam("id") URI id, ChangePortGroupParam param) throws ControllerException {
// Basic validation of ExportGroup and the request
param.logParameters(_log);
ExportGroup exportGroup = queryObject(ExportGroup.class, id, true);
if (exportGroup.checkInternalFlags(DataObject.Flag.DELETION_IN_PROGRESS)) {
throw BadRequestException.badRequests.deletionInProgress(exportGroup.getClass().getSimpleName(), exportGroup.getLabel());
}
validateExportGroupNoPendingEvents(exportGroup);
Boolean wait = new Boolean(param.getWaitBeforeRemovePaths());
validateSuspendSetForNonDiscoverableHosts(exportGroup, wait, true);
ArgValidator.checkUri(param.getNewPortGroup());
StoragePortGroup newPortGroup = queryObject(StoragePortGroup.class, param.getNewPortGroup(), true);
if (!newPortGroup.isUsable()) {
throw APIException.badRequests.portGroupInvalid(newPortGroup.getNativeGuid());
}
URI systemURI = newPortGroup.getStorageDevice();
StorageSystem system = queryObject(StorageSystem.class, systemURI, true);
// Get the virtual array, default to Export Group varray. Validate it matches.
URI varray = exportGroup.getVirtualArray();
String value = customConfigHandler.getComputedCustomConfigValue(CustomConfigConstants.VMAX_USE_PORT_GROUP_ENABLED, Type.vmax.name(), null);
if (!Boolean.TRUE.toString().equalsIgnoreCase(value)) {
throw APIException.badRequests.portGroupSettingIsOff();
}
com.emc.storageos.api.service.impl.resource.utils.ExportUtils.validatePortGroupWithVirtualArray(newPortGroup, varray, _dbClient);
URI currentPortGroup = param.getCurrentPortGroup();
if (currentPortGroup != null && currentPortGroup.equals(newPortGroup.getId())) {
throw APIException.badRequests.changePortGroupSameNewPortGroup(newPortGroup.getNativeGuid());
}
URI exportMaskURI = param.getExportMask();
ExportMask mask = null;
if (exportMaskURI != null) {
mask = queryObject(ExportMask.class, exportMaskURI, true);
if (mask != null) {
if (!exportGroup.getExportMasks().contains(exportMaskURI.toString())) {
throw APIException.badRequests.changePortGroupInvalidExportMask(mask.getMaskName());
}
if (!systemURI.equals(mask.getStorageDevice())) {
throw APIException.badRequests.changePortGroupInvalidExportMask(mask.getMaskName());
}
if (currentPortGroup != null && !currentPortGroup.equals(mask.getPortGroup())) {
throw APIException.badRequests.changePortGroupInvalidExportMask(mask.getMaskName());
}
}
}
List<ExportMask> exportMasks = new ArrayList<ExportMask>();
if (mask != null) {
exportMasks.add(mask);
} else {
exportMasks = ExportMaskUtils.getExportMasks(_dbClient, exportGroup, system.getId(), currentPortGroup);
}
if (exportMasks.isEmpty()) {
throw APIException.badRequests.noValidExportMaskInExportGroup(exportGroup.getLabel());
}
List<URI> affectedMasks = new ArrayList<URI>();
for (ExportMask exportMask : exportMasks) {
URI currentPGUri = exportMask.getPortGroup();
StringSet newPorts = newPortGroup.getStoragePorts();
if (!newPortGroup.getId().equals(currentPGUri)) {
StoragePortGroup currentPG = queryObject(StoragePortGroup.class, currentPGUri, false);
StringSet currentPorts = currentPG.getStoragePorts();
if (!Collections.disjoint(newPorts, currentPorts)) {
throw APIException.badRequests.changePortGroupPortGroupNoOverlap(newPortGroup.getLabel());
}
// because we could not add use the same storage group and a new port group to create the new masking view
if (system.checkIfVmax3()) {
String volumeWithHostIO = ExportUtils.getVolumeHasHostIOLimitSet(_dbClient, exportMask.getVolumes());
if (volumeWithHostIO != null) {
throw APIException.badRequests.changePortGroupNotSupportedforHostIOLimit(volumeWithHostIO);
}
}
// Check if there is any existing volumes in the export mask
if (exportMask.getExistingVolumes() != null && !exportMask.getExistingVolumes().isEmpty()) {
throw APIException.badRequests.changePortGroupExistingVolumes(exportMask.getMaskName(), Joiner.on(',').join(exportMask.getExistingVolumes().keySet()));
}
if (exportMask.getExistingInitiators() != null && !exportMask.getExistingInitiators().isEmpty()) {
throw APIException.badRequests.changePortGroupExistingInitiators(exportMask.getMaskName(), Joiner.on(',').join(exportMask.getExistingInitiators()));
}
affectedMasks.add(exportMask.getId());
} else {
_log.info(String.format("The export mask %s uses the same port group %s", exportMask.getMaskName(), newPortGroup.getLabel()));
}
}
String task = UUID.randomUUID().toString();
if (affectedMasks.isEmpty()) {
_log.info("No export mask to change port group, do nothing");
Operation op = new Operation();
op.setResourceType(ResourceOperationTypeEnum.EXPORT_CHANGE_PORT_GROUP);
op.setMessage("No port group change is needed for this export group");
op.ready();
exportGroup.getOpStatus().createTaskStatus(task, op);
_dbClient.updateObject(exportGroup);
return toTask(exportGroup, task, op);
}
Operation op = initTaskStatus(exportGroup, task, Operation.Status.pending, ResourceOperationTypeEnum.EXPORT_CHANGE_PORT_GROUP);
TaskResourceRep taskRes = toTask(exportGroup, task, op);
// persist the export group to the database
_dbClient.updateObject(exportGroup);
auditOp(OperationTypeEnum.EXPORT_CHANGE_PORT_GROUP, true, AuditLogManager.AUDITOP_BEGIN, exportGroup.getLabel(), exportGroup.getId().toString(), exportGroup.getVirtualArray().toString(), exportGroup.getProject().toString());
BlockExportController exportController = getExportController();
_log.info(String.format("Submitting change port group %s request.", newPortGroup.getNativeGuid()));
exportController.exportGroupChangePortGroup(systemURI, id, newPortGroup.getId(), affectedMasks, wait, task);
return taskRes;
}
Aggregations