Search in sources :

Example 26 with StringSetMap

use of com.emc.storageos.db.client.model.StringSetMap in project coprhd-controller by CoprHD.

the class VolumeIngestionUtil method verifyHostNumPath.

/**
 * Given the zoneInfoMap, check the existing paths to make sure they
 * comply with the ingestion vpool requirements.
 *
 * @param pathParams the ingestion parameter
 * @param initiators the host initiators to be checked
 * @param zoneInfoMap the zoneInfoMap that is stored in the UnManagedExportMask
 * @param dbClient a reference to the database client
 * @return true if the host paths are compliant. False otherwise.
 */
private static boolean verifyHostNumPath(ExportPathParams pathParams, List<Initiator> initiators, ZoneInfoMap zoneInfoMap, DbClient dbClient) {
    _logger.info("verifyHostNumPath for initiators {} with zoningMap {}", initiators, zoneInfoMap);
    if (initiators == null || initiators.isEmpty()) {
        _logger.error("Host has no initiators configured.");
        throw IngestionException.exceptions.hostHasNoInitiators();
    }
    int unassignedInitiators = 0;
    int totalPaths = 0;
    StringSetMap zoningMap = ExportMaskUtils.getZoneMapFromZoneInfoMap(zoneInfoMap, initiators);
    if (null == zoningMap || zoningMap.isEmpty()) {
        _logger.error("No zoning information found for the initiators");
        List<String> messageArray = new ArrayList<String>();
        for (Initiator init : initiators) {
            messageArray.add(init.getHostName() + ":" + init.getInitiatorPort());
        }
        throw IngestionException.exceptions.hostHasNoZoning(Joiner.on(", ").join(messageArray));
    }
    if (VPlexControllerUtils.isVplexInitiator(initiators.get(0), dbClient)) {
        _logger.info("these are VPLEX backend initiators, " + "so no need to validate against virtual pool path params");
        return true;
    }
    String hostName = initiators.get(0).getHostName();
    URI hostURI = initiators.get(0).getHost() == null ? URIUtil.NULL_URI : initiators.get(0).getHost();
    _logger.info("Checking numpath for host {}", hostName);
    for (Initiator initiator : initiators) {
        if (initiator.getHostName() != null) {
            hostName = initiator.getHostName();
        }
        StringSet ports = zoningMap.get(initiator.getId().toString());
        if (ports == null || ports.isEmpty()) {
            unassignedInitiators++;
            _logger.info("Initiator {} of host {} is not assigned to any ports.", new Object[] { initiator.getInitiatorPort(), hostName });
        } else if (ports.size() < pathParams.getPathsPerInitiator()) {
            _logger.error("Initiator {} of host {} has fewer SAN paths than what is required according to the virtual pool " + "({} are zoned, but {} are required)", new Object[] { initiator.getInitiatorPort(), hostName, ports.size(), pathParams.getPathsPerInitiator() });
            throw IngestionException.exceptions.hostZoningHasDifferentPortCount(initiator.getInitiatorPort(), hostName, String.valueOf(ports.size()), String.valueOf(pathParams.getPathsPerInitiator()));
        } else {
            totalPaths += ports.size();
            _logger.info("Initiator {} of host {} has {} paths", new Object[] { initiator.getInitiatorPort(), hostName, ports.size(), ports.size() });
        }
    }
    if (totalPaths < pathParams.getMinPaths()) {
        _logger.error(String.format("Host %s (%s) has fewer paths assigned %d than min_paths %d", hostName, hostURI.toString(), totalPaths, pathParams.getMinPaths()));
        throw IngestionException.exceptions.hostZoningHasFewerPorts(hostName, String.valueOf(totalPaths), String.valueOf(pathParams.getMinPaths()));
    }
    if (totalPaths > pathParams.getMaxPaths()) {
        _logger.warn(String.format("Host %s (%s) has more paths assigned %d than max_paths %d", hostName, hostURI.toString(), totalPaths, pathParams.getMaxPaths()));
    }
    if (unassignedInitiators > 0) {
        _logger.info(String.format("Host %s (%s) has %d unassigned initiators", hostName, hostURI.toString(), unassignedInitiators));
    }
    return true;
}
Also used : StringSetMap(com.emc.storageos.db.client.model.StringSetMap) Initiator(com.emc.storageos.db.client.model.Initiator) ArrayList(java.util.ArrayList) StringSet(com.emc.storageos.db.client.model.StringSet) BlockObject(com.emc.storageos.db.client.model.BlockObject) DataObject(com.emc.storageos.db.client.model.DataObject) RemoteMirrorObject(com.emc.storageos.volumecontroller.impl.plugins.discovery.smis.processor.detailedDiscovery.RemoteMirrorObject) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) PrefixConstraint(com.emc.storageos.db.client.constraint.PrefixConstraint) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint) ContainmentConstraint(com.emc.storageos.db.client.constraint.ContainmentConstraint)

