Search in sources :

Example 11 with WBEMException

use of javax.wbem.WBEMException in project coprhd-controller by CoprHD.

the class VmaxSnapshotOperations method unlinkSnapshotSessionTarget.

/**
 * {@inheritDoc}
 */
@SuppressWarnings("rawtypes")
@Override
public void unlinkSnapshotSessionTarget(StorageSystem system, URI snapSessionURI, URI snapshotURI, Boolean deleteTarget, TaskCompleter completer) throws DeviceControllerException {
    // Only supported for VMAX3 storage systems.
    if (!system.checkIfVmax3()) {
        throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
    }
    try {
        _log.info("Unlink target {} from snapshot session {} START", snapshotURI, snapSessionURI);
        BlockSnapshot snapshot = _dbClient.queryObject(BlockSnapshot.class, snapshotURI);
        String targetDeviceId = snapshot.getNativeId();
        if (isNullOrEmpty(targetDeviceId)) {
            // The snapshot has no target device id. This means we must
            // have failed creating the target device for a link target
            // request and unlink target is being called in rollback.
            // Since the target was never created, we just return
            // success.
            _log.info("Snapshot target {} was never created.", snapshotURI);
            completer.ready(_dbClient);
            return;
        }
        // If the snapshot has a native id, then we at least
        // know the target device was created. Now we try and get
        // the sync object path representing the linked target so
        // that it can be detached.
        boolean syncObjectFound = false;
        List<BlockSnapshot> snapshots = null;
        BlockObject sourceObj = BlockObject.fetch(_dbClient, snapshot.getParent().getURI());
        CIMObjectPath syncObjectPath = SmisConstants.NULL_CIM_OBJECT_PATH;
        if (snapshot.hasConsistencyGroup() && NullColumnValueGetter.isNotNullValue(snapshot.getReplicationGroupInstance())) {
            String replicationGroupName = snapshot.getReplicationGroupInstance();
            String sourceReplicationGroupName = sourceObj.getReplicationGroupInstance();
            List<CIMObjectPath> groupSyncs = getAllGroupSyncObjects(system, snapshot);
            if (groupSyncs != null && !groupSyncs.isEmpty()) {
                // the passed snapshot is the sync'd element.
                for (CIMObjectPath groupSynchronized : groupSyncs) {
                    String syncElementPath = groupSynchronized.getKeyValue(SmisConstants.CP_SYNCED_ELEMENT).toString();
                    String systemElementPath = groupSynchronized.getKeyValue(SmisConstants.CP_SYSTEM_ELEMENT).toString();
                    if (syncElementPath.contains(replicationGroupName) && systemElementPath.contains(sourceReplicationGroupName)) {
                        syncObjectPath = groupSynchronized;
                        break;
                    }
                }
            }
            snapshots = ControllerUtils.getSnapshotsPartOfReplicationGroup(snapshot, _dbClient);
        } else {
            syncObjectPath = getSyncObject(system, snapshot, sourceObj);
            snapshots = Lists.newArrayList(snapshot);
        }
        if (!SmisConstants.NULL_CIM_OBJECT_PATH.equals(syncObjectPath)) {
            syncObjectFound = true;
            CIMArgument[] inArgs = _helper.getUnlinkBlockSnapshotSessionTargetInputArguments(syncObjectPath);
            CIMArgument[] outArgs = new CIMArgument[5];
            CIMObjectPath replicationSvcPath = _cimPath.getControllerReplicationSvcPath(system);
            SmisBlockSnapshotSessionUnlinkTargetJob job = new SmisBlockSnapshotSessionUnlinkTargetJob(null, system.getId(), completer);
            _helper.invokeMethodSynchronously(system, replicationSvcPath, SmisConstants.MODIFY_REPLICA_SYNCHRONIZATION, inArgs, outArgs, job);
            // Succeeded in unlinking the target from the snapshot.
            for (BlockSnapshot snapshotToUpdate : snapshots) {
                snapshotToUpdate.setSettingsInstance(NullColumnValueGetter.getNullStr());
            }
            _dbClient.updateObject(snapshots);
        } else {
            // For some reason we could not find the path for the
            // CIM_StorageSychronized instance for the linked target.
            // If the settingsInstance for the snapshot is not set,
            // this may mean we just failed a link target request
            // and unlink target is being called in rollback. In this
            // case we successfully created the target volume, but
            // failed to link the target to the snapshot, in which
            // case the settingsInstance would be null. Otherwise,
            // we could be retrying a failed unlink request. In this
            // case, we must have succeeded in unlinking the target
            // from the array snapshot, but failed attempting to
            // delete the target volume. If the unlink is successful,
            // the settingsInstance is reset to null. So, if the
            // settingsInstance is null, we move on without failing.
            // Otherwise, we should throw an exception.
            String settingsInstance = snapshot.getSettingsInstance();
            if (NullColumnValueGetter.isNotNullValue(settingsInstance)) {
                throw DeviceControllerException.exceptions.couldNotFindSyncObjectToUnlinkTarget(targetDeviceId);
            }
        }
        if (deleteTarget) {
            _log.info("Delete target device {} :{}", targetDeviceId, snapshotURI);
            Collection<String> nativeIds = transform(snapshots, fctnBlockObjectToNativeID());
            if (snapshot.hasConsistencyGroup() && NullColumnValueGetter.isNotNullValue(snapshot.getReplicationGroupInstance())) {
                try {
                    checkReplicationGroupAccessibleOrFail(system, snapshot, _dbClient, _helper, _cimPath);
                    deleteTargetGroup(system, snapshot.getReplicationGroupInstance());
                } catch (DeviceControllerException | WBEMException e) {
                    _log.info("Failed to delete the target group.  It may have already been deleted.");
                }
            }
            // remove snapshot from them before deleting it.
            for (BlockSnapshot snap : snapshots) {
                try {
                    _helper.removeVolumeFromStorageGroupsIfVolumeIsNotInAnyMV(system, snap);
                } catch (Exception e) {
                    _log.info("Failed to remove snap {} from storage groups.  It may have already been removed.", snap.getNativeGuid());
                }
            }
            callEMCRefresh(_helper, system, true);
            deleteTargetDevices(system, nativeIds.toArray(new String[] {}), completer);
            _log.info("Delete target device complete");
        } else if (!syncObjectFound) {
            // Need to be sure the completer is called.
            completer.ready(_dbClient);
        }
    } catch (Exception e) {
        _log.error("Exception unlinking snapshot session target", e);
        ServiceError error = DeviceControllerErrors.smis.unableToCallStorageProvider(e.getMessage());
        completer.error(_dbClient, error);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) SmisBlockSnapshotSessionUnlinkTargetJob(com.emc.storageos.volumecontroller.impl.smis.job.SmisBlockSnapshotSessionUnlinkTargetJob) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) CIMObjectPath(javax.cim.CIMObjectPath) WBEMException(javax.wbem.WBEMException) SmisException(com.emc.storageos.volumecontroller.impl.smis.SmisException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) WBEMException(javax.wbem.WBEMException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) BlockObject(com.emc.storageos.db.client.model.BlockObject) CIMArgument(javax.cim.CIMArgument)

