package jnetman.network; import java.net.InetAddress; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Vector; /** * This class represents the NetworkManager abstraction for a node. A node could * be a router as well as a simple host. A node is defined by its name and its * network interfaces. * * @author Carmelo Cascone * */ public class Node extends NetworkDevice { private Map<String, IfCard> ifCards; protected NodeAgent agent; public Node(String name, Network network) { super(name, network); this.ifCards = new HashMap<String, IfCard>(); } /** * Returns the IP address of the node. If no address is explicitly set the * address of a random interface will be returned. * * @return IP address of the node in InetAddress format * @throws AddressException * If no address is explicitly set and there are no interfaces * declared for the node */ public InetAddress getAddress() throws AddressException { if (super.getAddress() != null) return super.getAddress(); else if (!this.ifCards.isEmpty()) { for (IfCard ifCard : this.ifCards.values()) if (ifCard.getAddress() != null) { super.setAddress(ifCard.getAddress()); logger.debug("No explicit address declared, using " + super.getAddress().getHostAddress() + " from interface " + ifCard.getName()); return super.getAddress(); } } throw new AddressException( "Unable to get the IP address of " + this.getName() + ", there are no InterfaceCards specified for this node. " + "You need to add at least one IfCard to get a valid IP address."); } /** * Returns a network interface defined for this node * * @param name * The name of the network interface to get * @return The network interface as an IfCard object */ public IfCard getInterfaceCard(String name) { return this.ifCards.get(name); } /** * Add a network interface to the node. This method is protected and so * should be used only inside the NetworkManager package. See also * createInterfaceCard. * * @param ifCard * IfCard to be added * @throws DuplicateElementException * If a network interface with the same name already exist for * this node */ protected void addInterfaceCard(IfCard ifCard) throws DuplicateElementException { if (this.ifCards.containsKey(ifCard.getName())) throw new DuplicateElementException("A network interface named '" + ifCard.getName() + "' already exist for the node " + this.getName()); ifCard.setRouter(this); this.ifCards.put(ifCard.getName(), ifCard); logger.debug("New interface card added >> " + ifCard.getName()); } /** * Create a network interface for the node. * * @param name * Name of the network interface to be crated * @return The network interface created as an IfCard object * @throws DuplicateElementException * If a network interface with the same name already exist for * this node */ public IfCard createInterfaceCard(String name) throws DuplicateElementException { if (this.ifCards.containsKey(name)) throw new DuplicateElementException("An interfaceCard named '" + name + "' already exist"); IfCard newIfCard = new IfCard(name, this); this.addInterfaceCard(newIfCard); return newIfCard; } /** * Returns all the network interfaces of this node * * @return A Collection of network interfaces as IfCard objects */ public Collection<IfCard> getIfCards() { return this.ifCards.values(); } /** * Check if this node is connected with the specified node. A node is * connected with another node when at least one link exists between the two * nodes and it's connected to the network interfaces of both nodes. * * @param node * The node for which to check the connection * @return true if it's connected, false elsewhere. */ public boolean isConnectedWith(Node node) { if (this.ifCards.isEmpty()) return false; else for (IfCard ifCard : this.getIfCards()) if (ifCard.getLinkEndpoint() != null && ifCard.getLinkEndpoint().getNode() == node) return true; return false; } /** * Returns all the nodes connected with this nodes * * @return a Collection of nodes connected with this node as a Node object */ public Collection<Node> getNeighbours() { Vector<Node> neighbours = new Vector<Node>(); if (!this.ifCards.isEmpty()) { for (IfCard ifCard : this.ifCards.values()) { if (ifCard.hasLink() && ifCard.getLinkEndpoint() != null) { neighbours.add(ifCard.getLinkEndpoint().getNode()); } } } return neighbours; } /** * Returns all the links that connect this node with the specified node * * @param node * The other endpoint of the links * @return A Collection of links in as a Link object. * @throws NotConnectedException * If this node is not connected with the specified node (no * links exists between the two nodes) */ public Collection<Link> getAllLinks(Node node) throws NotConnectedException { if (this.isConnectedWith(node)) { Vector<Link> links = new Vector<Link>(); for (IfCard ifCard : this.getIfCards()) { if (ifCard.getLinkEndpoint() != null && ifCard.getLinkEndpoint().getNode() == node) links.add(ifCard.getLink()); } return links; } else throw new NotConnectedException(); } /** * Returns a a textual description of the node, intended as the node name * and a list of its network interfaces * * @return a description of the node in a string format */ public String getDescription() { String text; text = this.getName() + " : "; if (!this.ifCards.isEmpty()) for (IfCard ifCard : ifCards.values()) text += "\n- " + ifCard.getDescription(); return text; } public synchronized NodeAgent getAgent() throws AddressException { if (this.agent == null) this.agent = new NodeAgent(this); return this.agent; } }