Example 27 with StringSetMap

use of com.emc.storageos.db.client.model.StringSetMap in project coprhd-controller by CoprHD.

the class BlockDeviceExportController method updateVolumePathParams.

@Override
public void updateVolumePathParams(URI volumeURI, URI newVpoolURI, String opId) throws ControllerException {
    _log.info("Received request to update Volume path parameters. Creating master workflow.");
    VolumeVpoolChangeTaskCompleter taskCompleter = null;
    Volume volume = null;
    try {
        // Read volume from database, update the Vpool to the new completer, and create task completer.
        volume = _dbClient.queryObject(Volume.class, volumeURI);
        URI oldVpoolURI = volume.getVirtualPool();
        List<URI> rollbackList = new ArrayList<URI>();
        List<Volume> updatedVolumes = new ArrayList<Volume>();
        rollbackList.add(volumeURI);
        // Check if it is a VPlex volume, and get backend volumes
        Volume backendSrc = VPlexUtil.getVPLEXBackendVolume(volume, true, _dbClient, false);
        if (backendSrc != null) {
            // Change the back end volume's vpool too
            backendSrc.setVirtualPool(newVpoolURI);
            rollbackList.add(backendSrc.getId());
            updatedVolumes.add(backendSrc);
            // VPlex volume, check if it is distributed
            Volume backendHa = VPlexUtil.getVPLEXBackendVolume(volume, false, _dbClient, false);
            if (backendHa != null && backendHa.getVirtualPool() != null && backendHa.getVirtualPool().toString().equals(oldVpoolURI.toString())) {
                backendHa.setVirtualPool(newVpoolURI);
                rollbackList.add(backendHa.getId());
                updatedVolumes.add(backendHa);
            }
        }
        // The VolumeVpoolChangeTaskCompleter will restore the old Virtual Pool in event of error.
        taskCompleter = new VolumeVpoolChangeTaskCompleter(rollbackList, oldVpoolURI, opId);
        volume.setVirtualPool(newVpoolURI);
        updatedVolumes.add(volume);
        _log.info(String.format("Changing VirtualPool PathParams for volume %s (%s) from %s to %s", volume.getLabel(), volume.getId(), oldVpoolURI, newVpoolURI));
        _dbClient.updateObject(updatedVolumes);
    } catch (Exception ex) {
        _log.error("Unexpected exception reading volume or generating taskCompleter: ", ex);
        ServiceError serviceError = DeviceControllerException.errors.jobFailed(ex);
        VolumeWorkflowCompleter completer = new VolumeWorkflowCompleter(volumeURI, opId);
        completer.error(_dbClient, serviceError);
    }
    try {
        Workflow workflow = _wfUtils.newWorkflow("updateVolumePathParams", false, opId);
        // Locate all the ExportMasks containing the given volume, and their Export Group.
        Map<ExportMask, ExportGroup> maskToGroupMap = ExportUtils.getExportMasks(volume, _dbClient);
        Map<URI, StringSetMap> maskToZoningMap = new HashMap<URI, StringSetMap>();
        // Store the original zoning maps of the export masks to be used to restore in case of a failure
        for (ExportMask mask : maskToGroupMap.keySet()) {
            maskToZoningMap.put(mask.getId(), mask.getZoningMap());
        }
        taskCompleter.setMaskToZoningMap(maskToZoningMap);
        // Acquire all necessary locks for the workflow:
        // For each export group lock initiator's hosts and storage array keys.
        List<URI> initiatorURIs = new ArrayList<URI>();
        for (ExportGroup exportGroup : maskToGroupMap.values()) {
            initiatorURIs.addAll(StringSetUtil.stringSetToUriList(exportGroup.getInitiators()));
            List<String> lockKeys = ControllerLockingUtil.getHostStorageLockKeys(_dbClient, ExportGroup.ExportGroupType.valueOf(exportGroup.getType()), initiatorURIs, volume.getStorageController());
            initiatorURIs.clear();
            boolean acquiredLocks = _wfUtils.getWorkflowService().acquireWorkflowLocks(workflow, lockKeys, LockTimeoutValue.get(LockType.EXPORT_GROUP_OPS));
            if (!acquiredLocks) {
                throw DeviceControllerException.exceptions.failedToAcquireLock(lockKeys.toString(), "UpdateVolumePathParams: " + volume.getLabel());
            }
        }
        // These steps are serialized, which is required in case an ExportMask appears
        // in multiple Export Groups.
        String stepId = null;
        for (ExportGroup exportGroup : maskToGroupMap.values()) {
            stepId = _wfUtils.generateExportChangePathParams(workflow, "changePathParams", stepId, volume.getStorageController(), exportGroup.getId(), volumeURI);
        }
        if (!workflow.getAllStepStatus().isEmpty()) {
            _log.info("The updateVolumePathParams workflow has {} steps. Starting the workflow.", workflow.getAllStepStatus().size());
            workflow.executePlan(taskCompleter, "Update the export group on all storage systems successfully.");
        } else {
            taskCompleter.ready(_dbClient);
        }
    } catch (Exception ex) {
        _log.error("Unexpected exception: ", ex);
        ServiceError serviceError = DeviceControllerException.errors.jobFailed(ex);
        taskCompleter.error(_dbClient, serviceError);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) HashMap(java.util.HashMap) VolumeWorkflowCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeWorkflowCompleter) ExportMask(com.emc.storageos.db.client.model.ExportMask) ArrayList(java.util.ArrayList) Workflow(com.emc.storageos.workflow.Workflow) URI(java.net.URI) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) IOException(java.io.IOException) LockRetryException(com.emc.storageos.locking.LockRetryException) VolumeVpoolChangeTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeVpoolChangeTaskCompleter) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) Volume(com.emc.storageos.db.client.model.Volume)

