Search in sources :

Example 81 with NetworkLite

use of com.emc.storageos.util.NetworkLite in project coprhd-controller by CoprHD.

the class BlockStorageScheduler method getAllocatedPortsMap.

/**
 * Converts Map<NetworkLite, List<StoragePort> to Map<URI, List<StoragePort>
 * @param allocatedPorts map from NetworkLite to allocated ports
 * @return map from network URI to allocated ports
 */
private Map<URI, List<StoragePort>> getAllocatedPortsMap(Map<NetworkLite, List<StoragePort>> allocatedPorts) {
    Map<URI, List<StoragePort>> returnedPortMap = new HashMap<URI, List<StoragePort>>();
    for (Map.Entry<NetworkLite, List<StoragePort>> entry : allocatedPorts.entrySet()) {
        URI netURI = entry.getKey().getId();
        returnedPortMap.put(netURI, entry.getValue());
    }
    return returnedPortMap;
}
Also used : HashMap(java.util.HashMap) NetworkLite(com.emc.storageos.util.NetworkLite) StoragePort(com.emc.storageos.db.client.model.StoragePort) List(java.util.List) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) URI(java.net.URI) Map(java.util.Map) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) TreeMap(java.util.TreeMap)

Example 82 with NetworkLite

use of com.emc.storageos.util.NetworkLite in project coprhd-controller by CoprHD.

the class BlockStorageScheduler method assignPrezonedStoragePorts.

/**
 * Find the existing zones for a list of initiators. The initiators can be for a mask
 * that is being created or for a mask to which new initiators are added. In the latter
 * case the list of initiators would include only what is being added to the mask.
 * <p>
 * This existing zoning map returned by this function will be used by the port allocation code to give already zoned port priority over
 * other ports.
 * <p>
 * This function will only do its work if the config item controller_port_alloc_by_metrics_only is set to false. The default value of
 * the config is true.
 * <p>
 * This function will find existing zones for the list of initiators on the network system for all the storage system assignable ports.
 * If duplicate zones are found for an initiator-port pair, the existing zone selection algorithm is applied.
 * <p>
 * If zones were found on the network systems for the initiators and ports, there can be 3 possible scenarios
 * <ol>
 * <li>the number of existing paths is equal that what is requested in the vpool, in this case the port allocation/assignment code would
 * still be invoked but it will return no additional assignments</li>
 * <li>the number of existing paths is less that what is requested in the vpool, additional assignments will be made by the port
 * allocation/assignment code</li>
 * <li>Not all existing paths should be used, for example there are more paths than requested by the vpool or it could be that some
 * initiators have more paths that requested. The port allocation code is invoked to select the most favorable paths of the existing
 * ones.</li>
 * </ol>
 * Note that by using existing zones, the path-per-initiator may be violated.
 *
 * @param storage the storage system where the mask will be or was created
 * @param exportGroup the export group of the mask
 * @param initiators the initiators being added to the mask.
 * @param existingZoningMap this is the zoning map for an existing mask to which
 *            initiators are being added. It is null for new masks.
 * @param pathParams the export group aggregated path parameter
 * @param volumeURIs the volumes in the export mask
 * @param virtualArrayUri the URI of the export virtual array
 * @param token the workflow step Id
 * @return a map of existing zones paths between the storage system ports and the
 *         mask initiators.
 */
