Search in sources :

Example 11 with BlockExportController

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...");
}
Also used : HashMap(java.util.HashMap) URI(java.net.URI) InternalServerErrorException(com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) BlockExportController(com.emc.storageos.volumecontroller.BlockExportController) ServiceCoded(com.emc.storageos.svcs.errorhandling.model.ServiceCoded) HashMap(java.util.HashMap) Map(java.util.Map) ExportPathParams(com.emc.storageos.db.client.model.ExportPathParams) HashSet(java.util.HashSet)

Example 12 with BlockExportController

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;
}
Also used : StoragePortGroup(com.emc.storageos.db.client.model.StoragePortGroup) ExportMask(com.emc.storageos.db.client.model.ExportMask) ArrayList(java.util.ArrayList) TaskResourceRep(com.emc.storageos.model.TaskResourceRep) Operation(com.emc.storageos.db.client.model.Operation) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) BlockExportController(com.emc.storageos.volumecontroller.BlockExportController) StringSet(com.emc.storageos.db.client.model.StringSet) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) Path(javax.ws.rs.Path) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) PUT(javax.ws.rs.PUT) CheckPermission(com.emc.storageos.security.authorization.CheckPermission)

Aggregations

BlockExportController (com.emc.storageos.volumecontroller.BlockExportController)12 URI (java.net.URI)10 ExportGroup (com.emc.storageos.db.client.model.ExportGroup)8 NamedURI (com.emc.storageos.db.client.model.NamedURI)6 ArrayList (java.util.ArrayList)5 HashMap (java.util.HashMap)5 Operation (com.emc.storageos.db.client.model.Operation)4 HashSet (java.util.HashSet)4 ExportPathParams (com.emc.storageos.db.client.model.ExportPathParams)3 CheckPermission (com.emc.storageos.security.authorization.CheckPermission)3 Path (javax.ws.rs.Path)3 Produces (javax.ws.rs.Produces)3 ComputeSystemControllerException (com.emc.storageos.computesystemcontroller.exceptions.ComputeSystemControllerException)2 CoordinatorException (com.emc.storageos.coordinator.exceptions.CoordinatorException)2 Initiator (com.emc.storageos.db.client.model.Initiator)2 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)2 ClientControllerException (com.emc.storageos.exceptions.ClientControllerException)2 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)2 TaskResourceRep (com.emc.storageos.model.TaskResourceRep)2 ServiceCoded (com.emc.storageos.svcs.errorhandling.model.ServiceCoded)2