Example 28 with StringSetMap

use of com.emc.storageos.db.client.model.StringSetMap in project coprhd-controller by CoprHD.

the class ExternalDeviceUnManagedVolumeDiscoverer method processUnManagedSnapshots.

/**
 * Process snapshots of unManaged volume.
 * Check if unManaged snapshot should be created and create unManaged volume instance for a snapshot in such a case.
 * Add unManaged snapshot to parent volume CG if needed and update the snap with parent volume CG information.
 * Gets export information for snapshots and stores it in the provided map.
 *
 * @param driverVolume              driver volume for snap parent volume. [IN]
 * @param unManagedParentVolume     unManaged parent volume [IN/OUT]
 * @param storageSystem             storage system [IN]
 * @param storagePool               storage pool [IN]
 * @param unManagedVolumesToCreate  list of unmanaged volumes to create [OUT]
 * @param unManagedVolumesToUpdate  list of unmanaged volumes to update [OUT]
 * @param allCurrentUnManagedCgURIs set of unManaged CG uris found in the current discovery [OUT]
 * @param unManagedCGToUpdateMap    map of unManaged CG GUID to unManaged CG instance [IN/OUT]
 * @param unManagedVolumeNativeIdToUriMap map of unmanaged volumes nativeId to their uri [OUT]
 * @param hostToUnManagedVolumeExportInfoMap map  with export data for unmanaged volumes (including snaps and clones)
 * @param driver                    storage driver [IN]
 * @param dbClient                  reference to db client [IN]
 * @return                          set of URIs for unmanaged snapshots
 * @throws Exception
 */
