package com.onaro.sanscreen.client.view.common.functions; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.IProgressMonitor; import com.onaro.client.ClientUIUtils; import com.onaro.sanscreen.client.view.common.data.PortConnectionInfo; import com.onaro.sanscreen.server.interfaces.ServerInterfacesUtils; import com.onaro.sanscreen.server.interfaces.data.Context; import com.onaro.sanscreen.server.interfaces.data.ServerInterfaceException; import com.onaro.sanscreen.server.interfaces.data.inventory.FcNameServerEntry; import com.onaro.sanscreen.server.interfaces.data.inventory.Port; import com.onaro.sanscreen.server.interfaces.remote.InventoryRemote; /** * Immutable class for determining the ports (if any) used for a connection from a node port to a * fabric switch via a proxy switch (NPV device or Access Gateway). */ public class ProxyConnection { private static final InventoryRemote INVENTORY = ServerInterfacesUtils.getInventory(); private final Port proxySwitchPort; private final Port proxyNodePort; private final Port fabricSwitchPort; /** * Queries the server for the proxy node ports (e.g., NP-ports) and fabric switch ports, if any, * for a set of node port connections. There can only be a proxy node port and fabric switch port * for nodes connected to a proxy switch port (e.g., NPV switch F-port). * * @param connectedPortByNodePortId {@link Map} of node port ID to connected Port * @param context server load context * @param monitor the progress monitor to display progress and receive cancellation requests, * may be {code null} * @return {@link ProxyPorts}, which may be empty if no nodes are connected to a proxy switch * @throws InterruptedException * @throws ServerInterfaceException */ public static Map queryConnection (Map connectedPortByNodePortId, Context context, IProgressMonitor monitor) throws InterruptedException, ServerInterfaceException { // Create set of nodeIds. New set is necessary because can't marshal Set backed by Map. Set nodePortIds = new HashSet (connectedPortByNodePortId.keySet()); // Get FcNameServerEntries (FC login info). Map> nameServerEntriesByPort = INVENTORY.getFcNameServerEntriesByNxPorts(context, nodePortIds); ClientUIUtils.checkInterrupted(monitor); // Get fabric switch and proxy node port IDs from first name server entry for each connection. // NOTE: There is a set of name server entries to handle possible future extension for Tape ports. Map fabricSwitchPortIds = new HashMap(); Map proxyNodePortIds = new HashMap(); for (Map.Entry> mapEntry: nameServerEntriesByPort.entrySet()) { FcNameServerEntry nameServerEntry = mapEntry.getValue().iterator().next(); Long nodePortId = mapEntry.getKey(); Long fabricSwitchPortId = nameServerEntry.getSwitchPortId(); // Check for connection to proxy switch. Port connectedPort = connectedPortByNodePortId.get(nodePortId); if (connectedPort != null && ! connectedPort.isGenerated() && ! connectedPort.getId().equals(fabricSwitchPortId)) { fabricSwitchPortIds.put (nodePortId, fabricSwitchPortId); proxyNodePortIds.put (nodePortId, nameServerEntry.getPhysicalPortId()); } } // Return the proxy connections, if any. if (proxyNodePortIds.isEmpty()) { // No nodes with proxy connections. return Collections.emptyMap(); } else { // Get the proxy node and fabric switch Port objects. int proxyConnectionCount = fabricSwitchPortIds.size(); Set portIds = new HashSet(2 * proxyConnectionCount); portIds.addAll (fabricSwitchPortIds.values()); portIds.addAll (proxyNodePortIds.values()); Map portsByPortIds = INVENTORY.getSwitchOrGenericPorts (context, portIds); ClientUIUtils.checkInterrupted(monitor); // Create a map entry for each node with a proxy connection. Map proxies = new HashMap(proxyConnectionCount); for (Map.Entry nodeConnection: connectedPortByNodePortId.entrySet()) { Long nodePortId = nodeConnection.getKey(); Long npvNodePortId = proxyNodePortIds.get (nodePortId); if (npvNodePortId != null) { Port npvSwitchPort = nodeConnection.getValue(); Port npvNodePort = portsByPortIds.get (npvNodePortId); Port switchPort = portsByPortIds.get (fabricSwitchPortIds.get (nodePortId)); proxies.put (nodePortId, new ProxyConnection (npvSwitchPort, npvNodePort, switchPort)); } } return proxies; } } /** * Queries the server for the device descriptions (type + name) for all the ports directly connected * to a node or connected via a proxy switch. * @param connectedPortByNodePortId directly connected ports * @param proxyConnections ports connected via a proxy switch * @param context server load context * @param monitor the progress monitor to display progress and receive cancellation requests, * may be {code null} * @return map of ports to device descriptions * @throws ServerInterfaceException * @throws InterruptedException */ public static Map queryContainers(Map connectedPortByNodePortId, Map proxyConnections, Context context, IProgressMonitor monitor) throws ServerInterfaceException, InterruptedException { // Collect all directly connected and proxy connected ports. Set connectedPorts = new HashSet (connectedPortByNodePortId.size() + 2 * proxyConnections.size()); connectedPorts.addAll (connectedPortByNodePortId.values()); for (ProxyConnection connection: proxyConnections.values()) { connectedPorts.add (connection.getProxyNodePort()); connectedPorts.add (connection.getFabricSwitchPort()); } // Get information on containers of all ports. return PortDeviceNameFactory.queryContainers (connectedPorts, context, monitor); } private ProxyConnection (Port proxySwitchPort, Port proxyNodePort, Port fabricSwitchPort) { this.proxySwitchPort = proxySwitchPort; this.proxyNodePort = proxyNodePort; this.fabricSwitchPort = fabricSwitchPort; } /** * @return The proxy switch {@link Port} (the port directly connected to the node) for a node * connected to a fabric switch via a proxy switch. */ public Port getProxySwitchPort() { return proxySwitchPort; } /** * @return The proxy node {@link Port} (the port connected to the fabric switch) for a node * connected to a fabric switch via a proxy switch. */ public Port getProxyNodePort() { return proxyNodePort; } /** * @return The fabric switch {@link Port} (the switch port connected to the proxy node) for a node * connected to a fabric switch via a proxy switch. */ public Port getFabricSwitchPort() { return fabricSwitchPort; } }