public StringSetMap assignPrezonedStoragePorts(StorageSystem storage, ExportGroup exportGroup, List<Initiator> initiators, StringSetMap existingZoningMap, ExportPathParams pathParams, Collection<URI> volumeURIs, NetworkDeviceController networkDeviceController, URI virtualArrayUri, String token) {
    // Prime the new zoning map with existing ones
    StringSetMap newZoningMap = new StringSetMap();
    if (existingZoningMap != null) {
        newZoningMap.putAll(existingZoningMap);
    }
    // check if this is a backend export
    boolean backend = ExportMaskUtils.areBackendInitiators(initiators);
    // Adjust the paths param based on whether at the end of this call the ports selected should meet the paths requirement
    ExportPathParams prezoningPathParams = getPrezoningPathParam(virtualArrayUri, pathParams, storage, backend);
    try {
        if (networkDeviceController == null) {
            return newZoningMap;
        }
        if (!NetworkUtil.areNetworkSystemDiscovered(_dbClient)) {
            _log.info("Cannot discover existing zones. There are no network systems discovered.");
            return newZoningMap;
        }
        if (!_networkScheduler.portAllocationUseExistingZones(storage.getSystemType(), backend)) {
            _log.info("The system configuration requests port selection to be based on metrics only " + "i.e. ignore existing zones when selecting ports.");
            return newZoningMap;
        }
        _log.info("Checking for existing zoned ports for export {} before invoking port allocation.", exportGroup.getGeneratedName());
        List<Initiator> newInitiators = new ArrayList<Initiator>();
        for (Initiator initiator : initiators) {
            if (!newZoningMap.containsKey(initiator.getId().toString())) {
                newInitiators.add(initiator);
            }
        }
        Map<Initiator, List<StoragePort>> assignments = new HashMap<Initiator, List<StoragePort>>();
        Map<Initiator, List<StoragePort>> existingAssignments = generateInitiatorsToStoragePortsMap(existingZoningMap, virtualArrayUri);
        if (!newInitiators.isEmpty()) {
            // discover existing zones that are for the storage system and varray
            // At this time we are not discovering routed zones but we will take care of this
            Collection<StoragePort> ports = ExportUtils.getStorageSystemAssignablePorts(_dbClient, storage.getId(), virtualArrayUri, pathParams);
            Map<NetworkLite, List<Initiator>> initiatorsByNetwork = NetworkUtil.getInitiatorsByNetwork(newInitiators, _dbClient);
            Map<Initiator, NetworkLite> initiatorToNetworkLiteMap = getInitiatorToNetworkLiteMap(initiatorsByNetwork);
            Map<NetworkLite, List<StoragePort>> portByNetwork = ExportUtils.mapStoragePortsToNetworks(ports, initiatorsByNetwork.keySet(), _dbClient);
            Map<NetworkLite, StringSetMap> zonesByNetwork = new HashMap<NetworkLite, StringSetMap>();
            // get all the prezoned ports for the initiators
            Map<NetworkLite, List<StoragePort>> preZonedPortsByNetwork = getPrezonedPortsForInitiators(networkDeviceController, portByNetwork, initiatorsByNetwork, zonesByNetwork, token);
            if (!preZonedPortsByNetwork.isEmpty()) {
                // trim the initiators to the pre-zoned ports
                StringMapUtil.retainAll(initiatorsByNetwork, preZonedPortsByNetwork);
                Map<NetworkLite, List<StoragePort>> allocatedPortsByNetwork = allocatePorts(storage, virtualArrayUri, initiatorsByNetwork, preZonedPortsByNetwork, volumeURIs, prezoningPathParams, existingZoningMap);
                Map<URI, List<StoragePort>> allocatedPortsMap = getAllocatedPortsMap(allocatedPortsByNetwork);
                // Get a map of Host to Network to Initiators
                Map<URI, Map<URI, List<Initiator>>> hostsToNetToInitiators = getHostInitiatorsMapFromNetworkLite(initiatorsByNetwork);
                // Compute the number of Ports needed for each Network
                StoragePortsAssigner assigner = StoragePortsAssignerFactory.getAssignerForZones(storage.getSystemType(), zonesByNetwork);
                // Assign the storage ports on a per host basis.
                for (Map.Entry<URI, Map<URI, List<Initiator>>> entry : hostsToNetToInitiators.entrySet()) {
                    URI hostURI = entry.getKey();
                    // The map of switch name to Initiators per network
                    Map<URI, Map<String, List<Initiator>>> switchInitiatorsByNet = new HashMap<URI, Map<String, List<Initiator>>>();
                    // The map of swtich name to storage ports per network
                    Map<URI, Map<String, List<StoragePort>>> switchStoragePortsByNet = new HashMap<URI, Map<String, List<StoragePort>>>();
                    Map<URI, List<Initiator>> initiatorByNetMap = entry.getValue();
                    PlacementUtils.getSwitchfoForInititaorsStoragePorts(initiatorByNetMap, allocatedPortsMap, _dbClient, storage, switchInitiatorsByNet, switchStoragePortsByNet);
                    assigner.assignPortsToHost(assignments, entry.getValue(), allocatedPortsMap, prezoningPathParams, existingAssignments, hostURI, initiatorToNetworkLiteMap, switchInitiatorsByNet, switchStoragePortsByNet);
                }
                addAssignmentsToZoningMap(assignments, newZoningMap);
            }
            // if manual zoning is on, then make sure the paths discovered meet the path requirement
            if (allocateFromPrezonedPortsOnly(virtualArrayUri, storage.getSystemType(), backend)) {
                try {
                    validateMinPaths(storage, prezoningPathParams, existingAssignments, assignments, newInitiators);
                } catch (PlacementException pex) {
                    _log.error("There are fewer pre-zoned paths than required by the virtual pool." + " Please either add the needed paths or enable automatic SAN zoning in the virtual array" + " so that the additional paths can be added by the application.", pex);
                    throw pex;
                }
            }
        }
        _log.info("Zoning map after the assignment of pre-zoned ports: {}", newZoningMap);
    } catch (Exception ex) {
        _log.error("Failed to assign from pre-zoned storage ports because: ", ex);
        if (allocateFromPrezonedPortsOnly(virtualArrayUri, storage.getSystemType(), backend)) {
            _log.error("The virtual array is configured for manual zoning and the application " + "cannot assign from other storage ports. Failing the workflow.");
            throw ex;
        } else {
            _log.info("The virtual array is configured for auto zoning and the application " + "will attempt to assign from other storage ports. Resuming the workflow.");
        }
    }
    return newZoningMap;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) URI(java.net.URI) Initiator(com.emc.storageos.db.client.model.Initiator) List(java.util.List) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) NetworkLite(com.emc.storageos.util.NetworkLite) StoragePort(com.emc.storageos.db.client.model.StoragePort) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) Map(java.util.Map) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) TreeMap(java.util.TreeMap) ExportPathParams(com.emc.storageos.db.client.model.ExportPathParams)

Example 83 with NetworkLite

use of com.emc.storageos.util.NetworkLite in project coprhd-controller by CoprHD.

the class BlockStorageScheduler method getPrezonedPortsForInitiators.

/**
 * Reads the existing zones for the initiators from the network system and finds all ports that are
 * already prezoned to one or more of the initiators.
 *
 * @param networkDeviceController an instance of networkDeviceController
 * @param portByNetwork the ports in the export mask grouped by network
 * @param initiatorsByNetwork the initiators of interest grouped by network
 * @param zonesByNetwork an OUT param to collect the zones found grouped by network
 * @param token the workflow step id
 * @return a map of ports in networks that are already zoned to one or more of the initiators
 */
public Map<NetworkLite, List<StoragePort>> getPrezonedPortsForInitiators(NetworkDeviceController networkDeviceController, Map<NetworkLite, List<StoragePort>> portByNetwork, Map<NetworkLite, List<Initiator>> initiatorsByNetwork, Map<NetworkLite, StringSetMap> zonesByNetwork, String token) {
    // so now we have a a collection of initiators and ports, let's get the zones
    Map<NetworkLite, List<StoragePort>> preZonedPortsByNetwork = new HashMap<NetworkLite, List<StoragePort>>();
    StringSetMap zonesInNetwork = null;
    Map<String, List<Zone>> initiatorWwnToZonesMap = new HashMap<String, List<Zone>>();
    for (NetworkLite network : portByNetwork.keySet()) {
        if (!Transport.FC.toString().equals(network.getTransportType())) {
            continue;
        }
        List<Initiator> networkInitiators = initiatorsByNetwork.get(network);
        if (networkInitiators == null || networkInitiators.isEmpty()) {
            continue;
        }
        Map<String, StoragePort> portByWwn = DataObjectUtils.mapByProperty(portByNetwork.get(network), "portNetworkId");
        URI[] networkSystemURIUsed = new URI[1];
        zonesInNetwork = networkDeviceController.getZoningMap(network, networkInitiators, portByWwn, initiatorWwnToZonesMap, networkSystemURIUsed);
        _log.info("Existing zones in network {} are {}", network.getNativeGuid(), zonesInNetwork);
        // if the OUT parameter is not null, fill in the discovered zones
        if (zonesByNetwork != null && !zonesInNetwork.isEmpty()) {
            zonesByNetwork.put(network, zonesInNetwork);
        }
        for (String iniId : zonesInNetwork.keySet()) {
            for (String portId : zonesInNetwork.get(iniId)) {
                StringMapUtil.addToListMap(preZonedPortsByNetwork, network, DataObjectUtils.findInCollection(portByNetwork.get(network), URI.create(portId)));
            }
        }
    }
    // now store the retrieved zones in ZK
    if (!initiatorWwnToZonesMap.isEmpty()) {
        Map<String, List<Zone>> zonesMap = (Map<String, List<Zone>>) WorkflowService.getInstance().loadWorkflowData(token, "zonemap");
        // some workflows call port allocation more than one time, rather than overriding, add to these zones to already stored zones.
        if (zonesMap == null) {
            zonesMap = initiatorWwnToZonesMap;
        } else {
            zonesMap.putAll(initiatorWwnToZonesMap);
        }
        WorkflowService.getInstance().storeWorkflowData(token, "zonemap", zonesMap);
    }
    return preZonedPortsByNetwork;
}
Also used : StringSetMap(com.emc.storageos.db.client.model.StringSetMap) HashMap(java.util.HashMap) NetworkLite(com.emc.storageos.util.NetworkLite) Zone(com.emc.storageos.networkcontroller.impl.mds.Zone) StoragePort(com.emc.storageos.db.client.model.StoragePort) URI(java.net.URI) Initiator(com.emc.storageos.db.client.model.Initiator) List(java.util.List) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) Map(java.util.Map) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) TreeMap(java.util.TreeMap)