private Set<URI> processUnManagedSnapshots(StorageVolume driverVolume, UnManagedVolume unManagedParentVolume, com.emc.storageos.db.client.model.StorageSystem storageSystem, com.emc.storageos.db.client.model.StoragePool storagePool, List<UnManagedVolume> unManagedVolumesToCreate, List<UnManagedVolume> unManagedVolumesToUpdate, Set<URI> allCurrentUnManagedCgURIs, Map<String, UnManagedConsistencyGroup> unManagedCGToUpdateMap, Map<String, URI> unManagedVolumeNativeIdToUriMap, Map<String, List<HostExportInfo>> hostToUnManagedVolumeExportInfoMap, BlockStorageDriver driver, DbClient dbClient) throws Exception {
    log.info("Processing snapshots for volume {} ", unManagedParentVolume.getNativeGuid());
    Set<URI> snapshotUris = new HashSet<>();
    List<VolumeSnapshot> driverSnapshots = driver.getVolumeSnapshots(driverVolume);
    if (driverSnapshots == null || driverSnapshots.isEmpty()) {
        log.info("There are no snapshots for volume {} ", unManagedParentVolume.getNativeGuid());
    } else {
        log.info("Snapshots for unManaged volume {}:" + Joiner.on("\t").join(driverSnapshots), unManagedParentVolume.getNativeGuid());
        StringSet unManagedSnaps = new StringSet();
        for (VolumeSnapshot driverSnapshot : driverSnapshots) {
            String managedSnapNativeGuid = NativeGUIDGenerator.generateNativeGuidForVolumeOrBlockSnapShot(storageSystem.getNativeGuid(), driverSnapshot.getNativeId());
            BlockSnapshot systemSnap = DiscoveryUtils.checkBlockSnapshotExistsInDB(dbClient, managedSnapNativeGuid);
            if (null != systemSnap) {
                log.info("Skipping snapshot {} as it is already managed by the system.", managedSnapNativeGuid);
                continue;
            }
            String unManagedSnapNatvieGuid = NativeGUIDGenerator.generateNativeGuidForPreExistingVolume(storageSystem.getNativeGuid(), driverSnapshot.getNativeId());
            UnManagedVolume unManagedSnap = createUnManagedSnapshot(driverSnapshot, unManagedParentVolume, storageSystem, storagePool, unManagedVolumesToCreate, unManagedVolumesToUpdate, dbClient);
            snapshotUris.add(unManagedSnap.getId());
            unManagedSnaps.add(unManagedSnapNatvieGuid);
            // Check if this snap is for a volume in consistency group on device.
            String isParentVolumeInCG = unManagedParentVolume.getVolumeCharacterstics().get(UnManagedVolume.SupportedVolumeCharacterstics.IS_VOLUME_ADDED_TO_CONSISTENCYGROUP.toString());
            if (isParentVolumeInCG.equals(Boolean.TRUE.toString())) {
                // add snapshot to parent volume unManaged consistency group, update snapshot with parent volume CG information.
                addObjectToUnManagedConsistencyGroup(storageSystem, driverVolume.getConsistencyGroup(), unManagedSnap, allCurrentUnManagedCgURIs, unManagedCGToUpdateMap, driver, dbClient);
            }
            // get export data for the snapshot
            unManagedVolumeNativeIdToUriMap.put(driverSnapshot.getNativeId(), unManagedSnap.getId());
            getSnapshotExportInfo(driver, driverSnapshot, hostToUnManagedVolumeExportInfoMap);
        }
        if (!unManagedSnaps.isEmpty()) {
            // set the HAS_REPLICAS property
            unManagedParentVolume.getVolumeCharacterstics().put(UnManagedVolume.SupportedVolumeCharacterstics.HAS_REPLICAS.toString(), TRUE);
            StringSetMap unManagedVolumeInformation = unManagedParentVolume.getVolumeInformation();
            log.info("New unManaged snaps for unManaged volume {}:" + Joiner.on("\t").join(unManagedSnaps), unManagedParentVolume.getNativeGuid());
            if (unManagedVolumeInformation.containsKey(UnManagedVolume.SupportedVolumeInformation.SNAPSHOTS.toString())) {
                log.info("Old unManaged snaps for unManaged volume {}:" + Joiner.on("\t").join(unManagedVolumeInformation.get(UnManagedVolume.SupportedVolumeInformation.SNAPSHOTS.toString())), unManagedParentVolume.getNativeGuid());
                // replace with new StringSet
                unManagedParentVolume.putVolumeInfo(UnManagedVolume.SupportedVolumeInformation.SNAPSHOTS.toString(), unManagedSnaps);
                log.info("Replaced snaps :" + Joiner.on("\t").join(unManagedVolumeInformation.get(UnManagedVolume.SupportedVolumeInformation.SNAPSHOTS.toString())));
            } else {
                unManagedParentVolume.putVolumeInfo(UnManagedVolume.SupportedVolumeInformation.SNAPSHOTS.toString(), unManagedSnaps);
            }
        } else {
            log.info("All snapshots for volume {} are already managed.", unManagedParentVolume.getNativeGuid());
        }
    }
    return snapshotUris;
}
Also used : StringSetMap(com.emc.storageos.db.client.model.StringSetMap) UnManagedVolume(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume) StringSet(com.emc.storageos.db.client.model.StringSet) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) URI(java.net.URI) VolumeSnapshot(com.emc.storageos.storagedriver.model.VolumeSnapshot) HashSet(java.util.HashSet)