Example 12 with WBEMException

use of javax.wbem.WBEMException in project coprhd-controller by CoprHD.

the class VnxExportOperations method deleteStorageHWIDs.

/**
 * Method invokes the SMI-S operation to remove the initiator hardware ID from the
 * array. This should be called whenever the initiator is removed from an export or
 * when the export is deleted.
 *
 * @param storage
 *            [in] - StorageSystem representing the array
 * @param initiators
 *            [in] - An array Initiator objects, whose representation will
 *            be removed from the array.
 * @throws Exception
 */
private void deleteStorageHWIDs(StorageSystem storage, List<Initiator> initiators) throws Exception {
    if (initiators == null || initiators.isEmpty()) {
        _log.debug("No initiators ...");
        return;
    }
    CIMObjectPath hwIdManagementSvc = _cimPath.getStorageHardwareIDManagementService(storage);
    for (Initiator initiator : initiators) {
        try {
            CIMArgument[] createHwIdIn = _helper.getDeleteStorageHardwareIDArgs(storage, initiator);
            CIMArgument[] createHwIdOut = new CIMArgument[5];
            _helper.invokeMethod(storage, hwIdManagementSvc, SmisConstants.DELETE_STORAGE_HARDWARE_ID, createHwIdIn, createHwIdOut);
        } catch (WBEMException e) {
            _log.error("deleteStorageHWIDs -- WBEMException: " + e.getMessage());
            throw e;
        } catch (Exception e) {
            _log.error("deleteStorageHWIDs -- Exception: " + e.getMessage());
            throw e;
        }
    }
}
Also used : Initiator(com.emc.storageos.db.client.model.Initiator) CIMObjectPath(javax.cim.CIMObjectPath) WBEMException(javax.wbem.WBEMException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) WBEMException(javax.wbem.WBEMException) SmisException(com.emc.storageos.volumecontroller.impl.smis.SmisException) CIMArgument(javax.cim.CIMArgument)