Example 84 with NetworkLite

use of com.emc.storageos.util.NetworkLite in project coprhd-controller by CoprHD.

the class VPlexBackendManager method generateExportMasks.

private Map<ExportMask, ExportGroup> generateExportMasks(URI varrayURI, StorageSystem vplex, StorageSystem array, String stepId, StringBuilder errorMessages) {
    // Build the data structures used for analysis and validation.
    buildDataStructures(vplex, array, varrayURI);
    // Assign initiators to hosts
    String clusterName = getClusterName(vplex);
    Set<Map<String, Map<URI, Set<Initiator>>>> initiatorGroups = getInitiatorGroups(clusterName, _directorToInitiatorIds, _initiatorIdToNetwork, _idToInitiatorMap, array.getSystemType().equals(SystemType.vnxblock.name()), false);
    // First we must determine the Initiator Groups and PortGroups to be used.
    VplexBackEndMaskingOrchestrator orca = getOrch(array);
    // set VPLEX director count to set number of paths per director
    if (orca instanceof VplexXtremIOMaskingOrchestrator) {
        // get VPLEX director count
        int directorCount = getVplexDirectorCount(initiatorGroups);
        ((VplexXtremIOMaskingOrchestrator) orca).setVplexDirectorCount(directorCount);
    }
    // get the allocatable ports - if the custom config requests pre-zoned ports to be used
    // get the existing zones in zonesByNetwork
    Map<NetworkLite, StringSetMap> zonesByNetwork = new HashMap<NetworkLite, StringSetMap>();
    Map<URI, List<StoragePort>> allocatablePorts = getAllocatablePorts(array, _networkMap.keySet(), varrayURI, zonesByNetwork, stepId);
    Map<ExportMask, ExportGroup> exportMasksMap = new HashMap<ExportMask, ExportGroup>();
    if (allocatablePorts.isEmpty()) {
        String message = "No allocatable ports found for export to VPLEX backend. ";
        _log.warn(message);
        if (errorMessages != null) {
            errorMessages.append(message);
        }
        _log.warn("Returning empty export mask map because no allocatable ports could be found.");
        return exportMasksMap;
    }
    Map<URI, Map<String, Integer>> switchToPortNumber = getSwitchToMaxPortNumberMap(array);
    Set<Map<URI, List<List<StoragePort>>>> portGroups = orca.getPortGroups(allocatablePorts, _networkMap, varrayURI, initiatorGroups.size(), switchToPortNumber, null, errorMessages);
    // Now generate the Masking Views that will be needed.
    Map<URI, String> initiatorSwitchMap = new HashMap<URI, String>();
    Map<URI, Map<String, List<StoragePort>>> switchStoragePortsMap = new HashMap<URI, Map<String, List<StoragePort>>>();
    Map<URI, List<StoragePort>> storageports = getStoragePorts(portGroups);
    Map<URI, String> portSwitchMap = new HashMap<URI, String>();
    PlacementUtils.getSwitchNameForInititaorsStoragePorts(_initiators, storageports, _dbClient, array, initiatorSwitchMap, switchStoragePortsMap, portSwitchMap);
    Iterator<Map<String, Map<URI, Set<Initiator>>>> igIterator = initiatorGroups.iterator();
    // get the assigner needed - it is with a pre-zoned ports assigner or the default
    StoragePortsAssigner assigner = StoragePortsAssignerFactory.getAssignerForZones(array.getSystemType(), zonesByNetwork);
    for (Map<URI, List<List<StoragePort>>> portGroup : portGroups) {
        String maskName = clusterName.replaceAll("[^A-Za-z0-9_]", "_");
        _log.info("Generating ExportMask: " + maskName);
        if (!igIterator.hasNext()) {
            igIterator = initiatorGroups.iterator();
        }
        Map<String, Map<URI, Set<Initiator>>> initiatorGroup = igIterator.next();
        StringSetMap zoningMap = orca.configureZoning(portGroup, initiatorGroup, _networkMap, assigner, initiatorSwitchMap, switchStoragePortsMap, portSwitchMap);
        ExportMask exportMask = generateExportMask(array.getId(), maskName, portGroup, initiatorGroup, zoningMap);
        // Set a flag indicating that we do not want to remove zoningMap entries
        StringSetMap map = new StringSetMap();
        StringSet values = new StringSet();
        values.add(Boolean.TRUE.toString());
        map.put(ExportMask.DeviceDataMapKeys.ImmutableZoningMap.name(), values);
        if (array.getSystemType().equals(SystemType.vmax.name())) {
            // If VMAX, set consisteLUNs = false
            values = new StringSet();
            values.add(Boolean.FALSE.toString());
            map.put(ExportMask.DeviceDataMapKeys.VMAXConsistentLUNs.name(), values);
        }
        exportMask.addDeviceDataMap(map);
        // Create an ExportGroup for the ExportMask.
        List<Initiator> initiators = new ArrayList<Initiator>();
        for (String director : initiatorGroup.keySet()) {
            for (URI networkURI : initiatorGroup.get(director).keySet()) {
                for (Initiator initiator : initiatorGroup.get(director).get(networkURI)) {
                    initiators.add(initiator);
                }
            }
        }
        _dbClient.createObject(exportMask);
        ExportGroup exportGroup = ExportUtils.createVplexExportGroup(_dbClient, vplex, array, initiators, varrayURI, _projectURI, _tenantURI, 0, exportMask);
        exportMasksMap.put(exportMask, exportGroup);
    }
    return exportMasksMap;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) StringSet(com.emc.storageos.db.client.model.StringSet) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) URI(java.net.URI) Initiator(com.emc.storageos.db.client.model.Initiator) VplexBackEndMaskingOrchestrator(com.emc.storageos.volumecontroller.impl.block.VplexBackEndMaskingOrchestrator) StringSet(com.emc.storageos.db.client.model.StringSet) List(java.util.List) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) NetworkLite(com.emc.storageos.util.NetworkLite) ExportMask(com.emc.storageos.db.client.model.ExportMask) StoragePort(com.emc.storageos.db.client.model.StoragePort) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint) StoragePortsAssigner(com.emc.storageos.volumecontroller.placement.StoragePortsAssigner) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) VplexXtremIOMaskingOrchestrator(com.emc.storageos.volumecontroller.impl.block.VplexXtremIOMaskingOrchestrator) Map(java.util.Map) HashMap(java.util.HashMap) StringSetMap(com.emc.storageos.db.client.model.StringSetMap)

