Commit 96637f35 authored by Björn Richerzhagen's avatar Björn Richerzhagen
Browse files

Merge branch 'master' into 'releases/v2-3'

graph-interface of 2.3-API and updated Repo-locations

See merge request !8
parents 4fa0cf3a 86bce24a
......@@ -112,7 +112,7 @@
<!-- simonstrator-repository -->
<repository>
<id>simonstrator</id>
<url>http://dev.kom.e-technik.tu-darmstadt.de/mvn/</url>
<url>https://dev.kom.e-technik.tu-darmstadt.de/mvn/</url>
</repository>
<!-- local kom repository -->
......
......@@ -26,6 +26,8 @@ import de.tud.kom.p2psim.api.energy.EnergyComponent;
import de.tud.kom.p2psim.api.topology.movement.MovementListener;
import de.tud.kom.p2psim.api.topology.movement.MovementSupported;
import de.tud.kom.p2psim.api.topology.views.TopologyView;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationSensor;
import de.tudarmstadt.maki.simonstrator.api.component.topology.UnderlayTopologyProvider;
/**
* One component for each host, holding the position. These are maintained
......@@ -36,7 +38,7 @@ import de.tud.kom.p2psim.api.topology.views.TopologyView;
* @version 1.0, 21.02.2012
*/
public interface TopologyComponent extends SimHostComponent, MovementSupported,
MovementListener {
MovementListener, UnderlayTopologyProvider, LocationSensor {
/**
* Abstract QoS-Classes for the Accuracy of the position. Implementation
......
......@@ -20,6 +20,7 @@
package de.tud.kom.p2psim.api.topology.views;
import java.util.Collection;
import java.util.List;
import de.tud.kom.p2psim.api.common.Position;
......@@ -104,6 +105,12 @@ public interface TopologyView extends TopologyListener, MovementListener {
* @return an <b>unmodifiable</b> view on the current neighbors
*/
public List<MacAddress> getNeighbors(MacAddress address);
/**
* Returns all MACs that are currently in the TopologyView.
* @return
*/
public Collection<MacLayer> getAllMacs();
/**
* Gets the real Position of the host.
......
......@@ -164,6 +164,7 @@ public class ConstantPeerCountChurnModel implements ChurnModel {
clientSessionInfos.put(host.getHostId(), info);
if (hasFlashcrowd && !flashCrowdFinished
&& currentJoin > flashcrowdStart) {
currentJoin = flashcrowdStart;
inFlashcrowd = true;
}
lastJoin = currentJoin;
......@@ -187,6 +188,7 @@ public class ConstantPeerCountChurnModel implements ChurnModel {
clientSessionInfos.put(host.getHostId(), info);
if (hasFlashcrowd && !flashCrowdFinished
&& currentJoin > flashcrowdStart) {
currentJoin = flashcrowdStart;
inFlashcrowd = true;
}
lastJoin = currentJoin;
......
......@@ -22,6 +22,7 @@ package de.tud.kom.p2psim.impl.topology;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
......@@ -29,19 +30,32 @@ import java.util.Set;
import de.tud.kom.p2psim.api.common.HostProperties;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.linklayer.mac.MacAddress;
import de.tud.kom.p2psim.api.linklayer.mac.MacLayer;
import de.tud.kom.p2psim.api.linklayer.mac.PhyType;
import de.tud.kom.p2psim.api.topology.Topology;
import de.tud.kom.p2psim.api.topology.TopologyComponent;
import de.tud.kom.p2psim.api.topology.movement.MovementListener;
import de.tud.kom.p2psim.api.topology.movement.MovementSupported;
import de.tud.kom.p2psim.api.topology.movement.PositionListener;
import de.tud.kom.p2psim.api.topology.placement.PlacementModel;
import de.tud.kom.p2psim.api.topology.views.TopologyView;
import de.tud.kom.p2psim.impl.simengine.Simulator;
import de.tud.kom.p2psim.impl.topology.movement.modular.attraction.AttractionPoint;
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.DirectedEdge;
import de.tudarmstadt.maki.simonstrator.api.common.graph.Graph;
import de.tudarmstadt.maki.simonstrator.api.common.graph.Node;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetInterface;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetworkComponent.NetInterfaceName;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationListener;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationRequest;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationSensor;
import de.tudarmstadt.maki.simonstrator.api.component.topology.TopologyID;
import de.tudarmstadt.maki.simonstrator.api.component.transport.ConnectivityListener;
import de.tudarmstadt.maki.simonstrator.api.operation.Operations;
import de.tudarmstadt.maki.simonstrator.api.operation.PeriodicOperation;
......@@ -51,8 +65,8 @@ import de.tudarmstadt.maki.simonstrator.api.operation.PeriodicOperation;
* @author Bjoern Richerzhagen
* @version 1.0, 29.02.2012
*/
public class DefaultTopologyComponent implements TopologyComponent,
LocationSensor {
public class DefaultTopologyComponent implements TopologyComponent {
protected static Random rnd = Randoms.getRandom(AttractionPoint.class);
private SimHost host;
......@@ -290,4 +304,242 @@ public class DefaultTopologyComponent implements TopologyComponent,
}
/*
* Methods for the Graph Interface
*/
/**
* Graph views: static, as we use global knowledge and maintain one shared
* graph (potentially with partitions!)
*/
private final static LinkedHashMap<TopologyID, LocalGraphView> graphViews = new LinkedHashMap<>();
@Override
public TopologyID getTopologyID(NetInterfaceName netName, boolean onlyOnline) {
TopologyID id = TopologyID.getIdentifier(netName.toString()
+ (onlyOnline ? "-online" : "-all"),
DefaultTopologyComponent.class);
if (!this.graphViews.containsKey(id)) {
this.graphViews.put(id, new LocalGraphView(netName, onlyOnline));
}
return id;
}
@Override
public TopologyID getTopologyID(NetInterfaceName netName,
boolean onlyOnline, double range) {
TopologyID id = TopologyID.getIdentifier(netName.toString()
+ (onlyOnline ? "-online" : "-all") + String.valueOf(range),
DefaultTopologyComponent.class);
if (!this.graphViews.containsKey(id)) {
this.graphViews.put(id, new LocalGraphView(netName, onlyOnline,
range));
}
return id;
}
@Override
public Node getNode(TopologyID identifier) {
assert graphViews.containsKey(identifier);
return graphViews.get(identifier).getOwnNode(host);
}
@Override
public Set<DirectedEdge> getNeighbors(TopologyID topologyIdentifier) {
assert graphViews.containsKey(topologyIdentifier);
return graphViews.get(topologyIdentifier).getNeighbors(host);
}
@Override
public Graph getLocalView(TopologyID topologyIdentifier) {
assert graphViews.containsKey(topologyIdentifier);
return graphViews.get(topologyIdentifier).getLocalView();
}
@Override
public Iterable<TopologyID> getTopologyIdentifiers() {
return graphViews.keySet();
}
/**
* This is calculated based on global knowledge. It only registers as
* {@link MovementListener}, if a range is specified by the Provider.
*
* @author Bjoern Richerzhagen
* @version 1.0, May 13, 2015
*/
private class LocalGraphView implements MovementListener,
ConnectivityListener {
/**
* Marker: has there been any movement since the graph view was last
* requested? If so: recalculate! Otherwise, we ignore this object to
* not perform calculations if no one is interested...
*/
private final double distance;
private final boolean isDistanceBased;
private final NetInterfaceName medium;
private final TopologyView topoView;
private final boolean onlyOnline;
private Graph currentView;
private boolean isInvalid = true;
private final PhyType phy;
public LocalGraphView(NetInterfaceName medium, boolean onlyOnline) {
this(medium, onlyOnline, -1);
}
public LocalGraphView(NetInterfaceName medium, boolean onlyOnline,
double distance) {
this.medium = medium;
PhyType localPhy = null;
for (PhyType currPhy : PhyType.values()) {
if (currPhy.getNetInterfaceName() == medium) {
localPhy = currPhy;
break;
}
}
phy = localPhy;
assert localPhy != null;
this.topoView = getTopology().getTopologyView(localPhy);
this.distance = distance;
this.onlyOnline = onlyOnline;
this.isDistanceBased = (distance > 0);
assert !isDistanceBased || phy.isBroadcastMedium();
if (phy.isBroadcastMedium()) {
// register as listener for movement
addMovementListener(LocalGraphView.this);
}
// register as listener for online/offline events
if (onlyOnline) {
getHost().getNetworkComponent().getByName(medium)
.addConnectivityListener(LocalGraphView.this);
}
}
private void recalculateLocalView() {
if (!isInvalid) {
/*
* Graphs are invalidated (i) based on movement, IFF a range was
* specified, (ii) based on online/offline events, IFF only
* online hosts are to be considered.
*/
return;
}
/*
* Calculate a complete global connectivity graph
*/
// Create new, empty graph
currentView = Graphs.createGraph();
// Add all (online?) nodes
for (MacLayer mac : topoView.getAllMacs()) {
if (!onlyOnline || mac.isOnline()) {
currentView.createAndAddNode(mac.getHost().getHostId());
}
}
if (isDistanceBased) {
// Build neighbors solely based on an assumed range
for (MacLayer mac : topoView.getAllMacs()) {
// Add neighbors
Node currentNode = currentView.createNode(mac
.getMacAddress());
// Consider all nodes as potential neighbors
for (MacLayer neighborMac : topoView.getAllMacs()) {
// create, but do NOT add the node object
Node neighbor = currentView.createNode(neighborMac
.getMacAddress());
// only online nodes (already in graph)
if (!onlyOnline || currentView.contains(neighbor)) {
// Distance?
if (topoView.getDistance(mac.getMacAddress(),
neighborMac.getMacAddress()) <= distance) {
currentView.createAndAddEdge(currentNode,
neighbor);
}
}
}
}
} else {
// Build neighborhoods based on underlay neighbors (1-hop)
for (MacLayer mac : topoView.getAllMacs()) {
// Add neighbors
Node currentNode = currentView.createNode(mac
.getMacAddress());
// Rely on underlay for neighbors
List<MacAddress> neighbors = topoView.getNeighbors(mac
.getMacAddress());
for (MacAddress neighborMac : neighbors) {
// create, but do NOT add the node object
Node neighbor = currentView.createNode(neighborMac);
// only online nodes (already in graph)
if (!onlyOnline || currentView.contains(neighbor)) {
currentView.createAndAddEdge(currentNode, neighbor);
}
}
}
}
isInvalid = false;
}
public Node getOwnNode(SimHost ownHost) {
MacLayer mac = ownHost.getLinkLayer().getMac(phy);
if (!onlyOnline || mac.isOnline()) {
return currentView.createNode(ownHost.getLinkLayer()
.getMac(phy).getMacAddress());
}
return null;
}
public Set<DirectedEdge> getNeighbors(SimHost ownHost) {
recalculateLocalView();
Node ownNode = getOwnNode(ownHost);
return currentView.getOutgoingEdges(ownNode);
}
/**
* This is the global view, therefore we do not distinguish between
* hosts.
*
* @return
*/
public Graph getLocalView() {
recalculateLocalView();
return currentView;
}
@Override
public void afterComponentsMoved() {
this.isInvalid = true;
}
@Override
public void afterComponentMoved(MovementSupported comp) {
// don't care, we calculate based on global knowledge.
}
@Override
public void wentOnline(Host host, NetInterface netInterface) {
assert netInterface.getName() == medium;
this.isInvalid = true;
}
@Override
public void wentOffline(Host host, NetInterface netInterface) {
assert netInterface.getName() == medium;
this.isInvalid = true;
}
}
}
......@@ -20,6 +20,7 @@
package de.tud.kom.p2psim.impl.topology.views;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
......@@ -306,6 +307,11 @@ public abstract class AbstractTopologyView<L extends DefaultLink> implements
public MacLayer getMac(MacAddress address) {
return macs.get(address);
}
@Override
public Collection<MacLayer> getAllMacs() {
return macs.values();
}
@Override
public void afterComponentsMoved() {
......
......@@ -36,6 +36,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -285,6 +286,11 @@ public class VisualizationTopologyView extends JFrame implements TopologyView,
throw new UnsupportedOperationException();
}
@Override
public Collection<MacLayer> getAllMacs() {
throw new UnsupportedOperationException();
}
@Override
public List<MacAddress> getNeighbors(MacAddress address) {
throw new UnsupportedOperationException();
......
......@@ -22,16 +22,26 @@ 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.DirectedEdge;
import de.tudarmstadt.maki.simonstrator.api.common.graph.Graph;
import de.tudarmstadt.maki.simonstrator.api.common.graph.Node;
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
......@@ -172,6 +182,92 @@ public class GlobalOracle implements OracleComponent {
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 <T extends TopologyProvider> Graph getTopology(
Class<T> component, TopologyID identifier) {
HashSet<DirectedEdge> edges = new LinkedHashSet<>();
HashSet<Node> nodes = new LinkedHashSet<Node>();
LinkedList<TopologyProvider> allProviders = new LinkedList<>();
for (SimHost host : getHosts()) {
try {
TopologyProvider topologyProvider = host
.getComponent(component);
Node 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<de.tudarmstadt.maki.simonstrator.api.common.graph.DirectedEdge> neighbors = topologyProvider
.getNeighbors(identifier);
edges.addAll(neighbors);
}
Graph graph = Graphs.createGraph();
for(Node node : nodes){
graph.add(node);
}
for(DirectedEdge edge : edges) {
graph.add(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 <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();
}
/**
* Checks whether the host with the given NetID is online using a global
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment