org.cloudbus.cloudsim.network.switches.AbstractSwitch Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cloudsim-plus Show documentation
Show all versions of cloudsim-plus Show documentation
CloudSim Plus: A modern, highly extensible and easier-to-use Java 8 Framework for Modeling and Simulation of Cloud Computing Infrastructures and Services
/*
* Title: CloudSim Toolkit
* Description: CloudSim (Cloud Simulation) Toolkit for Modeling and Simulation of Clouds
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2009-2012, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.network.switches;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.core.CloudSimEntity;
import org.cloudbus.cloudsim.core.CloudSimTags;
import org.cloudbus.cloudsim.core.events.PredicateType;
import org.cloudbus.cloudsim.core.events.SimEvent;
import org.cloudbus.cloudsim.datacenters.network.NetworkDatacenter;
import org.cloudbus.cloudsim.hosts.network.NetworkHost;
import org.cloudbus.cloudsim.network.HostPacket;
import org.cloudbus.cloudsim.util.Conversion;
import org.cloudbus.cloudsim.vms.Vm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
/**
* An base class for implementing Network Switch.
*
* @author Saurabh Kumar Garg
* @author Manoel Campos da Silva Filho
*/
public abstract class AbstractSwitch extends CloudSimEntity implements Switch {
private static final Logger logger = LoggerFactory.getLogger(AbstractSwitch.class.getSimpleName());
/**
* Map of packets sent to Datacenter on the uplink, where each key is a switch
* and the corresponding value is the list of packets to sent to that switch.
*/
private final Map> uplinkSwitchPacketMap;
/**
* Map of packets sent to Datacenter on the downlink, where each key is a
* switch and the corresponding value is the list of packets to sent to that switch.
*/
private final Map> downlinkSwitchPacketMap;
/**
* List of hosts connected to the switch.
*/
private final List hostList;
/**
* List of uplink Datacenter.
*/
private final List uplinkSwitches;
/**
* List of downlink Datacenter.
*/
private final List downlinkSwitches;
/**
* Map of packets sent to hosts connected in the switch, where each key is a
* host and the corresponding value is the list of packets to sent to that host.
*/
private final Map> packetToHostMap;
/**
* @see #getUplinkBandwidth()
*/
private double uplinkBandwidth;
/**
* @see #getDownlinkBandwidth()
*/
private double downlinkBandwidth;
/**
* @see #getPorts()
*/
private int ports;
/**
* @see #getDatacenter()
*/
private NetworkDatacenter datacenter;
private final List packetList;
/**
* @see #getSwitchingDelay()
*/
private double switchingDelay;
public AbstractSwitch(final CloudSim simulation, final NetworkDatacenter dc) {
super(simulation);
this.packetList = new ArrayList<>();
this.hostList = new ArrayList<>();
this.packetToHostMap = new HashMap<>();
this.uplinkSwitchPacketMap = new HashMap<>();
this.downlinkSwitchPacketMap = new HashMap<>();
this.downlinkSwitches = new ArrayList<>();
this.uplinkSwitches = new ArrayList<>();
this.datacenter = dc;
}
@Override
protected void startEntity() {
logger.info("{} is starting...", getName());
schedule(this, 0, CloudSimTags.DATACENTER_LIST_REQUEST);
}
@Override
public void processEvent(final SimEvent ev) {
switch (ev.getTag()) {
case CloudSimTags.NETWORK_EVENT_UP:
// process the packet from down switch or host
processPacketUp(ev);
break;
case CloudSimTags.NETWORK_EVENT_DOWN:
// process the packet from uplink
processPacketDown(ev);
break;
case CloudSimTags.NETWORK_EVENT_SEND:
processPacketForward();
break;
case CloudSimTags.NETWORK_EVENT_HOST:
processHostPacket(ev);
break;
case CloudSimTags.NETWORK_HOST_REGISTER:
registerHost(ev);
break;
}
}
/**
* Process a packet sent to a host.
*
* @param ev The packet sent.
*/
protected void processHostPacket(final SimEvent ev) {
final HostPacket pkt = (HostPacket) ev.getData();
final NetworkHost host = pkt.getDestination();
host.addReceivedNetworkPacket(pkt);
}
/**
* Sends a packet to Datacenter connected through a downlink port.
*
* @param ev Event/packet to process
*/
protected void processPacketDown(final SimEvent ev) {
// packet coming from up level router
// has to send downward.
// check which switch to forward to
// add packet in the switch list
// add packet in the host list
// int src=ev.getSource();
getSimulation().cancelAll(this, new PredicateType(CloudSimTags.NETWORK_EVENT_SEND));
schedule(this, getSwitchingDelay(), CloudSimTags.NETWORK_EVENT_SEND);
}
/**
* Gets the Host where a VM is placed.
* @param vm the VM to get its Host
* @return the Host where the VM is placed
*/
protected NetworkHost getVmHost(final Vm vm) {
return (NetworkHost)vm.getHost();
}
/**
* Sends a packet to Datacenter connected through a uplink port.
*
* @param ev Event/packet to process
*/
protected void processPacketUp(final SimEvent ev) {
// packet coming from down level router has to be sent up.
// check which switch to forward to and add packet in the switch list
getSimulation().cancelAll(this, new PredicateType(CloudSimTags.NETWORK_EVENT_SEND));
schedule(this, switchingDelay, CloudSimTags.NETWORK_EVENT_SEND);
}
/**
* Register a host that is connected to the switch.
*
* @param ev the event containing the host to be registered
*/
private void registerHost(final SimEvent ev) {
final NetworkHost host = (NetworkHost) ev.getData();
hostList.add(host);
}
/**
* Sends a packet to hosts connected to the switch
*
*/
private void processPacketForward() {
forwardPacketsToDownlinkSwitches();
forwardPacketsToUplinkSwitches();
forwardPacketsToHosts();
}
/**
* Gets the list of packets to be sent to each Downlink AbstractSwitch
* and forward them.
*
* @see #downlinkSwitchPacketMap
*/
private void forwardPacketsToDownlinkSwitches() {
for (final Switch destinationSwitch: downlinkSwitchPacketMap.keySet()) {
final List netPktList = getDownlinkSwitchPacketList(destinationSwitch);
for (final HostPacket pkt : netPktList) {
final double delay = networkDelayForPacketTransmission(pkt, downlinkBandwidth, netPktList);
this.send(destinationSwitch, delay, CloudSimTags.NETWORK_EVENT_DOWN, pkt);
}
netPktList.clear();
}
}
/**
* Gets the list of packets to be sent to each Uplink Switch
* and forward them.
*
* @see #uplinkSwitchPacketMap
*/
private void forwardPacketsToUplinkSwitches() {
for (final Switch destinationSwitch : uplinkSwitchPacketMap.keySet()) {
final List packetList = getUplinkSwitchPacketList(destinationSwitch);
for(final HostPacket pkt: packetList) {
final double delay = networkDelayForPacketTransmission(pkt, uplinkBandwidth, packetList);
this.send(destinationSwitch, delay, CloudSimTags.NETWORK_EVENT_UP, pkt);
}
packetList.clear();
}
}
/**
* Gets the list of packets to be sent to each Host
* and forward them.
*
* @see #packetToHostMap
*/
private void forwardPacketsToHosts() {
for (final NetworkHost host : packetToHostMap.keySet()) {
final List packetList = getHostPacketList(host);
for (final HostPacket pkt: packetList) {
final double delay = networkDelayForPacketTransmission(pkt, downlinkBandwidth, packetList);
this.send(this, delay, CloudSimTags.NETWORK_EVENT_HOST, pkt);
}
packetList.clear();
}
}
/**
* Computes the network delay to send a packet through the network.
*
* @param netPkt the packet to be sent
* @param bwCapacity the total bandwidth capacity (in Megabits/s)
* @param netPktList the list of packets waiting to be sent
* @return the expected time to transfer the packet through the network (in seconds)
*/
protected double networkDelayForPacketTransmission(final HostPacket netPkt, final double bwCapacity, final List netPktList) {
return Conversion.bytesToMegaBits(netPkt.getVmPacket().getSize()) / getAvailableBwForEachPacket(bwCapacity, netPktList);
}
/**
* Considering a list of packets to be sent,
* gets the amount of available bandwidth for each packet,
* assuming that the bandwidth is shared equally among
* all packets, disregarding the packet size.
*
* @param bwCapacity the total bandwidth capacity to be shared among
* the packets to be sent (in Megabits/s)
* @param netPktList list of packets to be sent
* @return the available bandwidth for each packet in the list of packets to send (in Megabits/s)
* or the total bandwidth capacity if the packet list has 0 or 1 element
*/
private double getAvailableBwForEachPacket(final double bwCapacity, final List netPktList) {
return (netPktList.isEmpty() ? bwCapacity : bwCapacity / netPktList.size());
}
@Override
public void shutdownEntity() {
super.shutdownEntity();
logger.info("{} is shutting down...", getName());
}
@Override
public double getUplinkBandwidth() {
return uplinkBandwidth;
}
@Override
public final void setUplinkBandwidth(double uplinkBandwidth) {
this.uplinkBandwidth = uplinkBandwidth;
}
@Override
public double getDownlinkBandwidth() {
return downlinkBandwidth;
}
@Override
public final void setDownlinkBandwidth(double downlinkBandwidth) {
this.downlinkBandwidth = downlinkBandwidth;
}
@Override
public int getPorts() {
return ports;
}
@Override
public final void setPorts(final int ports) {
this.ports = ports;
}
@Override
public double getSwitchingDelay() {
return switchingDelay;
}
@Override
public final void setSwitchingDelay(final double switchingDelay) {
this.switchingDelay = switchingDelay;
}
@Override
public List getUplinkSwitches() {
return uplinkSwitches;
}
@Override
public List getHostList() {
return Collections.unmodifiableList(hostList);
}
@Override
public void connectHost(final NetworkHost host) {
hostList.add(host);
}
@Override
public boolean disconnectHost(final NetworkHost host) {
return hostList.remove(host);
}
@Override
public Map> getPacketToHostMap() {
return Collections.unmodifiableMap(packetToHostMap);
}
@Override
public List getDownlinkSwitches() {
return downlinkSwitches;
}
@Override
public List getDownlinkSwitchPacketList(final Switch downlinkSwitch) {
downlinkSwitchPacketMap.putIfAbsent(downlinkSwitch, new ArrayList<>());
return downlinkSwitchPacketMap.get(downlinkSwitch);
}
@Override
public List getUplinkSwitchPacketList(final Switch uplinkSwitch) {
uplinkSwitchPacketMap.putIfAbsent(uplinkSwitch, new ArrayList<>());
return uplinkSwitchPacketMap.get(uplinkSwitch);
}
@Override
public List getHostPacketList(final NetworkHost host) {
packetToHostMap.putIfAbsent(host, new ArrayList<>());
return packetToHostMap.get(host);
}
@Override
public Map> getUplinkSwitchPacketMap() {
return Collections.unmodifiableMap(uplinkSwitchPacketMap);
}
@Override
public void addPacketToBeSentToDownlinkSwitch(final Switch downlinkSwitch, final HostPacket packet) {
getDownlinkSwitchPacketList(downlinkSwitch).add(packet);
}
@Override
public void addPacketToBeSentToUplinkSwitch(final Switch uplinkSwitch, final HostPacket packet) {
getUplinkSwitchPacketList(uplinkSwitch).add(packet);
}
@Override
public void addPacketToBeSentToHost(final NetworkHost host, final HostPacket packet) {
getHostPacketList(host).add(packet);
}
@Override
public NetworkDatacenter getDatacenter() {
return datacenter;
}
@Override
public void setDatacenter(final NetworkDatacenter datacenter) {
this.datacenter = datacenter;
}
@Override
public List getPacketList() {
return packetList;
}
/**
* Gets the {@link EdgeSwitch} that the Host where the VM is placed is connected to.
* @param vm the VM to get the Edge Switch
* @return the connected Edge Switch
*/
protected EdgeSwitch getVmEdgeSwitch(final Vm vm) {
return ((NetworkHost)vm.getHost()).getEdgeSwitch();
}
}