Example 13 with WBEMException

use of javax.wbem.WBEMException in project coprhd-controller by CoprHD.

the class VnxExportOperations method getEMCTargetEndpoints.

/**
 * Looks up the targets that are associated with the initiator (if any).
 *
 * @param idMgmtSvcPath
 *            [in] - Clar_StorageHardwareIDManagementService CIMObjectPath
 * @param storage
 *            [in] - StorageSystem object representing the array
 * @param initiator
 *            [in] - CIMObjectPath representing initiator to lookup target endpoints (StoragePorts) for
 * @return List or StoragePort URIs that were found to be end points for the initiator
 * @throws Exception
 */
private List<String> getEMCTargetEndpoints(CIMObjectPath idMgmtSvcPath, StorageSystem storage, CIMObjectPath initiator) throws Exception {
    List<String> endpoints = new ArrayList<>();
    try {
        CIMArgument[] input = _helper.getEMCGetConnectedTargetEndpoints(initiator);
        CIMArgument[] output = new CIMArgument[5];
        _helper.invokeMethod(storage, idMgmtSvcPath, SmisConstants.EMC_GET_TARGET_ENDPOINTS, input, output);
        CIMObjectPath[] tePaths = (CIMObjectPath[]) _cimPath.getFromOutputArgs(output, SmisConstants.CP_TARGET_ENDPOINTS);
        if (tePaths != null) {
            for (CIMObjectPath tePath : tePaths) {
                CIMInstance teInstance = _helper.getInstance(storage, tePath, false, false, SmisConstants.PS_NAME);
                String tePortNetworkId = CIMPropertyFactory.getPropertyValue(teInstance, SmisConstants.CP_NAME);
                List<StoragePort> storagePorts = CustomQueryUtility.queryActiveResourcesByAltId(_dbClient, StoragePort.class, "portNetworkId", WWNUtility.getWWNWithColons(tePortNetworkId));
                for (StoragePort port : storagePorts) {
                    endpoints.add(port.getNativeGuid());
                }
            }
        }
        _log.info(String.format("Initiator %s has these target endpoints: [ %s ]", initiator.toString(), Joiner.on(',').join(endpoints)));
    } catch (WBEMException e) {
        // The initiator CIMObjectPath passed into this function was determined by getting
        // the associators to the StorageHardwareIDManagementService. When we call
        // getEMCTargetEndpoints, it is done based on seeing that the initiator is in this
        // associator list. Sometimes, the provider is returing initiator CIMObjectPaths
        // that actually do not exist on the array. In this case, there will be WBEMException
        // thrown when we try to get the targets storage ports using this CIMObject reference.
        // So, here we're trying to protect against this possibility.
        _log.info(String.format("Could not get TargetEndPoints for %s - %s", initiator, e.getMessage()));
    }
    return endpoints;
}
Also used : ArrayList(java.util.ArrayList) CIMObjectPath(javax.cim.CIMObjectPath) StoragePort(com.emc.storageos.db.client.model.StoragePort) WBEMException(javax.wbem.WBEMException) CIMInstance(javax.cim.CIMInstance) CIMArgument(javax.cim.CIMArgument)

Example 14 with WBEMException

use of javax.wbem.WBEMException in project coprhd-controller by CoprHD.

the class VnxExportOperations method refreshExportMask.

