Commit 439b8773 authored by Nils Richerzhagen's avatar Nils Richerzhagen
Browse files

Merge branch 'nr/monitoring-model' into 'nr/monitoring-req-resp'

Merge nr/monitoring model into nr/monitoring-req-resp

See merge request !15
parents 2570fa3c fcc75d5e
......@@ -30,7 +30,6 @@ import de.tud.kom.p2psim.api.linklayer.mac.Link;
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.movement.MovementSupported;
import de.tud.kom.p2psim.api.topology.obstacles.ObstacleModel;
import de.tud.kom.p2psim.api.topology.waypoints.WaypointModel;
import de.tud.kom.p2psim.impl.topology.PositionVector;
......@@ -529,8 +528,9 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
public long getBandwidth(boolean isBroadcast) {
assert (apLinkData != null && supportsAccessPoints)
|| apLinkData == null;
return apLinkData != null ? apLinkData.getBandwidth(isUpload)
long tmp = apLinkData != null ? apLinkData.getBandwidth(isUpload)
: linkData.getBandwidth(isUpload);
return tmp;
}
@Override
......@@ -628,4 +628,4 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
}
}
}
\ No newline at end of file
/*
* Copyright (c) 2005-2010 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.topology.views.fiveg;
import java.util.HashMap;
import java.util.HashSet;
import de.tud.kom.p2psim.api.linklayer.mac.MacAddress;
import de.tud.kom.p2psim.api.scenario.ConfigurationException;
import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector;
import de.tud.kom.p2psim.impl.topology.views.fiveg.models.AbstractModel;
import de.tud.kom.p2psim.impl.topology.views.fiveg.utils.Direction;
import de.tud.kom.p2psim.impl.topology.views.fiveg.utils.ParameterType;
import de.tud.kom.p2psim.impl.topology.views.visualization.world.ModelFiveGVisualization;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Time;
public class ModelBasedSegmentDatabase
extends AbstractGridBasedTopologyDatabase {
final Integer DEFAULT_SEGMENT_ID = new Integer(-1);
// Models[Type][SegID][Up/Down/Both]
HashMap<ParameterType, HashMap<Integer, HashMap<Direction, AbstractModel>>> models = new HashMap<>();
public ModelBasedSegmentDatabase() {
super(100, true);
super.setSupportCloudlets(true);
}
@Override
protected Entry createEntryFor(int segmentID, boolean isCloudlet) {
return new ModelBasedEntry(segmentID);
}
@Override
public void setEnableVis(boolean enableVis) {
if (enableVis == true) {
Event.scheduleImmediately(new EventHandler() {
@Override
public void eventOccurred(Object content, int type) {
ModelFiveGVisualization viz = ModelFiveGVisualization.getInstance();
viz.setDatabase(ModelBasedSegmentDatabase.this);
VisualizationInjector.injectComponent(viz);
}
}, null, 0);
}
}
/**
* Add a model to Database
*
* @param model
* the model to add
*/
public void setModel(AbstractModel model) {
// Enable debugging
model.debug();
// Check if model is valid
ParameterType type = model.getParameterType();
if (type == null) {
throw new ConfigurationException(
"Model is not defined for any Parameter Type. Please specify the Type for this Model.");
}
Direction dir = model.getDirection();
if (dir == null) {
throw new ConfigurationException(
"Model is not defined for any Direction. Please specify the Direction for this Model.");
}
Integer segmentID = new Integer(model.getSegmentID());
// Check if there is no contradicting model
if (models.containsKey(type)) {
// There is already this Type
if (models.get(type).containsKey(segmentID)) {
// There is already this SegID
if (models.get(type).get(segmentID).containsKey(dir)
|| (models.get(type).get(segmentID)
.containsKey(Direction.BOTH)
&& (dir.equals(Direction.DOWNLOAD)
|| dir.equals(Direction.UPLOAD)))
|| (dir.equals(Direction.BOTH) && (models.get(type)
.get(segmentID).containsKey(Direction.DOWNLOAD)
|| models.get(type).get(segmentID)
.containsKey(Direction.UPLOAD)))) {
// There is already a model defined
throw new ConfigurationException(
"Conflicting Models for SegmentID " + segmentID
+ ", Type " + type.toString()
+ " and Direction " + dir.toString());
} else {
// Add new model
models.get(type).get(segmentID).put(dir, model);
}
} else {
// Add new SegmentID
// Direction => Model
HashMap<Direction, AbstractModel> tmp1 = new HashMap<>();
tmp1.put(dir, model);
models.get(type).put(segmentID, tmp1);
}
} else {
// Add new model
// Direction => Model
HashMap<Direction, AbstractModel> tmp1 = new HashMap<>();
tmp1.put(dir, model);
// SegID => [Direction => Model]
HashMap<Integer, HashMap<Direction, AbstractModel>> tmp2 = new HashMap<>();
tmp2.put(segmentID, tmp1);
models.put(type, tmp2);
}
}
/**
* Get the model for the specific combination
*
* @param segID
* The SegmentID to get the model for
* @param type
* The Type of the Parameter
* @param isUpload
* Is it a Up or Downlink
* @return The Model for the given segment
*/
AbstractModel getModel(int segID, ParameterType type, Boolean isUpload) {
Integer segmentID = new Integer(segID);
Direction dir = Direction.DOWNLOAD;
if (isUpload) {
dir = Direction.UPLOAD;
}
// Check if type exists
if (!this.models.containsKey(type)) {
throw new ConfigurationException(
"No Model is defined for " + type + ".");
}
// Check if there is a specific model
if(this.models.get(type).containsKey(segmentID) && this.models.get(type).get(segmentID).containsKey(dir)) {
return this.models.get(type).get(segmentID).get(dir);
}
// Check if there is a BOTH model in this segment
if(this.models.get(type).containsKey(segmentID) && this.models.get(type).get(segmentID).containsKey(Direction.BOTH)) {
return this.models.get(type).get(segmentID).get(Direction.BOTH);
}
// Check default model for specific model
if(this.models.get(type).containsKey(DEFAULT_SEGMENT_ID) && this.models.get(type).get(DEFAULT_SEGMENT_ID).containsKey(dir)) {
return this.models.get(type).get(DEFAULT_SEGMENT_ID).get(dir);
}
// Check if there is a default BOTH model
if(this.models.get(type).containsKey(DEFAULT_SEGMENT_ID) && this.models.get(type).get(DEFAULT_SEGMENT_ID).containsKey(Direction.BOTH)) {
return this.models.get(type).get(DEFAULT_SEGMENT_ID).get(Direction.BOTH);
}
throw new ConfigurationException(
"No Model is defined for Type " + type + ", Segment ID "
+ segmentID + " and Direction " + dir + ".");
}
public class ModelBasedEntry implements FiveGTopologyDatabase.Entry {
// How is a overload defined
// FIXME Can the time in the Latency result in problems if the drop-rate is set to 100%?
private final long OVERLOAD_LATENCY = 9999 * Time.MILLISECOND;
private final long OVERLOAD_BANDWIDTH = 1;
private final double OVERLOAD_DROPRATE = 1;
// When is a node considered overloaded
private final long THRESHOLD_LATENCY = Time.SECOND;
private final long THRESHOLD_BANDWIDTH = 10;
private final double THRESHOLD_DROPRATE = 1;
private final double YELLOW_INDICATOR = .8;
// Other storage
private final int segment;
private boolean isAvailable = true;
private HashSet<MacAddress> hostsInSegment = new HashSet<>();
private boolean overload;
// The current metrics of this segment
private long bandUp;
private long bandDown;
private long latUp;
private long latDown;
private double dropUp;
private double dropDown;
/**
* Create a new entry for the given segment
*
* @param segment
*/
public ModelBasedEntry(int segment) {
this.segment = segment;
calc();
}
@Override
public int getSegmentID() {
return segment;
}
/**
* A host leaves this segment
*/
public void onHostLeavesSegment(MacAddress hostAddr) {
// Remove MAC from current users
this.hostsInSegment.remove(hostAddr);
calc();
}
/**
* A host enters this segment
*/
public void onHostEntersSegment(MacAddress hostAddr) {
// Add MAC to current users
this.hostsInSegment.add(hostAddr);
calc();
}
@Override
public double getDropProbability(boolean isUpload) {
// Segment is overloaded or not available return overloaded drop
// probability
if (!isAvailable || overload) {
return OVERLOAD_DROPRATE;
}
// Return calculated drop probability
if (isUpload) {
return dropUp;
} else {
return dropDown;
}
}
@Override
public long getLatency(boolean isUpload) {
// Segment is overloaded or not available return overloaded latency
if (!isAvailable || overload) {
return OVERLOAD_LATENCY;
}
// Return calculated latency
if (isUpload) {
return latUp;
} else {
return latDown;
}
}
@Override
public long getBandwidth(boolean isUpload) {
// Segment is overloaded or not available return overloaded
// bandwidth
if (!isAvailable || overload) {
return OVERLOAD_BANDWIDTH;
}
// Return calculated bandwidth
if (isUpload) {
return bandUp;
} else {
return bandDown;
}
}
@Override
public boolean isAvailable() {
return isAvailable;
}
@Override
public void setAvailability(boolean isAvailable) {
this.isAvailable = isAvailable;
}
public int getStatus(ParameterType type, Direction dir) {
if(type.equals(ParameterType.BANDWIDTH) && dir.equals(Direction.UPLOAD)) {
if(this.bandUp <= THRESHOLD_BANDWIDTH) {
return 2;
}
if(this.bandUp < ((2 - YELLOW_INDICATOR) * THRESHOLD_BANDWIDTH)) {
return 1;
}
return 0;
}
if(type.equals(ParameterType.BANDWIDTH) && dir.equals(Direction.DOWNLOAD)) {
if(this.bandDown <= THRESHOLD_BANDWIDTH) {
return 2;
}
if(this.bandDown < ((2 - YELLOW_INDICATOR) * THRESHOLD_BANDWIDTH)) {
return 1;
}
return 0;
}
if(type.equals(ParameterType.DROPRATE) && dir.equals(Direction.UPLOAD)) {
if(this.dropUp >= THRESHOLD_DROPRATE) {
return 2;
}
if(this.dropUp > (YELLOW_INDICATOR * THRESHOLD_DROPRATE)) {
return 1;
}
return 0;
}
if(type.equals(ParameterType.DROPRATE) && dir.equals(Direction.DOWNLOAD)) {
if(this.dropDown >= THRESHOLD_DROPRATE) {
return 2;
}
if(this.dropDown > (YELLOW_INDICATOR * THRESHOLD_DROPRATE)) {
return 1;
}
return 0;
}
if(type.equals(ParameterType.LATENCY) && dir.equals(Direction.UPLOAD)) {
if(this.latUp >= THRESHOLD_LATENCY) {
return 2;
}
if(this.latUp > ((2 - YELLOW_INDICATOR) * THRESHOLD_LATENCY)) {
return 1;
}
return 0;
}
if(type.equals(ParameterType.LATENCY) && dir.equals(Direction.DOWNLOAD)) {
if(this.latDown >= THRESHOLD_LATENCY) {
return 2;
}
if(this.latDown > ((2 - YELLOW_INDICATOR) * THRESHOLD_LATENCY)) {
return 1;
}
return 0;
}
return 0;
}
public boolean isOverloaded() {
return overload;
}
public int getHostsInSegment() {
return this.hostsInSegment.size();
}
/**
* Recalculate every metric when a host leaves or enters
*/
private void calc() {
int users = this.hostsInSegment.size();
// Assume not overloaded
this.overload = false;
// Calc Bandwidth
this.bandUp = getModel(getSegmentID(), ParameterType.BANDWIDTH,
true).getLong(users);
this.bandDown = getModel(getSegmentID(), ParameterType.BANDWIDTH,
false).getLong(users);
if (bandDown <= THRESHOLD_BANDWIDTH
|| bandUp <= THRESHOLD_BANDWIDTH) {
overload = true;
}
// Calc Latency
this.latUp = getModel(getSegmentID(), ParameterType.LATENCY, true)
.getLong(users);
this.latDown = getModel(getSegmentID(), ParameterType.LATENCY,
false).getLong(users);
if (latUp >= THRESHOLD_LATENCY || latDown >= THRESHOLD_LATENCY) {
overload = true;
}
// Calc Droprate
this.dropUp = getModel(getSegmentID(), ParameterType.DROPRATE, true)
.getDouble(users);
this.dropDown = getModel(getSegmentID(), ParameterType.DROPRATE,
false).getDouble(users);
if (dropUp >= THRESHOLD_DROPRATE
|| dropDown >= THRESHOLD_DROPRATE) {
overload = true;
}
}
}
}
/*
* Copyright (c) 2005-2010 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.topology.views.fiveg.models;
import de.tud.kom.p2psim.api.scenario.ConfigurationException;
import de.tud.kom.p2psim.impl.topology.views.FiveGTopologyView;
import de.tud.kom.p2psim.impl.topology.views.fiveg.ModelBasedSegmentDatabase;
import de.tud.kom.p2psim.impl.topology.views.fiveg.utils.Direction;
import de.tud.kom.p2psim.impl.topology.views.fiveg.utils.Graph;
import de.tud.kom.p2psim.impl.topology.views.fiveg.utils.ParameterType;
/**
* Abstract base model for the {@link FiveGTopologyView} when using the {@link ModelBasedSegmentDatabase}.
*
* @author Nils
* @version 1.0, 05.03.2017
*/
public abstract class AbstractModel {
// Storage
private int segmentID = -1;
private ParameterType type;
private Direction dir = Direction.BOTH;
// Is debug enabled for this model
private boolean debug = false;
public void setSegmentID(int segmentid) {
assert segmentid > 0;
this.segmentID = segmentid;
}
public int getSegmentID() {
return this.segmentID;
}
/**
* Set the parameter type {@link ParameterType}
* @param param
*/
public void setParameterType(String param) {
param = param.toUpperCase();
// Check if type is valid
try {
this.type = ParameterType.valueOf(param);
} catch (IllegalArgumentException e) {
throw new ConfigurationException(
"The Parameter " + param + " is unknown. Please select one of "
+ ParameterType.printTypes());
}
if(this.type == null) {
throw new ConfigurationException(
"The Parameter " + param + " is unknown. Please select one of "
+ ParameterType.printTypes());
}
}
public ParameterType getParameterType() {
return type;
}
/**
* Set the direction of model {@link Direction}
* @param param
*/
public void setDirection(String param) {
param = param.toUpperCase();
try {
this.dir = Direction.valueOf(param);
} catch (IllegalArgumentException e) {
throw new ConfigurationException(
"Direction " + param + " is unknown. Please select one of "
+ Direction.printTypes());
}
if(this.type == null) {
throw new ConfigurationException(
"Direction " + param + " is unknown. Please select one of "
+ Direction.printTypes());
}
}
public Direction getDirection() {
return dir;
}
/**
* Enable debugging - visualization of the model set in the config.
*
* @param debug
*/
public void setDebug(boolean debug) {
this.debug = debug;
}
public boolean getDebug() {
return this.debug;
}
public abstract long getLong(int users);
public abstract double getDouble(int users);
/**
* Debug this model
*/
public void debug() {
Graph test = new Graph();
test.setModel(this);
}
}
/*
* Copyright (c) 2005-2010 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.topology.views.fiveg.models;
/**
* A Constant Model which return always the constant value C
* c(u) = C
* @author Marc Schiller
* @version 1.0, 15 Dec 2016
*/
public class ConstantModel extends AbstractModel {
private double c = 0;
public void setC(double c) {
this.c = c;
}
@Override
public long getLong(int users) {
return (long) this.c;
}
@Override
public double getDouble(int users) {
return this.c;
}
public String toString() {
return "Constant Model: c(u) = " + c;
}
}
/*
* Copyright (c) 2005-2010 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.topology.views.fiveg.models;
/**
* A cut off model based on the heaviside step function.
*
* https://de.wikipedia.org/wiki/Heaviside-Funktion
*
* cut(u) = a * θ(c * u + d) + b
* @author Marc Schiller
* @version 1.0, 15 Dec 2016
*/
public class CutOffModel extends AbstractModel {
private double a = 1;
private double b = 0;
private double c = 1;
private double d = 0;
public void setA(double a) {
this.a = a;
}
public void setB(double b) {
this.b = b;
}
public void setC(double c) {
this.c = c;
}
public void setD(double d) {
this.d = d;
}
private double heaviside(double x) {
if(x < 0) {
return 0;
} else {
return 1;
}
}
@Override
public long getLong(int users) {
return (long) getDouble(users);
}
@Override
public double getDouble(int users) {
return this.a * heaviside(this.c * users + this.d) + this.b;
}
@Override
public String toString() {
return "CutOffModel: cut(u) = " + this.a + " * θ(" + this.c + " * u + " + this.d + ") + " + this.b;
}
}
/*
* Copyright (c) 2005-2010 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.topology.views.fiveg.models;
/**
* An exponential model
* exp(u) = a * e^(c * (u - d)) + b
* @author Marc Schiller
* @version 1.0, 15 Dec 2016
*/
public class ExponentialModel extends AbstractModel {
// exp(u) = a * e ^(c * u + d) + b
private double a = 1;
private double b = 0;
private double c = 1;
private double d = 0;
public void setA(double a) {
this.a = a;
}
public void setB(double b) {
this.b = b;
}
public void setC(double c) {
this.c = c;
}
public void setD(double d) {
this.d = d;
}
@Override
public long getLong(int users) {
return (long) getDouble(users);
}
@Override
public double getDouble(int users) {
return this.a * Math.exp(this.c * (users - this.d)) + this.b;
}
@Override
public String toString() {
return "Exponential Model: exp(u) = " + this.a + " * e^(" + this.c + " * (u - " + this.d + ")) + " + this.b;
}
}
/*
* Copyright (c) 2005-2010 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.topology.views.fiveg.models;
/**
* Linear Model
* lin(u) = a * u + b
* @author Marc Schiller
* @version 1.0, 15 Dec 2016
*/
public class LinearModel extends AbstractModel {
private double a = 1;
private double b = 0;
public void setA(double a) {
this.a = a;
}
public void setB(double b) {
this.b = b;
}
@Override
public long getLong(int users) {
return (long) (this.a * users + this.b);
}
@Override
public double getDouble(int users) {
return this.a * users + this.b;
}
public String toString() {
return "Linear Model: lin(u) = " + a + " * u + " + b;
}
}
/*
* Copyright (c) 2005-2010 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.topology.views.fiveg.models;
/**
* Logarithmic model
* log(u) = a * ln(c * (u - d)) + b
* @author Marc Schiller
* @version 1.0, 15 Dec 2016
*/
public class LogarithmicModel extends AbstractModel {
private double a = 1;
private double b = 0;
private double c = 1;
private double d = 0;
public void setA(double a) {
this.a = a;
}
public void setB(double b) {
this.b = b;
}
public void setC(double c) {
this.c = c;
}
public void setD(double d) {
this.d = d;
}
@Override
public long getLong(int users) {
return (long) getDouble(users);
}
@Override
public double getDouble(int users) {
double tmp = this.a * Math.log(this.c * (users - this.d)) + this.b;
if(tmp < 0) {
return 0;
} else {
return tmp;
}
}
@Override
public String toString() {
return "Logarithmic Model: log(u) = " + this.a + " * ln(" + this.c + " * (u - " + this.d + ")) + " + this.b;
}
}
# 5G Models
> **IMPORTANT!** The colors of each segment reflect the status *per* characteristic not the global status of this segment. If a segment is overloaded the text "overload" is shown.
This module allows to add transmission models to each segment of the map to accommodate different behaviors of wireless network transmission technologies. It enables the developer to define different models for **Latency**, **Bandwidth** and **Drop Rate** (called *characteristics*), for **Upload** and **Download** and for every **Segment**.
Whenever one of the characteristic for a client is requested every other characteristic is evaluated to check if one of them is overloaded such that no connection is possible. The thresholds for the overload are defined in [`FiveGTopologyDatabase.Entry`](https://dev.kom.e-technik.tu-darmstadt.de/gitlab/simonstrator/simonstrator-peerfactsim/blob/nr/monitoring-model/src/de/tud/kom/p2psim/impl/topology/views/fiveg/ModelBasedSegmentDatabase.java#L182)
## Configuration / Setup
The models are enabled by changing the `Database` of the `FiveGTopologyView` to `ModelBasedSegmentDatabase`. For a minimal config the `ModelBasedSegmentDatabase` needs at least a model for each characteristic. Therefore, the models are passed to the database. Each model has its specific defaults described [here](#models). In addition to that every model has parameters for `direction` (*UPLOAD*, *DOWNLOAD* or **BOTH**), `parameterType` (*BANDWIDTH*, *LATENCY* and *DROPRATE*), `segmentID` (to which segmentID this model is applied - **-1** means that it is applied to every segment) and debug (TRUE or **FALSE**). **Bold** values mark the defaults.
## Examples
> **IMPORTANT!** For every characteristic there needs to be one and *only one* default model.
### General Setup
Here the general setup for the model based segments is shown. The models are placed inside the database element.
```xml
<View class="de.tud.kom.p2psim.impl.topology.views.FiveGTopologyView" phy="UMTS" cloudGroups="Cloud">
<Database class="de.tud.kom.p2psim.impl.topology.views.fiveg.ModelBasedSegmentDatabase" enableVis="$ENABLE_VIS" gridSize="$CELL_GRID_SIZE">
<!-- Place model definitions here -->
</Database>
</View>
```
### A default constant model for every characteristic
```xml
<Model class="de.tud.kom.p2psim.impl.topology.views.fiveg.models.ConstantModel" c="300" parameterType="BANDWIDTH" />
<Model class="de.tud.kom.p2psim.impl.topology.views.fiveg.models.ConstantModel" c="5" parameterType="LATENCY" />
<Model class="de.tud.kom.p2psim.impl.topology.views.fiveg.models.ConstantModel" c="0.1" parameterType="DROPRATE" />
```
For every segment the bandwidth is 300 kBit/s, the latency 5 ms and drop rate is 1% (0.1) in both directions.
### Advanced setup
```xml
<Model class="de.tud.kom.p2psim.impl.topology.views.fiveg.models.ConstantModel" c="300" parameterType="BANDWIDTH" direction="UPLOAD" />
<Model class="de.tud.kom.p2psim.impl.topology.views.fiveg.models.ConstantModel" c="10" parameterType="BANDWIDTH" direction="DOWNLOAD" />
<Model class="de.tud.kom.p2psim.impl.topology.views.fiveg.models.LogarithmicModel" a="3" b="10" c="-5" d="-10" parameterType="LATENCY" />
<Model class="de.tud.kom.p2psim.impl.topology.views.fiveg.models.ExponentialModel" parameterType="DROPRATE" />
<Model class="de.tud.kom.p2psim.impl.topology.views.fiveg.models.CutoffModel" parameterType="BANDWIDTH" segmentID="123" debug="TRUE" />
```
Every segment has 300 kBit/s upload bandwidth and 10 kBit/s download bandwidth with a constant model. The latency of every segment is equal for up- and download and is based on a logarithmic model with $`a=3`$, $`b=10`$, $`c=-5`$ and $`d=-10`$. A default exponential model is applied on the latency. At last there is a cut-off model for the bandwidth for the segment with the ID `123`. It also shows the debug graph.
## Models
* [Constant](#constant)
* [Linear](#linear)
* [Exponential](#exponential)
* [Logarithmic](#logarithmic)
* [Cut-Off](#cut-off)
### Constant
![](https://dev.kom.e-technik.tu-darmstadt.de/gitlab/simonstrator/simonstrator-peerfactsim/raw/nr/monitoring-model/src/de/tud/kom/p2psim/impl/topology/views/fiveg/models/img/constant.png)
$`c(u)=C`$
> The constant model applies the the same constant value `c` to the selected characteristic regardless of the number of hosts in the segment.
*Model-specific Parameters*:
`c` the constant value (*default* `0`)
### Linear
![](https://dev.kom.e-technik.tu-darmstadt.de/gitlab/simonstrator/simonstrator-peerfactsim/raw/nr/monitoring-model/src/de/tud/kom/p2psim/impl/topology/views/fiveg/models/img/linear.png)
$`lin(u)=a*u+b`$
*Model-specific Parameters*:
`a` the slope (*default* `1`)
`b` y-axis intersection (*default* `0`)
### Exponential
![](https://dev.kom.e-technik.tu-darmstadt.de/gitlab/simonstrator/simonstrator-peerfactsim/raw/nr/monitoring-model/src/de/tud/kom/p2psim/impl/topology/views/fiveg/models/img/exponential.png)
$`exp(u)=a*e^{c(u-d)}+b`$
*Model-specific Parameters*:
`a` scaling factor (*default* `1`)
`b` y-axis offset (*default* `0`)
`c` exponent scaling (*default* `1`)
`d` x-axis offset (*default* `0`)
### Logarithmic
![](https://dev.kom.e-technik.tu-darmstadt.de/gitlab/simonstrator/simonstrator-peerfactsim/raw/nr/monitoring-model/src/de/tud/kom/p2psim/impl/topology/views/fiveg/models/img/logarithmic.png)
$`log(u)=a*ln(c(u-d))+b`$
*Model-specific Parameters*:
`a` scaling factor (*default* `1`)
`b` y-axis offset (*default* `0`)
`c` logarithm scaling (*default* `1`)
`d` x-axis offset (*default* `0`)
### Cut-Off
![](https://dev.kom.e-technik.tu-darmstadt.de/gitlab/simonstrator/simonstrator-peerfactsim/raw/nr/monitoring-model/src/de/tud/kom/p2psim/impl/topology/views/fiveg/models/img/cutoff.png)
$`cut(u)=a*\theta(c(u-d))+b`$
> The cut-off model is based on the [Heaviside step function](https://en.wikipedia.org/wiki/Heaviside_step_function).
*Model-specific Parameters*:
`a` scaling factor (*default* `1`)
`b` y-axis offset (*default* `0`)
`c` scaling (*default* `1`)
`d` x-axis offset (*default* `0`)
\ No newline at end of file
/*
* Copyright (c) 2005-2010 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.topology.views.fiveg.utils;
/**
* Enumeration for defining the direction (Up,Down or Both) for a model.
* @author Marc Schiller
* @version 1.0, 15 Dec 2016
*/
public enum Direction {
BOTH(),
UPLOAD(),
DOWNLOAD();
public static String printTypes() {
Direction[] types = values();
String out = "";
for (int i = 0; i < types.length; i++) {
if (i > 0) {
out += ", ";
}
out += types[i].name();
}
return out;
}
}
/*
* Copyright (c) 2005-2010 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.topology.views.fiveg.utils;
import javax.swing.JFrame;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import de.tud.kom.p2psim.impl.topology.views.FiveGTopologyView;
import de.tud.kom.p2psim.impl.topology.views.fiveg.ModelBasedSegmentDatabase;
import de.tud.kom.p2psim.impl.topology.views.fiveg.models.AbstractModel;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Oracle;
/**
* A simple graph for debugging the models of the
* {@link ModelBasedSegmentDatabase} used by the {@link FiveGTopologyView}.
*
* @author Marc Schiller
* @version 1.0, 15 Dec 2016
*/
public class Graph extends JFrame implements EventHandler {
AbstractModel model = null;
public Graph() {
super("FiveGTopology - Cell Model Debug Graph");
Event.scheduleImmediately(this, null, 0);
}
public void setModel(AbstractModel model) {
this.model = model;
}
@Override
public void eventOccurred(Object content, int type) {
if (model.getDebug()) {
XYSeries data = new XYSeries("ModelData");
for (int i = 0; i < Oracle.getAllHosts().size(); i += 1) {
data.add(i, model.getDouble(i));
}
JFreeChart xyChart = ChartFactory.createXYLineChart(
model.getParameterType().toString() + " -- " + model.toString(), "Users", "Value",
new XYSeriesCollection(data), PlotOrientation.VERTICAL,
false, true, false);
// X-Axis Ticks every 5%
((NumberAxis) xyChart.getXYPlot().getDomainAxis())
.setTickUnit(new NumberTickUnit(Oracle.getAllHosts().size() / 20));
ChartPanel chartPanel = new ChartPanel(xyChart);
setContentPane(chartPanel);
pack();
setVisible(true);
}
}
}
/*
* Copyright (c) 2005-2010 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.topology.views.fiveg.utils;
/**
* Enumeration for defining the type (Bandwidth, Drop Rate, Latency) for a model.
* @author Marc Schiller
* @version 1.0, 15 Dec 2016
*/
public enum ParameterType {
BANDWIDTH(),
DROPRATE(),
LATENCY();
public static String printTypes() {
ParameterType[] types = values();
String out = "";
for (int i = 0; i < types.length; i++) {
if (i > 0) {
out += ", ";
}
out += types[i].name();
}
return out;
}
}
/*
* Copyright (c) 2005-2010 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.topology.views.visualization.world;
import de.tud.kom.p2psim.impl.topology.views.FiveGTopologyView;
import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector;
import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector.MouseClickListener;
import de.tud.kom.p2psim.impl.topology.views.fiveg.ModelBasedSegmentDatabase;
import de.tud.kom.p2psim.impl.topology.views.fiveg.ModelBasedSegmentDatabase.ModelBasedEntry;
import de.tud.kom.p2psim.impl.topology.views.fiveg.utils.Direction;
import de.tud.kom.p2psim.impl.topology.views.fiveg.utils.ParameterType;
import de.tud.kom.p2psim.impl.topology.views.fiveg.FiveGTopologyDatabase.Entry;
import de.tud.kom.p2psim.impl.topology.views.visualization.ui.VisualizationComponent;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.HashSet;
import javax.swing.*;
/**
* Visualization for the {@link FiveGTopologyView}
*
* Added 06.10.2016 Nils Richerzhagen, Clemens Krug Functionality to 'destroy'
* cells using SHIFT + Left-click. Enable/Disable using the
* enableCellDestruction
*
* @author Bjoern Richerzhagen
* @version 1.0, Nov 5, 2015
*/
public class ModelFiveGVisualization extends JComponent
implements VisualizationComponent, ActionListener, MouseClickListener {
private static final ModelFiveGVisualization instance = new ModelFiveGVisualization();
private ModelBasedSegmentDatabase database;
private final JMenu menu = new JMenu("FiveG");
protected BufferedImage image;
protected volatile boolean needsRedraw = false;
private Direction selectedDirection = null;
private ParameterType selectedType = null;
private HashSet<JCheckBoxMenuItem> menuItems = new HashSet<>(6);
private Boolean showText = true;
private ModelFiveGVisualization() {
setBounds(0, 0, VisualizationInjector.getWorldX(),
VisualizationInjector.getWorldY());
setOpaque(true);
setVisible(true);
image = new BufferedImage(VisualizationInjector.getWorldX(),
VisualizationInjector.getWorldY(), BufferedImage.TYPE_INT_ARGB);
this.generateMenu();
VisualizationInjector.addMouseListener(this);
}
public static ModelFiveGVisualization getInstance() {
return instance;
}
public void setDatabase(ModelBasedSegmentDatabase database) {
this.database = database;
}
@Override
public String getDisplayName() {
return "FiveG";
}
@Override
public JComponent getComponent() {
return this;
}
@Override
public JMenu getCustomMenu() {
return menu;
}
@Override
public boolean isHidden() {
return false;
}
private void generateMenu() {
String[] entries1 = { "Bandwidth", "Latency", "Droprate" };
String[] entries2 = { "Download", "Upload" };
for (String entry1 : entries1) {
JMenu tmpMenu = new JMenu(entry1);
for (String entry2 : entries2) {
JCheckBoxMenuItem checkbox = new JCheckBoxMenuItem(entry2);
checkbox.setName(entry1 + " " + entry2);
checkbox.addActionListener(this);
tmpMenu.add(checkbox);
menuItems.add(checkbox);
}
menu.add(tmpMenu);
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (needsRedraw) {
redraw();
}
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(image, 0, 0, null);
}
protected void redraw() {
needsRedraw = false;
Graphics2D g2 = (Graphics2D) image.getGraphics();
Composite c = g2.getComposite();
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
Rectangle2D.Double rect = new Rectangle2D.Double(0, 0,
VisualizationInjector.getWorldX(),
VisualizationInjector.getWorldY());
g2.fill(rect);
g2.setComposite(c);
try {
drawEntries(g2);
} catch (RuntimeException e) {
e.printStackTrace();
System.exit(0);
needsRedraw = true;
} finally {
// Schedule next redraw
new Thread(() -> {
try {
Thread.sleep(100);
needsRedraw = true;
} catch (InterruptedException e) {
// Ignore any error in Timer
}
}).start();
}
}
private void drawEntries(Graphics2D g2) {
// Iterate over grid coordinates
int stepSize = database.getGridSize();
boolean isUpload = selectedDirection.equals(Direction.UPLOAD) ? true
: false;
// Loop through world
for (int x = 0; x < VisualizationInjector.getWorldX(); x += stepSize) {
for (int y = 0; y < VisualizationInjector
.getWorldY(); y += stepSize) {
// Fetch entry
ModelBasedEntry entry = (ModelBasedEntry) database
.getEntryFor(database.getSegmentID(x, y), false);
// Skip cell if no entry is found
if (entry == null) {
continue;
}
int status = entry.getStatus(selectedType, selectedDirection);
Color color = null;
if (entry.isAvailable() && status == 0) {
// Cell is ok => green
color = new Color(0, 128, 0, 40);
} else if (entry.isAvailable() && status == 1) {
// Cell is shortly before overload
color = new Color(255, 255, 0, 40);
} else if (!entry.isAvailable() || status == 2) {
// Cell is overloaded or unavailable
color = new Color(255, 0, 0, 100);
}
// Fill with color for given metric
g2.setColor(color);
g2.fillRect(x, y, stepSize, stepSize);
// Draw border
// TODO: Draw red border if segment is overload if
// (entry.isAvailable() && !entry.isOverloaded()) {
if (entry.isAvailable()) {
g2.setColor(new Color(255, 0, 0, 10));
g2.setStroke(new BasicStroke(1));
} else {
g2.setColor(new Color(255, 0, 0, 100));
g2.setStroke(new BasicStroke(5));
}
g2.drawRect(x, y, stepSize, stepSize);
// Write current values to cell
// Set text color for yellow to grey else to white
if(status== 1) {
g2.setColor(new Color(160, 160, 160, 255));
} else {
g2.setColor(new Color(255, 255, 255, 255));
}
if (showText) {
// Latency
if (entry.isAvailable() && !entry.isOverloaded()) {
g2.drawString(
"L: " + entry.getLatency(isUpload) + " ms",
x + 10, y + 15);
} else {
g2.drawString("L: ∞ ms", x + 10, y + 15);
}
// Droprate
g2.drawString("D: "
+ (int) (entry.getDropProbability(isUpload) * 100)
+ " %", x + 10, y + 25);
// Bandwidth
g2.drawString(
"B: " + entry.getBandwidth(isUpload) + " kBit/s",
x + 10, y + 35);
// SegmentID
g2.drawString("S:" + entry.getSegmentID(), x + 10, y + 45);
// Current Hosts in Segment
g2.drawString("H:" + entry.getHostsInSegment(), x + 10,
y + 55);
}
// Segment is overloaded
if (entry.isOverloaded()) {
g2.drawString("OVERLOAD", x + 20, y + 80);
}
// Host has been killed manually
if (!entry.isAvailable()) {
g2.drawString("!DEAD!", x + 30, y + 70);
}
}
}
}
@Override
public void actionPerformed(ActionEvent e) {
JCheckBoxMenuItem source = (JCheckBoxMenuItem) e.getSource();
String sourceName = source.getName();
switch (sourceName) {
case "Bandwidth Upload":
selectedDirection = Direction.UPLOAD;
selectedType = ParameterType.BANDWIDTH;
break;
case "Bandwidth Download":
selectedDirection = Direction.DOWNLOAD;
selectedType = ParameterType.BANDWIDTH;
break;
case "Latency Upload":
selectedDirection = Direction.UPLOAD;
selectedType = ParameterType.LATENCY;
break;
case "Latency Download":
selectedDirection = Direction.DOWNLOAD;
selectedType = ParameterType.LATENCY;
break;
case "Droprate Upload":
selectedDirection = Direction.UPLOAD;
selectedType = ParameterType.DROPRATE;
break;
case "Droprate Download":
selectedDirection = Direction.DOWNLOAD;
selectedType = ParameterType.DROPRATE;
break;
default:
break;
}
needsRedraw = true;
for (JCheckBoxMenuItem item : menuItems) {
item.setSelected(false);
}
source.setSelected(true);
}
@Override
public void mouseClicked(int x, int y, int modifier) {
// 17 == Shift
if (modifier == 17) {
int segID = database.getSegmentID(x, y);
Entry entry = database.getEntryFor(segID, false);
entry.setAvailability(!entry.isAvailable());
needsRedraw = true;
}
// 18 == STRG || CMD
if (modifier == 18) {
showText = !showText;
needsRedraw = true;
}
}
}
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