GlobalOracle.java 8.27 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
 * 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 <http://www.gnu.org/licenses/>.
 *
 */

package de.tud.kom.p2psim.impl.util.oracle;

import java.util.ArrayList;
import java.util.HashMap;
25
import java.util.HashSet;
26
import java.util.LinkedHashMap;
27
import java.util.LinkedHashSet;
28
29
import java.util.LinkedList;
import java.util.List;
30
import java.util.Set;
31
32

import de.tud.kom.p2psim.api.common.SimHost;
33
import de.tudarmstadt.maki.simonstrator.api.Graphs;
34
35
import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
36
import de.tudarmstadt.maki.simonstrator.api.common.graph.Graph;
Björn Richerzhagen's avatar
Björn Richerzhagen committed
37
38
import de.tudarmstadt.maki.simonstrator.api.common.graph.IEdge;
import de.tudarmstadt.maki.simonstrator.api.common.graph.INode;
39
import de.tudarmstadt.maki.simonstrator.api.component.ComponentNotAvailableException;
40
41
42
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;
43
44
import de.tudarmstadt.maki.simonstrator.api.component.topology.TopologyID;
import de.tudarmstadt.maki.simonstrator.api.component.topology.TopologyProvider;
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175

/**
 * 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<Long, SimHost> hostIDtoHosts = new LinkedHashMap<Long, SimHost>();

	private static HashMap<NetID, SimHost> netIDtoHosts = new LinkedHashMap<NetID, SimHost>();

	private static List<SimHost> hosts = new LinkedList<SimHost>();

	private static List<NetID> bootstrapList = new LinkedList<NetID>();

	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<SimHost> 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<NetID> bootstrapList) {
		GlobalOracle.bootstrapList = bootstrapList;
	}

	/**
	 * Gets the bootstrap hosts.
	 * 
	 * @return the bootstrap hosts
	 */
	public static List<NetID> 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 <code>NetID</code>
	 */
	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<SimHost> getHosts() {
		synchronized (hosts) {
			return new ArrayList<SimHost>(hosts);
		}
	}

176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
	/**
	 * @return the list with all hosts of the scenario
	 */
	public static List<SimHost> getHosts(String groupID) {
		
		if(groupID.equals("")) {
			return getHosts();
		}
		else {
			synchronized (hosts) {
				ArrayList<SimHost> groupedHosts = new ArrayList<SimHost>();
				
				for (SimHost h : hosts) {
					if(h.getProperties().getGroupID().equals(groupID)) {
						groupedHosts.add(h);
					}
				}
				
				return groupedHosts;
			}
		}	
	}
	
199
200
201
202
203
204
205
206
207
	@Override
	public List<Host> getAllHosts() {
		return new ArrayList<Host>(hosts);
	}

	@Override
	public boolean isSimulation() {
		return true;
	}
208
209
210
211
212
213
214
215
216
217
218
219
220
221
	
	/**
	 * 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 <T extends TopologyProvider> Graph getTopology(
			Class<T> component, TopologyID identifier) {

Björn Richerzhagen's avatar
Björn Richerzhagen committed
222
223
		HashSet<IEdge> edges = new LinkedHashSet<>();
		HashSet<INode> nodes = new LinkedHashSet<>();
224
225
226
227
228
229
230
231

		LinkedList<TopologyProvider> allProviders = new LinkedList<>();

		for (SimHost host : getHosts()) {
			try {
				TopologyProvider topologyProvider = host
						.getComponent(component);

Björn Richerzhagen's avatar
Björn Richerzhagen committed
232
				INode providerNode = topologyProvider.getNode(identifier);
233
234
235
236
237
238
239
240
241
242
243
244
245
246

				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) {
Björn Richerzhagen's avatar
Björn Richerzhagen committed
247
			Set<IEdge> neighbors = topologyProvider.getNeighbors(identifier);
248
249
250
			edges.addAll(neighbors);
		}

Björn Richerzhagen's avatar
Björn Richerzhagen committed
251
252
253
		/*
		 * Copy elements and (!) attached properties
		 */
254
		Graph graph = Graphs.createGraph();
Björn Richerzhagen's avatar
Björn Richerzhagen committed
255
256
257
		for(INode node : nodes){
			INode copy = graph.createNode(node.getId());
			copy.addPropertiesFrom(node);
258
		}
Björn Richerzhagen's avatar
Björn Richerzhagen committed
259
260
261
		for(IEdge edge : edges) {
			IEdge copy = graph.createEdge(edge.fromId(), edge.toId());
			copy.addPropertiesFrom(edge);
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
		}
		
		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 <T extends TopologyProvider> Iterable<TopologyID> getTopologyIdentifiers(
			Class<T> 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();
	}

	
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

	/**
	 * 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();
	}
}