Commit 29ba1deb authored by Björn Richerzhagen's avatar Björn Richerzhagen
Browse files

Preparations for generic lifecycles (churn generators)

implemented by all netlayers
updates MaxPeerCountChurnGenerator to support the interface (default
behavior still triggers the network-layer functions)
parent fd9ecf86
......@@ -45,27 +45,4 @@ public interface WorkloadListener {
*/
public Application getApplication();
/**
* Informs, that the application should do an Action like publishing or
* request something.
*/
public void doAction();
/**
* Informs the application, that they should do an interaction with the
* given host.
*
* @param host
* The interacting host.
*/
public void doInteraction(SimHost host);
/**
* Do a react to an action of the given host. This could be called on the
* opposite, if an doAction is executed.
*
* @param host
* A host, which makes an action.
*/
public void doReact(SimHost host);
}
......@@ -25,6 +25,7 @@ package de.tud.kom.p2psim.api.network;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.network.routing.RoutingAlgorithm;
import de.tudarmstadt.maki.simonstrator.api.Message;
import de.tudarmstadt.maki.simonstrator.api.component.LifecycleComponent;
import de.tudarmstadt.maki.simonstrator.api.component.network.Bandwidth;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetInterface;
......@@ -45,7 +46,7 @@ import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
*
*/
public interface NetLayer extends NetInterface {
public interface NetLayer extends NetInterface, LifecycleComponent {
/**
*
......@@ -108,7 +109,7 @@ public interface NetLayer extends NetInterface {
* Releases the connection to the physical network. Further to this, if
* installed, the correspondent ConnectivityListener will be informed about
* the changes in connectivity.
*
*
*/
public void goOffline();
......
......@@ -20,6 +20,7 @@
package de.tud.kom.p2psim.api.network;
import de.tudarmstadt.maki.simonstrator.api.component.LifecycleComponent;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetworkComponent;
......@@ -31,7 +32,7 @@ import de.tudarmstadt.maki.simonstrator.api.component.network.NetworkComponent;
* @author Bjoern Richerzhagen
* @version 1.0, Aug 5, 2013
*/
public interface SimNetworkComponent extends NetworkComponent {
public interface SimNetworkComponent extends NetworkComponent, LifecycleComponent {
/**
* Returns the NetInterface that corresponds to the local IP.
......
......@@ -30,7 +30,6 @@ import java.util.List;
import java.util.PriorityQueue;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.network.SimNetInterface;
import de.tud.kom.p2psim.api.network.SimNetworkComponent;
import de.tud.kom.p2psim.impl.scenario.DefaultConfigurator;
import de.tud.kom.p2psim.impl.simengine.Simulator;
......@@ -40,7 +39,9 @@ import de.tud.kom.p2psim.impl.util.toolkits.Predicates;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.ComponentNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.GlobalComponent;
import de.tudarmstadt.maki.simonstrator.api.component.LifecycleComponent;
import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
/**
......@@ -57,7 +58,7 @@ import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
*
* numberOfClients - the number of clients to be achieved.
*
* The model checks for a minimum intervalLength of 10 minutes.
* The model checks for a minimum intervalLength of 1 minute.
*
*
* @author Nils Richerzhagen
......@@ -78,10 +79,15 @@ public class MaxPeerCountChurnGenerator
private final String SEP = ",";
private final long _minBurstLength = 10 * Time.MINUTE;
private final long _minBurstLength = 1 * Time.MINUTE;
private final int maxNumberOfNodes;
/**
* Default behavior: this generator operates on a NetLayer.
*/
private Class<? extends LifecycleComponent> targetClass = SimNetworkComponent.class;
/**
* {@link ChurnInfo} from the csv file.
*/
......@@ -101,12 +107,23 @@ public class MaxPeerCountChurnGenerator
}
};
@XMLConfigurableConstructor({ "file", "maxNumberOfNodes"})
@XMLConfigurableConstructor({ "file", "maxNumberOfNodes" })
public MaxPeerCountChurnGenerator(String file, int maxNumberOfNodes) {
this.maxNumberOfNodes = maxNumberOfNodes;
parseTrace(file);
}
/**
* A class that implements the {@link LifecycleComponent}-interface and can
* then be controlled by this generator.
*
* @param targetClass
*/
@SuppressWarnings("unchecked")
public void setTargetClass(Class<?> targetClass) {
this.targetClass = (Class<? extends LifecycleComponent>) targetClass;
}
/**
* Called by the configurator.
*
......@@ -151,11 +168,9 @@ public class MaxPeerCountChurnGenerator
.poll();
assert hostSessionInfo != null : "HostSessionInfo shouldn't be null - means to few hosts were configured.";
ChurnEvent churnEvent = new ChurnEvent(hostSessionInfo.host,
true);
ChurnEvent churnEvent = new ChurnEvent(hostSessionInfo.component, true);
long currentJoin = i
* (currentChurnInfo.getBurstLength() / count);
Event.scheduleWithDelay(currentJoin, this, churnEvent,
_CHURN_EVENT);
}
......@@ -178,7 +193,7 @@ public class MaxPeerCountChurnGenerator
.poll();
assert hostSessionInfo != null : "HostSessionInfo shouldn't be null - means no hosts were online.";
ChurnEvent churnEvent = new ChurnEvent(hostSessionInfo.host,
ChurnEvent churnEvent = new ChurnEvent(hostSessionInfo.component,
false);
long currentLeave = i
* (currentChurnInfo.getBurstLength() / count);
......@@ -198,27 +213,21 @@ public class MaxPeerCountChurnGenerator
} else if (type == _CHURN_EVENT) {
long currentTime = Simulator.getCurrentTime();
ChurnEvent churnEvent = (ChurnEvent) content;
SimNetworkComponent net = churnEvent.host.getNetworkComponent();
if (churnEvent.goOnline) {
for (SimNetInterface netI : net.getSimNetworkInterfaces()) {
if (netI.isOffline()) {
netI.goOnline();
}
}
if (churnEvent.start) {
churnEvent.component.startComponent();
onlineHostsSortedByOnlineTime
.add(new HostSessionInfo(churnEvent.host, currentTime));
.add(new HostSessionInfo(churnEvent.component, currentTime));
} else {
for (SimNetInterface netI : net.getSimNetworkInterfaces()) {
if (netI.isOnline()) {
netI.goOffline();
}
}
churnEvent.component.stopComponent();
offlineHostsSortedByOfflineTime
.add(new HostSessionInfo(churnEvent.host, currentTime));
.add(new HostSessionInfo(churnEvent.component, currentTime));
}
} else if (type == _CHURN_START) {
initialize();
/*
* FIXME we might want to add means to filter not only based on the host property?
*/
List<SimHost> hosts = new ArrayList<SimHost>(this.filterHosts());
this.prepare(hosts);
......@@ -228,20 +237,29 @@ public class MaxPeerCountChurnGenerator
(int) Math.ceil(hosts.size() / 10.0), COMP_TIME);
long currentTime = Simulator.getCurrentTime();
for (SimHost host : hosts) {
offlineHostsSortedByOfflineTime
.add(new HostSessionInfo(host, currentTime));
/*
* Find class (LifecycleComponent) implementation per host
*/
for (SimHost simHost : hosts) {
try {
LifecycleComponent comp = simHost.getComponent(targetClass);
offlineHostsSortedByOfflineTime.add(new HostSessionInfo(comp, currentTime));
} catch (ComponentNotAvailableException e) {
throw new AssertionError("No implementation of "+targetClass+" found on host "+simHost);
}
}
} else if (type == _CHURN_NOCHURN_HOSTS) {
// Send no-churn-hosts online immediately
// Start on all no-churn hosts (e.g., they will be active right from the beginning)
List<SimHost> nochurnhosts = (List<SimHost>) content;
for (SimHost host : nochurnhosts) {
for (SimNetInterface netI : host.getNetworkComponent()
.getSimNetworkInterfaces()) {
if (netI.isOffline()) {
netI.goOnline();
try {
LifecycleComponent comp = host.getComponent(targetClass);
if (!comp.isActive()) {
comp.startComponent();
}
} catch (ComponentNotAvailableException e) {
// Filtered hosts might not even have the component
}
}
}
......@@ -252,14 +270,18 @@ public class MaxPeerCountChurnGenerator
* state.
*
* @param hosts
* @deprecated use startOffline-flag in the netlayer-config instead!
*/
@Deprecated
private void prepare(List<SimHost> hosts) {
for (SimHost host : hosts) {
for (SimNetInterface netI : host.getNetworkComponent()
.getSimNetworkInterfaces()) {
if (netI.isOnline()) {
netI.goOffline();
try {
LifecycleComponent comp = host.getComponent(targetClass);
if (comp.isActive()) {
comp.stopComponent();
}
} catch (ComponentNotAvailableException e) {
// Filtered hosts might not even have the component
}
}
}
......@@ -331,12 +353,12 @@ public class MaxPeerCountChurnGenerator
// Insanity Checks
assert startTime >= previousEndTime : "Start time for next fluctuation must be greater than previous end time.";
assert burstLength >= _minBurstLength : "The minimal length of the burst must be at least 10m.";
assert burstLength >= _minBurstLength : "The minimal length of the burst must be at least 1m.";
assert numberOfClients > 0 : "Number of nodes must be positive.";
assert numberOfClients > 0: "Number of nodes must be positive.";
assert numberOfClients <= maxNumberOfNodes : "Cannot configure more nodes than configured in configuration.";
previousEndTime = startTime + burstLength;
churnInfos.add(new ChurnInfo(startTime, burstLength,
......@@ -377,25 +399,25 @@ public class MaxPeerCountChurnGenerator
*/
private class HostSessionInfo {
public final SimHost host;
public final LifecycleComponent component;
public final long timestamp;
public HostSessionInfo(SimHost host, long timestamp) {
this.host = host;
public HostSessionInfo(LifecycleComponent component, long timestamp) {
this.component = component;
this.timestamp = timestamp;
}
}
private class ChurnEvent {
public final SimHost host;
public final LifecycleComponent component;
public final boolean goOnline;
public final boolean start;
ChurnEvent(SimHost host, boolean goOnline) {
this.host = host;
this.goOnline = goOnline;
ChurnEvent(LifecycleComponent component, boolean start) {
this.component = component;
this.start = start;
}
}
......
......@@ -361,6 +361,21 @@ public abstract class AbstractNetLayer implements SimNetworkComponent,
public boolean isOnline() {
return online;
}
@Override
public boolean isActive() {
return online;
}
@Override
public void startComponent() {
goOnline();
}
@Override
public void stopComponent() {
goOffline();
}
/*
* (non-Javadoc)
......
......@@ -93,7 +93,7 @@ public class RoutedNetLayer implements SimNetworkComponent, NetworkComponent,
/**
* If this is set to "true", hosts will start offline.
*/
public static boolean START_HOSTS_OFFLINE = false;
private final boolean startOffline;
private boolean enableFragmenting = false;
......@@ -105,7 +105,7 @@ public class RoutedNetLayer implements SimNetworkComponent, NetworkComponent,
* @param netID
*/
public RoutedNetLayer(SimHost host) {
this(host, false, 0);
this(host, false, 0, false);
}
/**
......@@ -116,8 +116,9 @@ public class RoutedNetLayer implements SimNetworkComponent, NetworkComponent,
* @param fragmentSize
*/
public RoutedNetLayer(SimHost host, boolean enableFragmenting,
long fragmentSize) {
long fragmentSize, boolean startOffline) {
this.host = host;
this.startOffline = startOffline;
this.enableFragmenting = enableFragmenting;
this.fragmentSize = fragmentSize;
if (!_analyzersInitialized) {
......@@ -146,6 +147,37 @@ public class RoutedNetLayer implements SimNetworkComponent, NetworkComponent,
throw new AssertionError(
"You are not supposed to shutdown this component.");
}
@Override
public boolean isActive() {
/*
* Active, as long as at least one interface is active.
*/
for (SimNetInterface netI : nets.values()) {
if (netI.isActive()) {
return true;
}
}
return false;
}
@Override
public void startComponent() {
for (SimNetInterface netI : nets.values()) {
if (!netI.isActive()) {
netI.startComponent();
}
}
}
@Override
public void stopComponent() {
for (SimNetInterface netI : nets.values()) {
if (netI.isActive()) {
netI.stopComponent();
}
}
}
/**
* Configures the NetLayer with the provided routing Algorithm for a PHY
......@@ -219,6 +251,7 @@ public class RoutedNetLayer implements SimNetworkComponent, NetworkComponent,
/**
* Called by the NetComponent-wrapper
*/
@Override
public void initialize() {
getHost().getLinkLayer().addMacStateListener(this);
getHost().getLinkLayer().addLinkMessageListener(this);
......@@ -231,7 +264,7 @@ public class RoutedNetLayer implements SimNetworkComponent, NetworkComponent,
* you can set START_HOSTS_OFFLINE in the configuration of the
* factory.
*/
if (!START_HOSTS_OFFLINE) {
if (!startOffline) {
goOnline();
}
......@@ -242,6 +275,11 @@ public class RoutedNetLayer implements SimNetworkComponent, NetworkComponent,
// No analyzer, no problem.
}
}
@Override
public void shutdown() {
throw new UnsupportedOperationException();
}
@Override
public void send(Message msg, NetID receiver, NetProtocol protocol) {
......@@ -541,6 +579,21 @@ public class RoutedNetLayer implements SimNetworkComponent, NetworkComponent,
public boolean isOffline() {
return !isOnline();
}
@Override
public boolean isActive() {
return isOnline();
}
@Override
public void startComponent() {
goOnline();
}
@Override
public void stopComponent() {
goOffline();
}
@Override
public NetID getNetID() {
......
......@@ -50,6 +50,8 @@ public class RoutedNetLayerFactory implements HostComponentFactory {
private boolean enableFragmenting = false;
private boolean newHostGroup = false;
private boolean startOffline = false;
private List<RoutingConfiguration> routingConfigs = new Vector<RoutingConfiguration>();
......@@ -65,7 +67,7 @@ public class RoutedNetLayerFactory implements HostComponentFactory {
newHostGroup = true;
}
RoutedNetLayer nl = new RoutedNetLayer(host, enableFragmenting,
fragmentSize);
fragmentSize, startOffline);
int netIds = 0;
for (RoutingConfiguration routingConfig : routingConfigs) {
......@@ -97,7 +99,7 @@ public class RoutedNetLayerFactory implements HostComponentFactory {
* @param startHostsOffline
*/
public void setStartHostsOffline(boolean startHostsOffline) {
RoutedNetLayer.START_HOSTS_OFFLINE = startHostsOffline;
this.startOffline = startHostsOffline;
}
/**
......
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