Example 85 with NetworkLite

use of com.emc.storageos.util.NetworkLite in project coprhd-controller by CoprHD.

the class VPlexBackendManager method getAllocatablePorts.

/**
 * Returns a list of all possible allocatable ports on an array for a given set of Networks.
 *
 * @param array
 *            the storage array
 * @param varray
 *            -- URI of varray
 * @param networkURI
 *            -- Set<URI> of networks
 * @param zonesByNetwork
 *            an OUT param to collect the zones found grouped by network
 * @param token
 *            the workflow step id
 *
 * @return
 */
public Map<URI, List<StoragePort>> getAllocatablePorts(StorageSystem array, Set<URI> networkURIs, URI varray, Map<NetworkLite, StringSetMap> zonesByNetwork, String stepId) {
    Collection<NetworkLite> networks = NetworkUtil.queryNetworkLites(networkURIs, _dbClient);
    Map<URI, List<StoragePort>> map = new HashMap<URI, List<StoragePort>>();
    // find all the available storage ports
    Map<NetworkLite, List<StoragePort>> tempMap = _blockStorageScheduler.selectStoragePortsInNetworks(array.getId(), networks, varray, null);
    // if the user requests to use only pre-zoned ports, then filter to pre-zoned ports only
    if (_networkDeviceController.getNetworkScheduler().portAllocationUseExistingZones(array.getSystemType(), true)) {
        Map<NetworkLite, List<Initiator>> initiatorsByNetwork = NetworkUtil.getInitiatorsByNetwork(_initiators, _dbClient);
        tempMap = _blockStorageScheduler.getPrezonedPortsForInitiators(_networkDeviceController, tempMap, initiatorsByNetwork, zonesByNetwork, stepId);
    }
    for (NetworkLite network : tempMap.keySet()) {
        map.put(network.getId(), tempMap.get(network));
    }
    return map;
}
Also used : HashMap(java.util.HashMap) NetworkLite(com.emc.storageos.util.NetworkLite) StoragePort(com.emc.storageos.db.client.model.StoragePort) List(java.util.List) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) URI(java.net.URI)

Aggregations

NetworkLite (com.emc.storageos.util.NetworkLite)130 StoragePort (com.emc.storageos.db.client.model.StoragePort)110 URI (java.net.URI)86 ArrayList (java.util.ArrayList)85 PortAllocationContext (com.emc.storageos.volumecontroller.placement.StoragePortsAllocator.PortAllocationContext)82 HashMap (java.util.HashMap)48 List (java.util.List)44 StringSetMap (com.emc.storageos.db.client.model.StringSetMap)25 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)22 Map (java.util.Map)22 HashSet (java.util.HashSet)20 Initiator (com.emc.storageos.db.client.model.Initiator)19 StringSet (com.emc.storageos.db.client.model.StringSet)19 TreeMap (java.util.TreeMap)10 Set (java.util.Set)9 SortedMap (java.util.SortedMap)9 StringMap (com.emc.storageos.db.client.model.StringMap)7 StoragePortsAllocator (com.emc.storageos.volumecontroller.placement.StoragePortsAllocator)6 DummyDbClient (com.emc.storageos.util.DummyDbClient)4 PortAllocatorTestContext (com.emc.storageos.volumecontroller.placement.PortAllocatorTestContext)4