@Override
public ExportMask refreshExportMask(StorageSystem storage, ExportMask mask) throws DeviceControllerException {
    try {
        CIMInstance instance = _helper.getLunMaskingProtocolController(storage, mask);
        if (instance != null) {
            StringBuilder builder = new StringBuilder();
            WBEMClient client = _helper.getConnection(storage).getCimClient();
            String name = CIMPropertyFactory.getPropertyValue(instance, SmisConstants.CP_ELEMENT_NAME);
            // Get volumes and initiators for the masking instance
            Map<String, Integer> discoveredVolumes = _helper.getVolumesFromLunMaskingInstance(client, instance);
            // Update user added volume's HLU information in ExportMask and ExportGroup
            ExportMaskUtils.updateHLUsInExportMask(mask, discoveredVolumes, _dbClient);
            List<String> discoveredPorts = _helper.getInitiatorsFromLunMaskingInstance(client, instance);
            Set existingInitiators = (mask.getExistingInitiators() != null) ? mask.getExistingInitiators() : Collections.emptySet();
            Set existingVolumes = (mask.getExistingVolumes() != null) ? mask.getExistingVolumes().keySet() : Collections.emptySet();
            builder.append(String.format("%nXM existing objects: %s I{%s} V:{%s}%n", name, Joiner.on(',').join(existingInitiators), Joiner.on(',').join(existingVolumes)));
            builder.append(String.format("XM discovered: %s I:{%s} V:{%s}%n", name, Joiner.on(',').join(discoveredPorts), Joiner.on(',').join(discoveredVolumes.keySet())));
            List<String> initiatorsToAddToExisting = new ArrayList<String>();
            List<Initiator> initiatorsToAddToUserAddedAndInitiatorList = new ArrayList<Initiator>();
            /**
             * For the newly discovered initiators, if they are ViPR discovered ports and belong to same resource
             * add them to user added and initiators list, otherwise add to existing list.
             */
            for (String port : discoveredPorts) {
                String normalizedPort = Initiator.normalizePort(port);
                if (!mask.hasExistingInitiator(normalizedPort) && !mask.hasUserInitiator(normalizedPort)) {
                    Initiator existingInitiator = ExportUtils.getInitiator(Initiator.toPortNetworkId(port), _dbClient);
                    // Don't add additional initiator to initiators list if it belongs to different host/cluster
                    if (existingInitiator != null && !ExportMaskUtils.checkIfDifferentResource(mask, existingInitiator)) {
                        _log.info("Initiator {}->{} belonging to same compute, adding to userAdded and initiator list.", normalizedPort, existingInitiator.getId());
                        initiatorsToAddToUserAddedAndInitiatorList.add(existingInitiator);
                    } else {
                        initiatorsToAddToExisting.add(normalizedPort);
                    }
                }
            }
            /**
             * Get the existing initiators from the mask and remove the non-discovered ports because
             * they are not discovered and are stale.
             *
             * If the mask has existing initiators but if they are discovered and belongs to same compute resource, then the
             * initiators has to get added to user Added and initiators list, and removed from existing list.
             */
            List<String> initiatorsToRemoveFromExistingList = new ArrayList<String>();
            if (mask.getExistingInitiators() != null && !mask.getExistingInitiators().isEmpty()) {
                for (String existingInitiatorStr : mask.getExistingInitiators()) {
                    if (!discoveredPorts.contains(existingInitiatorStr)) {
                        initiatorsToRemoveFromExistingList.add(existingInitiatorStr);
                    } else {
                        Initiator existingInitiator = ExportUtils.getInitiator(Initiator.toPortNetworkId(existingInitiatorStr), _dbClient);
                        if (existingInitiator != null && !ExportMaskUtils.checkIfDifferentResource(mask, existingInitiator)) {
                            _log.info("Initiator {}->{} belonging to same compute, removing from existing," + " and adding to userAdded and initiator list", existingInitiatorStr, existingInitiator.getId());
                            initiatorsToAddToUserAddedAndInitiatorList.add(existingInitiator);
                            initiatorsToRemoveFromExistingList.add(existingInitiatorStr);
                        }
                    }
                }
            }
            /**
             * Get all the initiators from the mask and remove all the ViPR discovered ports.
             * The remaining list has to be removed from user Added and initiator list, because they are not available in ViPR
             * but has to be moved to existing list.
             */
            List<URI> initiatorsToRemoveFromUserAddedAndInitiatorList = new ArrayList<URI>();
            if (mask.getInitiators() != null && !mask.getInitiators().isEmpty()) {
                initiatorsToRemoveFromUserAddedAndInitiatorList.addAll(transform(mask.getInitiators(), CommonTransformerFunctions.FCTN_STRING_TO_URI));
                for (String port : discoveredPorts) {
                    String normalizedPort = Initiator.normalizePort(port);
                    Initiator initiatorDiscoveredInViPR = ExportUtils.getInitiator(Initiator.toPortNetworkId(port), _dbClient);
                    if (initiatorDiscoveredInViPR != null) {
                        initiatorsToRemoveFromUserAddedAndInitiatorList.remove(initiatorDiscoveredInViPR.getId());
                    } else if (!mask.hasExistingInitiator(normalizedPort)) {
                        _log.info("Initiator {} not found in database, removing from user Added and initiator list," + " and adding to existing list.", port);
                        initiatorsToAddToExisting.add(normalizedPort);
                    }
                }
            }
            boolean removeInitiators = !initiatorsToRemoveFromExistingList.isEmpty() || !initiatorsToRemoveFromUserAddedAndInitiatorList.isEmpty();
            boolean addInitiators = !initiatorsToAddToUserAddedAndInitiatorList.isEmpty() || !initiatorsToAddToExisting.isEmpty();
            // Check the volumes and update the lists as necessary
            Map<String, Integer> volumesToAdd = ExportMaskUtils.diffAndFindNewVolumes(mask, discoveredVolumes);
            boolean addVolumes = !volumesToAdd.isEmpty();
            boolean removeVolumes = false;
            List<String> volumesToRemove = new ArrayList<String>();
            if (mask.getExistingVolumes() != null && !mask.getExistingVolumes().isEmpty()) {
                volumesToRemove.addAll(mask.getExistingVolumes().keySet());
                volumesToRemove.removeAll(discoveredVolumes.keySet());
            }
            // if the volume is in export mask's user added volumes and also in the existing volumes, remove from existing volumes
            for (String wwn : discoveredVolumes.keySet()) {
                if (mask.hasExistingVolume(wwn)) {
                    URIQueryResultList volumeList = new URIQueryResultList();
                    _dbClient.queryByConstraint(AlternateIdConstraint.Factory.getVolumeWwnConstraint(wwn), volumeList);
                    if (volumeList.iterator().hasNext()) {
                        URI volumeURI = volumeList.iterator().next();
                        if (mask.hasUserCreatedVolume(volumeURI)) {
                            builder.append(String.format("\texisting volumes contain wwn %s, but it is also in the " + "export mask's user added volumes, so removing from existing volumes", wwn));
                            volumesToRemove.add(wwn);
                        }
                    }
                }
            }
            removeVolumes = !volumesToRemove.isEmpty();
            // NOTE/TODO: We are not modifying the storage ports upon refresh like we do for VMAX.
            // Refer to CTRL-6982.
            builder.append(String.format("XM refresh: %s existing initiators; add:{%s} remove:{%s}%n", name, Joiner.on(',').join(initiatorsToAddToExisting), Joiner.on(',').join(initiatorsToRemoveFromExistingList)));
            builder.append(String.format("XM refresh: %s user added and initiator list; add:{%s} remove:{%s}%n", name, Joiner.on(',').join(initiatorsToAddToUserAddedAndInitiatorList), Joiner.on(',').join(initiatorsToRemoveFromUserAddedAndInitiatorList)));
            builder.append(String.format("XM refresh: %s volumes; add:{%s} remove:{%s}%n", name, Joiner.on(',').join(volumesToAdd.keySet()), Joiner.on(',').join(volumesToRemove)));
            // Any changes indicated, then update the mask and persist it
            if (addInitiators || removeInitiators || addVolumes || removeVolumes) {
                builder.append("XM refresh: There are changes to mask, " + "updating it...\n");
                mask.removeFromExistingInitiators(initiatorsToRemoveFromExistingList);
                mask.removeInitiatorURIs(initiatorsToRemoveFromUserAddedAndInitiatorList);
                mask.removeFromUserAddedInitiatorsByURI(initiatorsToRemoveFromUserAddedAndInitiatorList);
                mask.addInitiators(initiatorsToAddToUserAddedAndInitiatorList);
                mask.addToUserCreatedInitiators(initiatorsToAddToUserAddedAndInitiatorList);
                mask.addToExistingInitiatorsIfAbsent(initiatorsToAddToExisting);
                mask.removeFromExistingVolumes(volumesToRemove);
                mask.addToExistingVolumesIfAbsent(volumesToAdd);
                // Update the volume list to include existing volumes if know about them.
                if (addVolumes) {
                    for (String wwn : volumesToAdd.keySet()) {
                        URIQueryResultList results = new URIQueryResultList();
                        _dbClient.queryByConstraint(AlternateIdConstraint.Factory.getVolumeWwnConstraint(wwn.toUpperCase()), results);
                        if (results != null) {
                            Iterator<URI> resultsIter = results.iterator();
                            if (resultsIter.hasNext()) {
                                Volume volume = _dbClient.queryObject(Volume.class, resultsIter.next());
                                if (null != volume) {
                                    mask.addVolume(volume.getId(), volumesToAdd.get(wwn));
                                }
                            }
                        }
                    }
                }
                ExportMaskUtils.sanitizeExportMaskContainers(_dbClient, mask);
                _dbClient.updateObject(mask);
            } else {
                builder.append("XM refresh: There are no changes to the mask\n");
            }
            _networkDeviceController.refreshZoningMap(mask, transform(initiatorsToRemoveFromUserAddedAndInitiatorList, CommonTransformerFunctions.FCTN_URI_TO_STRING), Collections.<String>emptyList(), (addInitiators || removeInitiators), true);
            _log.info(builder.toString());
        }
    } catch (Exception e) {
        boolean throwException = true;
        if (e instanceof WBEMException) {
            WBEMException we = (WBEMException) e;
            // Only throw exception if code is not CIM_ERROR_NOT_FOUND
            throwException = (we.getID() != WBEMException.CIM_ERR_NOT_FOUND);
        }
        if (throwException) {
            String msg = "Error when attempting to query LUN masking information: " + e.getMessage();
            _log.error(MessageFormat.format("Encountered an SMIS error when attempting to refresh existing exports: {0}", msg), e);
            throw SmisException.exceptions.refreshExistingMaskFailure(msg, e);
        }
    }
    return mask;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) ArrayList(java.util.ArrayList) WBEMException(javax.wbem.WBEMException) URI(java.net.URI) CIMInstance(javax.cim.CIMInstance) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) WBEMException(javax.wbem.WBEMException) SmisException(com.emc.storageos.volumecontroller.impl.smis.SmisException) Initiator(com.emc.storageos.db.client.model.Initiator) Volume(com.emc.storageos.db.client.model.Volume) WBEMClient(javax.wbem.client.WBEMClient)