Example 29 with StringSetMap

use of com.emc.storageos.db.client.model.StringSetMap in project coprhd-controller by CoprHD.

the class HDSVolumeDiscoverer method updateUnManagedVolumeInfo.

/**
 * Updates the UnManagedVolumeInfo.
 *
 * @param logicalUnit
 * @param system
 * @param pool
 * @param unManagedVolume
 * @param dbClient
 */
private void updateUnManagedVolumeInfo(LogicalUnit logicalUnit, StorageSystem system, StoragePool pool, UnManagedVolume unManagedVolume, DbClient dbClient) {
    StringSetMap unManagedVolumeInformation = new StringSetMap();
    Map<String, String> unManagedVolumeCharacteristics = new HashMap<String, String>();
    StringSet systemTypes = new StringSet();
    systemTypes.add(system.getSystemType());
    StringSet provCapacity = new StringSet();
    provCapacity.add(String.valueOf(Long.parseLong(logicalUnit.getCapacityInKB()) * 1024));
    unManagedVolumeInformation.put(SupportedVolumeInformation.PROVISIONED_CAPACITY.toString(), provCapacity);
    StringSet allocatedCapacity = new StringSet();
    allocatedCapacity.add(String.valueOf(Long.parseLong(logicalUnit.getCapacityInKB()) * 1024));
    unManagedVolumeInformation.put(SupportedVolumeInformation.ALLOCATED_CAPACITY.toString(), allocatedCapacity);
    unManagedVolumeInformation.put(SupportedVolumeInformation.SYSTEM_TYPE.toString(), systemTypes);
    StringSet deviceLabel = new StringSet();
    String luLabel = getLabelFromLogicalUnit(logicalUnit);
    if (null != luLabel) {
        deviceLabel.add(luLabel);
    }
    unManagedVolumeInformation.put(SupportedVolumeInformation.DEVICE_LABEL.toString(), deviceLabel);
    unManagedVolumeCharacteristics.put(SupportedVolumeCharacterstics.IS_INGESTABLE.toString(), Boolean.TRUE.toString());
    if (logicalUnit.getPath() == 1) {
        unManagedVolumeCharacteristics.put(SupportedVolumeCharacterstics.IS_VOLUME_EXPORTED.toString(), Boolean.TRUE.toString());
    } else {
        unManagedVolumeCharacteristics.put(SupportedVolumeCharacterstics.IS_VOLUME_EXPORTED.toString(), Boolean.FALSE.toString());
    }
    if (logicalUnit.getDpType().equals(HDSConstants.DPTYPE_THIN)) {
        unManagedVolumeCharacteristics.put(SupportedVolumeCharacterstics.IS_THINLY_PROVISIONED.toString(), Boolean.TRUE.toString());
    } else if (logicalUnit.getDpType().equals(HDSConstants.DPTYPE_THICK)) {
        unManagedVolumeCharacteristics.put(SupportedVolumeCharacterstics.IS_THINLY_PROVISIONED.toString(), Boolean.FALSE.toString());
    } else {
        log.info("Provisioning type not found for volume: {}", logicalUnit.getObjectID());
    }
    String raidType = logicalUnit.getRaidType();
    if (null != raidType) {
        StringSet raidLevels = new StringSet();
        raidLevels.add(raidType);
        unManagedVolumeInformation.put(SupportedVolumeInformation.RAID_LEVEL.toString(), raidLevels);
    }
    StringSet pools = new StringSet();
    pools.add(pool.getId().toString());
    unManagedVolumeInformation.put(SupportedVolumeInformation.STORAGE_POOL.toString(), pools);
    unManagedVolume.setWwn(HDSUtils.generateHitachiWWN(logicalUnit.getObjectID(), String.valueOf(logicalUnit.getDevNum())));
    StringSet nativeId = new StringSet();
    nativeId.add(String.valueOf(logicalUnit.getDevNum()));
    unManagedVolumeInformation.put(SupportedVolumeInformation.NATIVE_ID.toString(), nativeId);
    String luTieringPolicy = fetchLogicalUnitTieringPolicy(system, logicalUnit, dbClient);
    if (null != luTieringPolicy) {
        StringSet volumeTieringPolicy = new StringSet();
        volumeTieringPolicy.add(luTieringPolicy);
        unManagedVolumeInformation.put(SupportedVolumeInformation.AUTO_TIERING_POLICIES.toString(), volumeTieringPolicy);
        unManagedVolumeCharacteristics.put(SupportedVolumeCharacterstics.IS_AUTO_TIERING_ENABLED.toString(), Boolean.TRUE.toString());
    } else {
        unManagedVolumeCharacteristics.put(SupportedVolumeCharacterstics.IS_AUTO_TIERING_ENABLED.toString(), Boolean.FALSE.toString());
    }
    StringSet driveTypes = pool.getSupportedDriveTypes();
    if (null != driveTypes) {
        unManagedVolumeInformation.put(SupportedVolumeInformation.DISK_TECHNOLOGY.toString(), driveTypes);
    }
    StringSet matchedVPools = DiscoveryUtils.getMatchedVirtualPoolsForPool(dbClient, pool.getId(), unManagedVolumeCharacteristics.get(SupportedVolumeCharacterstics.IS_THINLY_PROVISIONED.name()).toString(), unManagedVolume);
    log.debug("Matched Pools : {}", Joiner.on("\t").join(matchedVPools));
    if (null == matchedVPools || matchedVPools.isEmpty()) {
        // clear all matched vpools
        unManagedVolume.getSupportedVpoolUris().clear();
    } else {
        // replace with new StringSet
        unManagedVolume.getSupportedVpoolUris().replace(matchedVPools);
        log.info("Replaced Pools : {}", Joiner.on("\t").join(unManagedVolume.getSupportedVpoolUris()));
    }
    unManagedVolume.setVolumeInformation(unManagedVolumeInformation);
    if (unManagedVolume.getVolumeCharacterstics() == null) {
        unManagedVolume.setVolumeCharacterstics(new StringMap());
    }
    unManagedVolume.getVolumeCharacterstics().replace(unManagedVolumeCharacteristics);
}
Also used : StringSetMap(com.emc.storageos.db.client.model.StringSetMap) StringMap(com.emc.storageos.db.client.model.StringMap) HashMap(java.util.HashMap) StringSet(com.emc.storageos.db.client.model.StringSet)

