/* * Copyright (c) 2005-2011 KOM - Multimedia Communications Lab * * This file is part of PeerfactSim.KOM. * * PeerfactSim.KOM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * PeerfactSim.KOM is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with PeerfactSim.KOM. If not, see . * */ package de.tud.kom.p2psim.impl.util.oracle; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import de.tud.kom.p2psim.api.common.SimHost; import de.tudarmstadt.maki.simonstrator.api.Graphs; import de.tudarmstadt.maki.simonstrator.api.Host; import de.tudarmstadt.maki.simonstrator.api.Randoms; import de.tudarmstadt.maki.simonstrator.api.common.graph.Graph; import de.tudarmstadt.maki.simonstrator.api.common.graph.IEdge; import de.tudarmstadt.maki.simonstrator.api.common.graph.INode; import de.tudarmstadt.maki.simonstrator.api.component.ComponentNotAvailableException; import de.tudarmstadt.maki.simonstrator.api.component.core.OracleComponent; import de.tudarmstadt.maki.simonstrator.api.component.network.NetID; import de.tudarmstadt.maki.simonstrator.api.component.network.NetInterface; import de.tudarmstadt.maki.simonstrator.api.component.topology.TopologyID; import de.tudarmstadt.maki.simonstrator.api.component.topology.TopologyProvider; /** * This class gives access to the hosts of the scenario. To work, it has to be * referenced in the configuration file after the host builder. * * The purpose of this class is to enable a global knowledge for analyzing. It * is not meant to be used within any functional parts of simulated systems. * * @author Julius Rueckert * */ public class GlobalOracle implements OracleComponent { private static HashMap hostIDtoHosts = new LinkedHashMap(); private static HashMap netIDtoHosts = new LinkedHashMap(); private static List hosts = new LinkedList(); private static List bootstrapList = new LinkedList(); private static GlobalOracle instance = new GlobalOracle(); private GlobalOracle() { // } public static GlobalOracle getInstance() { return instance; } /** * Initial population with hosts. * * @param hostBuilder */ public static void populate(List allHosts) { hosts = allHosts; if (hosts == null || hosts.size() <= 0) { return; } for (SimHost host : hosts) { /* Might happen in case of FakeHost. */ if (host.getNetworkComponent() == null) { continue; } hostIDtoHosts.put(host.getHostId(), host); for (NetInterface net : host.getNetworkComponent() .getNetworkInterfaces()) { netIDtoHosts.put(net.getLocalInetAddress(), host); bootstrapList.add(net.getLocalInetAddress()); } } return; } /** * Sets the bootstrap hosts. To be called by netLayer. * * @param bootstrapList * the new bootstrap hosts */ public static void setBootstrapHosts(List bootstrapList) { GlobalOracle.bootstrapList = bootstrapList; } /** * Gets the bootstrap hosts. * * @return the bootstrap hosts */ public static List getBootstrapHosts() { return GlobalOracle.bootstrapList; } /** * Gets the random host. * * @return the random host */ public static NetID getRandomHost() { return bootstrapList.get(Randoms.getRandom(GlobalOracle.class) .nextInt() % bootstrapList.size()); } /** * Gets the first host. * * @return the first host */ public static NetID getFirstHost() { if (bootstrapList.size() == 0) { assert (false) : "Bootstraplist is empty"; return null; } return bootstrapList.get(0); } /** * @param id * @return the host with the given NetID */ public static SimHost getHostForNetID(NetID id) { return netIDtoHosts.get(id); } /** * @param id * @return the host with the given host ID */ public static SimHost getHostForHostID(Long id) { return hostIDtoHosts.get(id); } /** * @return the list with all hosts of the scenario */ public static List getHosts() { synchronized (hosts) { return new ArrayList(hosts); } } /** * @return the list with all hosts of the scenario */ public static List getHosts(String groupID) { if(groupID.equals("")) { return getHosts(); } else { synchronized (hosts) { ArrayList groupedHosts = new ArrayList(); for (SimHost h : hosts) { if(h.getProperties().getGroupID().equals(groupID)) { groupedHosts.add(h); } } return groupedHosts; } } } @Override public List getAllHosts() { return new ArrayList(hosts); } @Override public boolean isSimulation() { return true; } /** * Returns a global view of the topology for the specified mechanism. The * mechanism must be a HostComponent that is registered at the local host. * Otherwise, this method will not be able to find the local mechanism * objects. * * @param component * @param identifier * @return */ public static Graph getTopology( Class component, TopologyID identifier) { HashSet edges = new LinkedHashSet<>(); HashSet nodes = new LinkedHashSet<>(); LinkedList allProviders = new LinkedList<>(); for (SimHost host : getHosts()) { try { TopologyProvider topologyProvider = host .getComponent(component); INode providerNode = topologyProvider.getNode(identifier); nodes.add(providerNode); allProviders.add(topologyProvider); } catch (ComponentNotAvailableException e) { // if the component is not available on the host, we can't do // anything about it // no reason to crash the simulation as this might be the case // in various scenarios } } for (TopologyProvider topologyProvider : allProviders) { Set neighbors = topologyProvider.getNeighbors(identifier); edges.addAll(neighbors); } /* * Copy elements and (!) attached properties */ Graph graph = Graphs.createGraph(); for(INode node : nodes){ INode copy = graph.createNode(node.getId()); copy.addPropertiesFrom(node); } for(IEdge edge : edges) { IEdge copy = graph.createEdge(edge.fromId(), edge.toId()); copy.addPropertiesFrom(edge); } return graph; } /** * Returns available topology identifiers for the given component. Throws an * {@link ComponentNotAvailableException} if the component is not available * on any node in the network. Assumes that all instances of a given * component class provide the same topology identifiers. * * @throws ComponentNotAvailableException */ public static Iterable getTopologyIdentifiers( Class component) throws ComponentNotAvailableException { // iterate over all the hosts, find one host that contains the given // component class and ask this component about available topologies for (SimHost host : getHosts()) { try { TopologyProvider topologyProvider = host .getComponent(component); return topologyProvider.getTopologyIdentifiers(); } catch (ComponentNotAvailableException e) { // if the component is not available on the host, we can't do // anything about it // no reason to crash the simulation as this might be the case // in various scenarios } } throw new ComponentNotAvailableException(); } /** * Checks whether the host with the given NetID is online using a global * list of all hosts in the current scenario. * * @param receiver * @return true if online */ public static boolean isHostOnline(NetID receiver) { if (netIDtoHosts.get(receiver) == null) return false; return netIDtoHosts.get(receiver).getNetworkComponent() .getByNetId(receiver).isUp(); } }