Example 15 with WBEMException

use of javax.wbem.WBEMException in project coprhd-controller by CoprHD.

the class VnxExportOperations method createOrGrowStorageGroup.

private CIMObjectPath[] createOrGrowStorageGroup(StorageSystem storage, URI exportMaskURI, VolumeURIHLU[] volumeURIHLUs, List<Initiator> initiatorList, List<URI> targetURIList, TaskCompleter completer) throws Exception {
    // TODO - Refactor createOrGrowStorageGroup by moving code for creating an empty storage group
    // to its own createStorageGroup method which calls exposePaths with null for initiators
    // and targets
    _log.info("{} createOrGrowStorageGroup START...", storage.getSerialNumber());
    try {
        List<CIMObjectPath> paths = new ArrayList<CIMObjectPath>();
        Map<String, CIMObjectPath> existingHwStorageIds = getStorageHardwareIds(storage);
        // If so, we need to register that initiator as the same name as the existing initiators. (CTRL-8407)
        if (initiatorList != null) {
            for (Initiator initiator : initiatorList) {
                updateInitiatorBasedOnPeers(storage, existingHwStorageIds, initiator);
                if (initiator != null) {
                    _log.info("After updateIntiatorBasedOnPeers : {} {}", initiator.getHostName(), initiator.toString());
                }
            }
        }
        Multimap<String, String> existingTargets = createStorageHWIDs(storage, existingHwStorageIds, initiatorList, completer);
        if (initiatorList != null && existingTargets.keySet().size() == initiatorList.size()) {
            _log.info(String.format("All the initiators are known to the array and have target endpoints: %s\n." + "These are the targets %s", Joiner.on(',').join(existingTargets.entries()), Joiner.on(',').join(targetURIList)));
        }
        Multimap<URI, Initiator> targetPortsToInitiators = HashMultimap.create();
        // Some of the Initiators are already registered partially on the array based on pre existing zoning
        // COP-16954 We need to manually register them, the Initiators will have HardwareId created but,
        // The registration is not complete.. createHardwareIDs method above will include those Initiators
        _log.info("Preregistered Target and Initiator ports processing .. Start");
        // Map to hash translations
        HashMap<String, URI> targetPortMap = new HashMap<>();
        for (String initPort : existingTargets.keySet()) {
            _log.info("InitiatorPort {} and TargetStoragePort {}", initPort, existingTargets.get(initPort));
            // CLARIION+CKM00115001014+PORT+50:06:01:61:3E:A0:45:79]
            if (!WWNUtility.isValidNoColonWWN(initPort)) {
                _log.info("InitiatorPort {} is not a valid FC WWN so ignore it", initPort);
                continue;
            }
            Collection<String> targetPorts = existingTargets.get(initPort);
            for (String targetPortGuid : targetPorts) {
                URI targetPortURI = targetPortMap.get(targetPortGuid);
                if (targetPortURI == null) {
                    targetPortURI = getStoragePortURI(targetPortGuid);
                    targetPortMap.put(targetPortGuid, targetPortURI);
                }
                Initiator translatedInitiator = getInitiatorForWWN(initPort);
                _log.info("Calculating Initiator {} and Target {}", translatedInitiator, targetPortURI);
                if (targetPortURI != null && translatedInitiator != null) {
                    targetPortsToInitiators.put(targetPortURI, translatedInitiator);
                } else {
                    _log.info("Initiator WWN {} translation was null or targetPort is null {}", initPort, targetPortURI);
                }
            }
        }
        _log.info("Preregistered Target and Initiator ports processing .. End");
        List<URI> volumeURIs = new ArrayList<URI>();
        if (volumeURIHLUs != null && volumeURIHLUs.length > 0) {
            for (VolumeURIHLU volumeURIHLU : volumeURIHLUs) {
                volumeURIs.add(volumeURIHLU.getVolumeURI());
            }
        }
        if (initiatorList == null || initiatorList.isEmpty()) {
            _log.info("InitiatorList is null or Empty so call exposePathsWithVolumesOnly");
            paths.addAll(Arrays.asList(exposePathsWithVolumesOnly(storage, exportMaskURI, volumeURIHLUs)));
        } else {
            ExportMask mask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
            for (Initiator initiator : initiatorList) {
                // TODO - Ask Tom is there is a reason why we should not do this instead of old code
                List<URI> tzTargets = ExportUtils.getInitiatorPortsInMask(mask, initiator, _dbClient);
                _log.info("Calculating Intiator {} and Targets {}", initiator, tzTargets);
                if (!tzTargets.isEmpty()) {
                    for (URI targetURI : tzTargets) {
                        targetPortsToInitiators.put(targetURI, initiator);
                    }
                }
            }
            _log.info("Call manuallyRegisterHostInitiators with {} ", targetPortsToInitiators.toString());
            // Register the initiator to target port mappings
            manuallyRegisterHostInitiators(storage, targetPortsToInitiators);
            // CTRL-9086
            // Modify the list of initiators list to match what is being mapped. If there are any initiators
            // that are passed to the ExposePaths call that weren't manuallyRegistered (above), then those
            // initiators will automatically get mapped all the array's StoragePorts.
            // 
            // If the targetPortsToInitiators MultiMap is empty, then we will send all the initiators.
            // Presumably, in this situation there are already some existing mappings for the initiators,
            // so would just need to call ExposePaths with those initiators, so that they get added to the
            // StorageGroup
            List<Initiator> initiatorsToExpose = initiatorList;
            if (!targetPortsToInitiators.isEmpty()) {
                Map<URI, Initiator> uniqueInitiatorMap = new HashMap<>();
                for (Collection<Initiator> initiatorCollection : targetPortsToInitiators.asMap().values()) {
                    for (Initiator initiator : initiatorCollection) {
                        uniqueInitiatorMap.put(initiator.getId(), initiator);
                    }
                }
                initiatorsToExpose = new ArrayList<>(uniqueInitiatorMap.values());
                // confused about the initiators.
                if (completer instanceof ExportMaskCreateCompleter) {
                    ExportMaskCreateCompleter createCompleter = ((ExportMaskCreateCompleter) completer);
                    List<URI> removedInitiators = new ArrayList<>();
                    List<URI> maskInitiators = StringSetUtil.stringSetToUriList(mask.getInitiators());
                    for (URI maskInitiator : maskInitiators) {
                        if (!uniqueInitiatorMap.containsKey(maskInitiator)) {
                            mask.removeInitiator(maskInitiator);
                            removedInitiators.add(maskInitiator);
                        }
                    }
                    _dbClient.updateObject(mask);
                    if (!removedInitiators.isEmpty()) {
                        _log.info(String.format("The following initiators will not be mapped, hence they will be " + "removed from the initiator list of ExportMask %s (%s): %s", mask.getMaskName(), mask.getId(), Joiner.on(',').join(removedInitiators)));
                    }
                    // Adjust the completer's initiator list
                    createCompleter.removeInitiators(removedInitiators);
                }
            }
            _log.info(String.format("ExposePaths will be called with these initiators: %s", Joiner.on(',').join(Collections2.transform(initiatorsToExpose, CommonTransformerFunctions.fctnInitiatorToPortName()))));
            // Add all the initiators to the StorageGroup
            paths.addAll(Arrays.asList(exposePathsWithVolumesAndInitiatorsOnly(storage, exportMaskURI, volumeURIHLUs, initiatorsToExpose)));
        }
        ExportOperationContext.insertContextOperation(completer, VnxExportOperationContext.OPERATION_ADD_VOLUMES_TO_STORAGE_GROUP, volumeURIs);
        _log.info("{} createOrGrowStorageGroup END...", storage.getSerialNumber());
        return paths.toArray(new CIMObjectPath[paths.size()]);
    } catch (WBEMException e) {
        _log.error("Problem making SMI-S call: ", e);
        throw e;
    } catch (Exception e) {
        _log.error("Unexpected error: createOrGrowStorageGroup failed.", e);
        throw e;
    }
}
Also used : HashMap(java.util.HashMap) ExportMask(com.emc.storageos.db.client.model.ExportMask) CIMObjectPath(javax.cim.CIMObjectPath) ArrayList(java.util.ArrayList) WBEMException(javax.wbem.WBEMException) URI(java.net.URI) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) WBEMException(javax.wbem.WBEMException) SmisException(com.emc.storageos.volumecontroller.impl.smis.SmisException) ExportMaskCreateCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskCreateCompleter) Initiator(com.emc.storageos.db.client.model.Initiator) VolumeURIHLU(com.emc.storageos.volumecontroller.impl.VolumeURIHLU)

Aggregations

WBEMException (javax.wbem.WBEMException)122 CIMObjectPath (javax.cim.CIMObjectPath)90 CIMInstance (javax.cim.CIMInstance)63 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)60 CIMArgument (javax.cim.CIMArgument)52 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)38 ArrayList (java.util.ArrayList)29 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)27 Volume (com.emc.storageos.db.client.model.Volume)22 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)19 WBEMClient (javax.wbem.client.WBEMClient)19 SmisException (com.emc.storageos.volumecontroller.impl.smis.SmisException)16 HashSet (java.util.HashSet)15 URI (java.net.URI)13 HashMap (java.util.HashMap)13 BlockObject (com.emc.storageos.db.client.model.BlockObject)10 BlockSnapshot (com.emc.storageos.db.client.model.BlockSnapshot)10 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)10 QueueJob (com.emc.storageos.volumecontroller.impl.job.QueueJob)9 CimConnection (com.emc.storageos.cimadapter.connections.cim.CimConnection)8