Example 30 with StringSetMap

use of com.emc.storageos.db.client.model.StringSetMap in project coprhd-controller by CoprHD.

the class HDSExportOperations method removeInitiators.

@Override
public void removeInitiators(StorageSystem storage, URI exportMaskURI, List<URI> volumeURIList, List<Initiator> initiators, List<URI> targets, TaskCompleter taskCompleter) throws DeviceControllerException {
    long startTime = System.currentTimeMillis();
    log.info("{} removeInitiator START...", storage.getSerialNumber());
    try {
        log.info("removeInitiator: Export mask id: {}", exportMaskURI);
        if (volumeURIList != null) {
            log.info("removeInitiator: volumes : {}", Joiner.on(',').join(volumeURIList));
        }
        log.info("removeInitiator: initiators : {}", Joiner.on(',').join(initiators));
        log.info("removeInitiator: targets : {}", Joiner.on(',').join(targets));
        if (null == initiators || initiators.isEmpty()) {
            log.info("No initiators found to remove {}", exportMaskURI);
            taskCompleter.ready(dbClient);
            return;
        }
        ExportMask exportMask = dbClient.queryObject(ExportMask.class, exportMaskURI);
        // 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(volumeURIList, dbClient);
        ctx.setInitiators(initiators);
        // Allow exceptions to be thrown when not rolling back
        ctx.setAllowExceptions(!isRollback);
        AbstractHDSValidator removeInitiatorFromMaskValidator = (AbstractHDSValidator) validator.removeInitiators(ctx);
        removeInitiatorFromMaskValidator.validate();
        HDSApiClient hdsApiClient = hdsApiFactory.getClient(HDSUtils.getHDSServerManagementServerInfo(storage), storage.getSmisUserName(), storage.getSmisPassword());
        HDSApiExportManager exportMgr = hdsApiClient.getHDSApiExportManager();
        String systemObjectID = HDSUtils.getSystemObjectID(storage);
        StringSetMap deviceDataMap = exportMask.getDeviceDataMap();
        if (null != deviceDataMap && !deviceDataMap.isEmpty()) {
            Set<String> hsdObjectIDSet = deviceDataMap.keySet();
            for (String hsdObjectID : hsdObjectIDSet) {
                HostStorageDomain hsd = exportMgr.getHostStorageDomain(systemObjectID, hsdObjectID);
                if (null == hsd) {
                    log.warn("Not able to remove initiators as HSD {} couldn't find on array.", hsdObjectID);
                    continue;
                }
                List<String> fcInitiators = getFCInitiatorsExistOnHSD(hsd, initiators);
                List<String> iSCSIInitiators = getISCSIInitiatorsExistOnHSD(hsd, initiators);
                boolean isLastFCInitiator = (fcInitiators.size() == 1 && null != hsd.getWwnList() && hsd.getWwnList().size() == fcInitiators.size());
                boolean isLastISCSIInitiator = (iSCSIInitiators.size() == 1 && null != hsd.getIscsiList() && hsd.getIscsiList().size() == iSCSIInitiators.size());
                // If Initiator is last one, remove the HSD
                if (isLastFCInitiator || isLastISCSIInitiator) {
                    exportMgr.deleteHostStorageDomain(systemObjectID, hsd.getObjectID(), storage.getModel());
                    exportMask.getDeviceDataMap().remove(hsd.getObjectID());
                } else {
                    if (null != fcInitiators && !fcInitiators.isEmpty()) {
                        // remove FC initiators from HSD.
                        exportMgr.deleteWWNsFromHostStorageDomain(systemObjectID, hsd.getObjectID(), fcInitiators, storage.getModel());
                    }
                    if (null != iSCSIInitiators && !iSCSIInitiators.isEmpty()) {
                        // remove ISCSInames from HSD.
                        exportMgr.deleteISCSIsFromHostStorageDomain(systemObjectID, hsd.getObjectID(), iSCSIInitiators, storage.getModel());
                    }
                }
            }
            dbClient.updateObject(exportMask);
            // update the task status after processing all HSD's.
            taskCompleter.ready(dbClient);
        } else {
            log.info("No Host groups found on exportMask {}", exportMaskURI);
            // No HSD's found in exportMask.
            taskCompleter.ready(dbClient);
        }
    } catch (Exception e) {
        log.error(String.format("removeInitiator failed - maskURI: %s", exportMaskURI.toString()), e);
        ServiceError serviceError = DeviceControllerException.errors.jobFailedOpMsg(ResourceOperationTypeEnum.DELETE_EXPORT_INITIATOR.getName(), e.getMessage());
        taskCompleter.error(dbClient, serviceError);
    } finally {
        long totalTime = System.currentTimeMillis() - startTime;
        log.info(String.format("findExportMasks took %f seconds", (double) totalTime / (double) 1000));
    }
    log.info("{} removeInitiator END...", storage.getSerialNumber());
}
Also used : HDSApiClient(com.emc.storageos.hds.api.HDSApiClient) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) AbstractHDSValidator(com.emc.storageos.volumecontroller.impl.validators.hds.AbstractHDSValidator) ExportMask(com.emc.storageos.db.client.model.ExportMask) HDSApiExportManager(com.emc.storageos.hds.api.HDSApiExportManager) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) HDSException(com.emc.storageos.hds.HDSException) ExportMaskValidationContext(com.emc.storageos.volumecontroller.impl.validators.contexts.ExportMaskValidationContext) HostStorageDomain(com.emc.storageos.hds.model.HostStorageDomain)

Aggregations

StringSetMap (com.emc.storageos.db.client.model.StringSetMap)158 StringSet (com.emc.storageos.db.client.model.StringSet)95 URI (java.net.URI)72 ArrayList (java.util.ArrayList)68 List (java.util.List)49 HashMap (java.util.HashMap)43 StoragePort (com.emc.storageos.db.client.model.StoragePort)37 Map (java.util.Map)32 Initiator (com.emc.storageos.db.client.model.Initiator)31 NamedURI (com.emc.storageos.db.client.model.NamedURI)31 StringMap (com.emc.storageos.db.client.model.StringMap)31 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)26 UnManagedVolume (com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume)26 ExportMask (com.emc.storageos.db.client.model.ExportMask)25 VirtualPool (com.emc.storageos.db.client.model.VirtualPool)25 HashSet (java.util.HashSet)22 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)21 TenantOrg (com.emc.storageos.db.client.model.TenantOrg)18 BlockConsistencyGroup (com.emc.storageos.db.client.model.BlockConsistencyGroup)17 Test (org.junit.Test)16