This commit is contained in:
2021-04-06 00:45:28 +02:00
commit 17fabc368e
836 changed files with 3042963 additions and 0 deletions

View File

@@ -0,0 +1,19 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
/**
* Activities that can be performed by VM. (Transmission or Compute)
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public interface Activity {
}

View File

@@ -0,0 +1,24 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
/**
* Represent aggregation switch
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public class AggregationSwitch extends Switch {
public AggregationSwitch(String name,int bw, long iops, int upports, int downports, NetworkOperatingSystem nos) {
super(name, bw, iops, upports, downports, nos);
}
}

View File

@@ -0,0 +1,53 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
/**
* Traffic requirements between two VMs
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public class Arc {
int srcId;
int dstId;
int flowId;
long requiredBandwidth;
double requiredLatency;
public Arc(int srcId, int dstId, int flowId, long reqBW, double reqLatency) {
super();
this.srcId = srcId;
this.dstId = dstId;
this.flowId = flowId;
this.requiredBandwidth = reqBW;
this.requiredLatency = reqLatency;
}
public int getSrcId() {
return srcId;
}
public int getDstId() {
return dstId;
}
public int getFlowId() {
return flowId;
}
public long getBw() {
return requiredBandwidth;
}
public double getLatency() {
return requiredLatency;
}
}

View File

@@ -0,0 +1,341 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
import java.util.LinkedList;
import java.util.List;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.core.CloudSim;
/**
* This class represents a channel for transmission of data between switches.
* It controls sharing of available bandwidth. Relation between
* Transmission and Channel is the same as Cloudlet and CloudletScheduler,
* but here we consider only the time shared case, representing a shared
* channel among different simultaneous package transmissions.
*
* This is logical channel. One physical link (class Link) can hold more than one logical channels (class Channel).
* Channel is directional. It is one way.
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public class Channel {
private List<Node> nodes;
private List<Link> links;
private double allocatedBandwidth; // Actual bandwidth allocated to the channel
private double previousTime;
private LinkedList<Transmission> inTransmission;
private LinkedList<Transmission> completed;
private final int srcId;
private final int dstId;
private final int chId;
private final double requestedBandwidth; // Requested by user
public Channel(int chId, int srcId, int dstId, List<Node> nodes, List<Link> links, double bandwidth) {
this.chId = chId;
this.srcId = srcId;
this.dstId = dstId;
this.nodes = nodes;
this.links = links;
this.allocatedBandwidth = bandwidth;
this.requestedBandwidth = bandwidth;
this.inTransmission = new LinkedList<Transmission>();
this.completed = new LinkedList<Transmission>();
}
public void initialize() {
// Assign BW to all links
for(int i=0; i<nodes.size()-1; i++) {
Node from = nodes.get(i);
Link link = links.get(i);
link.addChannel(from, this);
from.updateNetworkUtilization();
}
nodes.get(nodes.size()-1).updateNetworkUtilization();
}
public void terminate() {
// Assign BW to all links
for(int i=0; i<nodes.size()-1; i++) {
Link link = links.get(i);
link.removeChannel(this);
Node node = nodes.get(i);
node.updateNetworkUtilization();
}
nodes.get(nodes.size()-1).updateNetworkUtilization();
}
private double getLowestSharedBandwidth() {
// Get the lowest bandwidth along links in the channel
double lowestSharedBw = Double.POSITIVE_INFINITY;
for(int i=0; i<nodes.size()-1; i++) {
Node from = nodes.get(i);
Node to = nodes.get(i+1);
Link link = links.get(i);
if(lowestSharedBw > link.getSharedBandwidthPerChannel(from, to))
lowestSharedBw = link.getSharedBandwidthPerChannel(from, to);
}
return lowestSharedBw;
}
public double getAdjustedRequestedBandwidth() {
double lowest_factor = 1.0;
// Find the slowest link (low bw) among all links where this channel is passing through
for(int i=0; i<nodes.size()-1; i++) {
Node from = nodes.get(i);
Link link = links.get(i);
double factor = link.getDedicatedChannelAdjustFactor(from);
if(lowest_factor > factor)
lowest_factor = factor;
}
return lowest_factor;
}
public boolean adjustDedicatedBandwidthAlongLink() {
if(chId == -1)
return false;
double lowestLinkBwShared = Double.POSITIVE_INFINITY;
double factor = this.getAdjustedRequestedBandwidth();
double adjustedBandwidth = this.getRequestedBandwidth() * factor;
if(factor < 1.0) {
Log.printLine("Link.adjustDedicatedBandwidthAlongLink(): Cannot allocate requested amount of BW"
+adjustedBandwidth+"/"+this.getRequestedBandwidth());
}
// Find the slowest link (low bw) among all links where this channel is passing through
for(int i=0; i<nodes.size()-1; i++) {
Node from = nodes.get(i);
Link link = links.get(i);
double link_bw = link.getBw();
int numChannels = link.getChannelCount(from);
double link_bw_per_channel = link_bw / numChannels;
if(lowestLinkBwShared > link_bw_per_channel)
lowestLinkBwShared = link_bw_per_channel;
}
// Dedicated channel.
if(adjustedBandwidth < lowestLinkBwShared) {
changeBandwidth(lowestLinkBwShared);
return true;
}
else if(this.allocatedBandwidth != adjustedBandwidth) {
changeBandwidth(adjustedBandwidth);
return true;
}
return false;
}
public boolean adjustSharedBandwidthAlongLink() {
if(chId != -1)
return false;
// Get the lowest bandwidth along links in the channel
double lowestLinkBw = getLowestSharedBandwidth();
if(this.allocatedBandwidth != lowestLinkBw) {
changeBandwidth(lowestLinkBw);
return true;
}
return false;
}
public boolean changeBandwidth(double newBandwidth){
if (newBandwidth == allocatedBandwidth)
return false; //nothing changed
boolean isChanged = this.updatePackageProcessing();
this.allocatedBandwidth=newBandwidth;
return isChanged;
}
public double getAllocatedBandwidth() {
return allocatedBandwidth;
}
private double getAllocatedBandwidthPerTransmission() {
// If this channel shares a link with another channel, this channel might not get the full BW from link.
if(inTransmission.size() == 0) {
return getAllocatedBandwidth();
}
return getAllocatedBandwidth()/inTransmission.size();
}
public int getActiveTransmissionNum() {
return inTransmission.size();
}
/**
* Updates processing of transmissions taking place in this Channel.
* @param currentTime current simulation time (in seconds)
* @return delay to next transmission completion or
* Double.POSITIVE_INFINITY if there is no pending transmissions
*/
public boolean updatePackageProcessing(){
double currentTime = CloudSim.clock();
double timeSpent = NetworkOperatingSystem.round(currentTime - this.previousTime);
if(timeSpent <= 0 || inTransmission.size() == 0)
return false; // Nothing changed
//update the amount of transmission
long processedThisRound = Math.round(timeSpent*getAllocatedBandwidthPerTransmission());
//update transmission table; remove finished transmission
LinkedList<Transmission> completedTransmissions = new LinkedList<Transmission>();
for(Transmission transmission: inTransmission){
transmission.addCompletedLength(processedThisRound);
if (transmission.isCompleted()){
completedTransmissions.add(transmission);
this.completed.add(transmission);
}
}
this.inTransmission.removeAll(completedTransmissions);
previousTime=currentTime;
Log.printLine(CloudSim.clock() + ": Channel.updatePackageProcessing() ("+this.toString()+"):Time spent:"+timeSpent+
", BW/host:"+getAllocatedBandwidthPerTransmission()+", Processed:"+processedThisRound);
if(completedTransmissions.isEmpty())
return false; // Nothing changed
return true;
}
// Estimated finish time of one transmission
private double estimateFinishTime(Transmission t) {
double bw = getAllocatedBandwidthPerTransmission();
if(bw == 0) {
return Double.POSITIVE_INFINITY;
}
double eft= (double)t.getSize()/bw;
return eft;
}
// The earliest finish time among all transmissions in this channel
public double nextFinishTime() {
//now, predicts delay to next transmission completion
double delay = Double.POSITIVE_INFINITY;
for (Transmission transmission:this.inTransmission){
double eft = estimateFinishTime(transmission);
if (eft<delay)
delay = eft;
}
if(delay == Double.POSITIVE_INFINITY) {
return delay;
}
else if(delay < 0) {
throw new IllegalArgumentException("Channel.nextFinishTime: delay"+delay);
}
delay=NetworkOperatingSystem.round(delay);
if (delay < NetworkOperatingSystem.getMinTimeBetweenNetworkEvents()) {
//Log.printLine(CloudSim.clock() + ":Channel: delay is too short: "+ delay);
delay = NetworkOperatingSystem.getMinTimeBetweenNetworkEvents();
}
return delay;
}
/**
* Adds a new Transmission to be submitted via this Channel
* @param transmission transmission initiating
* @return estimated delay to complete this transmission
*
*/
public double addTransmission(Transmission transmission){
if (this.inTransmission.isEmpty())
previousTime=CloudSim.clock();
this.inTransmission.add(transmission);
double eft = estimateFinishTime(transmission);
return eft;
}
/**
* Remove a transmission submitted to this Channel
* @param transmission to be removed
*
*/
public void removeTransmission(Transmission transmission){
inTransmission.remove(transmission);
}
/**
* @return list of Packages whose transmission finished, or empty
* list if no package arrived.
*/
public LinkedList<Transmission> getArrivedPackages(){
LinkedList<Transmission> returnList = new LinkedList<Transmission>();
if (!completed.isEmpty()){
returnList.addAll(completed);
}
completed.removeAll(returnList);
return returnList;
}
public int getChId() {
return chId;
}
public double getLastUpdateTime(){
return previousTime;
}
public String toString() {
return "Channel("+this.srcId+"->"+this.dstId+"|"+this.chId
+"): BW:"+allocatedBandwidth+", Transmissions:"+inTransmission.size();
}
public Node getLastNode() {
Node node = this.nodes.get(this.nodes.size()-1);
return node;
}
public int getSrcId() {
return srcId;
}
public int getDstId() {
return dstId;
}
public double getRequestedBandwidth() {
return requestedBandwidth;
}
}

View File

@@ -0,0 +1,28 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
/**
* Constant variables to use
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public class Constants {
private static final int SDN_BASE = 89000000;
public static final int SDN_PACKAGE = SDN_BASE + 1;
public static final int SDN_INTERNAL_PACKAGE_PROCESS = SDN_BASE + 2;
public static final int REQUEST_SUBMIT = SDN_BASE + 10;
public static final int REQUEST_COMPLETED = SDN_BASE + 11;
public static final int APPLICATION_SUBMIT = SDN_BASE + 20; // Broker -> Datacenter.
public static final int APPLICATION_SUBMIT_ACK = SDN_BASE + 21;
}

View File

@@ -0,0 +1,25 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
/**
* Represent core switch
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public class CoreSwitch extends Switch {
public CoreSwitch(String name,int bw, long iops, int upports, int downports, NetworkOperatingSystem nos) {
super(name, bw, iops, upports, downports, nos);
//if (upports>0) throw new IllegalArgumentException("Core switches cannot have uplinks.");
}
}

View File

@@ -0,0 +1,24 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
/**
* Represent edge switch
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public class EdgeSwitch extends Switch {
public EdgeSwitch(String name,int bw, long iops, int upports, int downports, NetworkOperatingSystem nos) {
super(name, bw, iops, upports, downports, nos);
}
}

View File

@@ -0,0 +1,95 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
import java.util.HashMap;
import java.util.Map;
import org.cloudbus.cloudsim.Log;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
/**
* ForwardingRule class is to represent a forwarding table in each switch.
* This is for VM routing, not host routing. Addresses used here are the addresses of VM.
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public class ForwardingRule {
Table<Integer, Integer, Map<Integer,Node>> table;
public ForwardingRule(){
this.table = HashBasedTable.create();
}
public void clear(){
table.clear();
}
public void addRule(int src, int dest, int flowId, Node to){
Map<Integer, Node> map = table.get(src, dest);
if(map == null)
map = new HashMap<Integer, Node>();
map.put(flowId, to);
table.put(src, dest, map);
}
public void removeRule(int src, int dest, int flowId){
Map<Integer, Node> map = table.get(src, dest);
map.remove(flowId);
if(map.isEmpty())
table.remove(src, dest);
else
table.put(src, dest, map);
}
public Node getRoute(int src, int dest, int flowId) {
Map<Integer, Node> map = table.get(src, dest);
if(map==null)
return null;
return map.get(flowId);
}
public void printForwardingTable(String thisNode) {
for(Integer rowK:table.rowKeySet()) {
Map<Integer, Map<Integer,Node>> row = table.row(rowK);
for(Integer colK: row.keySet()) {
Map<Integer, Node> nodes = row.get(colK);
for(Integer flowId:nodes.keySet()) {
Node node = nodes.get(flowId);
if(node instanceof SDNHost) {
Log.printLine(thisNode + ": "+
NetworkOperatingSystem.debugVmIdName.get(rowK) + "->" +
NetworkOperatingSystem.debugVmIdName.get(colK) + "->"+"(flow:"+flowId+")" +
((SDNHost) node).getName());
}
else if(node instanceof Switch) {
Log.printLine(thisNode + ": "+
NetworkOperatingSystem.debugVmIdName.get(rowK) + "->" +
NetworkOperatingSystem.debugVmIdName.get(colK) + "->"+"(flow:"+flowId+")" +
((Switch) node).getName());
}
else {
Log.printLine(thisNode + ": "+
NetworkOperatingSystem.debugVmIdName.get(rowK) + "->" +
NetworkOperatingSystem.debugVmIdName.get(colK) + "->"+"(flow:"+flowId+")" +
node.getAddress());
}
}
}
}
}
}

View File

@@ -0,0 +1,211 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
import java.util.ArrayList;
import java.util.List;
import org.cloudbus.cloudsim.Log;
/**
* This is physical link between hosts and switches to build physical topology.
* Links have latency and bandwidth.
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public class Link {
// bi-directional link (one link = both ways)
Node highOrder;
Node lowOrder;
double upBW; // low -> high
double downBW; // high -> low
double latency;
private List<Channel> upChannels;
private List<Channel> downChannels;
public Link(Node highOrder, Node lowOrder, double latency, double bw) {
this.highOrder = highOrder;
this.lowOrder = lowOrder;
this.upBW = this.downBW = bw;
this.latency = latency;
this.upChannels = new ArrayList<Channel>();
this.downChannels = new ArrayList<Channel>();
}
public Link(Node highOrder, Node lowOrder, double latency, double upBW, double downBW) {
this(highOrder, lowOrder, latency, upBW);
this.downBW = downBW;
}
public Node getHighOrder() {
return highOrder;
}
public Node getLowOrder() {
return lowOrder;
}
public Node getOtherNode(Node from) {
if(highOrder.equals(from))
return lowOrder;
return highOrder;
}
private boolean isUplink(Node from) {
if(from.equals(lowOrder)) {
return true;
}
else if(from.equals(highOrder)) {
return false;
}
else {
throw new IllegalArgumentException("Link.isUplink(): from("+from+") Node is wrong!!");
}
}
public double getBw(Node from) {
if(isUplink(from)) {
return upBW;
}
else {
return downBW;
}
}
public double getBw() {
if(upBW != downBW) {
throw new IllegalArgumentException("Downlink/Uplink BW are different!");
}
return upBW;
}
public double getLatency() {
return latency;
}
private List<Channel> getChannels(Node from) {
List<Channel> channels;
if(isUplink(from)) {
channels = this.upChannels;
}
else {
channels = this.downChannels;
}
return channels;
}
public double getDedicatedChannelAdjustFactor(Node from) {
double factor = 1.0;
double totalRequested = getRequestedBandwidthForDedicatedChannels(from);
if(totalRequested > this.getBw()) {
Log.printLine("Link.getDedicatedChannelAdjustFactor() Exceeds link bandwidth. Reduce requested bandwidth");
factor = this.getBw() / totalRequested;
}
return factor;
}
public boolean addChannel(Node from, Channel ch) {
getChannels(from).add(ch);
return true;
}
public boolean removeChannel(Channel ch) {
boolean ret = this.upChannels.remove(ch);
if(!ret) {
// the channel is down link
ret = this.downChannels.remove(ch);
}
return ret;
}
public double getAllocatedBandwidthForDedicatedChannels(Node from) {
double bw=0;
for(Channel ch: getChannels(from)) {
if(ch.getChId() != -1) {
// chId == -1 : default channel
bw += ch.getAllocatedBandwidth();
}
}
return bw;
}
public double getRequestedBandwidthForDedicatedChannels(Node from) {
double bw=0;
for(Channel ch: getChannels(from)) {
if(ch.getChId() != -1) {
// chId == -1 : default channel
bw += ch.getRequestedBandwidth();
}
}
return bw;
}
public int getChannelCount(Node from) {
List<Channel> channels = getChannels(from);
return channels.size();
}
public int getDedicatedChannelCount(Node from) {
int num=0;
for(Channel ch: getChannels(from)) {
if(ch.getChId() != -1) {
// chId == -1 : default channel
num ++;
}
}
return num;
}
public int getSharedChannelCount(Node from) {
int num = getChannels(from).size() - getDedicatedChannelCount(from);
return num;
}
public double getFreeBandwidth(Node from) {
double bw = this.getBw(from);
double dedicatedBw = getAllocatedBandwidthForDedicatedChannels(from);
return bw-dedicatedBw;
}
public double getFreeBandwidthForDedicatedChannel(Node from) {
double bw = this.getBw(from);
double dedicatedBw = getRequestedBandwidthForDedicatedChannels(from);
return bw-dedicatedBw;
}
public double getSharedBandwidthPerChannel(Node from, Node to) {
double freeBw = getFreeBandwidth(from);
double sharedBwEachChannel = freeBw / getSharedChannelCount(from);
return sharedBwEachChannel;
}
public String toString() {
return "Link:"+this.highOrder.toString() + " <-> "+this.lowOrder.toString() + ", upBW:" + upBW + ", Latency:"+ latency;
}
public boolean isActive() {
if(this.upChannels.size() >0 || this.downChannels.size() >0)
return true;
return false;
}
}

View File

@@ -0,0 +1,56 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
import org.cloudbus.cloudsim.Cloudlet;
import org.cloudbus.cloudsim.UtilizationModelFull;
import org.cloudbus.cloudsim.Vm;
import org.cloudbus.cloudsim.core.CloudSimTags;
/**
* Middlebox represent specific VM that acts as a middle box
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public abstract class Middlebox {
Vm vm;
int mipsPerOp;
SDNHost host;
static int id=0;
public Middlebox(Vm vm, int misPerOperation){
this.vm=vm;
this.mipsPerOp=misPerOperation;
}
public abstract void editRequest(Request req);
public int getId(){
return vm.getId();
}
public Vm getVm(){
return vm;
}
public void setHost(SDNHost host){
this.host=host;
}
public void submitRequest(Request req){
Cloudlet cl = new Cloudlet(id++,mipsPerOp,1,0,0,new UtilizationModelFull(),new UtilizationModelFull(),new UtilizationModelFull());
cl.setVmId(vm.getId());
host.schedule(host.getHost().getDatacenter().getId(), 0.0, CloudSimTags.CLOUDLET_SUBMIT, cl);
}
}

View File

@@ -0,0 +1,687 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.cloudbus.cloudsim.CloudletSchedulerTimeShared;
import org.cloudbus.cloudsim.Host;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.Pe;
import org.cloudbus.cloudsim.Vm;
import org.cloudbus.cloudsim.VmScheduler;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.core.CloudSimTags;
import org.cloudbus.cloudsim.core.SimEntity;
import org.cloudbus.cloudsim.core.SimEvent;
import org.cloudbus.cloudsim.core.predicates.PredicateType;
import org.cloudbus.cloudsim.provisioners.BwProvisioner;
import org.cloudbus.cloudsim.provisioners.BwProvisionerSimple;
import org.cloudbus.cloudsim.provisioners.PeProvisionerSimple;
import org.cloudbus.cloudsim.provisioners.RamProvisioner;
import org.cloudbus.cloudsim.provisioners.RamProvisionerSimple;
import org.cloudbus.cloudsim.sdn.example.policies.VmSchedulerTimeSharedEnergy;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
/**
* NOS calculates and estimates network behaviour. It also mimics SDN Controller functions.
* It manages channels between switches, and assigns packages to channels and control their completion
* Once the transmission is completed, forward the packet to the destination.
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public abstract class NetworkOperatingSystem extends SimEntity {
String physicalTopologyFileName;
protected PhysicalTopology topology;
//Hashtable<Integer,SDNHost> vmHostTable;
Hashtable<Package,Node> pkgTable;
Hashtable<String, Channel> channelTable;
List<Host> hosts;
protected List<SDNHost> sdnhosts;
protected List<Switch> switches= new ArrayList<Switch>();
int vmId=0;
protected SDNDatacenter datacenter;
protected LinkedList<Vm> vmList;
protected LinkedList<Arc> arcList;
Map<Integer, Arc> flowIdArcTable;
Map<String, Integer> vmNameIdTable;
Map<String, Integer> flowNameIdTable;
public static Map<Integer, String> debugVmIdName = new HashMap<Integer, String>();
public static Map<Integer, String> debugFlowIdName = new HashMap<Integer, String>();
boolean isApplicationDeployed = false;
// Resolution of the result.
public static double minTimeBetweenEvents = 0.001; // in sec
public static int resolutionPlaces = 5;
public static int timeUnit = 1; // 1: sec, 1000: msec
/**
* 1. map VMs and middleboxes to hosts, add the new vm/mb to the vmHostTable, advise host, advise dc
* 2. set channels and bws
* 3. set routing tables to restrict hops to meet latency
*/
protected abstract boolean deployApplication(List<Vm> vms, List<Middlebox> middleboxes, List<Arc> links);
protected abstract Middlebox deployMiddlebox(String type, Vm vm);
public NetworkOperatingSystem(String fileName) {
super("NOS");
this.physicalTopologyFileName = fileName;
this.pkgTable = new Hashtable<Package, Node>();
this.channelTable = new Hashtable<String, Channel>();
initPhysicalTopology();
}
public static double getMinTimeBetweenNetworkEvents() {
return minTimeBetweenEvents* timeUnit;
}
public static double round(double value) {
int places = resolutionPlaces;
if (places < 0) throw new IllegalArgumentException();
if(timeUnit >= 1000) value = Math.floor(value*timeUnit);
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(places, RoundingMode.CEILING);
return bd.doubleValue();
//return value;
}
@Override
public void startEntity() {}
@Override
public void shutdownEntity() {}
@Override
public void processEvent(SimEvent ev) {
int tag = ev.getTag();
switch(tag){
case Constants.SDN_INTERNAL_PACKAGE_PROCESS:
internalPackageProcess();
break;
case CloudSimTags.VM_CREATE_ACK:
processVmCreateAck(ev);
break;
case CloudSimTags.VM_DESTROY:
processVmDestroyAck(ev);
break;
default: System.out.println("Unknown event received by "+super.getName()+". Tag:"+ev.getTag());
}
}
public void processVmCreateAck(SimEvent ev) {
}
protected void processVmDestroyAck(SimEvent ev) {
Vm destroyedVm = (Vm) ev.getData();
// remove all channels transferring data from or to this vm.
for(Vm vm:this.vmList) {
Channel ch = this.findChannel(vm.getId(), destroyedVm.getId(), -1);
if(ch != null) {
this.removeChannel(getKey(vm.getId(), destroyedVm.getId(), -1));
}
ch = this.findChannel(destroyedVm.getId(), vm.getId(), -1);
if(ch != null) {
this.removeChannel(getKey(destroyedVm.getId(), vm.getId(), -1));
}
}
sendInternalEvent();
}
public void addPackageToChannel(Node sender, Package pkg) {
int src = pkg.getOrigin();
int dst = pkg.getDestination();
int flowId = pkg.getFlowId();
if(sender.equals(sender.getVMRoute(src, dst, flowId))) {
// For loopback packet (when src and dst is on the same host)
//Log.printLine(CloudSim.clock() + ": " + getName() + ".addPackageToChannel: Loopback package: "+pkg +". Send to destination:"+dst);
sendNow(sender.getAddress(),Constants.SDN_PACKAGE,pkg);
return;
}
updatePackageProcessing();
pkgTable.put(pkg,sender);
Channel channel=findChannel(src, dst, flowId);
if(channel == null) {
//No channel establisihed. Add a channel.
channel = createChannel(src, dst, flowId, sender);
if(channel == null) {
// failed to create channel
return;
}
addChannel(src, dst, flowId, channel);
}
double eft = channel.addTransmission(new Transmission(pkg));
Log.printLine(CloudSim.clock() + ": " + getName() + ".addPackageToChannel ("+channel
+"): Transmission added:" +
NetworkOperatingSystem.debugVmIdName.get(src) + "->"+
NetworkOperatingSystem.debugVmIdName.get(dst) + ", flow ="+flowId + " / eft="+eft);
sendInternalEvent();
}
private void internalPackageProcess() {
if(updatePackageProcessing()) {
sendInternalEvent();
}
}
private void sendInternalEvent() {
CloudSim.cancelAll(getId(), new PredicateType(Constants.SDN_INTERNAL_PACKAGE_PROCESS));
if(channelTable.size() != 0) {
// More to process. Send event again
double delay = this.nextFinishTime();
Log.printLine(CloudSim.clock() + ": " + getName() + ".sendInternalEvent(): next finish time: "+ delay);
send(this.getId(), delay, Constants.SDN_INTERNAL_PACKAGE_PROCESS);
}
}
private double nextFinishTime() {
double earliestEft = Double.POSITIVE_INFINITY;
for(Channel ch:channelTable.values()){
double eft = ch.nextFinishTime();
if (eft<earliestEft){
earliestEft=eft;
}
}
if(earliestEft == Double.POSITIVE_INFINITY) {
throw new IllegalArgumentException("NOS.nextFinishTime(): next finish time is infinite!");
}
return earliestEft;
}
private boolean updatePackageProcessing() {
boolean needSendEvent = false;
LinkedList<Channel> completeChannels = new LinkedList<Channel>();
for(Channel ch:channelTable.values()){
boolean isCompleted = ch.updatePackageProcessing();
needSendEvent = needSendEvent || isCompleted;
//completeChannels.add(ch.getArrivedPackages());
completeChannels.add(ch);
}
if(completeChannels.size() != 0) {
processCompletePackages(completeChannels);
updateChannel();
}
return needSendEvent;
}
private void processCompletePackages(List<Channel> channels){
for(Channel ch:channels) {
Node dest = ch.getLastNode();
for (Transmission tr:ch.getArrivedPackages()){
Package pkg = tr.getPackage();
//Node sender = pkgTable.remove(pkg);
//Node nextHop = sender.getRoute(pkg.getOrigin(),pkg.getDestination(),pkg.getFlowId());
Log.printLine(CloudSim.clock() + ": " + getName() + ": Package completed: "+pkg +". Send to destination:"+dest);
sendNow(dest.getAddress(),Constants.SDN_PACKAGE,pkg);
}
}
}
public Map<String, Integer> getVmNameIdTable() {
return this.vmNameIdTable;
}
public Map<String, Integer> getFlowNameIdTable() {
return this.flowNameIdTable;
}
private Channel findChannel(int from, int to, int channelId) {
// check if there is a pre-configured channel for this application
Channel channel=channelTable.get(getKey(from,to, channelId));
if (channel == null) {
//there is no channel for specific flow, find the default channel for this link
channel=channelTable.get(getKey(from,to));
}
return channel;
}
private void addChannel(int src, int dst, int chId, Channel ch) {
//System.err.println("NOS.addChannel:"+getKey(src, dst, chId));
this.channelTable.put(getKey(src, dst, chId), ch);
ch.initialize();
adjustAllChannels();
}
private Channel removeChannel(String key) {
//System.err.println("NOS.removeChannel:"+key);
Channel ch = this.channelTable.remove(key);
ch.terminate();
adjustAllChannels();
return ch;
}
private void adjustAllChannels() {
for(Channel ch:this.channelTable.values()) {
if(ch.adjustDedicatedBandwidthAlongLink()) {
// Channel BW is changed. send event.
}
}
for(Channel ch:this.channelTable.values()) {
if(ch.adjustSharedBandwidthAlongLink()) {
// Channel BW is changed. send event.
}
}
}
private Channel createChannel(int src, int dst, int flowId, Node srcNode) {
List<Node> nodes = new ArrayList<Node>();
List<Link> links = new ArrayList<Link>();
Node origin = srcNode;
Node dest = origin.getVMRoute(src, dst, flowId);
if(dest==null)
return null;
Link link;
double lowestBw = Double.POSITIVE_INFINITY;
double reqBw = 0;
if(flowId != -1) {
Arc flow = this.flowIdArcTable.get(flowId);
reqBw = flow.getBw();
}
nodes.add(origin);
while(true) {
link = this.topology.getLink(origin.getAddress(), dest.getAddress());
links.add(link);
nodes.add(dest);
if(lowestBw > link.getFreeBandwidth(origin)) {
lowestBw = link.getFreeBandwidth(origin);
}
if(dest instanceof SDNHost)
break;
origin = dest;
dest = origin.getVMRoute(src, dst, flowId);
}
if(flowId != -1 && lowestBw < reqBw) {
// free bandwidth is less than required one.
// Cannot make channel.
Log.printLine(CloudSim.clock() + ": " + getName() + ": Free bandwidth is less than required.("+getKey(src,dst,flowId)+"): ReqBW="+ reqBw + "/ Free="+lowestBw);
//return null;
}
Channel channel=new Channel(flowId, src, dst, nodes, links, reqBw);
return channel;
}
private void updateChannel() {
List<String> removeCh = new ArrayList<String>();
for(String key:this.channelTable.keySet()) {
Channel ch = this.channelTable.get(key);
if(ch.getActiveTransmissionNum() == 0) {
// No more job in channel. Delete
removeCh.add(key);
}
}
for(String key:removeCh) {
removeChannel(key);
}
}
private String getKey(int origin, int destination) {
return origin+"-"+destination;
}
private String getKey(int origin, int destination, int appId) {
return getKey(origin,destination)+"-"+appId;
}
public void setDatacenter(SDNDatacenter dc) {
this.datacenter = dc;
}
public List<Host> getHostList() {
return this.hosts;
}
public List<Switch> getSwitchList() {
return this.switches;
}
public boolean isApplicationDeployed() {
return isApplicationDeployed;
}
protected Vm findVm(int vmId) {
for(Vm vm:vmList) {
if(vm.getId() == vmId)
return vm;
}
return null;
}
protected SDNHost findSDNHost(Host host) {
for(SDNHost sdnhost:sdnhosts) {
if(sdnhost.getHost().equals(host)) {
return sdnhost;
}
}
return null;
}
protected SDNHost findSDNHost(int vmId) {
Vm vm = findVm(vmId);
if(vm == null)
return null;
for(SDNHost sdnhost:sdnhosts) {
if(sdnhost.getHost().equals(vm.getHost())) {
return sdnhost;
}
}
//System.err.println("NOS.findSDNHost: Host is not found for VM:"+ vmId);
return null;
}
public int getHostAddressByVmId(int vmId) {
Vm vm = findVm(vmId);
if(vm == null) {
Log.printLine(CloudSim.clock() + ": " + getName() + ": Cannot find VM with vmId = "+ vmId);
return -1;
}
Host host = vm.getHost();
SDNHost sdnhost = findSDNHost(host);
if(sdnhost == null) {
Log.printLine(CloudSim.clock() + ": " + getName() + ": Cannot find SDN Host with vmId = "+ vmId);
return -1;
}
return sdnhost.getAddress();
}
protected Host createHost(int hostId, int ram, long bw, long storage, long pes, double mips) {
LinkedList<Pe> peList = new LinkedList<Pe>();
int peId=0;
for(int i=0;i<pes;i++) peList.add(new Pe(peId++,new PeProvisionerSimple(mips)));
RamProvisioner ramPro = new RamProvisionerSimple(ram);
BwProvisioner bwPro = new BwProvisionerSimple(bw);
VmScheduler vmScheduler = new VmSchedulerTimeSharedEnergy(peList);
Host newHost = new Host(hostId, ramPro, bwPro, storage, peList, vmScheduler);
return newHost;
}
protected void initPhysicalTopology() {
this.topology = new PhysicalTopology();
this.hosts = new ArrayList<Host>();
this.sdnhosts = new ArrayList<SDNHost>();
int hostId=0;
Hashtable<String,Integer> nameIdTable = new Hashtable<String, Integer>();
try {
JSONObject doc = (JSONObject) JSONValue.parse(new FileReader(this.physicalTopologyFileName));
JSONArray nodes = (JSONArray) doc.get("nodes");
@SuppressWarnings("unchecked")
Iterator<JSONObject> iter =nodes.iterator();
while(iter.hasNext()){
JSONObject node = iter.next();
String nodeType = (String) node.get("type");
String nodeName = (String) node.get("name");
if(nodeType.equalsIgnoreCase("host")){
long pes = (Long) node.get("pes");
long mips = (Long) node.get("mips");
int ram = new BigDecimal((Long)node.get("ram")).intValueExact();
long storage = (Long) node.get("storage");
long bw = new BigDecimal((Long)node.get("bw")).intValueExact();
int num = 1;
if (node.get("nums")!= null)
num = new BigDecimal((Long)node.get("nums")).intValueExact();
for(int n = 0; n< num; n++) {
String nodeName2 = nodeName;
if(num >1) nodeName2 = nodeName + n;
Host host = createHost(hostId, ram, bw, storage, pes, mips);
SDNHost sdnHost = new SDNHost(host, this);
nameIdTable.put(nodeName2, sdnHost.getAddress());
hostId++;
topology.addNode(sdnHost);
this.hosts.add(host);
this.sdnhosts.add(sdnHost);
}
} else {
int MAX_PORTS = 256;
int bw = new BigDecimal((Long)node.get("bw")).intValueExact();
long iops = (Long) node.get("iops");
int upports = MAX_PORTS;
int downports = MAX_PORTS;
if (node.get("upports")!= null)
upports = new BigDecimal((Long)node.get("upports")).intValueExact();
if (node.get("downports")!= null)
downports = new BigDecimal((Long)node.get("downports")).intValueExact();
Switch sw = null;
if(nodeType.equalsIgnoreCase("core")) {
sw = new CoreSwitch(nodeName, bw, iops, upports, downports, this);
} else if (nodeType.equalsIgnoreCase("aggregate")){
sw = new AggregationSwitch(nodeName, bw, iops, upports, downports, this);
} else if (nodeType.equalsIgnoreCase("edge")){
sw = new EdgeSwitch(nodeName, bw, iops, upports, downports, this);
} else {
throw new IllegalArgumentException("No switch found!");
}
if(sw != null) {
nameIdTable.put(nodeName, sw.getAddress());
topology.addNode(sw);
this.switches.add(sw);
}
}
}
JSONArray links = (JSONArray) doc.get("links");
@SuppressWarnings("unchecked")
Iterator<JSONObject> linksIter =links.iterator();
while(linksIter.hasNext()){
JSONObject link = linksIter.next();
String src = (String) link.get("source");
String dst = (String) link.get("destination");
double lat = (Double) link.get("latency");
int srcAddress = nameIdTable.get(src);
int dstAddress = nameIdTable.get(dst);
topology.addLink(srcAddress, dstAddress, lat);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
topology.buildDefaultRouting();
}
private static int flowNumbers=0;
public boolean deployApplication(int userId, String vmsFileName){
vmNameIdTable = new HashMap<String, Integer>();
vmList = new LinkedList<Vm>();
LinkedList<Middlebox> mbList = new LinkedList<Middlebox>();
arcList = new LinkedList<Arc>();
flowIdArcTable = new HashMap<Integer, Arc>();
flowNameIdTable = new HashMap<String, Integer>();
flowNameIdTable.put("default", -1);
try {
JSONObject doc = (JSONObject) JSONValue.parse(new FileReader(vmsFileName));
JSONArray nodes = (JSONArray) doc.get("nodes");
@SuppressWarnings("unchecked")
Iterator<JSONObject> iter = nodes.iterator();
while(iter.hasNext()){
JSONObject node = iter.next();
String nodeType = (String) node.get("type");
String nodeName = (String) node.get("name");
int pes = new BigDecimal((Long)node.get("pes")).intValueExact();
long mips = (Long) node.get("mips");
int ram = new BigDecimal((Long)node.get("ram")).intValueExact();
long size = (Long) node.get("size");
long bw = 1000;
if(node.get("bw") != null)
bw = (Long) node.get("bw");
double starttime = 0;
double endtime = Double.POSITIVE_INFINITY;
if(node.get("starttime") != null)
starttime = (Double) node.get("starttime");
if(node.get("endtime") != null)
endtime = (Double) node.get("endtime");
long nums =1;
if(node.get("nums") != null)
nums = (Long) node.get("nums");
for(int n=0; n<nums; n++) {
String nodeName2 = nodeName;
if(nums > 1) {
// Nodename should be numbered.
nodeName2 = nodeName + n;
}
if(nodeType.equalsIgnoreCase("vm")){
// VM
Vm vm = new TimedVm(vmId,userId,mips,pes,ram,bw,size,"VMM",new CloudletSchedulerTimeShared(), starttime, endtime);
vmNameIdTable.put(nodeName2, vmId);
NetworkOperatingSystem.debugVmIdName.put(vmId, nodeName2);
vmList.add(vm);
vmId++;
} else {
// Middle box
Vm vm = new Vm(vmId,userId,mips,pes,ram,bw,size,"VMM",new CloudletSchedulerTimeShared());
Middlebox m = deployMiddlebox(nodeType,vm);
vmNameIdTable.put(nodeName2, vmId);
mbList.add(m);
vmId++;
}
}
}
JSONArray links = (JSONArray) doc.get("links");
@SuppressWarnings("unchecked")
Iterator<JSONObject> linksIter = links.iterator();
while(linksIter.hasNext()){
JSONObject link = linksIter.next();
String name = (String) link.get("name");
String src = (String) link.get("source");
String dst = (String) link.get("destination");
Object reqLat = link.get("latency");
Object reqBw = link.get("bandwidth");
double lat = 0.0;
long bw = 0;
if(reqLat != null)
lat = (Double) reqLat;
if(reqBw != null)
bw = (Long) reqBw;
int srcId = vmNameIdTable.get(src);
int dstId = vmNameIdTable.get(dst);
int flowId = -1;
if(name == null || "default".equalsIgnoreCase(name)) {
// default flow.
flowId = -1;
}
else {
flowId = flowNumbers++;
flowNameIdTable.put(name, flowId);
}
Arc arc = new Arc(srcId, dstId, flowId, bw, lat);
arcList.add(arc);
if(flowId != -1) {
flowIdArcTable.put(flowId, arc);
}
}
boolean result = deployApplication(vmList, mbList, arcList);
if (result){
isApplicationDeployed = true;
return true;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return false;
}
}

View File

@@ -0,0 +1,40 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
import java.util.List;
/**
* Node represents network node (host or switch)
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public interface Node {
int getAddress();
public long getBandwidth();
public void setRank(int rank);
public int getRank();
public void clearVMRoutingTable();
public void addVMRoute(int srcVM, int destVM, int flowId, Node to);
public Node getVMRoute(int srcVM, int destVM, int flowId);
public void removeVMRoute(int srcVM, int destVM, int flowId);
public void printVMRoute();
public void addRoute(Node destHost, Link to);
public List<Link> getRoute(Node destHost);
public RoutingTable getRoutingTable();
public void addLink(Link l);
public void updateNetworkUtilization();
}

View File

@@ -0,0 +1,76 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
/**
* Network data packet to transfer from source to destination.
* Payload of Package will have a list of activities.
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public class Package {
int origin;
int destination;
long size;
int flowId;
Request payload;
private double startTime=-1;
private double finishTime=-1;
public Package(int origin, int destination, long size, int flowId, Request payload) {
this.origin = origin;
this.destination = destination;
this.size = size;
this.flowId = flowId;
this.payload = payload;
}
public int getOrigin() {
return origin;
}
public int getDestination() {
return destination;
}
public long getSize() {
return size;
}
public Request getPayload() {
return payload;
}
public int getFlowId() {
return flowId;
}
public String toString() {
return "PKG:"+origin + "->" + destination + " - " + payload.toString();
}
public void setStartTime(double time) {
this.startTime = time;
}
public void setFinishTime(double time) {
this.finishTime = time;
}
public double getStartTime() {
return this.startTime;
}
public double getFinishTime() {
return this.finishTime;
}
}

View File

@@ -0,0 +1,192 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
import java.util.Collection;
import java.util.Hashtable;
import org.cloudbus.cloudsim.network.datacenter.AggregateSwitch;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Table;
/**
* Network connection maps including switches, hosts, and links between them
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public class PhysicalTopology {
Hashtable<Integer,Node> nodesTable; // Address -> Node
Table<Integer, Integer, Link> links; // From : To -> Link
Multimap<Node,Link> nodeLinks; // Node -> all Links
public PhysicalTopology() {
nodesTable = new Hashtable<Integer,Node>();
nodeLinks = HashMultimap.create();
links = HashBasedTable.create();
}
public Link getLink(int from, int to) {
return links.get(from, to);
}
public Node getNode(int id) {
return nodesTable.get(id);
}
public double getLinkBandwidth(int from, int to){
return getLink(from, to).getBw(getNode(from));
}
public double getLinkLatency(int from, int to){
return getLink(from, to).getLatency();
}
public void addNode(Node node){
nodesTable.put(node.getAddress(), node);
if (node instanceof CoreSwitch){//coreSwitch is rank 0 (root)
node.setRank(0);
} else if (node instanceof AggregateSwitch){//Hosts are on the bottom of hierarchy (leaf)
node.setRank(1);
} else if (node instanceof EdgeSwitch){//Edge switches are just before hosts in the hierarchy
node.setRank(2);
} else if (node instanceof SDNHost){//Hosts are on the bottom of hierarchy (leaf)
node.setRank(3);
}
}
public void buildDefaultRouting() {
Collection<Node> nodes = getAllNodes();
// For SDNHost: build path to edge switch
// For Edge: build path to SDN Host
for(Node sdnhost:nodes) {
if(sdnhost.getRank() == 3) { // Rank3 = SDN Host
Collection<Link> links = getAdjacentLinks(sdnhost);
for(Link l:links) {
if(l.getLowOrder().equals(sdnhost)) {
sdnhost.addRoute(null, l);
Node edge = l.getHighOrder();
edge.addRoute(sdnhost, l);
}
}
}
}
// For Edge: build path to aggregate switch
// For Aggregate: build path to edge switch
for(Node lowerNode:nodes) {
if(lowerNode.getRank() == 2) { // Rank2 = Edge switch
Collection<Link> links = getAdjacentLinks(lowerNode);
for(Link l:links) {
if(l.getLowOrder().equals(lowerNode)) {
// Link is between Edge and Aggregate
lowerNode.addRoute(null, l);
Node higherNode = l.getHighOrder();
// Add all children hosts to
for(Node destination: lowerNode.getRoutingTable().getKnownDestination()) {
if(destination != null)
higherNode.addRoute(destination, l);
}
}
}
}
}
// For Agg: build path to core switch
// For Core: build path to aggregate switch
for(Node agg:nodes) {
if(agg.getRank() == 1) { // Rank1 = Agg switch
Collection<Link> links = getAdjacentLinks(agg);
for(Link l:links) {
if(l.getLowOrder().equals(agg)) {
// Link is between Edge and Aggregate
agg.addRoute(null, l);
Node core = l.getHighOrder();
// Add all children hosts to
for(Node destination: agg.getRoutingTable().getKnownDestination()) {
if(destination != null)
core.addRoute(destination, l);
}
}
}
}
}
for(Node n:nodes) {
System.out.println("============================================");
System.out.println("Node: "+n);
n.getRoutingTable().printRoutingTable();
}
}
public void addLink(int from, int to, double latency){
Node fromNode = nodesTable.get(from);
Node toNode = nodesTable.get(to);
long bw = (fromNode.getBandwidth()<toNode.getBandwidth())? fromNode.getBandwidth():toNode.getBandwidth();
if(!nodesTable.containsKey(from)||!nodesTable.containsKey(to)){
throw new IllegalArgumentException("Unknown node on link:"+nodesTable.get(from).getAddress()+"->"+nodesTable.get(to).getAddress());
}
if (links.contains(fromNode.getAddress(), toNode.getAddress())){
throw new IllegalArgumentException("Link added twice:"+fromNode.getAddress()+"->"+toNode.getAddress());
}
if(fromNode.getRank()==-1&&toNode.getRank()==-1){
throw new IllegalArgumentException("Unable to establish orders for nodes on link:"+nodesTable.get(from).getAddress()+"->"+nodesTable.get(to).getAddress());
}
if (fromNode.getRank()>=0 && toNode.getRank()>=0){
//we know the rank of both nodes; easy to establish topology
if ((toNode.getRank()-fromNode.getRank())!=1) {
//throw new IllegalArgumentException("Nodes need to be parent and child:"+nodesTable.get(from).getAddress()+"->"+nodesTable.get(to).getAddress());
}
}
if(fromNode.getRank()>=0&&toNode.getRank()==-1){
//now we now B is children of A
toNode.setRank(fromNode.getRank()+1);
}
if(fromNode.getRank()==-1&&toNode.getRank()>=1){
//now we now A is parent of B
fromNode.setRank(toNode.getRank()-1);
}
Link l = new Link(fromNode, toNode, latency, bw);
// Two way links (From -> to, To -> from)
links.put(from, to, l);
links.put(to, from, l);
nodeLinks.put(fromNode, l);
nodeLinks.put(toNode, l);
fromNode.addLink(l);
toNode.addLink(l);
}
public Collection<Link> getAdjacentLinks(Node node) {
return nodeLinks.get(node);
}
public Collection<Node> getAllNodes() {
return nodesTable.values();
}
public Collection<Link> getAllLinks() {
return nodeLinks.values();
}
}

View File

@@ -0,0 +1,31 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
import org.cloudbus.cloudsim.Cloudlet;
/**
* Processing activity to compute in VM. Basically a wrapper of Cloudlet.
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public class Processing implements Activity {
long requestId;
Cloudlet cl;
public Processing(Cloudlet cl){
this.cl=cl;
}
public Cloudlet getCloudlet(){
return cl;
}
}

View File

@@ -0,0 +1,83 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
import java.util.LinkedList;
import java.util.List;
/**
* Request class represents a message submitted to VM. Each request has a list of activities
* that should be performed at the VM. (Processing and Transmission)
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public class Request {
long requestId;
int userId;
LinkedList<Activity> activities;
private LinkedList<Activity> removedActivites; //Logging purpose only
public Request(long requestId, int userId){
this.requestId=requestId;
this.userId=userId;
this.activities = new LinkedList<Activity>();
this.removedActivites = new LinkedList<Activity>();
}
public long getRequestId(){
return requestId;
}
public int getUserId(){
return userId;
}
public boolean isFinished(){
return activities.size()==0;
}
public void addActivity(Activity act){
activities.add(act);
}
public Activity getNextActivity(){
Activity act = activities.get(0);
return act;
}
public Transmission getNextTransmission() {
for(Activity act:activities) {
if(act instanceof Transmission)
return (Transmission) act;
}
return null;
}
public Activity removeNextActivity(){
Activity act = activities.remove(0);
this.removedActivites.add(act);
return act;
}
public String toString() {
return "Request. UserID:"+ this.userId + ",Req ID:"+this.requestId;
}
public List<Activity> getRemovedActivities() {
return this.removedActivites;
}
}

View File

@@ -0,0 +1,69 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Routing table for hosts and switches. This has information about the next hop.
* When physical topology is set up, RoutingTable is created with the information
* about next hop
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public class RoutingTable {
Map<Node, List<Link>> table;
public RoutingTable(){
this.table = new HashMap<Node, List<Link>>();
}
public void clear(){
table.clear();
}
public void addRoute(Node destHost, Link to){
List<Link> links = table.get(destHost);
if(links == null)
{
links = new ArrayList<Link>();
}
links.add(to);
table.put(destHost, links);
}
public void removeRoute(Node destHost){
table.remove(destHost);
}
public List<Link> getRoute(Node destHost) {
List<Link> links = table.get(destHost);
if(links == null)
links = table.get(null);
return links;
}
public Set<Node> getKnownDestination() {
return table.keySet();
}
public void printRoutingTable() {
for(Node key:table.keySet()) {
for(Link l: table.get(key)) {
System.out.println("dst:"+key+" : "+l);
}
}
}
}

View File

@@ -0,0 +1,117 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
import java.util.List;
import java.util.Map;
import org.cloudbus.cloudsim.Cloudlet;
import org.cloudbus.cloudsim.Datacenter;
import org.cloudbus.cloudsim.DatacenterCharacteristics;
import org.cloudbus.cloudsim.Host;
import org.cloudbus.cloudsim.Storage;
import org.cloudbus.cloudsim.Vm;
import org.cloudbus.cloudsim.VmAllocationPolicy;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.core.CloudSimTags;
import org.cloudbus.cloudsim.core.SimEvent;
/**
* Extended class of Datacenter that supports processing SDN-specific events.
* In addtion to the default Datacenter, it processes Request submission to VM,
* and application deployment request.
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public class SDNDatacenter extends Datacenter {
NetworkOperatingSystem nos;
public SDNDatacenter(String name, DatacenterCharacteristics characteristics, VmAllocationPolicy vmAllocationPolicy, List<Storage> storageList, double schedulingInterval, NetworkOperatingSystem nos) throws Exception {
super(name, characteristics, vmAllocationPolicy, storageList, schedulingInterval);
this.nos=nos;
//nos.init();
}
public void addVm(Vm vm){
getVmList().add(vm);
if (vm.isBeingInstantiated()) vm.setBeingInstantiated(false);
vm.updateVmProcessing(CloudSim.clock(), getVmAllocationPolicy().getHost(vm).getVmScheduler().getAllocatedMipsForVm(vm));
}
@Override
protected void processVmCreate(SimEvent ev, boolean ack) {
super.processVmCreate(ev, ack);
if(ack) {
send(nos.getId(), CloudSim.getMinTimeBetweenEvents(), CloudSimTags.VM_CREATE_ACK, ev.getData());
}
}
@Override
public void processOtherEvent(SimEvent ev){
switch(ev.getTag()){
case Constants.REQUEST_SUBMIT: processRequest((Request) ev.getData()); break;
case Constants.APPLICATION_SUBMIT: processApplication(ev.getSource(),(String) ev.getData()); break;
default: System.out.println("Unknown event recevied by SdnDatacenter. Tag:"+ev.getTag());
}
}
@Override
protected void checkCloudletCompletion() {
if(!nos.isApplicationDeployed())
{
super.checkCloudletCompletion();
return;
}
List<? extends Host> list = getVmAllocationPolicy().getHostList();
for (int i = 0; i < list.size(); i++) {
Host host = list.get(i);
for (Vm vm : host.getVmList()) {
while (vm.getCloudletScheduler().isFinishedCloudlets()) {
Cloudlet cl = vm.getCloudletScheduler().getNextFinishedCloudlet();
if (cl != null) {
int hostAddress = nos.getHostAddressByVmId(cl.getVmId());
sendNow(hostAddress, CloudSimTags.CLOUDLET_RETURN, cl);
}
}
}
}
}
private void processRequest(Request req) {//Request received from user. Send to SdnHost
Activity ac = req.getNextActivity();
if(ac instanceof Processing) {
Cloudlet cl = ((Processing) ac).getCloudlet();
int hostAddress = nos.getHostAddressByVmId(cl.getVmId());
//for this first package, size doesn't matter
Package pkg = new Package(super.getId(), cl.getVmId(), -1, -1, req);
sendNow(hostAddress, Constants.SDN_PACKAGE, pkg);
}
else {
System.err.println("Request should start with Processing!!");
}
}
private void processApplication(int userId, String filename) {
nos.deployApplication(userId,filename);
send(userId, CloudSim.getMinTimeBetweenEvents(), Constants.APPLICATION_SUBMIT_ACK, filename);
}
public Map<String, Integer> getVmNameIdTable() {
return this.nos.getVmNameIdTable();
}
public Map<String, Integer> getFlowNameIdTable() {
return this.nos.getFlowNameIdTable();
}
}

View File

@@ -0,0 +1,240 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
import java.util.Hashtable;
import java.util.List;
import org.cloudbus.cloudsim.Cloudlet;
import org.cloudbus.cloudsim.Host;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.Vm;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.core.CloudSimTags;
import org.cloudbus.cloudsim.core.SimEntity;
import org.cloudbus.cloudsim.core.SimEvent;
/**
* Extended class of Host to support SDN.
* Added function includes data transmission after completion of Cloudlet compute processing.
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public class SDNHost extends SimEntity implements Node {
private static final double PROCESSING_DELAY= 0.1;
Host host;
EdgeSwitch sw;
//Hashtable<Integer,Vm> vms;
Hashtable<Integer,Middlebox> middleboxes;
Hashtable<Cloudlet,Request> requestsTable;
ForwardingRule forwardingTable;
RoutingTable routingTable;
int rank = -1;
NetworkOperatingSystem nos;
SDNHost(Host host, NetworkOperatingSystem nos){
super("Host"+host.getId());
this.host=host;
this.nos = nos;
//this.vms = new Hashtable<Integer,Vm>();
this.middleboxes = new Hashtable<Integer, Middlebox>();
this.requestsTable = new Hashtable<Cloudlet, Request>();
this.forwardingTable = new ForwardingRule();
this.routingTable = new RoutingTable();
}
public Host getHost(){
return host;
}
public void setEdgeSwitch(EdgeSwitch sw){
this.sw=sw;
}
/*
public void addVm(Vm vm){
vms.put(vm.getId(), vm);
host.vmCreate(vm);
}
*/
public void addMiddlebox(Middlebox m){
middleboxes.put(m.getId(), m);
host.vmCreate(m.getVm());
}
@Override
public void startEntity(){}
@Override
public void shutdownEntity(){}
@Override
public void processEvent(SimEvent ev) {
int tag = ev.getTag();
switch(tag){
case Constants.SDN_PACKAGE: processPackage((Package) ev.getData()); break;
case CloudSimTags.CLOUDLET_RETURN: processCloudletReturn((Cloudlet) ev.getData()); break;
default: System.out.println("Unknown event received by "+super.getName()+". Tag:"+ev.getTag());
}
}
private Vm findVm(int vmId) {
List<Vm> vms = host.getVmList();
for(Vm vm:vms) {
if(vm.getId() == vmId) {
return vm;
}
}
return null;
}
private void processPackage(Package data) {
int vmId = data.getDestination();
Vm dstVm = findVm(vmId);
if (dstVm != null){//Try to deliver package to a hosted VM
//Log.printLine(CloudSim.clock() + ": " + getName() + ".processPackage(): Deliver the request to dest VM: "+ dstVm);
data.setFinishTime(CloudSim.clock());
Request req = data.getPayload();
Activity ac = req.removeNextActivity();
processActivity(ac, req, vmId);
} else if (middleboxes.containsKey(vmId)){//Try to deliver package to a hosted middlebox
Request req = data.getPayload();
Middlebox m = middleboxes.get(vmId);
m.submitRequest(req);
} else {//Something wrong - package doesn't come from/goes to a VM from this Host
System.out.println("Warning package sent to wrong host. Host ID="+host.getId()+" DST VM ID="+vmId+", SRC VM ID="+data.getDestination());
}
}
private void processCloudletReturn(Cloudlet data) {
Request req = requestsTable.remove(data);
if (req.isFinished()){//return to user
send(req.getUserId(),PROCESSING_DELAY,Constants.REQUEST_COMPLETED,req);
} else {//consume next activity from request. It should be a transmission
Activity ac = req.removeNextActivity();
processActivity(ac, req, data.getVmId());
}
}
private void processActivity(Activity ac, Request req, int vmId) {
if(ac instanceof Transmission) {
Transmission tr = (Transmission)ac;
Package pkg = tr.getPackage();
//send package to router via channel (NOS)
nos.addPackageToChannel(this, pkg);
pkg.setStartTime(CloudSim.clock());
}
else if(ac instanceof Processing) {
Cloudlet cl = ((Processing) ac).getCloudlet();
cl.setVmId(vmId);
requestsTable.put(cl, req);
sendNow(host.getDatacenter().getId(),CloudSimTags.CLOUDLET_SUBMIT,cl);
} else {
Log.printLine(CloudSim.clock() + ": " + getName() + ": Activity is unknown..");
}
}
/******* Routeable interface implementation methods ******/
@Override
public int getAddress() {
return super.getId();
}
@Override
public long getBandwidth() {
return host.getBw();
}
@Override
public void clearVMRoutingTable(){
this.forwardingTable.clear();
}
@Override
public void addVMRoute(int src, int dest, int flowId, Node to){
forwardingTable.addRule(src, dest, flowId, to);
}
@Override
public Node getVMRoute(int src, int dest, int flowId){
Node route= this.forwardingTable.getRoute(src, dest, flowId);
if(route == null) {
this.printVMRoute();
System.err.println("SDNHost: ERROR: Cannot find route:" + src + "->"+dest + ", flow ="+flowId);
}
return route;
}
@Override
public void removeVMRoute(int src, int dest, int flowId){
forwardingTable.removeRule(src, dest, flowId);
}
@Override
public void setRank(int rank) {
this.rank=rank;
}
@Override
public int getRank() {
return rank;
}
@Override
public void printVMRoute() {
forwardingTable.printForwardingTable(getName());
}
public String toString() {
return "SDNHost: "+this.getName();
}
@Override
public void addLink(Link l) {
// TODO Auto-generated method stub
}
@Override
public void updateNetworkUtilization() {
// TODO Auto-generated method stub
}
@Override
public void addRoute(Node destHost, Link to) {
this.routingTable.addRoute(destHost, to);
}
@Override
public List<Link> getRoute(Node destHost) {
return this.routingTable.getRoute(destHost);
}
@Override
public RoutingTable getRoutingTable() {
return this.routingTable;
}
}

View File

@@ -0,0 +1,349 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.core.SimEntity;
import org.cloudbus.cloudsim.core.SimEvent;
/**
* This represents switches that maintain routing information.
* Note that all traffic estimation is calculated within NOS class, not in Switch class.
* Energy consumption of Switch is calculated in this class by utilization history.
*
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public class Switch extends SimEntity implements Node{
//private static long cont=0;
//private static long MULTI = 1;
private static double POWER_CONSUMPTION_IDLE = 66.7;
private static double POWER_CONSUMPTION_PER_ACTIVE_PORT = 1;
/* based on CARPO: Correlation-Aware Power Optimization in Data Center Networks by Xiaodong Wang et al. */
int bw;
long iops;
double previousTime;
int rank = -1;
int currentupports=0;
int currentdownports=0;
NetworkOperatingSystem nos;
Node[] upports;
Node[] downports;
ArrayList<Link> links = new ArrayList<Link>();
ForwardingRule forwardingTable;
RoutingTable routingTable;
Hashtable<Package,Long> processingTable;
public Switch(String name, int bw, long iops, int upports, int downports, NetworkOperatingSystem nos) {
super(name);
this.bw = bw;
this.iops = iops;
this.previousTime = 0.0;
this.nos=nos;
if (upports>0) this.upports = new Node[upports];
this.downports = new Node[downports];
this.forwardingTable = new ForwardingRule();
this.processingTable = new Hashtable<Package,Long>();
this.routingTable = new RoutingTable();
}
@Override
public void startEntity() {}
@Override
public void shutdownEntity() {}
@Override
public void processEvent(SimEvent ev) {
int tag = ev.getTag();
switch(tag){
//case Constants.SDN_INTERNAL_PACKAGE_PROCESS: internalPackageProcessing(); break;
//case Constants.SDN_PACKAGE: sendToBuffer((Package) ev.getData()); break;
default: System.out.println("Unknown event received by "+super.getName()+". Tag:"+ev.getTag());
}
}
public void addLink(Link l){
this.links.add(l);
}
/************************************************
* Calculate Utilization history
************************************************/
private List<HistoryEntry> utilizationHistories = null;
private static double powerOffDuration = 0; //if switch was idle for 1 hours, it's turned off.
public class HistoryEntry {
public double startTime;
public int numActivePorts;
HistoryEntry(double t, int n) { startTime=t; numActivePorts=n;}
}
public List<HistoryEntry> getUtilizationHisotry() {
return utilizationHistories;
}
public double getUtilizationEnergyConsumption() {
double total=0;
double lastTime=0;
int lastPort=0;
if(this.utilizationHistories == null)
return 0;
for(HistoryEntry h:this.utilizationHistories) {
double duration = h.startTime - lastTime;
double power = calculatePower(lastPort);
double energyConsumption = power * duration;
// Assume that the host is turned off when duration is long enough
if(duration > powerOffDuration && lastPort == 0)
energyConsumption = 0;
total += energyConsumption;
lastTime = h.startTime;
lastPort = h.numActivePorts;
}
return total/3600; // transform to Whatt*hour from What*seconds
}
public void updateNetworkUtilization() {
this.addUtilizationEntry();
}
public void addUtilizationEntryTermination(double finishTime) {
if(this.utilizationHistories != null)
this.utilizationHistories.add(new HistoryEntry(finishTime, 0));
}
private void addUtilizationEntry() {
double time = CloudSim.clock();
int totalActivePorts = getTotalActivePorts();
if(utilizationHistories == null)
utilizationHistories = new ArrayList<HistoryEntry>();
else {
HistoryEntry hist = this.utilizationHistories.get(this.utilizationHistories.size()-1);
if(hist.numActivePorts == totalActivePorts) {
return;
}
}
this.utilizationHistories.add(new HistoryEntry(time, totalActivePorts));
}
private double calculatePower(int numActivePort) {
double power = POWER_CONSUMPTION_IDLE + POWER_CONSUMPTION_PER_ACTIVE_PORT * numActivePort;
return power;
}
private int getTotalActivePorts() {
int num = 0;
for(Link l:this.links) {
if(l.isActive())
num++;
}
return num;
}
/*
private void updateTime(double now) {
this.previousTime = now;
}
private void internalPackageProcessing() {
if(updatePackageProcessing()) {
sendInternalEvent();
}
else {
System.err.println(CloudSim.clock() + ": " + getName() +": Nothing changed! omg");
sendInternalEvent();
}
}
private void sendInternalEvent() {
CloudSim.cancelAll(getId(), new PredicateType(Constants.SDN_INTERNAL_PACKAGE_PROCESS));
if(processingTable.size() != 0) {
// More to process. Send event again
double delay = this.nextFinishTime();
Log.printLine(CloudSim.clock() + ": " + getName() + ".sendInternalEvent(): next finish time: "+ delay);
send(this.getId(), delay, Constants.SDN_INTERNAL_PACKAGE_PROCESS);
}
}
// Return if anything removed?
private boolean updatePackageProcessing() {
double currentTime = CloudSim.clock();
double timeSpent = CloudSim.round(currentTime - this.previousTime);
if(timeSpent <= 0 || processingTable.size() == 0)
return false; // Nothing changed
//update the amount of iops processed this round
long processedThisRound= Math.round(timeSpent * iops * MULTI / processingTable.size())+1;
//update processing table; remove finished packs
List<Package> toRemove = new ArrayList<Package>();
for (Package key: processingTable.keySet()) {
//DEBUG ONLY
if(key.payload.requestId == 309) {
System.out.println("ID:309 HERE:rem_len="+processingTable.get(key)+","+key.size);
}
long remainingLength = processingTable.get(key);
remainingLength-=processedThisRound;
if (remainingLength <= 0) {// finished: remove from the list
toRemove.add(key);
} else { //not finished:update table, check if it is the smaller to be processed
processingTable.put(key, remainingLength);
}
}
// Remove all packages that is done.
for (Package pkg:toRemove){
processingTable.remove(pkg);
this.processPackageFinish(pkg);
}
updateTime(currentTime);
System.err.println(CloudSim.clock()+": Switch.updatePackageProcessing("+getName()+ ") #("+this.processingTable.size()+"):Time spent:"+timeSpent+
", Processed:"+processedThisRound);
if(toRemove.isEmpty())
return false; // Nothing changed
return true;
}
private void processPackageFinish(Package pkg) {
Log.printLine(CloudSim.clock() + ": " + getName() + ": finished processing a package:" + pkg);
nos.sendPackageToNextHop(this, pkg);
}
private void sendToBuffer(Package pkg) {
Log.printLine(CloudSim.clock() + ": " + getName() + ": Package received from Network:" + pkg);
updatePackageProcessing();
this.processingTable.put(pkg, pkg.getSize()*MULTI);
sendInternalEvent();
}
private double nextFinishTime() {
// Calculate the latest finish time among all jobs in the queue.
long smallerPkg = Long.MAX_VALUE;
for (Package key: processingTable.keySet()) {
// DEBUG
if(key.getPayload().requestId > 30 && key.getPayload().requestId < 35) {
System.out.println("Here!");
}
if(key.getPayload().requestId > 530 && key.getPayload().requestId < 535) {
System.out.println("Here!");
}
long remainingLength = processingTable.get(key);
if (remainingLength<smallerPkg) smallerPkg=remainingLength;
}
double delay = (double)smallerPkg/ iops / MULTI * processingTable.size();//smallerPkg*processingTable.size()/(iops*MULTI);
delay=CloudSim.round(delay);
if (delay < CloudSim.getMinTimeBetweenEvents()) {
Log.printLine(CloudSim.clock() + ": " + getName() + ": delay is too short: "+ delay);
delay = CloudSim.getMinTimeBetweenEvents();
}
return delay;
}
*/
/******* Routeable interface implementation methods ******/
@Override
public int getAddress() {
return super.getId();
}
@Override
public long getBandwidth() {
return bw;
}
@Override
public void clearVMRoutingTable(){
this.forwardingTable.clear();
}
@Override
public void addVMRoute(int src, int dest, int flowId, Node to){
this.forwardingTable.addRule(src, dest, flowId, to);
}
@Override
public Node getVMRoute(int src, int dest, int flowId){
Node route= this.forwardingTable.getRoute(src, dest, flowId);
if(route == null) {
this.printVMRoute();
System.err.println("SDNSwitch.getRoute() ERROR: Cannot find route:" +
NetworkOperatingSystem.debugVmIdName.get(src) + "->"+
NetworkOperatingSystem.debugVmIdName.get(dest) + ", flow ="+flowId);
}
return route;
}
@Override
public void removeVMRoute(int src, int dest, int flowId){
forwardingTable.removeRule(src, dest, flowId);
}
@Override
public void setRank(int rank) {
this.rank = rank;
}
@Override
public int getRank() {
return rank;
}
@Override
public void printVMRoute() {
forwardingTable.printForwardingTable(getName());
}
public String toString() {
return "Switch: "+this.getName();
}
@Override
public void addRoute(Node destHost, Link to) {
this.routingTable.addRoute(destHost, to);
}
@Override
public List<Link> getRoute(Node destHost) {
return this.routingTable.getRoute(destHost);
}
@Override
public RoutingTable getRoutingTable() {
return this.routingTable;
}
}

View File

@@ -0,0 +1,48 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
import org.cloudbus.cloudsim.CloudletScheduler;
import org.cloudbus.cloudsim.Vm;
/**
* Extension of VM that supports to set start and terminate time of VM in VM creation request.
* If start time and finish time is set up, specific CloudSim Event is triggered
* in datacenter to create and terminate the VM.
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public class TimedVm extends Vm {
private double startTime;
private double finishTime;
public TimedVm(int id, int userId, double mips, int numberOfPes, int ram,
long bw, long size, String vmm, CloudletScheduler cloudletScheduler) {
super(id, userId, mips, numberOfPes, ram, bw, size, vmm, cloudletScheduler);
}
public TimedVm(int id, int userId, double mips, int numberOfPes, int ram,
long bw, long size, String vmm, CloudletScheduler cloudletScheduler, double startTime, double finishTime) {
super(id, userId, mips, numberOfPes, ram, bw, size, vmm, cloudletScheduler);
this.startTime = startTime;
this.finishTime = finishTime;
}
public double getStartTime() {
return startTime;
}
public double getFinishTime() {
return finishTime;
}
}

View File

@@ -0,0 +1,65 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn;
/**
* This class represents transmission of a package. It controls
* amount of data transmitted in a shared data medium. Relation between
* Transmission and Channel is the same as Cloudlet and CloudletScheduler,
* but here we consider only the time shared case, representing a shared
* channel among different simultaneous package transmissions.
* Note that estimated transmission time is calculated in NOS.
*
* @author Jungmin Son
* @author Rodrigo N. Calheiros
* @since CloudSimSDN 1.0
*/
public class Transmission implements Activity {
Package pkg;
long amountToBeProcessed;
public Transmission(int origin, int destination, long size, int flowId, Request payload) {
this.pkg = new Package(origin, destination, size, flowId, payload);
this.amountToBeProcessed=pkg.getSize();
}
public Transmission(Package pkg){
this.pkg = pkg;
this.amountToBeProcessed=pkg.getSize();
}
public long getSize(){
return amountToBeProcessed;
}
public Package getPackage(){
return pkg;
}
/**
* Sums some amount of data to the already transmitted data
* @param completed amount of data completed since last update
*/
public void addCompletedLength(long completed){
amountToBeProcessed-=completed;
if (amountToBeProcessed<=0) amountToBeProcessed = 0;
}
/**
* Say if the Package transmission finished or not.
* @return true if transmission finished; false otherwise
*/
public boolean isCompleted(){
return amountToBeProcessed==0;
}
public String toString() {
return "Transmission:"+this.pkg.toString();
}
}

View File

@@ -0,0 +1,260 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn.example;
import java.util.List;
import org.cloudbus.cloudsim.Cloudlet;
import org.cloudbus.cloudsim.Host;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.sdn.Activity;
import org.cloudbus.cloudsim.sdn.Processing;
import org.cloudbus.cloudsim.sdn.Request;
import org.cloudbus.cloudsim.sdn.Switch;
import org.cloudbus.cloudsim.sdn.Transmission;
import org.cloudbus.cloudsim.sdn.Switch.HistoryEntry;
import org.cloudbus.cloudsim.sdn.power.PowerUtilizationHistoryEntry;
import org.cloudbus.cloudsim.sdn.power.PowerUtilizationInterface;
/**
* This class is to print out logs into console.
*
* @author Jungmin Son
* @since CloudSimSDN 1.0
*/
public class LogPrinter {
public static void printEnergyConsumption(List<Host> hostList, List<Switch> switchList, double finishTime) {
double hostEnergyConsumption = 0, switchEnergyConsumption = 0;
Log.printLine("========== HOST POWER CONSUMPTION AND DETAILED UTILIZATION ===========");
for(Host host:hostList) {
PowerUtilizationInterface scheduler = (PowerUtilizationInterface) host.getVmScheduler();
scheduler.addUtilizationEntryTermination(finishTime);
double energy = scheduler.getUtilizationEnergyConsumption();
Log.printLine("Host #"+host.getId()+": "+energy);
hostEnergyConsumption+= energy;
printHostUtilizationHistory(scheduler.getUtilizationHisotry());
}
Log.printLine("========== SWITCH POWER CONSUMPTION AND DETAILED UTILIZATION ===========");
for(Switch sw:switchList) {
sw.addUtilizationEntryTermination(finishTime);
double energy = sw.getUtilizationEnergyConsumption();
Log.printLine("Switch #"+sw.getId()+": "+energy);
switchEnergyConsumption+= energy;
printSwitchUtilizationHistory(sw.getUtilizationHisotry());
}
Log.printLine("========== TOTAL POWER CONSUMPTION ===========");
Log.printLine("Host energy consumed: "+hostEnergyConsumption);
Log.printLine("Switch energy consumed: "+switchEnergyConsumption);
Log.printLine("Total energy consumed: "+(hostEnergyConsumption+switchEnergyConsumption));
}
private static void printHostUtilizationHistory(
List<PowerUtilizationHistoryEntry> utilizationHisotry) {
if(utilizationHisotry != null)
for(PowerUtilizationHistoryEntry h:utilizationHisotry) {
Log.printLine(h.startTime+", "+h.usedMips);
}
}
private static void printSwitchUtilizationHistory(List<HistoryEntry> utilizationHisotry) {
if(utilizationHisotry != null)
for(HistoryEntry h:utilizationHisotry) {
Log.printLine(h.startTime+", "+h.numActivePorts);
}
}
static public String indent = ",";
static public String tabSize = "10";
static public String fString = "%"+tabSize+"s"+indent;
static public String fInt = "%"+tabSize+"d"+indent;
static public String fFloat = "%"+tabSize+".3f"+indent;
public static void printCloudletList(List<Cloudlet> list) {
int size = list.size();
Cloudlet cloudlet;
Log.printLine();
Log.printLine("========== OUTPUT ==========");
Log.print(String.format(fString, "Cloudlet_ID"));
Log.print(String.format(fString, "STATUS" ));
Log.print(String.format(fString, "DataCenter_ID"));
Log.print(String.format(fString, "VM_ID"));
Log.print(String.format(fString, "Length"));
Log.print(String.format(fString, "Time"));
Log.print(String.format(fString, "Start Time"));
Log.print(String.format(fString, "Finish Time"));
Log.print("\n");
//DecimalFormat dft = new DecimalFormat("######.##");
for (int i = 0; i < size; i++) {
cloudlet = list.get(i);
printCloudlet(cloudlet);
}
}
private static void printCloudlet(Cloudlet cloudlet) {
Log.print(String.format(fInt, cloudlet.getCloudletId()));
if (cloudlet.getCloudletStatus() == Cloudlet.SUCCESS) {
Log.print(String.format(fString, "SUCCESS"));
Log.print(String.format(fInt, cloudlet.getResourceId()));
Log.print(String.format(fInt, cloudlet.getVmId()));
Log.print(String.format(fInt, cloudlet.getCloudletLength()));
Log.print(String.format(fFloat, cloudlet.getActualCPUTime()));
Log.print(String.format(fFloat, cloudlet.getExecStartTime()));
Log.print(String.format(fFloat, cloudlet.getFinishTime()));
Log.print("\n");
}
else {
Log.printLine("FAILED");
}
}
private static double startTime, finishTime;
public static void printWorkloadList(List<Workload> wls) {
int[] appIdNum = new int[SDNBroker.appId];
double[] appIdTime = new double[SDNBroker.appId];
double[] appIdStartTime = new double[SDNBroker.appId];
double[] appIdFinishTime = new double[SDNBroker.appId];
double serveTime, totalTime = 0;
Log.printLine();
Log.printLine("========== DETAILED RESPONSE TIME OF WORKLOADS ===========");
if(wls.size() == 0) return;
Log.print(String.format(fString, "App_ID"));
printRequestTitle(wls.get(0).request);
Log.print(String.format(fString, "ResponseTime"));
Log.printLine();
for(Workload wl:wls) {
Log.print(String.format(fInt, wl.appId));
startTime = finishTime = -1;
printRequest(wl.request);
serveTime= (finishTime - startTime);
Log.print(String.format(fFloat, serveTime));
totalTime += serveTime;
appIdNum[wl.appId] ++; //How many workloads in this app.
appIdTime[wl.appId] += serveTime;
if(appIdStartTime[wl.appId] <=0) {
appIdStartTime[wl.appId] = wl.time;
}
appIdFinishTime[wl.appId] = wl.time;
Log.printLine();
}
Log.printLine("========== AVERAGE RESULT OF WORKLOADS ===========");
for(int i=0; i<SDNBroker.appId; i++) {
Log.printLine("App Id ("+i+"): "+appIdNum[i]+" requests, Start=" + appIdStartTime[i]+
", Finish="+appIdFinishTime[i]+", Rate="+(double)appIdNum[i]/(appIdFinishTime[i] - appIdStartTime[i])+
" req/sec, Response time=" + appIdTime[i]/appIdNum[i]);
}
//printGroupStatistics(WORKLOAD_GROUP_PRIORITY, appIdNum, appIdTime);
Log.printLine("Average Response Time:"+(totalTime / wls.size()));
}
private static void printRequestTitle(Request req) {
//Log.print(String.format(fString, "Req_ID"));
//Log.print(String.format(fFloat, req.getStartTime()));
//Log.print(String.format(fFloat, req.getFinishTime()));
List<Activity> acts = req.getRemovedActivities();
for(Activity act:acts) {
if(act instanceof Transmission) {
Transmission tr=(Transmission)act;
Log.print(String.format(fString, "Tr:Size"));
Log.print(String.format(fString, "Tr:Channel"));
Log.print(String.format(fString, "Tr:time"));
Log.print(String.format(fString, "Tr:Start"));
Log.print(String.format(fString, "Tr:End"));
printRequestTitle(tr.getPackage().getPayload());
}
else {
Log.print(String.format(fString, "Pr:Size"));
Log.print(String.format(fString, "Pr:time"));
Log.print(String.format(fString, "Pr:Start"));
Log.print(String.format(fString, "Pr:End"));
}
}
}
private static void printRequest(Request req) {
//Log.print(String.format(fInt, req.getRequestId()));
//Log.print(String.format(fFloat, req.getStartTime()));
//Log.print(String.format(fFloat, req.getFinishTime()));
List<Activity> acts = req.getRemovedActivities();
for(Activity act:acts) {
if(act instanceof Transmission) {
Transmission tr=(Transmission)act;
Log.print(String.format(fInt, tr.getPackage().getSize()));
Log.print(String.format(fInt, tr.getPackage().getFlowId()));
Log.print(String.format(fFloat, tr.getPackage().getFinishTime() - tr.getPackage().getStartTime()));
Log.print(String.format(fFloat, tr.getPackage().getStartTime()));
Log.print(String.format(fFloat, tr.getPackage().getFinishTime()));
printRequest(tr.getPackage().getPayload());
}
else {
Processing pr=(Processing)act;
Log.print(String.format(fInt, pr.getCloudlet().getCloudletLength()));
Log.print(String.format(fFloat, pr.getCloudlet().getActualCPUTime()));
Log.print(String.format(fFloat, pr.getCloudlet().getExecStartTime()));
Log.print(String.format(fFloat, pr.getCloudlet().getFinishTime()));
if(startTime == -1) startTime = pr.getCloudlet().getExecStartTime();
finishTime=pr.getCloudlet().getFinishTime();
}
}
}
public static void printGroupStatistics(int groupSeperateNum, int[] appIdNum, double[] appIdTime) {
double prioritySum = 0, standardSum = 0;
int priorityReqNum = 0, standardReqNum =0;
for(int i=0; i<SDNBroker.appId; i++) {
double avgResponseTime = appIdTime[i]/appIdNum[i];
if(i<groupSeperateNum) {
prioritySum += avgResponseTime;
priorityReqNum += appIdNum[i];
}
else {
standardSum += avgResponseTime;
standardReqNum += appIdNum[i];
}
}
Log.printLine("Average Response Time(Priority):"+(prioritySum / priorityReqNum));
Log.printLine("Average Response Time(Standard):"+(standardSum / standardReqNum));
}
}

View File

@@ -0,0 +1,175 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn.example;
import java.util.ArrayList;
import java.util.List;
import org.cloudbus.cloudsim.Cloudlet;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.UtilizationModelFull;
import org.cloudbus.cloudsim.Vm;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.core.CloudSimTags;
import org.cloudbus.cloudsim.core.SimEntity;
import org.cloudbus.cloudsim.core.SimEvent;
import org.cloudbus.cloudsim.sdn.Constants;
import org.cloudbus.cloudsim.sdn.SDNDatacenter;
/**
* Broker class for CloudSimSDN example. This class represents a broker (Service Provider)
* who uses the Cloud data center.
*
* @author Jungmin Son
* @since CloudSimSDN 1.0
*/
public class SDNBroker extends SimEntity {
private SDNDatacenter datacenter = null;
private String applicationFileName = null;
private List<String> workloadFileNames=null;
private List<Cloudlet> cloudletList;
private List<Workload> workloads;
public SDNBroker(String name) throws Exception {
super(name);
this.workloadFileNames = new ArrayList<String>();
this.cloudletList = new ArrayList<Cloudlet>();
this.workloads = new ArrayList<Workload>();
}
@Override
public void startEntity() {
sendNow(this.datacenter.getId(), Constants.APPLICATION_SUBMIT, this.applicationFileName);
}
@Override
public void shutdownEntity() {
List<Vm> vmList = this.datacenter.getVmList();
for(Vm vm:vmList) {
Log.printLine(CloudSim.clock() + ": " + getName() + ": Shuttingdown.. VM:" + vm.getId());
}
}
public void submitDeployApplication(SDNDatacenter dc, String filename) {
this.datacenter = dc;
this.applicationFileName = filename;
}
public void submitRequests(String filename) {
this.workloadFileNames.add(filename);
}
@Override
public void processEvent(SimEvent ev) {
int tag = ev.getTag();
switch(tag){
case CloudSimTags.VM_CREATE_ACK: processVmCreate(ev); break;
case Constants.APPLICATION_SUBMIT_ACK: applicationSubmitCompleted(ev); break;
case Constants.REQUEST_COMPLETED: requestCompleted(ev); break;
default: System.out.println("Unknown event received by "+super.getName()+". Tag:"+ev.getTag());
}
}
private void processVmCreate(SimEvent ev) {
}
private void requestCompleted(SimEvent ev) {
}
public List<Cloudlet> getCloudletReceivedList() {
return cloudletList;
}
public static int appId = 0;
private void applicationSubmitCompleted(SimEvent ev) {
for(String workloadFileName:this.workloadFileNames) {
scheduleRequest(workloadFileName);
SDNBroker.appId++;
}
}
private void scheduleRequest(String workloadFile) {
WorkloadParser rp = new WorkloadParser(workloadFile, this.getId(), new UtilizationModelFull(),
this.datacenter.getVmNameIdTable(), this.datacenter.getFlowNameIdTable());
for(Workload wl: rp.getWorkloads()) {
send(this.datacenter.getId(), wl.time, Constants.REQUEST_SUBMIT, wl.request);
wl.appId = SDNBroker.appId;
}
this.cloudletList.addAll(rp.getAllCloudlets());
this.workloads.addAll(rp.getWorkloads());
}
public List<Workload> getWorkloads() {
return this.workloads;
}
/*
private static int reqId=0;
private void scheduleRequestTest() {
cloudletList = new ArrayList<Cloudlet>();
int cloudletId = 0;
List<Vm> vmList = this.datacenter.getVmList();
Vm vm1 = vmList.get(0);
Vm vm2 = vmList.get(1);
Vm vm3 = vmList.get(2);
///////////////////////////////////////
// req = vm1:p1 -> tr1 -> vm2:p2 -> tr2 -> vm3:p3 -> tr3 -> vm1:p4
// req r1 r2 r3
long fileSize = 300;
long outputSize = 300;
UtilizationModel utilizationModel = new UtilizationModelFull();
Cloudlet cloudlet1 = new Cloudlet(cloudletId++, 4000, 1, fileSize, outputSize, utilizationModel, utilizationModel, utilizationModel);
Cloudlet cloudlet2 = new Cloudlet(cloudletId++, 30000, 1, fileSize, outputSize, utilizationModel, utilizationModel, utilizationModel);
Cloudlet cloudlet3 = new Cloudlet(cloudletId++, 6000, 1, fileSize, outputSize, utilizationModel, utilizationModel, utilizationModel);
Cloudlet cloudlet4 = new Cloudlet(cloudletId++, 10000, 1, fileSize, outputSize, utilizationModel, utilizationModel, utilizationModel);
cloudlet1.setUserId(getId());
cloudlet2.setUserId(getId());
cloudlet3.setUserId(getId());
cloudlet4.setUserId(getId());
cloudlet1.setVmId(vm1.getId());
cloudletList.add(cloudlet1);
cloudletList.add(cloudlet2);
cloudletList.add(cloudlet3);
cloudletList.add(cloudlet4);
Processing p1 = new Processing(cloudlet1);
Processing p2 = new Processing(cloudlet2);
Processing p3 = new Processing(cloudlet3);
Processing p4 = new Processing(cloudlet4);
Request req = new Request(reqId++, getId(), getId());
Request r1 = new Request(reqId++, getId(), getId());
Request r2 = new Request(reqId++, getId(), getId());
Request r3 = new Request(reqId++, getId(), getId());
r3.addActivity(p4);
Transmission tr3 = new Transmission(vm3.getId(), vm1.getId(), 30000, r3);
r2.addActivity(p3);
r2.addActivity(tr3);
Transmission tr2 = new Transmission(vm2.getId(), vm3.getId(), 7000, r2);
r1.addActivity(p2);
r1.addActivity(tr2);
Transmission tr1 = new Transmission(vm1.getId(), vm2.getId(), 3000, r1);
req.addActivity(p1);
req.addActivity(tr1);
sendNow(this.datacenter.getId(), Constants.REQUEST_SUBMIT, req);
}
*/
}

View File

@@ -0,0 +1,332 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn.example;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.List;
import org.cloudbus.cloudsim.Cloudlet;
import org.cloudbus.cloudsim.DatacenterCharacteristics;
import org.cloudbus.cloudsim.Host;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.Storage;
import org.cloudbus.cloudsim.VmAllocationPolicy;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.sdn.NetworkOperatingSystem;
import org.cloudbus.cloudsim.sdn.SDNDatacenter;
import org.cloudbus.cloudsim.sdn.Switch;
import org.cloudbus.cloudsim.sdn.example.policies.VmAllocationPolicyCombinedLeastFullFirst;
import org.cloudbus.cloudsim.sdn.example.policies.VmAllocationPolicyCombinedMostFullFirst;
import org.cloudbus.cloudsim.sdn.example.policies.VmAllocationPolicyMipsLeastFullFirst;
import org.cloudbus.cloudsim.sdn.example.policies.VmAllocationPolicyMipsMostFullFirst;
import org.cloudbus.cloudsim.sdn.overbooking.OverbookingNetworkOperatingSystem;
import org.cloudbus.cloudsim.sdn.overbooking.VmAllocationPolicyOverbooking;
import org.cloudbus.cloudsim.sdn.power.PowerUtilizationMaxHostInterface;
/**
* CloudSimSDN example main program. It loads physical topology file, application
* deployment configuration file and workload files, and run simulation.
* Simulation result will be shown on the console
*
* @author Jungmin Son
* @since CloudSimSDN 1.0
*/
public class SDNExample {
protected static String physicalTopologyFile = "dataset-energy/energy-physical.json";
protected static String deploymentFile = "dataset-energy/energy-virtual.json";
protected static String [] workload_files = {
"dataset-energy/energy-workload.csv",
//"sdn-example-workload-normal-user.csv",
//"sdn-example-workload-prio-user-prio-ch.csv",
//"sdn-example-workload-prio-user-normal-ch.csv",
};
protected static List<String> workloads;
private static boolean logEnabled = true;
public interface VmAllocationPolicyFactory {
public VmAllocationPolicy create(List<? extends Host> list);
}
enum VmAllocationPolicyEnum{ CombLFF, CombMFF, MipLFF, MipMFF, OverLFF, OverMFF, LFF, MFF, Overbooking}
private static void printUsage() {
String runCmd = "java SDNExample";
System.out.format("Usage: %s <LFF|MFF> [physical.json] [virtual.json] [workload1.csv] [workload2.csv] [...]\n", runCmd);
}
/**
* Creates main() to run this example.
*
* @param args the args
*/
@SuppressWarnings("unused")
public static void main(String[] args) {
workloads = new ArrayList<String>();
// Parse system arguments
if(args.length < 1) {
printUsage();
System.exit(1);
}
VmAllocationPolicyEnum vmAllocPolicy = VmAllocationPolicyEnum.valueOf(args[0]);
if(args.length > 1)
physicalTopologyFile = args[1];
if(args.length > 2)
deploymentFile = args[2];
if(args.length > 3)
for(int i=3; i<args.length; i++) {
workloads.add(args[i]);
}
else
workloads = (List<String>) Arrays.asList(workload_files);
printArguments(physicalTopologyFile, deploymentFile, workloads);
Log.printLine("Starting CloudSim SDN...");
try {
// Initialize
int num_user = 1; // number of cloud users
Calendar calendar = Calendar.getInstance();
boolean trace_flag = false; // mean trace events
CloudSim.init(num_user, calendar, trace_flag);
VmAllocationPolicyFactory vmAllocationFac = null;
NetworkOperatingSystem snos = null;
switch(vmAllocPolicy) {
case CombMFF:
case MFF:
vmAllocationFac = new VmAllocationPolicyFactory() {
public VmAllocationPolicy create(List<? extends Host> hostList) { return new VmAllocationPolicyCombinedMostFullFirst(hostList); }
};
snos = new SimpleNetworkOperatingSystem(physicalTopologyFile);
break;
case CombLFF:
case LFF:
vmAllocationFac = new VmAllocationPolicyFactory() {
public VmAllocationPolicy create(List<? extends Host> hostList) { return new VmAllocationPolicyCombinedLeastFullFirst(hostList); }
};
snos = new SimpleNetworkOperatingSystem(physicalTopologyFile);
break;
case MipMFF:
vmAllocationFac = new VmAllocationPolicyFactory() {
public VmAllocationPolicy create(List<? extends Host> hostList) { return new VmAllocationPolicyMipsMostFullFirst(hostList); }
};
snos = new SimpleNetworkOperatingSystem(physicalTopologyFile);
break;
case MipLFF:
vmAllocationFac = new VmAllocationPolicyFactory() {
public VmAllocationPolicy create(List<? extends Host> hostList) { return new VmAllocationPolicyMipsLeastFullFirst(hostList); }
};
snos = new SimpleNetworkOperatingSystem(physicalTopologyFile);
break;
case Overbooking:
vmAllocationFac = new VmAllocationPolicyFactory() {
public VmAllocationPolicy create(List<? extends Host> hostList) { return new VmAllocationPolicyOverbooking(hostList); }
};
snos = new OverbookingNetworkOperatingSystem(physicalTopologyFile);
break;
default:
System.err.println("Choose proper VM placement polilcy!");
printUsage();
System.exit(1);
}
// Create a Datacenter
SDNDatacenter datacenter = createSDNDatacenter("Datacenter_0", physicalTopologyFile, snos, vmAllocationFac);
// Broker
SDNBroker broker = createBroker();
int brokerId = broker.getId();
// Submit virtual topology
broker.submitDeployApplication(datacenter, deploymentFile);
// Submit individual workloads
submitWorkloads(broker);
// Sixth step: Starts the simulation
if(!SDNExample.logEnabled)
Log.disable();
double finishTime = CloudSim.startSimulation();
CloudSim.stopSimulation();
Log.enable();
Log.printLine(finishTime+": ========== EXPERIMENT FINISHED ===========");
// Print results when simulation is over
//*
List<Cloudlet> newList = broker.getCloudletReceivedList();
if(SDNExample.logEnabled)
LogPrinter.printCloudletList(newList);
List<Workload> wls = broker.getWorkloads();
LogPrinter.printWorkloadList(wls);
//*/
// Print hosts' and switches' total utilization.
List<Host> hostList = nos.getHostList();
List<Switch> switchList = nos.getSwitchList();
LogPrinter.printEnergyConsumption(hostList, switchList, finishTime);
Log.printLine("Simultanously used hosts:"+maxHostHandler.getMaxNumHostsUsed());
Log.printLine("CloudSim SDN finished!");
} catch (Exception e) {
e.printStackTrace();
Log.printLine("Unwanted errors happen");
}
}
public static void submitWorkloads(SDNBroker broker) {
// Submit workload files individually
if(workloads != null) {
for(String workload:workloads)
broker.submitRequests(workload);
}
// Or, Submit groups of workloads
//submitGroupWorkloads(broker, WORKLOAD_GROUP_NUM, WORKLOAD_GROUP_PRIORITY, WORKLOAD_GROUP_FILENAME, WORKLOAD_GROUP_FILENAME_BG);
}
public static void printArguments(String physical, String virtual, List<String> workloads) {
System.out.println("Data center infrastructure (Physical Topology) : "+ physical);
System.out.println("Virtual Machine and Network requests (Virtual Topology) : "+ virtual);
System.out.println("Workloads: ");
for(String work:workloads)
System.out.println(" "+work);
}
/**
* Creates the datacenter.
*
* @param name the name
*
* @return the datacenter
*/
protected static NetworkOperatingSystem nos;
protected static PowerUtilizationMaxHostInterface maxHostHandler = null;
protected static SDNDatacenter createSDNDatacenter(String name, String physicalTopology, NetworkOperatingSystem snos, VmAllocationPolicyFactory vmAllocationFactory) {
// In order to get Host information, pre-create NOS.
nos=snos;
List<Host> hostList = nos.getHostList();
String arch = "x86"; // system architecture
String os = "Linux"; // operating system
String vmm = "Xen";
double time_zone = 10.0; // time zone this resource located
double cost = 3.0; // the cost of using processing in this resource
double costPerMem = 0.05; // the cost of using memory in this resource
double costPerStorage = 0.001; // the cost of using storage in this
// resource
double costPerBw = 0.0; // the cost of using bw in this resource
LinkedList<Storage> storageList = new LinkedList<Storage>(); // we are not adding SAN
// devices by now
DatacenterCharacteristics characteristics = new DatacenterCharacteristics(
arch, os, vmm, hostList, time_zone, cost, costPerMem,
costPerStorage, costPerBw);
// Create Datacenter with previously set parameters
SDNDatacenter datacenter = null;
try {
VmAllocationPolicy vmPolicy = vmAllocationFactory.create(hostList);
maxHostHandler = (PowerUtilizationMaxHostInterface)vmPolicy;
datacenter = new SDNDatacenter(name, characteristics, vmPolicy, storageList, 0, nos);
nos.setDatacenter(datacenter);
} catch (Exception e) {
e.printStackTrace();
}
return datacenter;
}
// We strongly encourage users to develop their own broker policies, to
// submit vms and cloudlets according
// to the specific rules of the simulated scenario
/**
* Creates the broker.
*
* @return the datacenter broker
*/
protected static SDNBroker createBroker() {
SDNBroker broker = null;
try {
broker = new SDNBroker("Broker");
} catch (Exception e) {
e.printStackTrace();
return null;
}
return broker;
}
static String WORKLOAD_GROUP_FILENAME = "workload_10sec_100_default.csv"; // group 0~9
static String WORKLOAD_GROUP_FILENAME_BG = "workload_10sec_100.csv"; // group 10~29
static int WORKLOAD_GROUP_NUM = 50;
static int WORKLOAD_GROUP_PRIORITY = 1;
public static void submitGroupWorkloads(SDNBroker broker, int workloadsNum, int groupSeperateNum, String filename_suffix_group1, String filename_suffix_group2) {
for(int set=0; set<workloadsNum; set++) {
String filename = filename_suffix_group1;
if(set>=groupSeperateNum)
filename = filename_suffix_group2;
filename = set+"_"+filename;
broker.submitRequests(filename);
}
}
/// Under development
/*
static class WorkloadGroup {
static int autoIdGenerator = 0;
final int groupId;
String groupFilenamePrefix;
int groupFilenameStart;
int groupFileNum;
WorkloadGroup(int id, String groupFilenamePrefix, int groupFileNum, int groupFilenameStart) {
this.groupId = id;
this.groupFilenamePrefix = groupFilenamePrefix;
this.groupFileNum = groupFileNum;
}
List<String> getFileList() {
List<String> filenames = new LinkedList<String>();
for(int fileId=groupFilenameStart; fileId< this.groupFilenameStart+this.groupFileNum; fileId++) {
String filename = groupFilenamePrefix + fileId;
filenames.add(filename);
}
return filenames;
}
public static WorkloadGroup createWorkloadGroup(String groupFilenamePrefix, int groupFileNum) {
return new WorkloadGroup(autoIdGenerator++, groupFilenamePrefix, groupFileNum, 0);
}
public static WorkloadGroup createWorkloadGroup(String groupFilenamePrefix, int groupFileNum, int groupFilenameStart) {
return new WorkloadGroup(autoIdGenerator++, groupFilenamePrefix, groupFileNum, groupFilenameStart);
}
}
static LinkedList<WorkloadGroup> workloadGroups = new LinkedList<WorkloadGroup>();
*/
}

View File

@@ -0,0 +1,215 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn.example;
import java.util.List;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.Vm;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.core.CloudSimTags;
import org.cloudbus.cloudsim.core.SimEvent;
import org.cloudbus.cloudsim.sdn.Arc;
import org.cloudbus.cloudsim.sdn.Link;
import org.cloudbus.cloudsim.sdn.Middlebox;
import org.cloudbus.cloudsim.sdn.NetworkOperatingSystem;
import org.cloudbus.cloudsim.sdn.Node;
import org.cloudbus.cloudsim.sdn.SDNHost;
import org.cloudbus.cloudsim.sdn.TimedVm;
/**
* Simple network operating system class for the example.
* In this example, network operating system (aka SDN controller) finds shortest path
* when deploying the application onto the cloud.
*
* @author Jungmin Son
* @since CloudSimSDN 1.0
*/
public class SimpleNetworkOperatingSystem extends NetworkOperatingSystem {
public SimpleNetworkOperatingSystem(String fileName) {
super(fileName);
}
@Override
public boolean deployApplication(List<Vm> vms, List<Middlebox> middleboxes, List<Arc> links) {
Log.printLine(CloudSim.clock() + ": " + getName() + ": Starting deploying application..");
for(Vm vm:vms)
{
TimedVm tvm = (TimedVm) vm;
Log.printLine(CloudSim.clock() + ": " + getName() + ": Trying to Create VM #" + vm.getId()
+ " in " + datacenter.getName() + ", (" + tvm.getStartTime() + "~" +tvm.getFinishTime() + ")");
send(datacenter.getId(), tvm.getStartTime(), CloudSimTags.VM_CREATE_ACK, vm);
if(tvm.getFinishTime() != Double.POSITIVE_INFINITY) {
//System.err.println("VM will be terminated at: "+tvm.getFinishTime());
send(datacenter.getId(), tvm.getFinishTime(), CloudSimTags.VM_DESTROY, vm);
send(this.getId(), tvm.getFinishTime(), CloudSimTags.VM_DESTROY, vm);
}
}
return true;
}
public boolean deployFlow(List<Arc> links) {
for(Arc link:links) {
int srcVm = link.getSrcId();
int dstVm = link.getDstId();
int flowId = link.getFlowId();
SDNHost srchost = findSDNHost(srcVm);
SDNHost dsthost = findSDNHost(dstVm);
if(srchost == null || dsthost == null) {
continue;
}
if(srchost.equals(dsthost)) {
Log.printLine(CloudSim.clock() + ": " + getName() + ": Source SDN Host is same as Destination. Go loopback");
srchost.addVMRoute(srcVm, dstVm, flowId, dsthost);
}
else {
Log.printLine(CloudSim.clock() + ": " + getName() + ": VMs are in different hosts. Create entire routing table (hosts, switches)");
boolean findRoute = buildForwardingTables(srchost, srcVm, dstVm, flowId, null);
if(!findRoute) {
System.err.println("SimpleNetworkOperatingSystem.deployFlow: Could not find route!!" +
NetworkOperatingSystem.debugVmIdName.get(srcVm) + "->"+NetworkOperatingSystem.debugVmIdName.get(dstVm));
}
}
}
// Print all routing tables.
for(Node node:this.topology.getAllNodes()) {
node.printVMRoute();
}
return true;
}
private Link selectLinkFirst(List<Link> links) {
return links.get(0);
}
int i=0;
private Link selectLinkRandom(List<Link> links) {
return links.get(i++ % links.size());
}
private Link selectLinkByFlow(List<Link> links, int flowId) {
if(flowId == -1)
return links.get(0);
else
return links.get(1 % links.size());
}
private Link selectLinkByChannelCount(Node from, List<Link> links) {
Link lighter = links.get(0);
for(Link l:links) {
if(l.getChannelCount(from) < lighter.getChannelCount(from)) {
// Less traffic flows using this link
lighter = l;
}
}
return lighter;
}
private Link selectLinkByDestination(List<Link> links, SDNHost destHost) {
int numLinks = links.size();
int linkid = destHost.getAddress() % numLinks;
Link link = links.get(linkid);
return link;
}
private boolean buildForwardingTables(Node node, int srcVm, int dstVm, int flowId, Node prevNode) {
// There are many links. Determine which hop to go.
SDNHost desthost = findSDNHost(dstVm);
if(node.equals(desthost))
return true;
List<Link> nextLinks = node.getRoute(desthost);
// Let's choose the first link. make simple
Link nextLink = selectLinkByFlow(nextLinks, flowId);
//Link nextLink = selectLinkRandom(nextLinks);
//Link nextLink = selectBestLink(node, nextLinks);
//Link nextLink = selectRandomTreeLink(nextLinks, desthost);
Node nextHop = nextLink.getOtherNode(node);
node.addVMRoute(srcVm, dstVm, flowId, nextHop);
buildForwardingTables(nextHop, srcVm, dstVm, flowId, null);
return true;
/*
Collection<Link> links = this.topology.getAdjacentLinks(node);
if(links.size() == 0) {
// No link. Do nothing
}
else if(links.size() == 1) {
// Only one way, no other choice (for Host to Edge switch)
for(Link l:links) {
Node nextHop= l.getHighOrder();
if(nextHop.equals(node))
nextHop= l.getLowOrder();
node.addVMRoute(srcVm, dstVm, flowId, nextHop);
buildForwardingTables(nextHop, srcVm, dstVm, flowId, node);
}
return true;
}
else {
// There are many links. Determine which hop to go.
SDNHost dsthost = findSDNHost(dstVm);
for(Link l:links) {
Node nextHop= l.getOtherNode(node);
if(nextHop.equals(prevNode)) {
// NextHop is going back to prev node
continue;
}
else if(nextHop.equals(dsthost)) {
// NextHop is the destination. Just add. No further route finding.
node.addVMRoute(srcVm, dstVm, flowId, nextHop);
return true;
}
else if(nextHop instanceof SDNHost) {
// NextHop is host but no destination. Can't forward
continue;
}
else {
// Nexthop is switch
if(buildForwardingTables(nextHop, srcVm, dstVm, flowId, node)) {
// If the route is right.
node.addVMRoute(srcVm, dstVm, flowId, nextHop);
return true;
}
else
continue;
}
}
}
return false;
*/
}
@Override
protected Middlebox deployMiddlebox(String type,Vm vm) {
return null;
}
@Override
public void processVmCreateAck(SimEvent ev) {
// print the created VM info
TimedVm vm = (TimedVm) ev.getData();
Log.printLine(CloudSim.clock() + ": " + getName() + ": VM Created: " + vm.getId() + " in " + this.findSDNHost(vm.getId()));
deployFlow(this.arcList);
}
}

View File

@@ -0,0 +1,94 @@
package org.cloudbus.cloudsim.sdn.example;
import java.util.List;
import org.cloudbus.cloudsim.Host;
import org.cloudbus.cloudsim.Vm;
public class VmAllocationPolicyCombinedLeastFullFirst extends VmAllocationPolicyCombinedMostFullFirst{
public VmAllocationPolicyCombinedLeastFullFirst(List<? extends Host> list) {
super(list);
}
/**
* Allocates a host for a given VM.
*
* @param vm VM specification
* @return $true if the host could be allocated; $false otherwise
* @pre $none
* @post $none
*/
@Override
public boolean allocateHostForVm(Vm vm) {
if (getVmTable().containsKey(vm.getUid())) { // if this vm was not created
return false;
}
int numHosts = getHostList().size();
// 1. Find/Order the best host for this VM by comparing a metric
int requiredPes = vm.getNumberOfPes();
double requiredMips = vm.getCurrentRequestedTotalMips();
long requiredBw = vm.getCurrentRequestedBw();
boolean result = false;
double[] freeResources = new double[numHosts];
for (int i = 0; i < numHosts; i++) {
double mipsFreePercent = (double)getFreeMips().get(i) / hostTotalMips;
double bwFreePercent = (double)getFreeBw().get(i) / hostTotalBw;
freeResources[i] = convertWeightedMetric(mipsFreePercent, bwFreePercent);
}
for(int tries = 0; tries < numHosts; tries++) {// we still trying until we find a host or until we try all of them
double moreFree = Double.NEGATIVE_INFINITY;
int idx = -1;
// we want the host with less pes in use
for (int i = 0; i < numHosts; i++) {
if (freeResources[i] > moreFree) {
moreFree = freeResources[i];
idx = i;
}
}
if(idx==-1) {
System.err.println("Cannot assign the VM to any host:"+tries+"/"+numHosts);
return false;
}
freeResources[idx] = Double.NEGATIVE_INFINITY;
Host host = getHostList().get(idx);
// Check whether the host can hold this VM or not.
if(getFreeMips().get(idx) < requiredMips ||
getFreeBw().get(idx) < requiredBw ||
getFreePes().get(idx) < requiredPes) {
//Cannot host the VM
continue;
}
result = host.vmCreate(vm);
if (result) { // if vm were succesfully created in the host
getVmTable().put(vm.getUid(), host);
getUsedPes().put(vm.getUid(), requiredPes);
getFreePes().set(idx, getFreePes().get(idx) - requiredPes);
getUsedMips().put(vm.getUid(), (long) requiredMips);
getFreeMips().set(idx, (long) (getFreeMips().get(idx) - requiredMips));
getUsedBw().put(vm.getUid(), (long) requiredBw);
getFreeBw().set(idx, (long) (getFreeBw().get(idx) - requiredBw));
break;
}
}
logMaxNumHostsUsed();
return result;
}
}

View File

@@ -0,0 +1,324 @@
package org.cloudbus.cloudsim.sdn.example;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.cloudbus.cloudsim.Host;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.Vm;
import org.cloudbus.cloudsim.VmAllocationPolicy;
import org.cloudbus.cloudsim.core.CloudSim;
public class VmAllocationPolicyCombinedMostFullFirst extends VmAllocationPolicy {
protected final double hostTotalMips;
protected final double hostTotalBw;
protected final int hostTotalPes;
/** The vm table. */
private Map<String, Host> vmTable;
/** The used pes. */
private Map<String, Integer> usedPes;
/** The free pes. */
private List<Integer> freePes;
private Map<String, Long> usedMips;
private List<Long> freeMips;
private Map<String, Long> usedBw;
private List<Long> freeBw;
/**
* Creates the new VmAllocationPolicySimple object.
*
* @param list the list
* @pre $none
* @post $none
*/
public VmAllocationPolicyCombinedMostFullFirst(List<? extends Host> list) {
super(list);
setFreePes(new ArrayList<Integer>());
setFreeMips(new ArrayList<Long>());
setFreeBw(new ArrayList<Long>());
for (Host host : getHostList()) {
getFreePes().add(host.getNumberOfPes());
getFreeMips().add((long) host.getTotalMips());
getFreeBw().add(host.getBw());
}
hostTotalMips = getHostList().get(0).getTotalMips();
hostTotalBw = getHostList().get(0).getBw();
hostTotalPes = getHostList().get(0).getNumberOfPes();
setVmTable(new HashMap<String, Host>());
setUsedPes(new HashMap<String, Integer>());
setUsedMips(new HashMap<String, Long>());
setUsedBw(new HashMap<String, Long>());
}
protected double convertWeightedMetric(double mipsPercent, double bwPercent) {
double ret = mipsPercent * bwPercent;
return ret;
}
/**
* Allocates a host for a given VM.
*
* @param vm VM specification
* @return $true if the host could be allocated; $false otherwise
* @pre $none
* @post $none
*/
@Override
public boolean allocateHostForVm(Vm vm) {
if (getVmTable().containsKey(vm.getUid())) { // if this vm was not created
return false;
}
int numHosts = getHostList().size();
// 1. Find/Order the best host for this VM by comparing a metric
int requiredPes = vm.getNumberOfPes();
double requiredMips = vm.getCurrentRequestedTotalMips();
long requiredBw = vm.getCurrentRequestedBw();
boolean result = false;
double[] freeResources = new double[numHosts];
for (int i = 0; i < numHosts; i++) {
double mipsFreePercent = (double)getFreeMips().get(i) / this.hostTotalMips;
double bwFreePercent = (double)getFreeBw().get(i) / this.hostTotalBw;
freeResources[i] = this.convertWeightedMetric(mipsFreePercent, bwFreePercent);
}
for(int tries = 0; result == false && tries < numHosts; tries++) {// we still trying until we find a host or until we try all of them
double lessFree = Double.POSITIVE_INFINITY;
int idx = -1;
// we want the host with less pes in use
for (int i = 0; i < numHosts; i++) {
if (freeResources[i] < lessFree) {
lessFree = freeResources[i];
idx = i;
}
}
freeResources[idx] = Double.POSITIVE_INFINITY;
Host host = getHostList().get(idx);
// Check whether the host can hold this VM or not.
if(getFreeMips().get(idx) < requiredMips ||
getFreeBw().get(idx) < requiredBw ||
getFreePes().get(idx) < requiredPes) {
//Cannot host the VM
continue;
}
result = host.vmCreate(vm);
if (result) { // if vm were succesfully created in the host
getVmTable().put(vm.getUid(), host);
getUsedPes().put(vm.getUid(), requiredPes);
getFreePes().set(idx, getFreePes().get(idx) - requiredPes);
getUsedMips().put(vm.getUid(), (long) requiredMips);
getFreeMips().set(idx, (long) (getFreeMips().get(idx) - requiredMips));
getUsedBw().put(vm.getUid(), (long) requiredBw);
getFreeBw().set(idx, (long) (getFreeBw().get(idx) - requiredBw));
break;
}
}
logMaxNumHostsUsed();
return result;
}
protected int maxNumHostsUsed=0;
protected void logMaxNumHostsUsed() {
// Get how many are used
int numHostsUsed=0;
for(int freePes:getFreePes()) {
if(freePes < hostTotalPes) {
numHostsUsed++;
}
}
if(maxNumHostsUsed < numHostsUsed)
maxNumHostsUsed = numHostsUsed;
System.err.println("Number of online hosts:"+numHostsUsed + ", max was ="+maxNumHostsUsed);
}
public int getMaxNumHostsUsed() { return maxNumHostsUsed;}
/**
* Releases the host used by a VM.
*
* @param vm the vm
* @pre $none
* @post none
*/
@Override
public void deallocateHostForVm(Vm vm) {
Host host = getVmTable().remove(vm.getUid());
if (host != null) {
int idx = getHostList().indexOf(host);
host.vmDestroy(vm);
Integer pes = getUsedPes().remove(vm.getUid());
getFreePes().set(idx, getFreePes().get(idx) + pes);
Long mips = getUsedMips().remove(vm.getUid());
getFreeMips().set(idx, getFreeMips().get(idx) + mips);
Long bw = getUsedBw().remove(vm.getUid());
getFreeBw().set(idx, getFreeBw().get(idx) + bw);
}
}
/**
* Gets the host that is executing the given VM belonging to the given user.
*
* @param vm the vm
* @return the Host with the given vmID and userID; $null if not found
* @pre $none
* @post $none
*/
@Override
public Host getHost(Vm vm) {
return getVmTable().get(vm.getUid());
}
/**
* Gets the host that is executing the given VM belonging to the given user.
*
* @param vmId the vm id
* @param userId the user id
* @return the Host with the given vmID and userID; $null if not found
* @pre $none
* @post $none
*/
@Override
public Host getHost(int vmId, int userId) {
return getVmTable().get(Vm.getUid(userId, vmId));
}
/**
* Gets the vm table.
*
* @return the vm table
*/
public Map<String, Host> getVmTable() {
return vmTable;
}
/**
* Sets the vm table.
*
* @param vmTable the vm table
*/
protected void setVmTable(Map<String, Host> vmTable) {
this.vmTable = vmTable;
}
/**
* Gets the used pes.
*
* @return the used pes
*/
protected Map<String, Integer> getUsedPes() {
return usedPes;
}
/**
* Sets the used pes.
*
* @param usedPes the used pes
*/
protected void setUsedPes(Map<String, Integer> usedPes) {
this.usedPes = usedPes;
}
/**
* Gets the free pes.
*
* @return the free pes
*/
protected List<Integer> getFreePes() {
return freePes;
}
/**
* Sets the free pes.
*
* @param freePes the new free pes
*/
protected void setFreePes(List<Integer> freePes) {
this.freePes = freePes;
}
protected Map<String, Long> getUsedMips() {
return usedMips;
}
protected void setUsedMips(Map<String, Long> usedMips) {
this.usedMips = usedMips;
}
protected Map<String, Long> getUsedBw() {
return usedBw;
}
protected void setUsedBw(Map<String, Long> usedBw) {
this.usedBw = usedBw;
}
protected List<Long> getFreeMips() {
return this.freeMips;
}
protected void setFreeMips(List<Long> freeMips) {
this.freeMips = freeMips;
}
protected List<Long> getFreeBw() {
return this.freeBw;
}
protected void setFreeBw(List<Long> freeBw) {
this.freeBw = freeBw;
}
/*
* (non-Javadoc)
* @see cloudsim.VmAllocationPolicy#optimizeAllocation(double, cloudsim.VmList, double)
*/
@Override
public List<Map<String, Object>> optimizeAllocation(List<? extends Vm> vmList) {
// TODO Auto-generated method stub
return null;
}
/*
* (non-Javadoc)
* @see org.cloudbus.cloudsim.VmAllocationPolicy#allocateHostForVm(org.cloudbus.cloudsim.Vm,
* org.cloudbus.cloudsim.Host)
*/
@Override
public boolean allocateHostForVm(Vm vm, Host host) {
if (host.vmCreate(vm)) { // if vm has been succesfully created in the host
getVmTable().put(vm.getUid(), host);
int requiredPes = vm.getNumberOfPes();
int idx = getHostList().indexOf(host);
getUsedPes().put(vm.getUid(), requiredPes);
getFreePes().set(idx, getFreePes().get(idx) - requiredPes);
Log.formatLine(
"%.2f: VM #" + vm.getId() + " has been allocated to the host #" + host.getId(),
CloudSim.clock());
return true;
}
return false;
}
}

View File

@@ -0,0 +1,94 @@
package org.cloudbus.cloudsim.sdn.example;
import java.util.List;
import org.cloudbus.cloudsim.Host;
import org.cloudbus.cloudsim.Vm;
public class VmAllocationPolicyMipsLeastFullFirst extends VmAllocationPolicyCombinedMostFullFirst{
public VmAllocationPolicyMipsLeastFullFirst(List<? extends Host> list) {
super(list);
}
/**
* Allocates a host for a given VM.
*
* @param vm VM specification
* @return $true if the host could be allocated; $false otherwise
* @pre $none
* @post $none
*/
@Override
public boolean allocateHostForVm(Vm vm) {
if (getVmTable().containsKey(vm.getUid())) { // if this vm was not created
return false;
}
int numHosts = getHostList().size();
// 1. Find/Order the best host for this VM by comparing a metric
int requiredPes = vm.getNumberOfPes();
double requiredMips = vm.getCurrentRequestedTotalMips();
long requiredBw = vm.getCurrentRequestedBw();
boolean result = false;
double[] freeResources = new double[numHosts];
for (int i = 0; i < numHosts; i++) {
double mipsFreePercent = (double)getFreeMips().get(i) / hostTotalMips;
//double bwFreePercent = (double)getFreeBw().get(i) / hostTotalBw;
freeResources[i] = mipsFreePercent;
}
for(int tries = 0; tries < numHosts; tries++) {// we still trying until we find a host or until we try all of them
double moreFree = Double.NEGATIVE_INFINITY;
int idx = -1;
// we want the host with less pes in use
for (int i = 0; i < numHosts; i++) {
if (freeResources[i] > moreFree) {
moreFree = freeResources[i];
idx = i;
}
}
if(idx==-1) {
System.err.println("Cannot assign the VM to any host:"+tries+"/"+numHosts);
return false;
}
freeResources[idx] = Double.NEGATIVE_INFINITY;
Host host = getHostList().get(idx);
// Check whether the host can hold this VM or not.
if(getFreeMips().get(idx) < requiredMips ||
getFreeBw().get(idx) < requiredBw ||
getFreePes().get(idx) < requiredPes) {
//Cannot host the VM
continue;
}
result = host.vmCreate(vm);
if (result) { // if vm were succesfully created in the host
getVmTable().put(vm.getUid(), host);
getUsedPes().put(vm.getUid(), requiredPes);
getFreePes().set(idx, getFreePes().get(idx) - requiredPes);
getUsedMips().put(vm.getUid(), (long) requiredMips);
getFreeMips().set(idx, (long) (getFreeMips().get(idx) - requiredMips));
getUsedBw().put(vm.getUid(), (long) requiredBw);
getFreeBw().set(idx, (long) (getFreeBw().get(idx) - requiredBw));
break;
}
}
logMaxNumHostsUsed();
return result;
}
}

View File

@@ -0,0 +1,88 @@
package org.cloudbus.cloudsim.sdn.example;
import java.util.List;
import org.cloudbus.cloudsim.Host;
import org.cloudbus.cloudsim.Vm;
public class VmAllocationPolicyMipsMostFullFirst extends VmAllocationPolicyCombinedMostFullFirst{
public VmAllocationPolicyMipsMostFullFirst(List<? extends Host> list) {
super(list);
}
/**
* Allocates a host for a given VM.
*
* @param vm VM specification
* @return $true if the host could be allocated; $false otherwise
* @pre $none
* @post $none
*/
@Override
public boolean allocateHostForVm(Vm vm) {
if (getVmTable().containsKey(vm.getUid())) { // if this vm was not created
return false;
}
int numHosts = getHostList().size();
// 1. Find/Order the best host for this VM by comparing a metric
int requiredPes = vm.getNumberOfPes();
double requiredMips = vm.getCurrentRequestedTotalMips();
long requiredBw = vm.getCurrentRequestedBw();
boolean result = false;
double[] freeResources = new double[numHosts];
for (int i = 0; i < numHosts; i++) {
double mipsFreePercent = (double)getFreeMips().get(i) / this.hostTotalMips;
freeResources[i] = mipsFreePercent;
}
for(int tries = 0; result == false && tries < numHosts; tries++) {// we still trying until we find a host or until we try all of them
double lessFree = Double.POSITIVE_INFINITY;
int idx = -1;
// we want the host with less pes in use
for (int i = 0; i < numHosts; i++) {
if (freeResources[i] < lessFree) {
lessFree = freeResources[i];
idx = i;
}
}
freeResources[idx] = Double.POSITIVE_INFINITY;
Host host = getHostList().get(idx);
// Check whether the host can hold this VM or not.
if(getFreeMips().get(idx) < requiredMips ||
getFreeBw().get(idx) < requiredBw ||
getFreePes().get(idx) < requiredPes) {
//Cannot host the VM
continue;
}
result = host.vmCreate(vm);
if (result) { // if vm were succesfully created in the host
getVmTable().put(vm.getUid(), host);
getUsedPes().put(vm.getUid(), requiredPes);
getFreePes().set(idx, getFreePes().get(idx) - requiredPes);
getUsedMips().put(vm.getUid(), (long) requiredMips);
getFreeMips().set(idx, (long) (getFreeMips().get(idx) - requiredMips));
getUsedBw().put(vm.getUid(), (long) requiredBw);
getFreeBw().set(idx, (long) (getFreeBw().get(idx) - requiredBw));
break;
}
}
logMaxNumHostsUsed();
return result;
}
}

View File

@@ -0,0 +1,214 @@
/*
* 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.sdn.example;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.cloudbus.cloudsim.Pe;
import org.cloudbus.cloudsim.Vm;
import org.cloudbus.cloudsim.VmScheduler;
import org.cloudbus.cloudsim.core.CloudSim;
/**
* VmSchedulerSpaceShared is a VMM allocation policy that allocates one or more Pe to a VM, and
* doesn't allow sharing of PEs. If there is no free PEs to the VM, allocation fails. Free PEs are
* not allocated to VMs
*
* @author Rodrigo N. Calheiros
* @author Anton Beloglazov
* @since CloudSim Toolkit 1.0
*/
public class VmSchedulerSpaceSharedEnergy extends VmScheduler {
/** Map containing VM ID and a vector of PEs allocated to this VM. */
private Map<String, List<Pe>> peAllocationMap;
/** The free pes vector. */
private List<Pe> freePes;
/**
* Instantiates a new vm scheduler space shared.
*
* @param pelist the pelist
*/
public VmSchedulerSpaceSharedEnergy(List<? extends Pe> pelist) {
super(pelist);
setPeAllocationMap(new HashMap<String, List<Pe>>());
setFreePes(new ArrayList<Pe>());
getFreePes().addAll(pelist);
}
/*
* (non-Javadoc)
* @see org.cloudbus.cloudsim.VmScheduler#allocatePesForVm(org.cloudbus.cloudsim.Vm,
* java.util.List)
*/
@Override
public boolean allocatePesForVm(Vm vm, List<Double> mipsShare) {
// if there is no enough free PEs, fails
if (getFreePes().size() < mipsShare.size()) {
return false;
}
List<Pe> selectedPes = new ArrayList<Pe>();
Iterator<Pe> peIterator = getFreePes().iterator();
Pe pe = peIterator.next();
double totalMips = 0;
for (Double mips : mipsShare) {
if (mips <= pe.getMips()) {
selectedPes.add(pe);
totalMips += mips;
if (!peIterator.hasNext()) {
break;
}
pe = peIterator.next();
}
}
if (mipsShare.size() > selectedPes.size()) {
return false;
}
getFreePes().removeAll(selectedPes);
getPeAllocationMap().put(vm.getUid(), selectedPes);
getMipsMap().put(vm.getUid(), mipsShare);
setAvailableMips(getAvailableMips() - totalMips);
return true;
}
/*
* (non-Javadoc)
* @see org.cloudbus.cloudsim.VmScheduler#deallocatePesForVm(org.cloudbus.cloudsim.Vm)
*/
@Override
public void deallocatePesForVm(Vm vm) {
getFreePes().addAll(getPeAllocationMap().get(vm.getUid()));
getPeAllocationMap().remove(vm.getUid());
double totalMips = 0;
for (double mips : getMipsMap().get(vm.getUid())) {
totalMips += mips;
}
setAvailableMips(getAvailableMips() + totalMips);
getMipsMap().remove(vm.getUid());
}
/**
* Sets the pe allocation map.
*
* @param peAllocationMap the pe allocation map
*/
protected void setPeAllocationMap(Map<String, List<Pe>> peAllocationMap) {
this.peAllocationMap = peAllocationMap;
}
/**
* Gets the pe allocation map.
*
* @return the pe allocation map
*/
protected Map<String, List<Pe>> getPeAllocationMap() {
return peAllocationMap;
}
/**
* Sets the free pes vector.
*
* @param freePes the new free pes vector
*/
protected void setFreePes(List<Pe> freePes) {
this.freePes = freePes;
}
/**
* Gets the free pes vector.
*
* @return the free pes vector
*/
protected List<Pe> getFreePes() {
return freePes;
}
/************************************************
* Calculate Utilization history
************************************************/
public class HistoryEntry {
public double startTime;
public double usedMips;
HistoryEntry(double t, double m) { startTime=t; usedMips=m;}
}
private List<HistoryEntry> utilizationHistories = null;
public List<HistoryEntry> getUtilizationHisotry() {
return utilizationHistories;
}
public double getUtilizationTotalMips() {
double total=0;
double lastTime=0;
double lastMips=0;
for(HistoryEntry h:this.utilizationHistories) {
total += lastMips * (h.startTime - lastTime);
lastTime = h.startTime;
lastMips = h.usedMips;
}
return total;
}
private static double powerOffDuration = 1*3600; //if host is idle for 1 hours, it's turned off.
public double getUtilizationEnergyConsumption() {
double total=0;
double lastTime=0;
double lastMips=0;
for(HistoryEntry h:this.utilizationHistories) {
double duration = h.startTime - lastTime;
double utilPercentage = lastMips/ getTotalMips();
double power = calculatePower(utilPercentage);
double energyConsumption = power * duration;
// Assume that the host is turned off when duration is long enough
if(duration > powerOffDuration && lastMips == 0)
energyConsumption = 0;
total += energyConsumption;
lastTime = h.startTime;
lastMips = h.usedMips;
}
return total/3600; // transform to Whatt*hour from What*seconds
}
private void addUtilizationEntry() {
double time = CloudSim.clock();
double totalMips = getTotalMips();
double usingMips = totalMips - this.getAvailableMips();
if(usingMips < 0) {
System.err.println("No way!");
}
if(utilizationHistories == null)
utilizationHistories = new ArrayList<HistoryEntry>();
this.utilizationHistories.add(new HistoryEntry(time, usingMips));
}
private double calculatePower(double u) {
double power = 120 + 154 * u;
return power;
}
private double getTotalMips() {
return this.getPeList().size() * this.getPeCapacity();
}
@Override
protected void setAvailableMips(double availableMips) {
super.setAvailableMips(availableMips);
addUtilizationEntry();
}
}

View File

@@ -0,0 +1,25 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn.example;
import org.cloudbus.cloudsim.sdn.Request;
/**
* Class to keep workload information parsed from files.
* This class is used in WorkloadParser
*
* @author Jungmin Son
* @since CloudSimSDN 1.0
*/
public class Workload {
public int appId;
public double time;
public int submitVmId;
public int submitPktSize;
public Request request;
}

View File

@@ -0,0 +1,187 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn.example;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import org.cloudbus.cloudsim.Cloudlet;
import org.cloudbus.cloudsim.UtilizationModel;
import org.cloudbus.cloudsim.sdn.Processing;
import org.cloudbus.cloudsim.sdn.Request;
import org.cloudbus.cloudsim.sdn.Transmission;
/**
* Parse [request].csv file.
*
* File format : req_time, vm_name(1), pkt_size(1), cloudlet_len(1),
* vm_name(2), pkt_size(2), cloudlet_len(2),
* ...
*
* @author Jungmin Son
* @since CloudSimSDN 1.0
*/
public class WorkloadParser {
private final Map<String, Integer> vmNames;
private final Map<String, Integer> flowNames;
private String file;
private static int reqId = 0;
private static int cloudletId = 0;
private int userId;
private UtilizationModel utilizationModel;
private List<Workload> workloads;
private List<Cloudlet> lastCloudlets;
private List<Cloudlet> allCloudlets;
public WorkloadParser(String file, int userId, UtilizationModel cloudletUtilModel,
Map<String, Integer> vmNameIdMap, Map<String, Integer> flowNameIdMap) {
this.file = file;
this.userId = userId;
this.utilizationModel = cloudletUtilModel;
this.vmNames = vmNameIdMap;
this.flowNames = flowNameIdMap;
startParsing();
}
public List<Workload> getWorkloads() {
return this.workloads;
}
public List<Cloudlet> getLastCloudlets() {
// Returns cloudlets that is done at last for each workload
return this.lastCloudlets;
}
public List<Cloudlet> getAllCloudlets() {
// Returns cloudlets that is done at last for each workload
return this.allCloudlets;
}
private int getVmId(String vmName) {
Integer vmId = this.vmNames.get(vmName);
if(vmId == null) {
System.err.println("Cannot find VM name:"+vmName);
return -1;
}
return vmId;
}
private Cloudlet generateCloudlet(int vmId, int length) {
int peNum=1;
long fileSize = 300;
long outputSize = 300;
Cloudlet cloudlet= new Cloudlet(cloudletId++, length, peNum, fileSize, outputSize, utilizationModel, utilizationModel, utilizationModel);
cloudlet.setUserId(userId);
cloudlet.setVmId(vmId);
return cloudlet;
}
// Cloud_Len -> /FlowId/ -> ToVmId -> PktSize
private Request parseRequest(int fromVmId, Queue<String> lineitems) {
if(lineitems.size() <= 0)
{
System.err.println("No REQUEST! ERROR");
return null;
}
long cloudletLen = Long.parseLong(lineitems.poll());
Request req = new Request(reqId++, userId);
Cloudlet cl = generateCloudlet(fromVmId, (int) cloudletLen);
this.allCloudlets.add(cl);
Processing proc = new Processing(cl);
req.addActivity(proc);
if(lineitems.size() != 0) {
// Has more requests after this. Create a transmission and add
String linkName = lineitems.poll();
Integer flowId = this.flowNames.get(linkName);
if(flowId == null) {
throw new IllegalArgumentException("No such link name in virtual.json:"+linkName);
}
String vmName = lineitems.poll();
int toVmId = getVmId(vmName);
long pktSize = Long.parseLong(lineitems.poll());
Request nextReq = parseRequest(toVmId, lineitems);
Transmission trans = new Transmission(fromVmId, toVmId, pktSize, flowId, nextReq);
req.addActivity(trans);
} else {
// this is the last request.
this.lastCloudlets.add(cl);
}
return req;
}
private void startParsing() {
this.workloads = new ArrayList<Workload>();
this.lastCloudlets = new ArrayList<Cloudlet>();
this.allCloudlets = new ArrayList<Cloudlet>();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(file));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String line;
try {
@SuppressWarnings("unused")
String head=br.readLine();
//System.out.println("Headline: "+ head);
while ((line = br.readLine()) != null) {
//System.out.println("parsing:"+line);
Workload tr = new Workload();
String[] splitLine = line.split(",");
Queue<String> lineitems = new LinkedList<String>(Arrays.asList(splitLine));
tr.time = Double.parseDouble(lineitems.poll());
String vmName = lineitems.poll();
tr.submitVmId = getVmId(vmName);
tr.submitPktSize = Integer.parseInt(lineitems.poll());
tr.request = parseRequest(tr.submitVmId, lineitems);
workloads.add(tr);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,117 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn.example.policies;
import java.util.List;
import org.cloudbus.cloudsim.Host;
import org.cloudbus.cloudsim.Vm;
/**
* VM Allocation Policy - BW and Compute combined, LFF.
* When select a host to create a new VM, this policy chooses
* the least full host in terms of both compute power and network bandwidth.
*
* @author Jungmin Son
* @since CloudSimSDN 1.0
*/
public class VmAllocationPolicyCombinedLeastFullFirst extends VmAllocationPolicyCombinedMostFullFirst{
public VmAllocationPolicyCombinedLeastFullFirst(List<? extends Host> list) {
super(list);
}
/**
* Allocates a host for a given VM.
*
* @param vm VM specification
* @return $true if the host could be allocated; $false otherwise
* @pre $none
* @post $none
*/
@Override
public boolean allocateHostForVm(Vm vm) {
if (getVmTable().containsKey(vm.getUid())) { // if this vm was not created
return false;
}
int numHosts = getHostList().size();
// 1. Find/Order the best host for this VM by comparing a metric
int requiredPes = vm.getNumberOfPes();
double requiredMips = vm.getCurrentRequestedTotalMips();
long requiredBw = vm.getCurrentRequestedBw();
boolean result = false;
double[] freeResources = new double[numHosts];
for (int i = 0; i < numHosts; i++) {
double mipsFreePercent = (double)getFreeMips().get(i) / hostTotalMips;
double bwFreePercent = (double)getFreeBw().get(i) / hostTotalBw;
freeResources[i] = convertWeightedMetric(mipsFreePercent, bwFreePercent);
}
for(int tries = 0; tries < numHosts; tries++) {// we still trying until we find a host or until we try all of them
double moreFree = Double.NEGATIVE_INFINITY;
int idx = -1;
// we want the host with less pes in use
for (int i = 0; i < numHosts; i++) {
if (freeResources[i] > moreFree) {
moreFree = freeResources[i];
idx = i;
}
}
if(idx==-1) {
System.err.println("Cannot assign the VM to any host:"+tries+"/"+numHosts);
return false;
}
freeResources[idx] = Double.NEGATIVE_INFINITY;
Host host = getHostList().get(idx);
// Check whether the host can hold this VM or not.
if( getFreeMips().get(idx) < requiredMips) {
//System.err.println("not enough MIPS");
//Cannot host the VM
continue;
}
if( getFreeBw().get(idx) < requiredBw) {
//System.err.println("not enough BW");
//Cannot host the VM
continue;
}
result = host.vmCreate(vm);
if (result) { // if vm were succesfully created in the host
getVmTable().put(vm.getUid(), host);
getUsedPes().put(vm.getUid(), requiredPes);
getFreePes().set(idx, getFreePes().get(idx) - requiredPes);
getUsedMips().put(vm.getUid(), (long) requiredMips);
getFreeMips().set(idx, (long) (getFreeMips().get(idx) - requiredMips));
getUsedBw().put(vm.getUid(), (long) requiredBw);
getFreeBw().set(idx, (long) (getFreeBw().get(idx) - requiredBw));
break;
}
}
if(!result) {
System.err.println("Cannot assign the VM to any host:"+"/"+numHosts);
}
logMaxNumHostsUsed();
return result;
}
}

View File

@@ -0,0 +1,346 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn.example.policies;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.cloudbus.cloudsim.Host;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.Vm;
import org.cloudbus.cloudsim.VmAllocationPolicy;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.sdn.power.PowerUtilizationMaxHostInterface;
/**
* VM Allocation Policy - BW and Compute combined, MFF.
* When select a host to create a new VM, this policy chooses
* the most full host in terms of both compute power and network bandwidth.
*
* @author Jungmin Son
* @since CloudSimSDN 1.0
*/
public class VmAllocationPolicyCombinedMostFullFirst extends VmAllocationPolicy implements PowerUtilizationMaxHostInterface {
protected final double hostTotalMips;
protected final double hostTotalBw;
protected final int hostTotalPes;
/** The vm table. */
private Map<String, Host> vmTable;
/** The used pes. */
private Map<String, Integer> usedPes;
/** The free pes. */
private List<Integer> freePes;
private Map<String, Long> usedMips;
private List<Long> freeMips;
private Map<String, Long> usedBw;
private List<Long> freeBw;
/**
* Creates the new VmAllocationPolicySimple object.
*
* @param list the list
* @pre $none
* @post $none
*/
public VmAllocationPolicyCombinedMostFullFirst(List<? extends Host> list) {
super(list);
setFreePes(new ArrayList<Integer>());
setFreeMips(new ArrayList<Long>());
setFreeBw(new ArrayList<Long>());
for (Host host : getHostList()) {
getFreePes().add(host.getNumberOfPes());
getFreeMips().add((long)host.getTotalMips());
getFreeBw().add(host.getBw());
}
hostTotalMips = getHostList().get(0).getTotalMips();
hostTotalBw = getHostList().get(0).getBw();
hostTotalPes = getHostList().get(0).getNumberOfPes();
setVmTable(new HashMap<String, Host>());
setUsedPes(new HashMap<String, Integer>());
setUsedMips(new HashMap<String, Long>());
setUsedBw(new HashMap<String, Long>());
}
protected double convertWeightedMetric(double mipsPercent, double bwPercent) {
double ret = mipsPercent * bwPercent;
return ret;
}
/**
* Allocates a host for a given VM.
*
* @param vm VM specification
* @return $true if the host could be allocated; $false otherwise
* @pre $none
* @post $none
*/
@Override
public boolean allocateHostForVm(Vm vm) {
if (getVmTable().containsKey(vm.getUid())) { // if this vm was not created
return false;
}
int numHosts = getHostList().size();
// 1. Find/Order the best host for this VM by comparing a metric
int requiredPes = vm.getNumberOfPes();
double requiredMips = vm.getCurrentRequestedTotalMips();
long requiredBw = vm.getCurrentRequestedBw();
boolean result = false;
double[] freeResources = new double[numHosts];
for (int i = 0; i < numHosts; i++) {
double mipsFreePercent = (double)getFreeMips().get(i) / this.hostTotalMips;
double bwFreePercent = (double)getFreeBw().get(i) / this.hostTotalBw;
freeResources[i] = this.convertWeightedMetric(mipsFreePercent, bwFreePercent);
}
for(int tries = 0; result == false && tries < numHosts; tries++) {// we still trying until we find a host or until we try all of them
double lessFree = Double.POSITIVE_INFINITY;
int idx = -1;
// we want the host with less pes in use
for (int i = 0; i < numHosts; i++) {
if (freeResources[i] < lessFree) {
lessFree = freeResources[i];
idx = i;
}
}
freeResources[idx] = Double.POSITIVE_INFINITY;
Host host = getHostList().get(idx);
// Check whether the host can hold this VM or not.
if( getFreeMips().get(idx) < requiredMips) {
//System.err.println("not enough MIPS");
//Cannot host the VM
continue;
}
if( getFreeBw().get(idx) < requiredBw) {
//System.err.println("not enough BW");
//Cannot host the VM
continue;
}
result = host.vmCreate(vm);
if (result) { // if vm were succesfully created in the host
getVmTable().put(vm.getUid(), host);
getUsedPes().put(vm.getUid(), requiredPes);
getFreePes().set(idx, getFreePes().get(idx) - requiredPes);
getUsedMips().put(vm.getUid(), (long) requiredMips);
getFreeMips().set(idx, (long) (getFreeMips().get(idx) - requiredMips));
getUsedBw().put(vm.getUid(), (long) requiredBw);
getFreeBw().set(idx, (long) (getFreeBw().get(idx) - requiredBw));
break;
}
}
if(!result) {
System.err.println("VmAllocationPolicy: WARNING:: Cannot create VM!!!!");
}
logMaxNumHostsUsed();
return result;
}
protected int maxNumHostsUsed=0;
public void logMaxNumHostsUsed() {
// Get how many are used
int numHostsUsed=0;
for(int freePes:getFreePes()) {
if(freePes < hostTotalPes) {
numHostsUsed++;
}
}
if(maxNumHostsUsed < numHostsUsed)
maxNumHostsUsed = numHostsUsed;
Log.printLine("Number of online hosts:"+numHostsUsed + ", max was ="+maxNumHostsUsed);
}
public int getMaxNumHostsUsed() { return maxNumHostsUsed;}
/**
* Releases the host used by a VM.
*
* @param vm the vm
* @pre $none
* @post none
*/
@Override
public void deallocateHostForVm(Vm vm) {
Host host = getVmTable().remove(vm.getUid());
if (host != null) {
int idx = getHostList().indexOf(host);
host.vmDestroy(vm);
Integer pes = getUsedPes().remove(vm.getUid());
getFreePes().set(idx, getFreePes().get(idx) + pes);
Long mips = getUsedMips().remove(vm.getUid());
getFreeMips().set(idx, getFreeMips().get(idx) + mips);
Long bw = getUsedBw().remove(vm.getUid());
getFreeBw().set(idx, getFreeBw().get(idx) + bw);
}
}
/**
* Gets the host that is executing the given VM belonging to the given user.
*
* @param vm the vm
* @return the Host with the given vmID and userID; $null if not found
* @pre $none
* @post $none
*/
@Override
public Host getHost(Vm vm) {
return getVmTable().get(vm.getUid());
}
/**
* Gets the host that is executing the given VM belonging to the given user.
*
* @param vmId the vm id
* @param userId the user id
* @return the Host with the given vmID and userID; $null if not found
* @pre $none
* @post $none
*/
@Override
public Host getHost(int vmId, int userId) {
return getVmTable().get(Vm.getUid(userId, vmId));
}
/**
* Gets the vm table.
*
* @return the vm table
*/
public Map<String, Host> getVmTable() {
return vmTable;
}
/**
* Sets the vm table.
*
* @param vmTable the vm table
*/
protected void setVmTable(Map<String, Host> vmTable) {
this.vmTable = vmTable;
}
/**
* Gets the used pes.
*
* @return the used pes
*/
protected Map<String, Integer> getUsedPes() {
return usedPes;
}
/**
* Sets the used pes.
*
* @param usedPes the used pes
*/
protected void setUsedPes(Map<String, Integer> usedPes) {
this.usedPes = usedPes;
}
/**
* Gets the free pes.
*
* @return the free pes
*/
protected List<Integer> getFreePes() {
return freePes;
}
/**
* Sets the free pes.
*
* @param freePes the new free pes
*/
protected void setFreePes(List<Integer> freePes) {
this.freePes = freePes;
}
protected Map<String, Long> getUsedMips() {
return usedMips;
}
protected void setUsedMips(Map<String, Long> usedMips) {
this.usedMips = usedMips;
}
protected Map<String, Long> getUsedBw() {
return usedBw;
}
protected void setUsedBw(Map<String, Long> usedBw) {
this.usedBw = usedBw;
}
protected List<Long> getFreeMips() {
return this.freeMips;
}
protected void setFreeMips(List<Long> freeMips) {
this.freeMips = freeMips;
}
protected List<Long> getFreeBw() {
return this.freeBw;
}
protected void setFreeBw(List<Long> freeBw) {
this.freeBw = freeBw;
}
/*
* (non-Javadoc)
* @see cloudsim.VmAllocationPolicy#optimizeAllocation(double, cloudsim.VmList, double)
*/
@Override
public List<Map<String, Object>> optimizeAllocation(List<? extends Vm> vmList) {
// TODO Auto-generated method stub
return null;
}
/*
* (non-Javadoc)
* @see org.cloudbus.cloudsim.VmAllocationPolicy#allocateHostForVm(org.cloudbus.cloudsim.Vm,
* org.cloudbus.cloudsim.Host)
*/
@Override
public boolean allocateHostForVm(Vm vm, Host host) {
if (host.vmCreate(vm)) { // if vm has been succesfully created in the host
getVmTable().put(vm.getUid(), host);
int requiredPes = vm.getNumberOfPes();
int idx = getHostList().indexOf(host);
getUsedPes().put(vm.getUid(), requiredPes);
getFreePes().set(idx, getFreePes().get(idx) - requiredPes);
Log.formatLine(
"%.2f: VM #" + vm.getId() + " has been allocated to the host #" + host.getId(),
CloudSim.clock());
return true;
}
return false;
}
}

View File

@@ -0,0 +1,110 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn.example.policies;
import java.util.List;
import org.cloudbus.cloudsim.Host;
import org.cloudbus.cloudsim.Vm;
/**
* VM Allocation Policy - Only compute power, LFF.
* When select a host to create a new VM, this policy chooses
* the least full host in terms of compute power (MIPS) only.
*
* @author Jungmin Son
* @since CloudSimSDN 1.0
*/
public class VmAllocationPolicyMipsLeastFullFirst extends VmAllocationPolicyCombinedMostFullFirst{
public VmAllocationPolicyMipsLeastFullFirst(List<? extends Host> list) {
super(list);
}
/**
* Allocates a host for a given VM.
*
* @param vm VM specification
* @return $true if the host could be allocated; $false otherwise
* @pre $none
* @post $none
*/
@Override
public boolean allocateHostForVm(Vm vm) {
if (getVmTable().containsKey(vm.getUid())) { // if this vm was not created
return false;
}
int numHosts = getHostList().size();
// 1. Find/Order the best host for this VM by comparing a metric
int requiredPes = vm.getNumberOfPes();
double requiredMips = vm.getCurrentRequestedTotalMips();
long requiredBw = vm.getCurrentRequestedBw();
boolean result = false;
double[] freeResources = new double[numHosts];
for (int i = 0; i < numHosts; i++) {
double mipsFreePercent = (double)getFreeMips().get(i) / hostTotalMips;
//double bwFreePercent = (double)getFreeBw().get(i) / hostTotalBw;
freeResources[i] = mipsFreePercent;
}
for(int tries = 0; tries < numHosts; tries++) {// we still trying until we find a host or until we try all of them
double moreFree = Double.NEGATIVE_INFINITY;
int idx = -1;
// we want the host with less pes in use
for (int i = 0; i < numHosts; i++) {
if (freeResources[i] > moreFree) {
moreFree = freeResources[i];
idx = i;
}
}
if(idx==-1) {
System.err.println("Cannot assign the VM to any host:"+tries+"/"+numHosts);
return false;
}
freeResources[idx] = Double.NEGATIVE_INFINITY;
Host host = getHostList().get(idx);
// Check whether the host can hold this VM or not.
if(getFreeMips().get(idx) < requiredMips ||
getFreeBw().get(idx) < requiredBw ||
getFreePes().get(idx) < requiredPes) {
//Cannot host the VM
continue;
}
result = host.vmCreate(vm);
if (result) { // if vm were succesfully created in the host
getVmTable().put(vm.getUid(), host);
getUsedPes().put(vm.getUid(), requiredPes);
getFreePes().set(idx, getFreePes().get(idx) - requiredPes);
getUsedMips().put(vm.getUid(), (long) requiredMips);
getFreeMips().set(idx, (long) (getFreeMips().get(idx) - requiredMips));
getUsedBw().put(vm.getUid(), (long) requiredBw);
getFreeBw().set(idx, (long) (getFreeBw().get(idx) - requiredBw));
break;
}
}
logMaxNumHostsUsed();
return result;
}
}

View File

@@ -0,0 +1,104 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn.example.policies;
import java.util.List;
import org.cloudbus.cloudsim.Host;
import org.cloudbus.cloudsim.Vm;
/**
* VM Allocation Policy - Only compute power, MFF.
* When select a host to create a new VM, this policy chooses
* the most full host in terms of compute power (MIPS) only.
*
* @author Jungmin Son
* @since CloudSimSDN 1.0
*/
public class VmAllocationPolicyMipsMostFullFirst extends VmAllocationPolicyCombinedMostFullFirst{
public VmAllocationPolicyMipsMostFullFirst(List<? extends Host> list) {
super(list);
}
/**
* Allocates a host for a given VM.
*
* @param vm VM specification
* @return $true if the host could be allocated; $false otherwise
* @pre $none
* @post $none
*/
@Override
public boolean allocateHostForVm(Vm vm) {
if (getVmTable().containsKey(vm.getUid())) { // if this vm was not created
return false;
}
int numHosts = getHostList().size();
// 1. Find/Order the best host for this VM by comparing a metric
int requiredPes = vm.getNumberOfPes();
double requiredMips = vm.getCurrentRequestedTotalMips();
long requiredBw = vm.getCurrentRequestedBw();
boolean result = false;
double[] freeResources = new double[numHosts];
for (int i = 0; i < numHosts; i++) {
double mipsFreePercent = (double)getFreeMips().get(i) / this.hostTotalMips;
freeResources[i] = mipsFreePercent;
}
for(int tries = 0; result == false && tries < numHosts; tries++) {// we still trying until we find a host or until we try all of them
double lessFree = Double.POSITIVE_INFINITY;
int idx = -1;
// we want the host with less pes in use
for (int i = 0; i < numHosts; i++) {
if (freeResources[i] < lessFree) {
lessFree = freeResources[i];
idx = i;
}
}
freeResources[idx] = Double.POSITIVE_INFINITY;
Host host = getHostList().get(idx);
// Check whether the host can hold this VM or not.
if(getFreeMips().get(idx) < requiredMips ||
getFreeBw().get(idx) < requiredBw ||
getFreePes().get(idx) < requiredPes) {
//Cannot host the VM
continue;
}
result = host.vmCreate(vm);
if (result) { // if vm were succesfully created in the host
getVmTable().put(vm.getUid(), host);
getUsedPes().put(vm.getUid(), requiredPes);
getFreePes().set(idx, getFreePes().get(idx) - requiredPes);
getUsedMips().put(vm.getUid(), (long) requiredMips);
getFreeMips().set(idx, (long) (getFreeMips().get(idx) - requiredMips));
getUsedBw().put(vm.getUid(), (long) requiredBw);
getFreeBw().set(idx, (long) (getFreeBw().get(idx) - requiredBw));
break;
}
}
logMaxNumHostsUsed();
return result;
}
}

View File

@@ -0,0 +1,100 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn.example.policies;
import java.util.ArrayList;
import java.util.List;
import org.cloudbus.cloudsim.Pe;
import org.cloudbus.cloudsim.VmSchedulerTimeShared;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.sdn.power.PowerUtilizationHistoryEntry;
import org.cloudbus.cloudsim.sdn.power.PowerUtilizationInterface;
/**
* VmSchedulerTimeSharedEnergy is a VMM allocation policy that allocates one or more Pe to a VM, and
* allows sharing of PEs by time. If there is no free PEs to the VM, allocation fails. Free PEs are
* not allocated to VMs
*
* @author Rodrigo N. Calheiros
* @author Anton Beloglazov
* @author Jungmin Son
* * @since CloudSim Toolkit 1.0
*/
public class VmSchedulerTimeSharedEnergy extends VmSchedulerTimeShared implements PowerUtilizationInterface{
public VmSchedulerTimeSharedEnergy(List<? extends Pe> pelist) {
super(pelist);
}
@Override
protected void setAvailableMips(double availableMips) {
super.setAvailableMips(availableMips);
addUtilizationEntry();
}
private List<PowerUtilizationHistoryEntry> utilizationHistories = null;
private static double powerOffDuration = 0; //if host is idle for 1 hours, it's turned off.
public void addUtilizationEntryTermination(double terminatedTime) {
if(this.utilizationHistories != null)
this.utilizationHistories.add(new PowerUtilizationHistoryEntry(terminatedTime, 0));
}
public List<PowerUtilizationHistoryEntry> getUtilizationHisotry() {
return utilizationHistories;
}
public double getUtilizationEnergyConsumption() {
double total=0;
double lastTime=0;
double lastMips=0;
if(this.utilizationHistories == null)
return 0;
for(PowerUtilizationHistoryEntry h:this.utilizationHistories) {
double duration = h.startTime - lastTime;
double utilPercentage = lastMips/ getTotalMips();
double power = calculatePower(utilPercentage);
double energyConsumption = power * duration;
// Assume that the host is turned off when duration is long enough
if(duration > powerOffDuration && lastMips == 0)
energyConsumption = 0;
total += energyConsumption;
lastTime = h.startTime;
lastMips = h.usedMips;
}
return total/3600; // transform to Whatt*hour from What*seconds
}
private double calculatePower(double u) {
double power = 120 + 154 * u;
return power;
}
private void addUtilizationEntry() {
double time = CloudSim.clock();
double totalMips = getTotalMips();
double usingMips = totalMips - this.getAvailableMips();
if(usingMips < 0) {
System.err.println("addUtilizationEntry : using mips is negative, No way!");
}
if(utilizationHistories == null)
utilizationHistories = new ArrayList<PowerUtilizationHistoryEntry>();
this.utilizationHistories.add(new PowerUtilizationHistoryEntry(time, usingMips));
}
private double getTotalMips() {
return this.getPeList().size() * this.getPeCapacity();
}
}

View File

@@ -0,0 +1,248 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn.example.topogenerators;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
/**
* Generate Physical topology Json file, for example:
{
"nodes" : [
{
"name": "core",
"type" : "core",
"iops" : 1000000000,
"bw" : 1000000000,
},
{
"name": "edge1",
"type" : "edge",
"iops" : 1000000000,
"bw" : 1000000000,
},
{
"name": "host01",
"type" : "host",
"pes" : 1,
"mips" : 30000000,
"ram" : 10240,
"storage" : 10000000,
"bw" : 200000000,
},
{
"name": "host02",
"type" : "host",
"pes" : 1,
"mips" : 30000000,
"ram" : 10240,
"storage" : 10000000,
"bw" : 200000000,
},
],
"links" : [
{ "source" : "core" , "destination" : "edge1" , "latency" : 0.5 },
{ "source" : "edge1" , "destination" : "host01" , "latency" : 0.5 },
{ "source" : "edge1" , "destination" : "host02" , "latency" : 0.5 },
]
}
*
* @author Jungmin Son
* @since CloudSimSDN 1.0
*/
public class PhysicalTopologyGenerator {
public static void main(String [] argv) {
String jsonFileName = "very_simple_physical.json";
int fanout = 2;
double latency = 0.1;
long iops = 1000000000L;
int pe = 8;
long mips = 4000;
int ram = 10240;
long storage = 10000000;
//long bw = 125000000;
long bw = 1000000000;
PhysicalTopologyGenerator reqg = new PhysicalTopologyGenerator();
HostSpec hostSpec = reqg.createHostSpec(pe, mips, ram, storage, bw);
reqg.createTopology(hostSpec, iops, bw, fanout, latency);
reqg.wrtieJSON(jsonFileName);
}
public void createTopology(HostSpec hostSpec, long swIops, long swBw, int fanout, double latency) {
// core, aggregation, edge
// Core switch
SwitchSpec c = addSwitch("c", "core", swBw, swIops);
for(int i=0; i<fanout; i++) {
SwitchSpec e = addSwitch("e"+i, "edge", swBw, swIops);
addLink(c, e, latency);
for(int j=0; j<fanout; j++) {
String hostname = "h_" + i + "_" + j;
HostSpec h = addHost(hostname, hostSpec);
addLink(e, h, latency);
}
}
}
private List<HostSpec> hosts = new ArrayList<HostSpec>();
private List<SwitchSpec> switches = new ArrayList<SwitchSpec>();
private List<LinkSpec> links = new ArrayList<LinkSpec>();
public HostSpec addHost(String name, HostSpec spec) {
HostSpec host = new HostSpec(spec.pe, spec.mips, spec.ram, spec.storage, spec.bw);
host.name = name;
host.type = "host";
hosts.add(host);
return host;
}
public HostSpec addHost(String name, int pes, long mips, int ram, long storage, long bw) {
HostSpec host = new HostSpec(pes, mips, ram, storage, bw);
return addHost(name, host);
}
public SwitchSpec addSwitch(String name, String type, long bw, long iops) {
SwitchSpec sw = new SwitchSpec();
sw.name = name;
sw.type = type; // core, aggregation, edge
sw.bw = bw;
sw.iops = iops;
switches.add(sw);
return sw;
}
private void addLink(NodeSpec source, NodeSpec dest, double latency) {
links.add(new LinkSpec(source.name,dest.name, latency));
}
public HostSpec createHostSpec(int pe, long mips, int ram, long storage, long bw) {
return new HostSpec(pe, mips, ram, storage, bw);
}
class NodeSpec {
String name;
String type;
long bw;
}
class HostSpec extends NodeSpec {
int pe;
long mips;
int ram;
long storage;
@SuppressWarnings("unchecked")
JSONObject toJSON() {
HostSpec o = this;
JSONObject obj = new JSONObject();
obj.put("name", o.name);
obj.put("type", o.type);
obj.put("storage", o.storage);
obj.put("pes", o.pe);
obj.put("mips", o.mips);
obj.put("ram", new Integer(o.ram));
obj.put("bw", o.bw);
return obj;
}
public HostSpec(int pe, long mips, int ram, long storage, long bw) {
this.pe = pe;
this.mips = mips;
this.ram = ram;
this.storage = storage;
this.bw = bw;
this.type = "host";
}
}
class SwitchSpec extends NodeSpec {
long iops;
@SuppressWarnings("unchecked")
JSONObject toJSON() {
SwitchSpec o = this;
JSONObject obj = new JSONObject();
obj.put("name", o.name);
obj.put("type", o.type);
obj.put("iops", o.iops);
obj.put("bw", o.bw);
return obj;
}
}
class LinkSpec {
String source;
String destination;
double latency;
public LinkSpec(String source,String destination,double latency2) {
this.source = source;
this.destination = destination;
this.latency = latency2;
}
@SuppressWarnings("unchecked")
JSONObject toJSON() {
LinkSpec link = this;
JSONObject obj = new JSONObject();
obj.put("source", link.source);
obj.put("destination", link.destination);
obj.put("latency", link.latency);
return obj;
}
}
int vmId = 0;
@SuppressWarnings("unchecked")
public void wrtieJSON(String jsonFileName) {
JSONObject obj = new JSONObject();
JSONArray nodeList = new JSONArray();
JSONArray linkList = new JSONArray();
for(HostSpec o:hosts) {
nodeList.add(o.toJSON());
}
for(SwitchSpec o:switches) {
nodeList.add(o.toJSON());
}
for(LinkSpec link:links) {
linkList.add(link.toJSON());
}
obj.put("nodes", nodeList);
obj.put("links", linkList);
try {
FileWriter file = new FileWriter(jsonFileName);
file.write(obj.toJSONString().replaceAll(",", ",\n"));
file.flush();
file.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(obj);
}
}

View File

@@ -0,0 +1,97 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn.example.topogenerators;
import java.util.Random;
import org.apache.commons.math3.distribution.ExponentialDistribution;
import org.apache.commons.math3.distribution.ParetoDistribution;
import org.apache.commons.math3.random.Well19937c;
/**
* Generate VM requests, for example:
{
"nodes" : [
{
"name" : "vm01",
"type" : "vm",
"size" : 1000,
"pes": 1,
"mips" : 30000000,
"ram" : 512,
"bw" : 100000,
"starttime": 1.3,
"endtime" : 20.5,
},
],
"links" : [
{
"name": "l32",
"source" : "vm03" ,
"destination" : "vm02" ,
"bandwidth" : 66000000
},
],
}
*
* @author Jungmin Son
* @since CloudSimSDN 1.0
*/
public class VMRequestRandomGenerator {
public static void main(String [] argv) {
int numVms = 5;
String jsonFileName = "very_simple_virtual.json";
VirtualTopologyGeneratorVmTypes vmGenerator = new VirtualTopologyGeneratorVmTypes();
VMRequestRandomGenerator reqg = new VMRequestRandomGenerator(vmGenerator, numVms, jsonFileName);
reqg.start();
}
private static long seed = 10;
int numVms = 0;
String jsonFileName = null;
VirtualTopologyGeneratorVmTypes vmGenerator = null;
public VMRequestRandomGenerator(VirtualTopologyGeneratorVmTypes vmGenerator, int numVms, String jsonFileName) {
this.vmGenerator = vmGenerator;
this.numVms = numVms;
this.jsonFileName = jsonFileName;
}
public void start() {
generateVMsRandom(numVms);
vmGenerator.wrtieJSON(jsonFileName);
}
public void generateVMsRandom(int totalVmNum) {
int vmCount = 0;
double lastStartTime = 0;
double startMean = 1800; // sec = 30min
double durScale=14400; // sec = 4 hours
double durShape=1.2;
Random rVmNum = new Random(seed);
ExponentialDistribution rStartTime = new ExponentialDistribution(new Well19937c(seed), startMean, ExponentialDistribution.DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
ParetoDistribution rDuration = new ParetoDistribution(new Well19937c(seed), durScale, durShape);
while(vmCount < totalVmNum) {
int vmsInGroup = rVmNum.nextInt(4)+2;
double duration = Math.floor(rDuration.sample());
vmGenerator.generateVMGroup(vmsInGroup, lastStartTime, lastStartTime+duration, null);
lastStartTime += Math.floor(rStartTime.sample());
vmCount += vmsInGroup;
}
}
}

View File

@@ -0,0 +1,183 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn.example.topogenerators;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
/**
* Generate virtual topology Json file from pre-configured VM type sets.
* VM types are defined in another class - VirtualTopologyGeneratorVmTypes.
*
* @author Jungmin Son
* @since CloudSimSDN 1.0
*/
public class VirtualTopologyGenerator {
private List<VMSpec> vms = new ArrayList<VMSpec>();
private List<LinkSpec> links = new ArrayList<LinkSpec>();
private List<DummyWorkloadSpec> dummyWorkload = new ArrayList<DummyWorkloadSpec>();
public VMSpec addVM(String name, VMSpec spec) {
return addVM(name, spec.pe, spec.mips, spec.ram, spec.size, spec.bw, spec.starttime, spec.endtime);
}
public VMSpec addVM(String name, int pes, long mips, int ram, long storage, long bw, double starttime, double endtime) {
VMSpec vm = new VMSpec(pes, mips, ram, storage, bw, starttime, endtime);
vm.name = name;
vms.add(vm);
return vm;
}
public LinkSpec addLink(String linkname, VMSpec source, VMSpec dest, Long bw) {
LinkSpec link = new LinkSpec(linkname, source.name,dest.name, bw);
links.add(link);
addWorkload(linkname, source, dest);
return link;
}
public void addWorkload(String linkname, VMSpec source, VMSpec dest) {
DummyWorkloadSpec wl = new DummyWorkloadSpec(source.starttime, source.name,dest.name, linkname);
this.dummyWorkload.add(wl);
}
public VMSpec createVmSpec(int pe, long mips, int ram, long storage, long bw, double starttime, double endtime) {
return new VMSpec(pe, mips, ram, storage, bw, starttime, endtime);
}
class VMSpec {
String name;
String type;
long size;
int pe;
long mips;
int ram;
long bw;
double starttime = -1;
double endtime = -1;
public VMSpec(int pe, long mips, int ram, long storage, long bw,double starttime,double endtime) {
this.pe = pe;
this.mips = mips;
this.ram = ram;
this.size = storage;
this.bw = bw;
this.type = "vm";
this.starttime = starttime;
this.endtime = endtime;
}
@SuppressWarnings("unchecked")
JSONObject toJSON() {
VMSpec vm = this;
JSONObject obj = new JSONObject();
obj.put("name", vm.name);
obj.put("type", vm.type);
obj.put("size", vm.size);
obj.put("pes", vm.pe);
obj.put("mips", vm.mips);
obj.put("ram", new Integer(vm.ram));
obj.put("bw", vm.bw);
if(vm.starttime != -1)
obj.put("starttime", vm.starttime);
if(vm.endtime != -1)
obj.put("endtime", vm.endtime);
return obj;
}
}
class DummyWorkloadSpec {
double startTime;
String source;
String linkname;
String destination;
public DummyWorkloadSpec(double startTime, String source,String destination,String linkname) {
this.linkname = linkname;
this.source = source;
this.destination = destination;
this.startTime = startTime;
}
public String toString() {
String st = startTime+ ","+ source + ",0,1,"+linkname+","+destination + ",1000000000000000,1";
return st;
}
}
class LinkSpec {
String name;
String source;
String destination;
Long bw;
public LinkSpec(String name,String source,String destination,Long bw) {
this.name = name;
this.source = source;
this.destination = destination;
this.bw = bw;
}
@SuppressWarnings("unchecked")
JSONObject toJSON() {
LinkSpec link = this;
JSONObject obj = new JSONObject();
obj.put("name", link.name);
obj.put("source", link.source);
obj.put("destination", link.destination);
if(link.bw != null)
obj.put("bandwidth", link.bw);
return obj;
}
}
int vmId = 0;
@SuppressWarnings("unchecked")
public void wrtieJSON(String jsonFileName) {
JSONObject obj = new JSONObject();
JSONArray vmList = new JSONArray();
JSONArray linkList = new JSONArray();
for(VMSpec vm:vms) {
vmList.add(vm.toJSON());
}
for(LinkSpec link:links) {
linkList.add(link.toJSON());
}
obj.put("nodes", vmList);
obj.put("links", linkList);
try {
FileWriter file = new FileWriter(jsonFileName);
file.write(obj.toJSONString().replaceAll(",", ",\n"));
file.flush();
file.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(obj);
System.out.println("===============WORKLOAD=============");
System.out.println("start, source, z, w1, link, dest, psize, w2");
for(DummyWorkloadSpec wl:this.dummyWorkload) {
System.out.println(wl);
}
}
}

View File

@@ -0,0 +1,211 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn.example.topogenerators;
/**
* This class specifies different type of VMs that will be generated from VirtualTopoGenerator.
* Please change the configurations of VMs (MIPs, bandwidth, etc) here.
*
* @author Jungmin Son
* @since CloudSimSDN 1.0
*/
public class VirtualTopologyGeneratorVmTypes extends VirtualTopologyGenerator{
public static void main(String [] argv) {
int numVms = 10;
String jsonFileName = "virtual_ccgrid.json";
VirtualTopologyGeneratorVmTypes vmGenerator = new VirtualTopologyGeneratorVmTypes();
vmGenerator.generate3TierTopology(numVms, jsonFileName);
}
public void generate3TierTopology(int num, String jsonFileName) {
final int TIER = 3;
final Long linkBW = (long) (125000000/3);
for(int i = 0;i < num; i++) {
generateVMGroup(TIER, -1, -1, linkBW); // Priority VMs
}
for(int i = 0;i < num*4; i++) {
generateVMGroup(TIER, -1, -1, null);
}
wrtieJSON(jsonFileName);
}
int vmGroupId = 0;
int vmNum = 0;
enum VMtype {
WebServer,
AppServer,
DBServer,
Proxy,
Firewall
}
public VMSpec createVM(VMtype vmtype, double startTime, double endTime) {
String name = "vm";
int pes = 1;
long vmSize = 1000;
long mips=1000;
int vmRam = 512;
long vmBW=100000000;
switch(vmtype) {
case WebServer:
//m1.large
mips=mips*2;
pes=2;
name="web";
break;
case AppServer:
//m2.xlarge
mips=(long) (mips*1.5);
pes=8;
name="app";
break;
case DBServer:
//c1.xlarge
mips=(long) (mips*2.4);
pes=8;
name="db";
break;
case Proxy:
mips=mips*2;
pes=8;
vmBW=500000000;
name="proxy";
break;
case Firewall:
mips=mips*3;
pes=8;
vmBW=500000000;
name="firewall";
break;
}
name += vmGroupId;
vmNum++;
VMSpec vm = addVM(name, pes, mips, vmRam, vmSize, vmBW, startTime, endTime);
return vm;
}
/*
public VMSpec createVM(VMtype vmtype, double startTime, double endTime) {
String name = "vm";
int pes = 1;
long vmSize = 1000;
long mips=10000000;
int vmRam = 512;
long vmBW=100000;
switch(vmtype) {
case WebServer:
//m1.large
mips=mips*2;
pes=2;
name="web";
break;
case AppServer:
//m2.xlarge
mips=(long) ( *1.5);
pes=8;
name="app";
break;
case DBServer:
//c1.xlarge
mips=(long) (mips*2.4);
pes=8;
name="db";
break;
case Proxy:
mips=mips*2;
pes=8;
vmBW=vmBW*5;
name="proxy";
break;
case Firewall:
mips=mips*3;
pes=8;
vmBW=vmBW*5;
name="firewall";
break;
}
name += vmGroupId;
vmNum++;
VMSpec vm = addVM(name, pes, mips, vmRam, vmSize, vmBW, startTime, endTime);
return vm;
}
*/
private void addLinkAutoName(VMSpec src, VMSpec dest, Long bw) {
String linkName = "default";
addLink(linkName, src, dest, bw);
if(bw != null) {
linkName = src.name + dest.name;
addLink(linkName, src, dest, bw);
}
}
private void addLinkAutoNameBoth(VMSpec vm1, VMSpec vm2, Long linkBw) {
addLinkAutoName(vm1, vm2, linkBw);
addLinkAutoName(vm2, vm1, linkBw);
}
public void generateVMGroup(int numVMsInGroup, double startTime, double endTime, Long linkBw) {
System.out.printf("Generating VM Group(%d): %f - %f\n", numVMsInGroup, startTime, endTime);
switch(numVMsInGroup) {
case 2:
{
VMSpec web = this.createVM(VMtype.WebServer, startTime, endTime);
VMSpec app = this.createVM(VMtype.AppServer, startTime, endTime);
addLinkAutoNameBoth(web, app, linkBw);
break;
}
case 3:
{
VMSpec web = this.createVM(VMtype.WebServer, startTime, endTime);
VMSpec app = this.createVM(VMtype.AppServer, startTime, endTime);
VMSpec db = this.createVM(VMtype.DBServer, startTime, endTime);
addLinkAutoNameBoth(web, app, linkBw);
addLinkAutoNameBoth(app, db, linkBw);
break;
}
case 4:
{
VMSpec web = this.createVM(VMtype.WebServer, startTime, endTime);
VMSpec app = this.createVM(VMtype.AppServer, startTime, endTime);
VMSpec db = this.createVM(VMtype.DBServer, startTime, endTime);
VMSpec proxy = this.createVM(VMtype.Proxy, startTime, endTime);
addLinkAutoNameBoth(web, app, linkBw);
addLinkAutoNameBoth(app, db, linkBw);
addLinkAutoNameBoth(web, proxy, linkBw);
break;
}
case 5:
{
VMSpec web = this.createVM(VMtype.WebServer, startTime, endTime);
VMSpec app = this.createVM(VMtype.AppServer, startTime, endTime);
VMSpec db = this.createVM(VMtype.DBServer, startTime, endTime);
VMSpec proxy = this.createVM(VMtype.Proxy, startTime, endTime);
this.createVM(VMtype.Firewall, startTime, endTime);
addLinkAutoNameBoth(web, app, linkBw);
addLinkAutoNameBoth(app, db, linkBw);
addLinkAutoNameBoth(web, proxy, linkBw);
break;
}
default:
System.err.println("Unknown group number"+numVMsInGroup);
break;
}
vmGroupId ++;
}
}

View File

@@ -0,0 +1,248 @@
package org.cloudbus.cloudsim.sdn.graph.core;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
public class Bridge {
private static Node getNode(Graph graph, String name){
for(Node node : graph.getAdjacencyList().keySet()){
if(node!=null){
if(node.getName().equals(name)){
return node;
}
}
}
return null;
}
// convert from JSON object to Graph object
public static Graph jsonToGraph(String fileName, int type){
Graph graph = new Graph();
// type 0->physical topology 1->virtual topology
if(0 == type){
try {
JSONObject doc = (JSONObject) JSONValue.parse(new FileReader(fileName));
JSONArray nodes = (JSONArray) doc.get("nodes");
@SuppressWarnings("unchecked")
Iterator<JSONObject> iter =nodes.iterator();
while(iter.hasNext()){
JSONObject node = iter.next();
String nodeType = (String) node.get("type");
String nodeName = (String) node.get("name");
if(nodeType.equalsIgnoreCase("host")){ //host
long pes = (Long) node.get("pes");
long mips = (Long) node.get("mips");
int ram = new BigDecimal((Long)node.get("ram")).intValueExact();
long storage = (Long) node.get("storage");
long bw = new BigDecimal((Long)node.get("bw")).intValueExact();
int num = 1;
if (node.get("nums")!= null)
num = new BigDecimal((Long)node.get("nums")).intValueExact();
for(int n = 0; n< num; n++) {
Node hNode = new HostNode(nodeName, nodeType, pes, mips, ram, storage, bw);
graph.addNode(hNode);
}
} else { //switch
int bw = new BigDecimal((Long)node.get("bw")).intValueExact();
long iops = (Long) node.get("iops");
int upports = new BigDecimal((Long)node.get("upports")).intValueExact();
int downports = new BigDecimal((Long)node.get("downports")).intValueExact();
Node sNode = new SwitchNode(nodeName, nodeType, iops, upports, downports, bw);
graph.addNode(sNode);
}
}
JSONArray links = (JSONArray) doc.get("links");
@SuppressWarnings("unchecked")
Iterator<JSONObject> linksIter =links.iterator();
while(linksIter.hasNext()){
JSONObject link = linksIter.next();
String src = (String) link.get("source");
String dst = (String) link.get("destination");
double lat = (Double) link.get("latency");
Node source = (Node) getNode(graph, src);
Node target = (Node) getNode(graph, dst);
if(source!=null && target!=null){
Edge edge = new Edge(target, lat);
graph.addEdge(source, edge);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}else if(1 == type){
try {
JSONObject doc = (JSONObject) JSONValue.parse(new FileReader(fileName));
JSONArray nodes = (JSONArray) doc.get("nodes");
@SuppressWarnings("unchecked")
Iterator<JSONObject> iter = nodes.iterator();
while(iter.hasNext()){
JSONObject node = iter.next();
String nodeType = (String) node.get("type");
String nodeName = (String) node.get("name");
int pes = new BigDecimal((Long)node.get("pes")).intValueExact();
long mips = (Long) node.get("mips");
int ram = new BigDecimal((Long)node.get("ram")).intValueExact();
long size = (Long) node.get("size");
Node vmNode = new VmNode(nodeName, nodeType, size, pes, mips, ram);
graph.addNode(vmNode);
}
JSONArray links = (JSONArray) doc.get("links");
@SuppressWarnings("unchecked")
Iterator<JSONObject> linksIter = links.iterator();
while(linksIter.hasNext()){
JSONObject link = linksIter.next();
String name = (String) link.get("name");
String src = (String) link.get("source");
String dst = (String) link.get("destination");
Object reqBw = link.get("bandwidth");
long bw = 0;
if(reqBw != null)
bw = (Long) reqBw;
Node source = getNode(graph, src);
Node target = getNode(graph, dst);
Edge edge = new Edge(target, name, bw);
graph.addEdge(source, edge);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
return graph;
}
// convert from Graph object to JSON object
@SuppressWarnings("unchecked")
public static String graphToJson(Graph graph){
if(graph.getAdjacencyList().size() < 1){
return "Graph is Empty";
}
Map<Node, List<Node>> edgeList = new HashMap<Node, List<Node>>();
JSONObject topo = new JSONObject();
JSONArray nodes = new JSONArray();
JSONArray links = new JSONArray();
for (Entry<Node, List<Edge>> entry : graph.getAdjacencyList().entrySet()) {
Node srcNode = entry.getKey();
// add node
JSONObject jobj = new JSONObject();
switch(srcNode.getType()){
case "host":
HostNode hNode = (HostNode)srcNode;
jobj.put("name", hNode.getName());
jobj.put("type", hNode.getType());
jobj.put("pes", hNode.getPes());
jobj.put("mips", hNode.getMips());
jobj.put("ram", hNode.getRam());
jobj.put("storage", hNode.getStorage());
jobj.put("bw", hNode.getBw());
break;
case "core":
case "edge":
SwitchNode sNode = (SwitchNode)srcNode;
jobj.put("name", sNode.getName());
jobj.put("type", sNode.getType());
jobj.put("iops", sNode.getIops());
jobj.put("upports", sNode.getDownports());
jobj.put("downports", sNode.getDownports());
jobj.put("bw", sNode.getBw());
break;
case "vm":
VmNode vNode = (VmNode)srcNode;
jobj.put("name", vNode.getName());
jobj.put("type", vNode.getType());
jobj.put("size", vNode.getSize());
jobj.put("pes", vNode.getPes());
jobj.put("mips", vNode.getMips());
jobj.put("ram", vNode.getRam());
break;
}
nodes.add(jobj);
// add edge
for (Edge edge : entry.getValue()) {
Node destNode = edge.getNode();
// check if edge exist (dest->src)
if (edgeList.containsKey(destNode) && edgeList.get(destNode).contains(srcNode)) {
continue;
}
JSONObject jobj2 = new JSONObject();
jobj2.put("source", srcNode.getName());
jobj2.put("destination", destNode.getName());
if("host"==destNode.getType() || "core"==destNode.getType() || "edge"==destNode.getType()){
jobj2.put("latency", edge.getLatency());
}else if("vm"==destNode.getName()){
if(edge.getBandwidth()>0){
jobj2.put("bandwidth", edge.getBandwidth());
}
}
links.add(jobj2);
// add exist edge to the edgeList
if (edgeList.containsKey(entry.getKey())) {
edgeList.get(entry.getKey()).add(edge.getNode());
} else {
List<Node> ns = new ArrayList<Node>();
ns.add(edge.getNode());
edgeList.put(entry.getKey(), ns);
}
}
}
topo.put("nodes", nodes);
topo.put("links", links);
StringWriter out = new StringWriter();
String jsonText = "";
try {
topo.writeJSONString(out);
jsonText = out.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//System.out.println(jsonText);
return jsonText;
}
}

View File

@@ -0,0 +1,36 @@
package org.cloudbus.cloudsim.sdn.graph.core;
public class Coordinates {
private int x;
private int y;
public Coordinates() {
this.x = 0;
this.y = 0;
}
public Coordinates(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
@Override
public String toString() {
return "Coordinates [abscissa=" + x + ", ordinate=" + y + "]";
}
}

View File

@@ -0,0 +1,93 @@
package org.cloudbus.cloudsim.sdn.graph.core;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* The model that represents an edge with two vertexes, for physical link and virtual edge.
*
*/
public class Edge implements Serializable {
private static final long serialVersionUID = -356975278987708987L;
private Node dest = null;
private double latency = 0.0;
private String name = "";
private long bandwidth = 0;
/**
* Constructor.
*
* @param node the node that belongs to the edge.
*/
public Edge(Node to) {
this.dest = to;
}
/** physical topology link */
public Edge(Node to, double latency) {
this.dest = to;
this.latency = latency;
}
/** virtual virtual edge */
public Edge(Node to, String name, long bw) {
this.dest = to;
this.name = name;
this.bandwidth = bw;
}
/** copy edge */
public Edge(Node to, Map<String, Object> info){
this.dest = to;
if(info.get("name")!=null){
this.name = (String) info.get("name");
}
if(info.get("bandwidth")!=null){
this.bandwidth = (long) info.get("bandwidth");
}
if(info.get("latency")!=null){
this.latency = (double) info.get("latency");
}
}
public Node getNode() {
return dest;
}
public long getBandwidth() {
return bandwidth;
}
public double getLatency() {
return latency;
}
public Map<String, Object> getInfo() {
Map<String, Object> info = new HashMap<String, Object>();
info.put("name", this.name);
info.put("bandwidth",this.bandwidth);
info.put("latency", this.latency);
return info;
}
public void setInfo(Map<String, Object> info){
if(info.get("name")!=null){
this.name = (String) info.get("name");
}
if(info.get("bandwidth")!=null){
this.bandwidth = (long) info.get("bandwidth");
}
if(info.get("latency")!=null){
this.latency = (double) info.get("latency");
}
}
@Override
public String toString() {
return "Edge [dest=" + dest + "]";
}
}

View File

@@ -0,0 +1,153 @@
package org.cloudbus.cloudsim.sdn.graph.core;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* A graph model. Normally a model should not have any logic, but in this case we implement logic to manipulate the
* adjacencyList like reorganizing, adding nodes, removing nodes, e.g
*
*/
public class Graph implements Serializable {
private static final long serialVersionUID = 745864022429447529L;
private Map<Node, List<Edge>> adjacencyList;
public Graph() {
// when creating a new graph ensure that a new adjacencyList is created
adjacencyList = new HashMap<Node, List<Edge>>();
}
public Graph(Map<Node, List<Edge>> adjacencyList) {
this.adjacencyList = adjacencyList;
}
public void setAdjacencyList(Map<Node, List<Edge>> adjacencyList) {
this.adjacencyList = adjacencyList;
}
public Map<Node, List<Edge>> getAdjacencyList() {
return adjacencyList;
}
/** Adds a given edge to the adjacency list. If the base node is not yet part of the adjacency list a new entry is added */
public void addEdge(Node key, Edge value) {
if (adjacencyList.containsKey(key)) {
if (adjacencyList.get(key) == null) {
adjacencyList.put(key, new ArrayList<Edge>());
}
// TODO: perhaps check if a value may not be added twice.
// add edge if not null
if (value != null) {
adjacencyList.get(key).add(value);
}
} else {
List<Edge> edges = new ArrayList<Edge>();
// add edge if not null
if (value != null) {
edges.add(value);
}
adjacencyList.put(key, edges);
}
// do bidirectional adding. Ugly duplicated code.
// only execute when there is an edge defined.
if (value != null) {
Edge reverseEdge = new Edge(key, value.getInfo());
if (adjacencyList.containsKey(value.getNode())) {
if (adjacencyList.get(value.getNode()) == null) {
adjacencyList.put(value.getNode(), new ArrayList<Edge>());
}
// TODO: perhaps check if a value may not be added twice.
// add edge if not null
if (reverseEdge != null) {
adjacencyList.get(value.getNode()).add(reverseEdge);
}
} else {
List<Edge> edges = new ArrayList<Edge>();
// add edge if not null
if (reverseEdge != null) {
edges.add(reverseEdge);
}
adjacencyList.put(value.getNode(), edges);
}
}
}
/** Simply adds a new node, without setting any edges */
public void addNode(Node node) {
addEdge(node, null);
}
public void removeEdge(Node key, Edge value) {
if (!adjacencyList.containsKey(key)) {
throw new IllegalArgumentException("The adjacency list does not contain a node for the given key: " + key);
}
List<Edge> edges = adjacencyList.get(key);
if (!edges.contains(value)) {
throw new IllegalArgumentException("The list of edges does not contain the given edge to remove: " + value);
}
edges.remove(value);
// remove bidirectional
List<Edge> reverseEdges = adjacencyList.get(value.getNode());
List<Edge> toRemove = new ArrayList<Edge>();
for (Edge edge : reverseEdges) {
if (edge.getNode().equals(key)) {
toRemove.add(edge);
}
}
//normally only one element
reverseEdges.removeAll(toRemove);
}
/** Deletes a node */
public void removeNode(Node key) {
if (!adjacencyList.containsKey(key)) {
throw new IllegalArgumentException("The adjacency list does not contain a node for the given key: " + key);
}
adjacencyList.remove(key);
// clean up all edges
for (Entry<Node, List<Edge>> entry : adjacencyList.entrySet()) {
List<Edge> toRemove = new ArrayList<Edge>();
for (Edge edge : entry.getValue()) {
if (edge.getNode().equals(key)) {
toRemove.add(edge);
}
}
entry.getValue().removeAll(toRemove);
}
}
public void clearGraph(){
adjacencyList.clear();
}
public String toJsonString(){
String jsonText = Bridge.graphToJson(this);
return jsonText;
}
@Override
public String toString() {
return "Graph [adjacencyList=" + adjacencyList + "]";
}
}

View File

@@ -0,0 +1,222 @@
package org.cloudbus.cloudsim.sdn.graph.core;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import org.cloudbus.cloudsim.sdn.graph.core.Coordinates;
/** Panel that displays a graph */
public class GraphView extends JPanel {
private static final long serialVersionUID = 1L;
private JPanel canvas;
private Graph graph;
private final int ARR_SIZE = 4;
private Image imgDefault;
private Image imgHost;
private Image imgSwitch;
private Image imgVm;
public GraphView(final Graph graph) {
this.graph = graph;
imgHost = Toolkit.getDefaultToolkit().getImage(this.getClass().getResource("/src/host.png"));
imgSwitch = Toolkit.getDefaultToolkit().getImage(this.getClass().getResource("/src/disk.png"));
imgVm = Toolkit.getDefaultToolkit().getImage(this.getClass().getResource("/src/vm2.png"));
initComponents();
}
private void initComponents() {
canvas = new JPanel() {
@Override
public void paint(Graphics g) {
if (graph.getAdjacencyList() == null) {
return;
}
Map<Node, Coordinates> coordForNodes = new HashMap<Node, Coordinates>();
int offsetX = canvas.getWidth() / 2;
int offsetY = canvas.getHeight() / 2;
//System.out.println("sys:"+canvas.getWidth() + ":" + canvas.getHeight());
int height = 40;
int width = 40;
double angle = 2 * Math.PI / graph.getAdjacencyList().keySet().size();
int radius = offsetY / 2 - 20;
FontMetrics f = g.getFontMetrics();
int nodeHeight = Math.max(height, f.getHeight());
int nodeWidth = nodeHeight;
int i = 0;
for (Node node : graph.getAdjacencyList().keySet()) {
// calculate coordinates
int x = Double.valueOf(offsetX + Math.cos(i * angle) * radius).intValue();
int y = Double.valueOf(offsetY + Math.sin(i * angle) * radius).intValue();
//System.out.println(i+":"+x+"-"+y);
coordForNodes.put(node, new Coordinates(x, y));
node.setCoordinate(new Coordinates(x, y));
i++;
}
Map<Node, List<Node>> drawnList = new HashMap<Node, List<Node>>();
// draw edges first
// TODO: we draw one edge two times at the moment because we have an undirected graph. But this
// shouldn`t matter because we have the same edge costs and no one will see in. Perhaps refactor later.
for (Entry<Node, List<Edge>> entry : graph.getAdjacencyList().entrySet()) {
Coordinates startNode = coordForNodes.get(entry.getKey());
for (Edge edge : entry.getValue()) {
// if other direction was drawn already continue
if (drawnList.containsKey(edge.getNode()) && drawnList.get(edge.getNode()).contains(entry.getKey())) {
continue;
}
Coordinates targetNode = coordForNodes.get(edge.getNode());
g.setColor(Color.RED);
g.drawLine(startNode.getX(), startNode.getY(), targetNode.getX(), targetNode.getY());
// add drawn edges to the drawnList
if (drawnList.containsKey(entry.getKey())) {
drawnList.get(entry.getKey()).add(edge.getNode());
} else {
List<Node> nodes = new ArrayList<Node>();
nodes.add(edge.getNode());
drawnList.put(entry.getKey(), nodes);
}
// if (startNode.getX() - targetNode.getX() < 0) {
// int tx = 0;
// int ty = 0;
// double gradient = (targetNode.getY() - startNode.getY()) /
// (targetNode.getX() - startNode.getX());
// LOGGER.log(Level.INFO, "Gradient: " + gradient);
// if (startNode.getX() == targetNode.getX()) {
// tx = targetNode.getX();
// } else {
// if ((startNode.getX() - targetNode.getX()) < 0) {
// tx = targetNode.getX() - Double.valueOf((nodeHeight / 2)).intValue();
// } else {
// tx = targetNode.getX() + Double.valueOf((nodeHeight / 2)).intValue();
// }
// }
// if (startNode.getY() == targetNode.getY()) {
// ty = targetNode.getY();
// } else {
// if ((startNode.getY() - targetNode.getY()) < 0) {
// ty = targetNode.getY() - Double.valueOf((nodeHeight / 2)).intValue();
// } else {
// ty = targetNode.getY() + Double.valueOf((nodeHeight / 2)).intValue();
// }
// }
// drawArrow(g, startNode.getX(), startNode.getY(), tx, ty);
// draw edge costs
int labelX = (startNode.getX() - targetNode.getX()) / 2;
int labelY = (startNode.getY() - targetNode.getY()) / 2;
labelX *= -1;
labelY *= -1;
labelX += startNode.getX();
labelY += startNode.getY();
//g.setColor(Color.BLACK);
//g.drawString(String.valueOf(edge.getInfo()), labelX - f.stringWidth(String.valueOf(edge.getInfo())) / 2, labelY + f.getHeight() / 2);
}
}
for (Entry<Node, Coordinates> entry : coordForNodes.entrySet()) {
// first paint a single node for testing.
g.setColor(Color.black);
// int nodeWidth = Math.max(width, f.stringWidth(entry.getKey().getNodeText()) + width / 2);
Coordinates wrapper = entry.getValue();
switch(entry.getKey().getType()){
case "host":
g.drawImage(imgHost, wrapper.getX() - nodeWidth / 2, wrapper.getY() - nodeHeight / 2, nodeWidth, nodeHeight, this);
break;
case "vm":
g.drawImage(imgVm, wrapper.getX() - nodeWidth / 2, wrapper.getY() - nodeHeight / 2, nodeWidth, nodeHeight, this);
break;
case "core":
case "edge":
g.drawImage(imgSwitch, wrapper.getX() - nodeWidth / 2, wrapper.getY() - nodeHeight / 2, nodeWidth, nodeHeight, this);
break;
}
//g.setColor(Color.white);
//g.fillOval(wrapper.getX() - nodeWidth / 2, wrapper.getY() - nodeHeight / 2, nodeWidth, nodeHeight);
//g.setColor(Color.black);
//g.drawOval(wrapper.getX() - nodeWidth / 2, wrapper.getY() - nodeHeight / 2, nodeWidth, nodeHeight);
//System.out.println((wrapper.getX())+" "+(wrapper.getY()));
//g.drawString(entry.getKey().getName(), wrapper.getX() - f.stringWidth(entry.getKey().getName()) / 2, wrapper.getY() + f.getHeight() / 2);
}
}
};
JScrollPane scrollPane = new JScrollPane(canvas);
// canvas.setBorder(BorderFactory.createLineBorder(Color.GREEN));
// scrollPane.setBorder(BorderFactory.createLineBorder(Color.BLUE));
// scrollPane.setPreferredSize(new Dimension(200, 200));
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(scrollPane);
}
private void drawArrow(Graphics g1, int x1, int y1, int x2, int y2) {
Graphics2D g = (Graphics2D) g1.create();
double dx = x2 - x1, dy = y2 - y1;
double angle = Math.atan2(dy, dx);
int len = (int) Math.sqrt(dx * dx + dy * dy);
AffineTransform at = AffineTransform.getTranslateInstance(x1, y1);
at.concatenate(AffineTransform.getRotateInstance(angle));
g.transform(at);
// Draw horizontal arrow starting in (0, 0)
// g.drawLine(0, 0, len, 0);
g.fillPolygon(new int[] { len, len - ARR_SIZE, len - ARR_SIZE, len }, new int[] { 0, -ARR_SIZE, ARR_SIZE, 0 }, 4);
}
public void setGraph(Graph newGraph){
this.graph = newGraph;
/*this.graph.clearGraph();
for (Entry<Node, List<Edge>> entry : newGraph.getAdjacencyList().entrySet()) {
graph.addNode(entry.getKey());
for (Edge edge : entry.getValue()) {
graph.addEdge(entry.getKey(), edge);
}
}*/
}
}

View File

@@ -0,0 +1,74 @@
package org.cloudbus.cloudsim.sdn.graph.core;
/**
* The model that represents virtual machine node for the graph.
*
*/
public class HostNode extends Node {
private static final long serialVersionUID = -8635044061126993668L;
private long pes;
private long mips;
private int ram;
private long storage;
private long bw;
public HostNode() {
}
public HostNode(String name, String type, long pes, long mips, int ram, long storage, long bw) {
super(name, type);
this.pes = pes;
this.mips = mips;
this.ram = ram;
this.storage = storage;
this.bw = bw;
}
public void setPes(long pes) {
this.pes = pes;
}
public long getPes() {
return pes;
}
public void setMips(long mips) {
this.mips = mips;
}
public long getMips() {
return mips;
}
public void setRam(int ram) {
this.ram = ram;
}
public int getRam() {
return ram;
}
public void setStorage(long storage) {
this.storage = storage;
}
public long getStorage() {
return storage;
}
public void setBw(long bw) {
this.bw = bw;
}
public long getBw() {
return bw;
}
@Override
public String toString() {
return "Node [pes=" + pes + " mips=" + mips + " ram=" + ram + " storage=" + storage + " bw=" + bw + "]";
}
}

View File

@@ -0,0 +1,82 @@
package org.cloudbus.cloudsim.sdn.graph.core;
import java.io.Serializable;
import org.cloudbus.cloudsim.sdn.graph.core.Coordinates;
/**
* The model that represents node (host or vm) for the graph.
*
*/
public class Node implements Serializable {
private static final long serialVersionUID = 823544330517091616L;
private Coordinates coord;
private String name;
private String type;
public Node() {
}
public Node(String name, String type) {
this.name = name;
this.type = type;
coord = new Coordinates();
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setType(String type) {
this.type = type;
}
public String getType() {
return type;
}
public void setCoordinate(Coordinates coord) {
this.coord.setX(coord.getX());
this.coord.setY(coord.getY());
}
public Coordinates getCoordinate() {
return coord;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Node other = (Node) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Node [name=" + name + " type=" + type + "]";
}
}

View File

@@ -0,0 +1,27 @@
package org.cloudbus.cloudsim.sdn.graph.core;
import java.awt.Component;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
/** A cell renderer for the JComboBox when displaying a node object */
@SuppressWarnings("rawtypes")
public class NodeCellRenderer extends JLabel implements ListCellRenderer {
private static final long serialVersionUID = 6021697923766790099L;
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Node node = (Node) value;
JLabel label = new JLabel();
if (node != null && node.getName() != null) {
label.setText(node.getName());
}
return label;
}
}

View File

@@ -0,0 +1,194 @@
package org.cloudbus.cloudsim.sdn.graph.core;
import javax.swing.*;
import javax.swing.SpringLayout;
import java.awt.*;
/**
* A 1.4 file that provides utility methods for
* creating form- or grid-style layouts with SpringLayout.
* These utilities are used by several programs, such as
* SpringBox and SpringCompactGrid.
*/
public class SpringUtilities {
/**
* A debugging utility that prints to stdout the component's
* minimum, preferred, and maximum sizes.
*/
public static void printSizes(Component c) {
System.out.println("minimumSize = " + c.getMinimumSize());
System.out.println("preferredSize = " + c.getPreferredSize());
System.out.println("maximumSize = " + c.getMaximumSize());
}
/**
* Aligns the first <code>rows</code> * <code>cols</code>
* components of <code>parent</code> in
* a grid. Each component is as big as the maximum
* preferred width and height of the components.
* The parent is made just big enough to fit them all.
*
* @param rows number of rows
* @param cols number of columns
* @param initialX x location to start the grid at
* @param initialY y location to start the grid at
* @param xPad x padding between cells
* @param yPad y padding between cells
*/
public static void makeGrid(Container parent,
int rows, int cols,
int initialX, int initialY,
int xPad, int yPad) {
SpringLayout layout;
try {
layout = (SpringLayout)parent.getLayout();
} catch (ClassCastException exc) {
System.err.println("The first argument to makeGrid must use SpringLayout.");
return;
}
Spring xPadSpring = Spring.constant(xPad);
Spring yPadSpring = Spring.constant(yPad);
Spring initialXSpring = Spring.constant(initialX);
Spring initialYSpring = Spring.constant(initialY);
int max = rows * cols;
//Calculate Springs that are the max of the width/height so that all
//cells have the same size.
Spring maxWidthSpring = layout.getConstraints(parent.getComponent(0)).
getWidth();
Spring maxHeightSpring = layout.getConstraints(parent.getComponent(0)).
getHeight();
for (int i = 1; i < max; i++) {
SpringLayout.Constraints cons = layout.getConstraints(
parent.getComponent(i));
maxWidthSpring = Spring.max(maxWidthSpring, cons.getWidth());
maxHeightSpring = Spring.max(maxHeightSpring, cons.getHeight());
}
//Apply the new width/height Spring. This forces all the
//components to have the same size.
for (int i = 0; i < max; i++) {
SpringLayout.Constraints cons = layout.getConstraints(
parent.getComponent(i));
cons.setWidth(maxWidthSpring);
cons.setHeight(maxHeightSpring);
}
//Then adjust the x/y constraints of all the cells so that they
//are aligned in a grid.
SpringLayout.Constraints lastCons = null;
SpringLayout.Constraints lastRowCons = null;
for (int i = 0; i < max; i++) {
SpringLayout.Constraints cons = layout.getConstraints(
parent.getComponent(i));
if (i % cols == 0) { //start of new row
lastRowCons = lastCons;
cons.setX(initialXSpring);
} else { //x position depends on previous component
cons.setX(Spring.sum(lastCons.getConstraint(SpringLayout.EAST),
xPadSpring));
}
if (i / cols == 0) { //first row
cons.setY(initialYSpring);
} else { //y position depends on previous row
cons.setY(Spring.sum(lastRowCons.getConstraint(SpringLayout.SOUTH),
yPadSpring));
}
lastCons = cons;
}
//Set the parent's size.
SpringLayout.Constraints pCons = layout.getConstraints(parent);
pCons.setConstraint(SpringLayout.SOUTH,
Spring.sum(
Spring.constant(yPad),
lastCons.getConstraint(SpringLayout.SOUTH)));
pCons.setConstraint(SpringLayout.EAST,
Spring.sum(
Spring.constant(xPad),
lastCons.getConstraint(SpringLayout.EAST)));
}
/* Used by makeCompactGrid. */
private static SpringLayout.Constraints getConstraintsForCell(
int row, int col,
Container parent,
int cols) {
SpringLayout layout = (SpringLayout) parent.getLayout();
Component c = parent.getComponent(row * cols + col);
return layout.getConstraints(c);
}
/**
* Aligns the first <code>rows</code> * <code>cols</code>
* components of <code>parent</code> in
* a grid. Each component in a column is as wide as the maximum
* preferred width of the components in that column;
* height is similarly determined for each row.
* The parent is made just big enough to fit them all.
*
* @param rows number of rows
* @param cols number of columns
* @param initialX x location to start the grid at
* @param initialY y location to start the grid at
* @param xPad x padding between cells
* @param yPad y padding between cells
*/
public static void makeCompactGrid(Container parent,
int rows, int cols,
int initialX, int initialY,
int xPad, int yPad) {
SpringLayout layout;
try {
layout = (SpringLayout)parent.getLayout();
} catch (ClassCastException exc) {
System.err.println("The first argument to makeCompactGrid must use SpringLayout.");
return;
}
//Align all cells in each column and make them the same width.
Spring x = Spring.constant(initialX);
for (int c = 0; c < cols; c++) {
Spring width = Spring.constant(0);
for (int r = 0; r < rows; r++) {
width = Spring.max(width,
getConstraintsForCell(r, c, parent, cols).
getWidth());
}
for (int r = 0; r < rows; r++) {
SpringLayout.Constraints constraints =
getConstraintsForCell(r, c, parent, cols);
constraints.setX(x);
constraints.setWidth(width);
}
x = Spring.sum(x, Spring.sum(width, Spring.constant(xPad)));
}
//Align all cells in each row and make them the same height.
Spring y = Spring.constant(initialY);
for (int r = 0; r < rows; r++) {
Spring height = Spring.constant(0);
for (int c = 0; c < cols; c++) {
height = Spring.max(height,
getConstraintsForCell(r, c, parent, cols).
getHeight());
}
for (int c = 0; c < cols; c++) {
SpringLayout.Constraints constraints =
getConstraintsForCell(r, c, parent, cols);
constraints.setY(y);
constraints.setHeight(height);
}
y = Spring.sum(y, Spring.sum(height, Spring.constant(yPad)));
}
//Set the parent's size.
SpringLayout.Constraints pCons = layout.getConstraints(parent);
pCons.setConstraint(SpringLayout.SOUTH, y);
pCons.setConstraint(SpringLayout.EAST, x);
}
}

View File

@@ -0,0 +1,62 @@
package org.cloudbus.cloudsim.sdn.graph.core;
/**
* The model that represents virtual machine node for the graph.
*
*/
public class SwitchNode extends Node {
private static final long serialVersionUID = 804858850147477656L;
private long iops;
private int upports;
private int downports;
private long bw;
public SwitchNode() {
}
public SwitchNode(String name, String type, long iops, int upports, int downports, long bw) {
super(name, type);
this.iops = iops;
this.upports = upports;
this.downports = downports;
this.bw = bw;
}
public void setIops(long iops) {
this.iops = iops;
}
public long getIops() {
return iops;
}
public void setUpports(int upports) {
this.upports = upports;
}
public int getUpports() {
return upports;
}
public void setDownports(int downports) {
this.downports = downports;
}
public int getDownports() {
return downports;
}
public void setBw(long bw) {
this.bw = bw;
}
public long getBw() {
return bw;
}
@Override
public String toString() {
return "Node [iops=" + iops + " upports=" + upports + " downports=" + downports + " bw=" + bw + "]";
}
}

View File

@@ -0,0 +1,62 @@
package org.cloudbus.cloudsim.sdn.graph.core;
/**
* The model that represents virtual machine node for the graph.
*
*/
public class VmNode extends Node {
private static final long serialVersionUID = 804858850147477656L;
private long size;
private int pes;
private long mips;
private int ram;
public VmNode() {
}
public VmNode(String name, String type, long size, int pes, long mips, int ram) {
super(name, type);
this.size = size;
this.pes = pes;
this.mips = mips;
this.ram = ram;
}
public void setSize(int size) {
this.size = size;
}
public long getSize() {
return size;
}
public void setPes(int pes) {
this.pes = pes;
}
public int getPes() {
return pes;
}
public void setMips(long mips) {
this.mips = mips;
}
public long getMips() {
return mips;
}
public void setRam(int ram) {
this.ram = ram;
}
public int getRam() {
return ram;
}
@Override
public String toString() {
return "Node [size=" + size + " pes=" + pes + " mips=" + mips + " ram=" + ram + "]";
}
}

View File

@@ -0,0 +1,59 @@
package org.cloudbus.cloudsim.sdn.graph.dialog;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
@SuppressWarnings("serial")
class About extends JDialog {
public About() {
initUI();
}
public final void initUI() {
setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
add(Box.createRigidArea(new Dimension(0, 10)));
ImageIcon icon = new ImageIcon("src/logo.png");
JLabel label = new JLabel(icon);
label.setAlignmentX(0.5f);
add(label);
add(Box.createRigidArea(new Dimension(0, 10)));
JLabel name = new JLabel("CloudSim SDN, 1.00");
name.setFont(new Font("Serif", Font.BOLD, 15));
name.setAlignmentX(0.5f);
add(name);
add(Box.createRigidArea(new Dimension(0, 50)));
JButton close = new JButton("Close");
close.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
dispose();
}
});
close.setAlignmentX(0.5f);
add(close);
setModalityType(ModalityType.APPLICATION_MODAL);
setTitle("About CloudSim");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setLocationRelativeTo(null);
setSize(350, 300);
}
}

View File

@@ -0,0 +1,217 @@
package org.cloudbus.cloudsim.sdn.graph.dialog;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import org.cloudbus.cloudsim.sdn.graph.core.Edge;
import org.cloudbus.cloudsim.sdn.graph.core.Graph;
import org.cloudbus.cloudsim.sdn.graph.core.Node;
import org.cloudbus.cloudsim.sdn.graph.core.NodeCellRenderer;
/** A dialog to add a new edge */
public class AddPhysicalEdge extends JDialog {
private static final long serialVersionUID = 4794808969864918000L;
private final Graph graph;
private JComboBox sourceNode;
private JComboBox targetNode;
private JTextField tfLatency;
public AddPhysicalEdge(final Graph graph, final JFrame frame) {
this.graph = graph;
setLayout(new BorderLayout());
add(createInputPanel(), BorderLayout.CENTER);
add(createButtonPanel(), BorderLayout.PAGE_END);
// show dialog
setTitle("Add Physical Topology edge");
setModal(true);
setPreferredSize(new Dimension(400, 200));
setResizable(false);
pack();
setLocationRelativeTo(frame); // must be called between pack and setVisible to work properly
setVisible(true);
}
@SuppressWarnings("unchecked")
private JPanel createInputPanel() {
Component rigid = Box.createRigidArea(new Dimension(10, 0));
JPanel inputPanelWrapper = new JPanel();
inputPanelWrapper.setLayout(new BoxLayout(inputPanelWrapper, BoxLayout.PAGE_AXIS));
JPanel inputPanel = new JPanel();
inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.LINE_AXIS));
JPanel textAreaPanel = new JPanel();
textAreaPanel.setLayout(new BoxLayout(textAreaPanel, BoxLayout.LINE_AXIS));
ComboBoxModel sourceNodeModel = new DefaultComboBoxModel(graph.getAdjacencyList().keySet().toArray());
sourceNodeModel.setSelectedItem(null);
sourceNode = new JComboBox(sourceNodeModel);
targetNode = new JComboBox();
sourceNode.setMaximumSize(sourceNode.getPreferredSize());
sourceNode.setMinimumSize(new Dimension(150, sourceNode.getPreferredSize().height));
sourceNode.setPreferredSize(new Dimension(150, sourceNode.getPreferredSize().height));
targetNode.setMaximumSize(targetNode.getPreferredSize());
targetNode.setMinimumSize(new Dimension(150, targetNode.getPreferredSize().height));
targetNode.setPreferredSize(new Dimension(150, targetNode.getPreferredSize().height));
NodeCellRenderer renderer = new NodeCellRenderer();
sourceNode.setRenderer(renderer);
targetNode.setRenderer(renderer);
sourceNode.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
// only display nodes which do not have already an edge
targetNode.removeAllItems();
Node selectedNode = (Node) sourceNode.getSelectedItem();
if (selectedNode != null) {
List<Node> nodesToDisplay = new ArrayList<Node>();
Set<Node> allNodes = graph.getAdjacencyList().keySet();
// get edged for selected node and throw out all target nodes where already an edge exists
List<Edge> edgesForSelectedNode = graph.getAdjacencyList().get(selectedNode);
Set<Node> nodesInEdges = new HashSet<Node>();
for (Edge edge : edgesForSelectedNode) {
nodesInEdges.add(edge.getNode());
}
for (Node node : allNodes) {
if (!node.equals(selectedNode) && !nodesInEdges.contains(node)) {
nodesToDisplay.add(node);
}
}
ComboBoxModel targetNodeModel = new DefaultComboBoxModel(nodesToDisplay.toArray());
targetNode.setModel(targetNodeModel);
}
}
});
inputPanel.add(sourceNode);
inputPanel.add(new Label(" ¡ª"));
inputPanel.add(targetNode);
inputPanel.add(Box.createHorizontalGlue());
inputPanelWrapper.add(inputPanel);
textAreaPanel.add(Box.createRigidArea(new Dimension(10, 0)));
textAreaPanel.add(new JLabel("Latency: "));
tfLatency = new JTextField();
tfLatency.setMaximumSize(tfLatency.getPreferredSize());
tfLatency.setMinimumSize(new Dimension(150, tfLatency.getPreferredSize().height));
tfLatency.setPreferredSize(new Dimension(150, tfLatency.getPreferredSize().height));
textAreaPanel.add(tfLatency);
textAreaPanel.add(Box.createHorizontalGlue());
inputPanelWrapper.add(textAreaPanel);
inputPanelWrapper.add(Box.createVerticalGlue());
inputPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
return inputPanelWrapper;
}
private JPanel createButtonPanel() {
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
JButton okBtn = new JButton("Ok");
JButton cancelBtn = new JButton("Cancel");
cancelBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
}
});
okBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
double latency = 0;
boolean catchedError = false;
if (tfLatency.getText() == null || tfLatency.getText().isEmpty()) {
catchedError = true;
prompt("Please type latency", "Error");
}else {
try {
latency = Double.valueOf(tfLatency.getText());
} catch (NumberFormatException e1) {
catchedError = true;
prompt("Latency should be double type", "Error");
}
}
if (!catchedError) {
if (sourceNode.getSelectedItem() == null || targetNode.getSelectedItem() == null) {
prompt("Please select node", "Error");
} else {
Node source = (Node) sourceNode.getSelectedItem();
Node target = (Node) targetNode.getSelectedItem();
Edge edge = new Edge(target, latency);
graph.addEdge(source, edge);
setVisible(false);
}
}
}
});
buttonPanel.add(Box.createHorizontalGlue());
buttonPanel.add(okBtn);
buttonPanel.add(Box.createRigidArea(new Dimension(10, 0)));
buttonPanel.add(cancelBtn);
buttonPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
return buttonPanel;
}
private void prompt(String msg, String type){
JOptionPane.showMessageDialog(AddPhysicalEdge.this, msg, type, JOptionPane.ERROR_MESSAGE);
}
}

View File

@@ -0,0 +1,290 @@
package org.cloudbus.cloudsim.sdn.graph.dialog;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SpringLayout;
import javax.swing.UIManager;
import org.cloudbus.cloudsim.sdn.graph.core.Graph;
import org.cloudbus.cloudsim.sdn.graph.core.Node;
import org.cloudbus.cloudsim.sdn.graph.core.SpringUtilities;
import org.cloudbus.cloudsim.sdn.graph.core.SwitchNode;
import org.cloudbus.cloudsim.sdn.graph.core.HostNode;
@SuppressWarnings({ "rawtypes", "unchecked" })
public class AddPhysicalNode extends JDialog {
private static final long serialVersionUID = -5116677861770319577L;
private final Graph graph;
private JLabel lName;
private JLabel lType;
private JLabel lBw;
private JLabel lop1;
private JLabel lop2;
private JLabel lop3;
private JLabel lop4;
private JTextField tfName;
private JComboBox cType;
private JTextField tfBw;
private JTextField top1;
private JTextField top2;
private JTextField top3;
private JTextField top4;
public AddPhysicalNode(final Graph graph, final JFrame frame) {
this.graph = graph;
setLayout(new BorderLayout());
add(createInputPanelArea(), BorderLayout.CENTER);
add(createButtonPanel(), BorderLayout.PAGE_END);
// show dialog
setTitle("Add Physical Node");
setModal(true);
setPreferredSize(new Dimension(350, 380));
setResizable(false);
pack();
setLocationRelativeTo(frame);
setVisible(true);
}
private JPanel createButtonPanel() {
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
JButton okBtn = new JButton("Ok");
JButton cancelBtn = new JButton("Cancel");
cancelBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
setVisible(false);
}
});
okBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
boolean catchedError = false;
if (tfName.getText() == null || tfName.getText().length() < 1) {
prompt("Please type VM name", "Error");
} else if (tfBw.getText() == null || tfBw.getText().length() < 1) {
prompt("Please type VM Bw", "Error");
} else if(cType.getSelectedIndex() < 0) {
prompt("Please type VM Type", "Error");
}else{
String type = (String)cType.getSelectedItem();
if("host"==getType(type)){
if (top1.getText() == null || top1.getText().length() < 1) {
prompt("Please type pes", "Error");
} else if (top2.getText() == null || top2.getText().length() < 1) {
prompt("Please type VM mips", "Error");
} else if (top3.getText() == null || top3.getText().length() < 1) {
prompt("Please type VM RAM", "Error");
} else if (top4.getText() == null || top4.getText().length() < 1) {
prompt("Please type VM Storage", "Error");
} else {
long t1 = 0;
long t2 = 0;
int t3 = 0;
long t4 = 0;
long t5 = 0;
try {
t1 = Long.parseLong(top1.getText());
t2 = Long.parseLong(top2.getText());
t3 = Integer.parseInt(top3.getText());
t4 = Long.parseLong(top4.getText());
t5 = Long.parseLong(tfBw.getText());
catchedError = false;
} catch (NumberFormatException e1) {
catchedError = true;
prompt("Input should be numerical character", "Error");
}
if(!catchedError){
Node node = new HostNode(tfName.getText().toString(), type, t1, t2, t3, t4, t5);
graph.addNode(node);
setVisible(false);
}
}
}else if("switch"==getType(type)){
if (top1.getText() == null || top1.getText().length() < 1) {
prompt("Please type Iops", "Error");
} else if (top2.getText() == null || top2.getText().length() < 1) {
prompt("Please type upports", "Error");
} else if (top3.getText() == null || top3.getText().length() < 1) {
prompt("Please type VM downports", "Error");
} else {
long t1 = 0;
int t2 = 0;
int t3 = 0;
long t4 = 0;
try {
t1 = Long.parseLong(top1.getText());
t2 = Integer.parseInt(top2.getText());
t3 = Integer.parseInt(top3.getText());
t4 = Long.parseLong(tfBw.getText());
catchedError = false;
} catch (NumberFormatException e1) {
catchedError = true;
prompt("Input should be numerical character", "Error");
}
if(!catchedError){
Node node = new SwitchNode(tfName.getText().toString(), type, t1, t2, t3, t4);
graph.addNode(node);
setVisible(false);
}
}
}
}
}
});
buttonPanel.add(Box.createHorizontalGlue());
buttonPanel.add(okBtn);
buttonPanel.add(Box.createRigidArea(new Dimension(10, 0)));
buttonPanel.add(cancelBtn);
buttonPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
return buttonPanel;
}
private void updatePanel(String type){
switch(type){
case "core":
case "edge":
lop1.setText("Iops: ");
lop2.setText("Upports: ");
lop3.setText("Downports: ");
lop4.setVisible(false);
top1.setText("");
top2.setText("");
top3.setText("");
top4.setVisible(false);
break;
case "host":
lop1.setText("Pes: ");
lop2.setText("Mips: ");
lop3.setText("Ram: ");
lop4.setVisible(true);
lop4.setText("Storage: ");
top1.setText("");
top2.setText("");
top3.setText("");
top4.setVisible(true);
top4.setText("");
break;
}
}
private String getType(String type){
if("core"==type || "edge"==type){
return "switch";
} else if("host"==type){
return "host";
}
return "";
}
private JPanel createInputPanelArea() {
String[] vmType = {"core","edge","host"};
//Create and populate the panel.
JPanel springPanel = new JPanel(new SpringLayout());
springPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
lName = new JLabel("Name: ");
springPanel.add(lName);
tfName = new JTextField();
lName.setLabelFor(tfName);
springPanel.add(tfName);
lType = new JLabel("Type: "); //, JLabel.TRAILING);
springPanel.add(lType);
cType = new JComboBox(vmType);
lType.setLabelFor(cType);
cType.setSelectedIndex(0);
cType.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
JComboBox ctype = (JComboBox)e.getSource();
String item = (String)ctype.getSelectedItem();
updatePanel(item);
}
});
springPanel.add(cType);
lBw = new JLabel("Bw: ");
springPanel.add(lBw);
tfBw = new JTextField();
lBw.setLabelFor(tfBw);
springPanel.add(tfBw);
/** switch and host */
lop1 = new JLabel("Pes: ");
springPanel.add(lop1);
top1 = new JTextField();
lop1.setLabelFor(top1);
springPanel.add(top1);
lop2 = new JLabel("Mips: ");
springPanel.add(lop2);
top2 = new JTextField();
lop2.setLabelFor(top2);
springPanel.add(top2);
lop3 = new JLabel("Ram: ");
springPanel.add(lop3);
top3 = new JTextField();
lop3.setLabelFor(top3);
springPanel.add(top3);
lop4 = new JLabel("Storage: ");
springPanel.add(lop4);
top4 = new JTextField();
lop4.setLabelFor(top4);
springPanel.add(top4);
//Lay out the panel.
SpringUtilities.makeCompactGrid(springPanel,
7, 2, //rows, cols
6, 6, //initX, initY
6, 6); //xPad, yPad
updatePanel("core");
return springPanel;
}
public static void setUIFont (javax.swing.plaf.FontUIResource f){
java.util.Enumeration keys = UIManager.getDefaults().keys();
while (keys.hasMoreElements()) {
Object key = keys.nextElement();
Object value = UIManager.get (key);
if (value != null && value instanceof javax.swing.plaf.FontUIResource)
UIManager.put (key, f);
}
}
private void prompt(String msg, String type){
JOptionPane.showMessageDialog(AddPhysicalNode.this, msg, type, JOptionPane.ERROR_MESSAGE);
}
}

View File

@@ -0,0 +1,239 @@
package org.cloudbus.cloudsim.sdn.graph.dialog;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import org.cloudbus.cloudsim.sdn.graph.core.Edge;
import org.cloudbus.cloudsim.sdn.graph.core.Graph;
import org.cloudbus.cloudsim.sdn.graph.core.Node;
import org.cloudbus.cloudsim.sdn.graph.core.NodeCellRenderer;
/** A dialog to add a new edge */
public class AddVirtualEdge extends JDialog {
private static final long serialVersionUID = 4794808969864918000L;
private final Graph graph;
private JComboBox sourceNode;
private JComboBox targetNode;
private JTextField tfName;
private JTextField tfBandwidth;
public AddVirtualEdge(final Graph graph, final JFrame frame) {
this.graph = graph;
setLayout(new BorderLayout());
add(createInputPanel(), BorderLayout.CENTER);
add(createButtonPanel(), BorderLayout.PAGE_END);
// show dialog
setTitle("Add Virtual Topology edge");
setModal(true);
setPreferredSize(new Dimension(400, 250));
setResizable(false);
pack();
setLocationRelativeTo(frame); // must be called between pack and setVisible to work properly
setVisible(true);
}
@SuppressWarnings("unchecked")
private JPanel createInputPanel() {
Component rigid = Box.createRigidArea(new Dimension(10, 0));
JPanel inputPanelWrapper = new JPanel();
inputPanelWrapper.setLayout(new BoxLayout(inputPanelWrapper, BoxLayout.PAGE_AXIS));
JPanel inputPanel = new JPanel();
inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.LINE_AXIS));
JPanel textAreaPanel = new JPanel();
textAreaPanel.setLayout(new BoxLayout(textAreaPanel, BoxLayout.LINE_AXIS));
JPanel textAreaPanel2 = new JPanel();
textAreaPanel2.setLayout(new BoxLayout(textAreaPanel2, BoxLayout.LINE_AXIS));
ComboBoxModel sourceNodeModel = new DefaultComboBoxModel(graph.getAdjacencyList().keySet().toArray());
sourceNodeModel.setSelectedItem(null);
sourceNode = new JComboBox(sourceNodeModel);
targetNode = new JComboBox();
sourceNode.setMaximumSize(sourceNode.getPreferredSize());
sourceNode.setMinimumSize(new Dimension(150, sourceNode.getPreferredSize().height));
sourceNode.setPreferredSize(new Dimension(150, sourceNode.getPreferredSize().height));
targetNode.setMaximumSize(targetNode.getPreferredSize());
targetNode.setMinimumSize(new Dimension(150, targetNode.getPreferredSize().height));
targetNode.setPreferredSize(new Dimension(150, targetNode.getPreferredSize().height));
NodeCellRenderer renderer = new NodeCellRenderer();
sourceNode.setRenderer(renderer);
targetNode.setRenderer(renderer);
sourceNode.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
// only display nodes which do not have already an edge
targetNode.removeAllItems();
Node selectedNode = (Node) sourceNode.getSelectedItem();
if (selectedNode != null) {
List<Node> nodesToDisplay = new ArrayList<Node>();
Set<Node> allNodes = graph.getAdjacencyList().keySet();
// get edged for selected node and throw out all target nodes where already an edge exists
List<Edge> edgesForSelectedNode = graph.getAdjacencyList().get(selectedNode);
Set<Node> nodesInEdges = new HashSet<Node>();
for (Edge edge : edgesForSelectedNode) {
nodesInEdges.add(edge.getNode());
}
for (Node node : allNodes) {
if (!node.equals(selectedNode) && !nodesInEdges.contains(node)) {
nodesToDisplay.add(node);
}
}
ComboBoxModel targetNodeModel = new DefaultComboBoxModel(nodesToDisplay.toArray());
targetNode.setModel(targetNodeModel);
}
}
});
inputPanel.add(sourceNode);
// inputPanel.add(Box.createRigidArea(new Dimension(10, 0)));
inputPanel.add(new Label(" ¡ª"));
inputPanel.add(targetNode);
inputPanel.add(Box.createHorizontalGlue());
inputPanelWrapper.add(inputPanel);
textAreaPanel.add(Box.createRigidArea(new Dimension(10, 0)));
textAreaPanel.add(new JLabel("Edge Name: "));
tfName = new JTextField();
tfName.setMaximumSize(tfName.getPreferredSize());
tfName.setMinimumSize(new Dimension(180, tfName.getPreferredSize().height));
tfName.setPreferredSize(new Dimension(180, tfName.getPreferredSize().height));
textAreaPanel.add(tfName);
textAreaPanel.add(Box.createHorizontalGlue());
inputPanelWrapper.add(textAreaPanel);
inputPanelWrapper.add(Box.createVerticalGlue());
textAreaPanel2.add(Box.createRigidArea(new Dimension(10, 0)));
textAreaPanel2.add(new JLabel("Bandwidth: "));
tfBandwidth = new JTextField();
tfBandwidth.setMaximumSize(tfBandwidth.getPreferredSize());
tfBandwidth.setMinimumSize(new Dimension(180, tfBandwidth.getPreferredSize().height));
tfBandwidth.setPreferredSize(new Dimension(180, tfBandwidth.getPreferredSize().height));
textAreaPanel2.add(tfBandwidth);
textAreaPanel2.add(Box.createHorizontalGlue());
inputPanelWrapper.add(textAreaPanel2);
inputPanelWrapper.add(Box.createVerticalGlue());
inputPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
return inputPanelWrapper;
}
private JPanel createButtonPanel() {
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
JButton okBtn = new JButton("Ok");
JButton cancelBtn = new JButton("Cancel");
cancelBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
}
});
okBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String name = "default";
long bandwidth = 0;
boolean catchedError = false;
if (tfName.getText() == null || tfName.getText().isEmpty()) {
catchedError = true;
prompt("Please type Edge Name", "Error");
}else {
name = (String)tfName.getText();
}
if (tfBandwidth.getText() == null || tfBandwidth.getText().isEmpty()) {
catchedError = true;
prompt("Please type Bandwidth", "Error");
}else {
try {
bandwidth = Long.valueOf(tfBandwidth.getText());
} catch (NumberFormatException e1) {
catchedError = true;
prompt("Bandwidth should be long type", "Error");
}
}
if (!catchedError) {
if (sourceNode.getSelectedItem() == null || targetNode.getSelectedItem() == null) {
prompt("Please select node", "Error");
} else {
Node source = (Node) sourceNode.getSelectedItem();
Node target = (Node) targetNode.getSelectedItem();
Edge edge = new Edge(target, name, bandwidth);
graph.addEdge(source, edge);
setVisible(false);
}
}
}
});
buttonPanel.add(Box.createHorizontalGlue());
buttonPanel.add(okBtn);
buttonPanel.add(Box.createRigidArea(new Dimension(10, 0)));
buttonPanel.add(cancelBtn);
buttonPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
return buttonPanel;
}
private void prompt(String msg, String type){
JOptionPane.showMessageDialog(AddVirtualEdge.this, msg, type, JOptionPane.ERROR_MESSAGE);
}
}

View File

@@ -0,0 +1,198 @@
package org.cloudbus.cloudsim.sdn.graph.dialog;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SpringLayout;
import javax.swing.UIManager;
import org.cloudbus.cloudsim.sdn.graph.core.Graph;
import org.cloudbus.cloudsim.sdn.graph.core.SpringUtilities;
import org.cloudbus.cloudsim.sdn.graph.core.VmNode;
import org.cloudbus.cloudsim.sdn.graph.core.Node;
@SuppressWarnings({ "rawtypes", "unchecked" })
public class AddVirtualNode extends JDialog {
private static final long serialVersionUID = -5116677861770319577L;
private final Graph graph;
private JTextField tfName;
private JComboBox cType;
private JTextField tfSize;
private JTextField tfPes;
private JTextField tfMips;
private JTextField tfRam;
/**
* Constructor.
*
* @param frame the parent frame
*/
public AddVirtualNode(final Graph graph, final JFrame frame) {
this.graph = graph;
setLayout(new BorderLayout());
add(createInputPanelArea(), BorderLayout.CENTER);
add(createButtonPanel(), BorderLayout.PAGE_END);
// show dialog
setTitle("Add Virtual Node");
setModal(true);
setPreferredSize(new Dimension(350, 400));
setResizable(false);
pack();
setLocationRelativeTo(frame);
setVisible(true);
}
private JPanel createButtonPanel() {
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
JButton okBtn = new JButton("Ok");
JButton cancelBtn = new JButton("Cancel");
cancelBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
setVisible(false);
}
});
okBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
boolean catchedError = false;
if (tfName.getText() == null || tfName.getText().length() < 1) {
prompt("Please type VM name", "Error");
} else if (cType.getSelectedIndex() < 0) {
prompt("Please select VM type", "Error");
} else if (tfSize.getText() == null || tfSize.getText().length() < 1) {
prompt("Please type VM size", "Error");
} else if (tfPes.getText() == null || tfPes.getText().length() < 1) {
prompt("Please type pes", "Error");
} else if (tfMips.getText() == null || tfMips.getText().length() < 1) {
prompt("Please type VM mips", "Error");
} else if (tfRam.getText() == null || tfRam.getText().length() < 1) {
prompt("Please type VM RAM", "Error");
} else {
long t1 = 0;
int t2 = 0;
long t3 = 0;
int t4 = 0;
try {
t1 = Long.parseLong(tfSize.getText());
t2 = Integer.parseInt(tfPes.getText());
t3 = Long.parseLong(tfMips.getText());
t4 = Integer.parseInt(tfRam.getText());
} catch (NumberFormatException e1) {
catchedError = true;
prompt("Input should be numerical character", "Error");
}
if(!catchedError){
Node node = new VmNode(tfName.getText().toString(), (String)cType.getSelectedItem(),
t1, t2, t3, t4);
graph.addNode(node);
setVisible(false);
}
}
}
});
buttonPanel.add(Box.createHorizontalGlue());
buttonPanel.add(okBtn);
buttonPanel.add(Box.createRigidArea(new Dimension(10, 0)));
buttonPanel.add(cancelBtn);
buttonPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
return buttonPanel;
}
private JPanel createInputPanelArea() {
String[] vmType = {"vm"};
//Create and populate the panel.
JPanel springPanel = new JPanel(new SpringLayout());
springPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
JLabel lName = new JLabel("Name: ");
springPanel.add(lName);
tfName = new JTextField();
lName.setLabelFor(tfName);
springPanel.add(tfName);
JLabel lType = new JLabel("Type: ", JLabel.TRAILING);
springPanel.add(lType);
cType = new JComboBox(vmType);
lType.setLabelFor(cType);
cType.setSelectedIndex(-1);
cType.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
}
});
springPanel.add(cType);
JLabel lSize = new JLabel("Size: ");
springPanel.add(lSize);
tfSize = new JTextField();
lSize.setLabelFor(tfSize);
springPanel.add(tfSize);
JLabel lPes = new JLabel("Pes: ");
springPanel.add(lPes);
tfPes = new JTextField();
lPes.setLabelFor(tfPes);
springPanel.add(tfPes);
JLabel lMips = new JLabel("Mips: ");
springPanel.add(lMips);
tfMips = new JTextField();
lMips.setLabelFor(tfMips);
springPanel.add(tfMips);
JLabel lRam = new JLabel("Ram: ");
springPanel.add(lRam);
tfRam = new JTextField();
lRam.setLabelFor(tfRam);
springPanel.add(tfRam);
//Lay out the panel.
SpringUtilities.makeCompactGrid(springPanel,
6, 2, //rows, columns
6, 6, //initX, initY
6, 6); //xPad, yPad
return springPanel;
}
public static void setUIFont (javax.swing.plaf.FontUIResource f){
java.util.Enumeration keys = UIManager.getDefaults().keys();
while (keys.hasMoreElements()) {
Object key = keys.nextElement();
Object value = UIManager.get (key);
if (value != null && value instanceof javax.swing.plaf.FontUIResource)
UIManager.put (key, f);
}
}
private void prompt(String msg, String type){
JOptionPane.showMessageDialog(AddVirtualNode.this, msg, type, JOptionPane.ERROR_MESSAGE);
}
}

View File

@@ -0,0 +1,174 @@
package org.cloudbus.cloudsim.sdn.graph.dialog;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.concurrent.ExecutionException;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import javax.swing.Timer;
import org.cloudbus.cloudsim.sdn.graph.example.GraphicSDNExample;
public class SDNRun extends JDialog {
private static final long serialVersionUID = -8313194085507492462L;
private String physicalTopologyFile = ""; //physical
private String deploymentFile = ""; //virtual
private String workloads_background = ""; //workload
private String workloads = ""; //workload
private JPanel panel;
private JScrollPane pane;
private JTextArea outputArea;
private JLabel imageLabel;
private JLabel msgLabel;
private JComponent space;
private int counter = 0;
private Timer timer;
private GraphicSDNExample sdn;
public SDNRun(final String phy, final String vir, final String wlbk, final String wl, final JFrame frame){
physicalTopologyFile = phy;
deploymentFile = vir;
workloads_background = wlbk;
workloads = wl;
setLayout(new BorderLayout());
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
initUI();
run();
add(panel, BorderLayout.CENTER);
setDefaultCloseOperation(DISPOSE_ON_CLOSE );
setTitle("Run Simulation");
setModal(true);
setPreferredSize(new Dimension(900, 600));
setResizable(false);
pack();
setLocationRelativeTo(frame); // must be called between pack and setVisible to work properly
setVisible(true);
}
private void initUI(){
ImageIcon ii = new ImageIcon(this.getClass().getResource("/src/1.gif"));
imageLabel = new JLabel(ii);
imageLabel.setAlignmentX(CENTER_ALIGNMENT);
msgLabel = new JLabel("Simulation is executing");
msgLabel.setAlignmentX(CENTER_ALIGNMENT);
space = (JComponent)Box.createRigidArea(new Dimension(0, 200));
panel.add(space);
panel.add(msgLabel);
panel.add(imageLabel);
pane = new JScrollPane();
outputArea = new JTextArea();
outputArea.setLineWrap(true);
outputArea.setWrapStyleWord(true);
outputArea.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
outputArea.setEditable(false);
//outputArea.setText("wo ai bei jin tian an men");
//readFile(physicalTopologyFile, outputArea);
pane.getViewport().add(outputArea);
panel.add(pane);
pane.setVisible(false);
}
private void run(){
sdn = new GraphicSDNExample(physicalTopologyFile, deploymentFile, workloads_background, workloads, outputArea);
SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
protected Boolean doInBackground() throws Exception {
boolean success = false;
success = sdn.simulate();
if(success){
sdn.output();
append("<<<<<<<<<< Simulation completed >>>>>>>>>");
}else{
append("<<<<<<<<<< Running Error >>>>>>>>>>");
}
return success;
}
protected void done() {
boolean status;
try {
status = get();
panel.remove(space);
panel.remove(imageLabel);
panel.remove(msgLabel);
pane.setVisible(true);
panel.revalidate();
panel.repaint();
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}
}
};
worker.execute();
}
private void append(String content){
outputArea.append(content+"\n");
}
/** below only used for testing reading file to textarea */
private void startTest(){
ActionListener updateProBar = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
if(counter>=100){
timer.stop();
panel.remove(space);
panel.remove(imageLabel);
panel.remove(msgLabel);
pane.setVisible(true);
panel.revalidate();
panel.repaint();
}else{
counter +=2;
}
}
};
timer = new Timer(50, updateProBar);
timer.start();
}
private void readFile(String path, JTextArea area) {
try{
FileReader reader = new FileReader(path);
BufferedReader br = new BufferedReader(reader);
area.read( br, null );
br.close();
area.requestFocus();
}catch(Exception e2) {
System.out.println(e2);
}
}
}

View File

@@ -0,0 +1,632 @@
package org.cloudbus.cloudsim.sdn.graph.example;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map.Entry;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JSeparator;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.cloudbus.cloudsim.sdn.graph.core.Bridge;
import org.cloudbus.cloudsim.sdn.graph.core.Edge;
import org.cloudbus.cloudsim.sdn.graph.core.Graph;
import org.cloudbus.cloudsim.sdn.graph.core.GraphView;
import org.cloudbus.cloudsim.sdn.graph.core.Node;
import org.cloudbus.cloudsim.sdn.graph.dialog.*;
public class GraphicSDN extends JFrame {
private static final long serialVersionUID = -2238414769964738933L;
private JPanel contentPane;
/** Import file names */
private String physicalTopologyFile = ""; //physical
private String deploymentFile = ""; //virtual
private String workloads_background = ""; //workload
private String workloads = ""; //workload
private JPanel panel;
private JPanel graph;
private Graph physicalGraph;
private Graph virtualGraph;
private GraphView physicalCanvas;
private GraphView virtualCanvas;
private JButton btnRun;
private String mode; //'m':manual; 'i':import
public GraphicSDN() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setPreferredSize(new Dimension(1280, 800));
setLocationRelativeTo(null);
//setResizable(false);
setTitle("CloudSim SDN");
contentPane = new JPanel();
setContentPane(contentPane);
contentPane.setLayout(new BorderLayout());
initUI();
initGraph();
pack();
setVisible(true);
}
public final void initUI() {
setUIFont (new javax.swing.plaf.FontUIResource("Serif",Font.BOLD,18));
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
graph = new JPanel(new java.awt.GridLayout(1, 2));
initBar();
doPosition();
}
/** position window */
private void doPosition() {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int height = screenSize.height;
int width = screenSize.width;
int x = (width / 2 - 1280 / 2);
int y = (height / 2 - 800 / 2);
// One could use the dimension of the frame. But when doing so, one have to call this method !BETWEEN! pack and
// setVisible. Otherwise the calculation will go wrong.
this.setLocation(x, y);
}
/** Initialize project menu and tool bar */
private final void initBar() {
//---------- Start ActionListener ----------
ActionListener readPhyTopoListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
physicalTopologyFile = importFile("josn");
checkImportStatus();
}
};
ActionListener readVirTopoListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
deploymentFile = importFile("json");
checkImportStatus();
}
};
ActionListener readWorkloadBkListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
workloads_background = importFile("cvs");
checkImportStatus();
}
};
ActionListener readWorkloadListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
workloads = importFile("cvs");
checkImportStatus();
}
};
ActionListener addPhysicalNodeListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
openAddPhysicalNodeDialog();
}
};
ActionListener addVirtualNodeListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
openAddVirtualNodeDialog();
}
};
ActionListener addPhysicalEdgeListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
openAddPhysicalEdgeDialog();
}
};
ActionListener addVirtualEdgeListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
openAddVirtualEdgeDialog();
}
};
ActionListener importPhyTopoListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
String fileName = importFile("josn");
Graph phyGraph= Bridge.jsonToGraph(fileName, 0);
/* System.out.println(phyGraph.getAdjacencyList().size());
for (Entry<Node, List<Edge>> entry : phyGraph.getAdjacencyList().entrySet()) {
System.out.println(entry.getKey().getName()+entry.getKey().getType());
}*/
physicalCanvas.setGraph(phyGraph);
}
};
ActionListener importVirTopoListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
String fileName = importFile("josn");
Graph virGraph= Bridge.jsonToGraph(fileName, 1);
virtualCanvas.setGraph(virGraph);
}
};
ActionListener savePhyTopoListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
saveFile("json", physicalGraph);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
};
ActionListener saveVirTopoListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
saveFile("json", virtualGraph);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
};
//---------- End ActionListener ----------
//---------- Start Creating project tool bar ----------
JToolBar toolbar = new JToolBar();
ImageIcon iHost = new ImageIcon(
getClass().getResource("/src/dc.png"));
ImageIcon iHline = new ImageIcon(
getClass().getResource("/src/hline2.png"));
ImageIcon iHOpen = new ImageIcon(
getClass().getResource("/src/openPhyTop.png"));
ImageIcon iHSave = new ImageIcon(
getClass().getResource("/src/savePhyTop.png"));
ImageIcon iVM = new ImageIcon(
getClass().getResource("/src/vm2.png"));
ImageIcon iVline = new ImageIcon(
getClass().getResource("/src/vline2.png"));
ImageIcon iVOpen = new ImageIcon(
getClass().getResource("/src/openVirTop.png"));
ImageIcon iVSave = new ImageIcon(
getClass().getResource("/src/saveVirTop.png"));
ImageIcon iPhy = new ImageIcon(
getClass().getResource("/src/upload1.png"));
ImageIcon iVir = new ImageIcon(
getClass().getResource("/src/upload2.png"));
ImageIcon iWl1 = new ImageIcon(
getClass().getResource("/src/upload3.png"));
ImageIcon iWl2 = new ImageIcon(
getClass().getResource("/src/upload4.png"));
ImageIcon run = new ImageIcon(
getClass().getResource("/src/play.png"));
ImageIcon exit = new ImageIcon(
getClass().getResource("/src/exit.png"));
final JButton btnHost = new JButton(iHost);
btnHost.setToolTipText("Add Host Node");
final JButton btnVm = new JButton(iVM);
btnVm.setToolTipText("Add virtual Machine");
final JButton btnHedge = new JButton(iHline);
btnHedge.setToolTipText("Add Host Edge");
final JButton btnVedge = new JButton(iVline);
btnVedge.setToolTipText("Add VM Edge");
final JButton btnHopen = new JButton(iHOpen);
btnHopen.setToolTipText("Open Physical Topology");
final JButton btnVopen = new JButton(iVOpen);
btnVopen.setToolTipText("Open virtual Topology");
final JButton btnHsave = new JButton(iHSave);
btnHsave.setToolTipText("Save Physical Topology");
final JButton btnVsave = new JButton(iVSave);
btnVsave.setToolTipText("Save virtual Topology");
final JButton btnPhy = new JButton(iPhy);
btnPhy.setToolTipText("Import topology network");
final JButton btnVir = new JButton(iVir);
btnVir.setToolTipText("Import virtual network");
final JButton btnWl1 = new JButton(iWl1);
btnWl1.setToolTipText("Import workload background");
final JButton btnWl2 = new JButton(iWl2);
btnWl2.setToolTipText("Import workload");
btnRun = new JButton(run);
btnRun.setToolTipText("Start simulation");
JButton btnExit = new JButton(exit);
btnExit.setToolTipText("Exit CloudSim");
toolbar.setAlignmentX(0);
btnHost.addActionListener(addPhysicalNodeListener);
btnHedge.addActionListener(addPhysicalEdgeListener);
btnHopen.addActionListener(importPhyTopoListener);
btnHsave.addActionListener(savePhyTopoListener);
btnVm.addActionListener(addVirtualNodeListener);
btnVedge.addActionListener(addVirtualEdgeListener);
btnVopen.addActionListener(importVirTopoListener);
btnVsave.addActionListener(saveVirTopoListener);
btnPhy.addActionListener(readPhyTopoListener);
btnVir.addActionListener(readVirTopoListener);
btnWl1.addActionListener(readWorkloadBkListener);
btnWl2.addActionListener(readWorkloadListener);
btnRun.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
if("i"==mode){
if(physicalTopologyFile==null || physicalTopologyFile.isEmpty()){
JOptionPane.showMessageDialog(panel, "Please select physicalTopologyFile", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
if(deploymentFile==null || deploymentFile.isEmpty()){
JOptionPane.showMessageDialog(panel, "Please select deploymentFile", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
if(workloads_background==null || workloads_background.isEmpty()){
JOptionPane.showMessageDialog(panel, "Please select workloads_background", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
if(workloads==null || workloads.isEmpty()){
JOptionPane.showMessageDialog(panel, "Please select workloads", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
// run simulation
SDNRun run = new SDNRun(physicalTopologyFile, deploymentFile,
workloads_background, workloads, GraphicSDN.this);
}else if("m"==mode){
}
}
});
btnExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
toolbar.add(btnHost);
toolbar.add(btnHedge);
toolbar.add(btnHopen);
toolbar.add(btnHsave);
toolbar.addSeparator();
toolbar.add(btnVm);
toolbar.add(btnVedge);
toolbar.add(btnVopen);
toolbar.add(btnVsave);
toolbar.add(btnPhy);
toolbar.add(btnVir);
toolbar.add(btnWl1);
toolbar.add(btnWl2);
toolbar.addSeparator();
toolbar.add(btnRun);
toolbar.add(btnExit);
panel.add(toolbar);
contentPane.add(panel, BorderLayout.NORTH);
//---------- End Creating project tool bar ----------
//---------- Start Creating project menu bar ----------
//1-1
JMenuBar menubar = new JMenuBar();
//ImageIcon iconNew = new ImageIcon(getClass().getResource("/src/new.png"));
//2-1
JMenu graph = new JMenu("Graph");
graph.setMnemonic(KeyEvent.VK_G);
//Graph by importing json and cvs files
final JMenuItem MiPhy = new JMenuItem("Physical Topology");
final JMenuItem MiVir = new JMenuItem("Virtual Topology");
final JMenuItem MiWl1 = new JMenuItem("Workload Background");
final JMenuItem MiWl2 = new JMenuItem("Workload");
//Graph drawing elements
final JMenu MuPhy = new JMenu("Physical");
JMenuItem MiPhyNode = new JMenuItem("Add Node");
JMenuItem MiPhyEdge = new JMenuItem("Add Edge");
JMenuItem MiPhyOpen = new JMenuItem("Import Physical Topology");
JMenuItem MiPhySave = new JMenuItem("Save Physical Topology");
MuPhy.add(MiPhyNode);
MuPhy.add(MiPhyEdge);
MuPhy.add(MiPhyOpen);
MuPhy.add(MiPhySave);
final JMenu MuVir = new JMenu("Virtual");
JMenuItem MiVirNode = new JMenuItem("Add Node");
JMenuItem MiVirEdge = new JMenuItem("Add Edge");
JMenuItem MiVirOpen = new JMenuItem("Import Virtual Topology");
JMenuItem MiVirSave = new JMenuItem("Save Virtual Topology");
MuVir.add(MiVirNode);
MuVir.add(MiVirEdge);
MuVir.add(MiVirOpen);
MuVir.add(MiVirSave);
MiPhy.addActionListener(readPhyTopoListener);
MiVir.addActionListener(readVirTopoListener);
MiWl1.addActionListener(readWorkloadBkListener);
MiWl2.addActionListener(readWorkloadListener);
MiPhyNode.addActionListener(addPhysicalNodeListener);
MiPhyEdge.addActionListener(addPhysicalEdgeListener);
MiPhyOpen.addActionListener(importPhyTopoListener);
MiPhySave.addActionListener(savePhyTopoListener);
MiVirNode.addActionListener(addVirtualNodeListener);
MiVirEdge.addActionListener(addVirtualEdgeListener);
MiVirOpen.addActionListener(importVirTopoListener);
MiVirSave.addActionListener(saveVirTopoListener);
graph.add(MuPhy);
graph.add(MuVir);
graph.add(MiPhy);
graph.add(MiVir);
graph.add(MiWl1);
graph.add(MiWl2);
//2-2
JMenu view = new JMenu("View");
view.setMnemonic(KeyEvent.VK_F);
//switch mode between manual mode (to create graph by hand) and import mode (to create graph from file)
ActionListener actionSwitcher = new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
String cmd = e.getActionCommand();
if("Canvas" == cmd){
btnHost.setVisible(true);
btnHedge.setVisible(true);
btnHopen.setVisible(true);
btnHsave.setVisible(true);
btnVm.setVisible(true);
btnVedge.setVisible(true);
btnVopen.setVisible(true);
btnVsave.setVisible(true);
btnPhy.setVisible(false);
btnVir.setVisible(false);
btnWl1.setVisible(false);
btnWl2.setVisible(false);
MiPhy.setVisible(false);
MiVir.setVisible(false);
MiWl1.setVisible(false);
MiWl2.setVisible(false);
MuPhy.setVisible(true);
MuVir.setVisible(true);
btnRun.setVisible(false);
btnRun.setEnabled(false);
mode = "m";
}else if("Execution" == cmd){
btnHost.setVisible(false);
btnHedge.setVisible(false);
btnHopen.setVisible(false);
btnHsave.setVisible(false);
btnVm.setVisible(false);
btnVedge.setVisible(false);
btnVopen.setVisible(false);
btnVsave.setVisible(false);
btnPhy.setVisible(true);
btnVir.setVisible(true);
btnWl1.setVisible(true);
btnWl2.setVisible(true);
MiPhy.setVisible(true);
MiVir.setVisible(true);
MiWl1.setVisible(true);
MiWl2.setVisible(true);
MuPhy.setVisible(false);
MuVir.setVisible(false);
btnRun.setVisible(true);
btnRun.setEnabled(false);
mode = "i";
}
//System.out.println(e.getActionCommand());
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
JRadioButtonMenuItem manualMode = new JRadioButtonMenuItem("Canvas");
manualMode.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_U, ActionEvent.CTRL_MASK));
manualMode.addActionListener(actionSwitcher);
JRadioButtonMenuItem importMode = new JRadioButtonMenuItem("Execution");
importMode.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_I, ActionEvent.CTRL_MASK));
importMode.addActionListener(actionSwitcher);
ButtonGroup group = new ButtonGroup();
group.add(manualMode);
group.add(importMode);
JMenuItem fileExit = new JMenuItem("Exit");
fileExit.setMnemonic(KeyEvent.VK_C);
fileExit.setToolTipText("Exit CloudSim");
fileExit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W,
ActionEvent.CTRL_MASK));
fileExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
view.add(manualMode);
view.add(importMode);
view.addSeparator();
view.add(fileExit);
//3-1
menubar.add(view);
menubar.add(graph);
//4-1
setJMenuBar(menubar);
//----- End Creating project menu bar -----
//----- Start Initialize menu and tool bar -----
manualMode.setSelected(true);
mode = "m";
btnHost.setVisible(true);
btnHedge.setVisible(true);
btnHopen.setVisible(true);
btnHsave.setVisible(true);
btnVm.setVisible(true);
btnVedge.setVisible(true);
btnVopen.setVisible(true);
btnVsave.setVisible(true);
btnPhy.setVisible(false);
btnVir.setVisible(false);
btnWl1.setVisible(false);
btnWl2.setVisible(false);
MiPhy.setVisible(false);
MiVir.setVisible(false);
MiWl1.setVisible(false);
MiWl2.setVisible(false);
MuPhy.setVisible(true);
MuVir.setVisible(true);
btnRun.setVisible(false);
btnRun.setEnabled(false);
//----- End Initialize menu and tool bar -----
}
/** initialize Canvas */
private void initGraph(){
physicalGraph = new Graph();
virtualGraph = new Graph();
physicalCanvas = new GraphView(physicalGraph);
virtualCanvas = new GraphView(virtualGraph);
graph.add(physicalCanvas);
graph.add(virtualCanvas);
contentPane.add(graph, BorderLayout.CENTER);
}
/** dialog opening */
private void openAddPhysicalNodeDialog(){
AddPhysicalNode phyNode = new AddPhysicalNode(physicalGraph, GraphicSDN.this);
physicalCanvas.repaint();
}
private void openAddPhysicalEdgeDialog(){
AddPhysicalEdge phyEdge = new AddPhysicalEdge(physicalGraph, GraphicSDN.this);
physicalCanvas.repaint();
}
private void openAddVirtualNodeDialog(){
AddVirtualNode vmNode = new AddVirtualNode(virtualGraph, GraphicSDN.this);
virtualCanvas.repaint();
}
private void openAddVirtualEdgeDialog(){
AddVirtualEdge phyNode = new AddVirtualEdge(virtualGraph, GraphicSDN.this);
virtualCanvas.repaint();
}
/** common utility */
private String importFile(String type){
JFileChooser fileopen = new JFileChooser();
FileFilter filter = new FileNameExtensionFilter(type.toUpperCase()+" Files", type);
fileopen.addChoosableFileFilter(filter);
int ret = fileopen.showDialog(panel, "Import file");
if (ret == JFileChooser.APPROVE_OPTION) {
File file = fileopen.getSelectedFile();
//System.out.println(file.getPath());
return file.getPath();
}
return "";
}
/** save network topology */
private void saveFile(String type, Graph graph) throws IOException{
JFileChooser fileopen = new JFileChooser();
FileFilter filter = new FileNameExtensionFilter(type.toUpperCase()+" Files", type);
fileopen.addChoosableFileFilter(filter);
int ret = fileopen.showSaveDialog(panel);
if (ret == JFileChooser.APPROVE_OPTION) {
String jsonText = graph.toJsonString();
System.out.println(jsonText);
String path = fileopen.getSelectedFile().toString();
File file = new File(path);
FileOutputStream out = new FileOutputStream(file);
out.write(jsonText.getBytes());
out.close();
}
}
private static void setUIFont(javax.swing.plaf.FontUIResource f){
java.util.Enumeration keys = UIManager.getDefaults().keys();
while (keys.hasMoreElements()) {
Object key = keys.nextElement();
Object value = UIManager.get (key);
if (value != null && value instanceof javax.swing.plaf.FontUIResource)
UIManager.put (key, f);
}
}
private void checkImportStatus(){
if((physicalTopologyFile!=null && !physicalTopologyFile.isEmpty()) &&
(deploymentFile!=null && !deploymentFile.isEmpty()) &&
(workloads_background!=null && !workloads_background.isEmpty()) &&
(workloads!=null && !workloads.isEmpty())){
btnRun.setEnabled(true);
}else{
btnRun.setEnabled(false);
}
}
/** Application entry point */
public static void main(String args[]) throws InterruptedException {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
GraphicSDN sdn = new GraphicSDN();
sdn.setVisible(true);
}
});
}
}

View File

@@ -0,0 +1,347 @@
package org.cloudbus.cloudsim.sdn.graph.example;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import org.cloudbus.cloudsim.Cloudlet;
import org.cloudbus.cloudsim.DatacenterCharacteristics;
import org.cloudbus.cloudsim.Host;
import org.cloudbus.cloudsim.Storage;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.sdn.Activity;
import org.cloudbus.cloudsim.sdn.Processing;
import org.cloudbus.cloudsim.sdn.Request;
import org.cloudbus.cloudsim.sdn.SDNDatacenter;
import org.cloudbus.cloudsim.sdn.Transmission;
import org.cloudbus.cloudsim.sdn.example.SDNBroker;
import org.cloudbus.cloudsim.sdn.example.SimpleNetworkOperatingSystem;
import org.cloudbus.cloudsim.sdn.example.VmAllocationPolicyCombinedLeastFullFirst;
import org.cloudbus.cloudsim.sdn.example.Workload;
import org.cloudbus.cloudsim.sdn.example.VmSchedulerSpaceSharedEnergy;
/** A simple example showing how to create a datacenter with one host and run one cloudlet on it */
public class GraphicSDNExample {
private String physicalTopologyFile = "";
private String deploymentFile = "";
private String workloads_background = "";
private String workloads = "";
private JTextArea outputArea;
private SDNBroker broker;
public GraphicSDNExample(String phy, String vir, String wlbk, String wl, JTextArea area){
physicalTopologyFile = phy;
deploymentFile = vir;
workloads_background = wlbk;
workloads = wl;
outputArea = area;
}
public boolean simulate() {
//append("Starting CloudSim SDN...");
try {
// Initialize
int num_user = 1; // number of cloud users
Calendar calendar = Calendar.getInstance();
boolean trace_flag = false; // mean trace events
CloudSim.init(num_user, calendar, trace_flag);
// Create a Datacenter
SDNDatacenter datacenter = createSDNDatacenter("Datacenter_0", physicalTopologyFile);
// Broker
broker = createBroker();
int brokerId = broker.getId();
broker.submitDeployApplication(datacenter, deploymentFile);
broker.submitRequests(workloads_background);
broker.submitRequests(workloads);
// Sixth step: Starts the simulation
CloudSim.startSimulation();
CloudSim.stopSimulation();
return true;
} catch (Exception e) {
e.printStackTrace();
//append("====== RUNNING ERROR ======");
}
return false;
}
public void output(){
try {
// Final step: Print hosts' total utilization.
List<Host> hostList = nos.getHostList();
printEnergyConsumption(hostList);
//Final step: Print results when simulation is over
List<Cloudlet> newList = broker.getCloudletReceivedList();
printCloudletList(newList);
List<Workload> wls = broker.getWorkloads();
printWorkloadList(wls);
append("CloudSim SDN finished!");
} catch (Exception e) {
e.printStackTrace();
append("====== OUTPUT ERROR ======");
}
}
private void printEnergyConsumption(List<Host> hostList) {
double totalEnergyConsumption = 0;
for(Host host:hostList) {
double energy = ((VmSchedulerSpaceSharedEnergy) host.getVmScheduler()).getUtilizationEnergyConsumption();
append("Host #"+host.getId()+": "+energy);
totalEnergyConsumption+= energy;
printHostUtilizationHistory(((VmSchedulerSpaceSharedEnergy) host.getVmScheduler()).getUtilizationHisotry());
}
append("Total energy consumed: "+totalEnergyConsumption);
}
private void printHostUtilizationHistory(
List<org.cloudbus.cloudsim.sdn.example.VmSchedulerSpaceSharedEnergy.HistoryEntry> utilizationHisotry) {
for(org.cloudbus.cloudsim.sdn.example.VmSchedulerSpaceSharedEnergy.HistoryEntry h:utilizationHisotry) {
append(h.startTime+", "+h.usedMips);
}
}
/**
* Creates the datacenter.
*
* @param name the name
*
* @return the datacenter
*/
private SimpleNetworkOperatingSystem nos;
private SDNDatacenter createSDNDatacenter(String name, String physicalTopology) {
// In order to get Host information, pre-create NOS.
nos = new SimpleNetworkOperatingSystem(physicalTopology);
List<Host> hostList = nos.getHostList();
String arch = "x86"; // system architecture
String os = "Linux"; // operating system
String vmm = "Xen";
double time_zone = 10.0; // time zone this resource located
double cost = 3.0; // the cost of using processing in this resource
double costPerMem = 0.05; // the cost of using memory in this resource
double costPerStorage = 0.001; // the cost of using storage in this
// resource
double costPerBw = 0.0; // the cost of using bw in this resource
LinkedList<Storage> storageList = new LinkedList<Storage>(); // we are not adding SAN
// devices by now
DatacenterCharacteristics characteristics = new DatacenterCharacteristics(
arch, os, vmm, hostList, time_zone, cost, costPerMem,
costPerStorage, costPerBw);
// Create Datacenter with previously set parameters
SDNDatacenter datacenter = null;
try {
datacenter = new SDNDatacenter(name, characteristics, new VmAllocationPolicyCombinedLeastFullFirst(hostList), storageList, 0, nos);
//datacenter = new SDNDatacenter(name, characteristics, new VmAllocationPolicyCombinedMostFullFirst(hostList), storageList, 0, nos);
//datacenter = new SDNDatacenter(name, characteristics, new VmAllocationPolicyMipsLeastFullFirst(hostList), storageList, 0, nos);
nos.setDatacenter(datacenter);
} catch (Exception e) {
e.printStackTrace();
}
return datacenter;
}
// We strongly encourage users to develop their own broker policies, to
// submit vms and cloudlets according
// to the specific rules of the simulated scenario
/**
* Creates the broker.
*
* @return the datacenter broker
*/
private SDNBroker createBroker() {
SDNBroker broker = null;
try {
broker = new SDNBroker("Broker");
} catch (Exception e) {
e.printStackTrace();
return null;
}
return broker;
}
public String indent = ",";
public String tabSize = "10";
public String fString = "%"+tabSize+"s"+indent;
public String fInt = "%"+tabSize+"d"+indent;
public String fFloat = "%"+tabSize+".2f"+indent;
private void printCloudletList(List<Cloudlet> list) {
int size = list.size();
String content = "";
Cloudlet cloudlet;
append("");
append("========== OUTPUT ==========");
content = String.format(fString, "Cloudlet_ID") +
String.format(fString, "STATUS" ) +
String.format(fString, "DataCenter_ID") +
String.format(fString, "VM_ID") +
String.format(fString, "Length") +
String.format(fString, "Time") +
String.format(fString, "Start Time") +
String.format(fString, "Finish Time");
append(content);
//DecimalFormat dft = new DecimalFormat("######.##");
for (int i = 0; i < size; i++) {
cloudlet = list.get(i);
printCloudlet(cloudlet);
}
}
private void printCloudlet(Cloudlet cloudlet) {
String content = String.format(fInt, cloudlet.getCloudletId());
if (cloudlet.getCloudletStatus() == Cloudlet.SUCCESS) {
content = content +
String.format(fString, "SUCCESS") +
String.format(fInt, cloudlet.getResourceId()) +
String.format(fInt, cloudlet.getVmId()) +
String.format(fInt, cloudlet.getCloudletLength()) +
String.format(fFloat, cloudlet.getActualCPUTime()) +
String.format(fFloat, cloudlet.getExecStartTime()) +
String.format(fFloat, cloudlet.getFinishTime());
}
else {
content += "FAILED";
}
append(content);
}
private double startTime, finishTime;
private void printWorkloadList(List<Workload> wls) {
int[] appIdNum = new int[SDNBroker.appId];
double[] appIdTime = new double[SDNBroker.appId];
double[] appIdStartTime = new double[SDNBroker.appId];
double[] appIdFinishTime = new double[SDNBroker.appId];
double serveTime, totalTime = 0;
append(" ");
append("========== OUTPUT ==========");
printRequestTitle(wls.get(0).request);
append(" ");
for(Workload wl:wls) {
startTime = finishTime = -1;
printRequest(wl.request);
serveTime= (finishTime - startTime);
append(String.format(fFloat, serveTime));
totalTime += serveTime;
appIdNum[wl.appId] ++;
appIdTime[wl.appId] += serveTime;
if(appIdStartTime[wl.appId] <=0) {
appIdStartTime[wl.appId] = wl.time;
}
appIdFinishTime[wl.appId] = wl.time;
append(" ");
}
for(int i=0; i<SDNBroker.appId; i++) {
append("App Id ("+i+"): "+appIdNum[i]+" requests, Start=" + appIdStartTime[i]+
", Finish="+appIdFinishTime[i]+", Rate="+(double)appIdNum[i]/(appIdFinishTime[i] - appIdStartTime[i])+
" req/sec, Response time=" + appIdTime[i]/appIdNum[i]);
}
append("Average Response Time:"+(totalTime / wls.size()));
}
private void printRequestTitle(Request req) {
String content = String.format(fString, "Req_ID");
//Log.print(String.format(fFloat, req.getStartTime()));
//Log.print(String.format(fFloat, req.getFinishTime()));
List<Activity> acts = req.getRemovedActivities();
for(Activity act:acts) {
if(act instanceof Transmission) {
Transmission tr=(Transmission)act;
content +=
String.format(fString, "Tr:Size") +
String.format(fString, "Tr:Channel") +
String.format(fString, "Tr:time") +
String.format(fString, "Tr:Start") +
String.format(fString, "Tr:End");
printRequestTitle(tr.getPackage().getPayload());
}
else {
content +=
String.format(fString, "Pr:Size") +
String.format(fString, "Pr:time") +
String.format(fString, "Pr:Start") +
String.format(fString, "Pr:End");
}
}
append(content);
}
private void printRequest(Request req) {
String content = String.format(fInt, req.getRequestId());
//Log.print(String.format(fFloat, req.getStartTime()));
//Log.print(String.format(fFloat, req.getFinishTime()));
List<Activity> acts = req.getRemovedActivities();
for(Activity act:acts) {
if(act instanceof Transmission) {
Transmission tr=(Transmission)act;
content +=
String.format(fInt, tr.getPackage().getSize()) +
String.format(fInt, tr.getPackage().getFlowId()) +
String.format(fFloat, tr.getPackage().getFinishTime() - tr.getPackage().getStartTime()) +
String.format(fFloat, tr.getPackage().getStartTime()) +
String.format(fFloat, tr.getPackage().getFinishTime());
printRequest(tr.getPackage().getPayload());
}
else {
Processing pr=(Processing)act;
content +=
String.format(fInt, pr.getCloudlet().getCloudletLength()) +
String.format(fFloat, pr.getCloudlet().getActualCPUTime()) +
String.format(fFloat, pr.getCloudlet().getExecStartTime()) +
String.format(fFloat, pr.getCloudlet().getFinishTime());
if(startTime == -1) startTime = pr.getCloudlet().getExecStartTime();
finishTime=pr.getCloudlet().getFinishTime();
}
}
append(content);
}
private void append(String content){
outputArea.append(content+"\n");
}
}

View File

@@ -0,0 +1,139 @@
/*
* 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.sdn.overbooking;
import java.util.HashMap;
import java.util.Map;
import org.cloudbus.cloudsim.Vm;
import org.cloudbus.cloudsim.provisioners.BwProvisioner;
/**
* BwProvisionerSimple is a class that implements a simple best effort allocation policy: if there
* is bw available to request, it allocates; otherwise, it fails.
*
* @author Rodrigo N. Calheiros
* @author Anton Beloglazov
* @since CloudSim Toolkit 1.0
*/
public class BwProvisionerOverbooking extends BwProvisioner {
/** The bw table. */
private Map<String, Long> bwTable;
public static final double overbookingRatioBw = 1.0; // 20% overbooking allowed for BW
/**
* Instantiates a new bw provisioner simple.
*
* @param bw the bw
*/
public BwProvisionerOverbooking(long bw) {
super(bw);
setAvailableBw((long) getOverbookedBw(bw)); //overwrite available BW to overbookable BW
setBwTable(new HashMap<String, Long>());
}
/*
* (non-Javadoc)
* @see cloudsim.provisioners.BwProvisioner#allocateBwForVm(cloudsim.Vm, long)
*/
@Override
public boolean allocateBwForVm(Vm vm, long bw) {
deallocateBwForVm(vm);
if (getAvailableBw() >= bw) {
setAvailableBw(getAvailableBw() - bw);
getBwTable().put(vm.getUid(), bw);
vm.setCurrentAllocatedBw(getAllocatedBwForVm(vm));
return true;
}
vm.setCurrentAllocatedBw(getAllocatedBwForVm(vm));
return false;
}
/*
* (non-Javadoc)
* @see cloudsim.provisioners.BwProvisioner#getAllocatedBwForVm(cloudsim.Vm)
*/
@Override
public long getAllocatedBwForVm(Vm vm) {
if (getBwTable().containsKey(vm.getUid())) {
return getBwTable().get(vm.getUid());
}
return 0;
}
/*
* (non-Javadoc)
* @see cloudsim.provisioners.BwProvisioner#deallocateBwForVm(cloudsim.Vm)
*/
@Override
public void deallocateBwForVm(Vm vm) {
if (getBwTable().containsKey(vm.getUid())) {
long amountFreed = getBwTable().remove(vm.getUid());
setAvailableBw(getAvailableBw() + amountFreed);
vm.setCurrentAllocatedBw(0);
}
}
/*
* (non-Javadoc)
* @see cloudsim.provisioners.BwProvisioner#deallocateBwForVm(cloudsim.Vm)
*/
@Override
public void deallocateBwForAllVms() {
super.deallocateBwForAllVms();
setAvailableBw((long) getOverbookedBw(getBw())); //Overbooking
getBwTable().clear();
}
/*
* (non-Javadoc)
* @see
* gridsim.virtualization.power.provisioners.BWProvisioner#isSuitableForVm(gridsim.virtualization
* .power.VM, long)
*/
@Override
public boolean isSuitableForVm(Vm vm, long bw) {
long allocatedBw = getAllocatedBwForVm(vm);
boolean result = allocateBwForVm(vm, bw);
deallocateBwForVm(vm);
if (allocatedBw > 0) {
allocateBwForVm(vm, allocatedBw);
}
return result;
}
/**
* Gets the bw table.
*
* @return the bw table
*/
protected Map<String, Long> getBwTable() {
return bwTable;
}
/**
* Sets the bw table.
*
* @param bwTable the bw table
*/
protected void setBwTable(Map<String, Long> bwTable) {
this.bwTable = bwTable;
}
public static double getOverbookedBw(long capacity) {
double overbookedBw = capacity * BwProvisionerOverbooking.overbookingRatioBw;
return overbookedBw;
}
}

View File

@@ -0,0 +1,166 @@
package org.cloudbus.cloudsim.sdn.overbooking;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import org.cloudbus.cloudsim.Host;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.Pe;
import org.cloudbus.cloudsim.Vm;
import org.cloudbus.cloudsim.VmScheduler;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.core.CloudSimTags;
import org.cloudbus.cloudsim.core.SimEvent;
import org.cloudbus.cloudsim.provisioners.BwProvisioner;
import org.cloudbus.cloudsim.provisioners.RamProvisioner;
import org.cloudbus.cloudsim.provisioners.RamProvisionerSimple;
import org.cloudbus.cloudsim.sdn.Arc;
import org.cloudbus.cloudsim.sdn.Link;
import org.cloudbus.cloudsim.sdn.Middlebox;
import org.cloudbus.cloudsim.sdn.NetworkOperatingSystem;
import org.cloudbus.cloudsim.sdn.Node;
import org.cloudbus.cloudsim.sdn.SDNHost;
import org.cloudbus.cloudsim.sdn.TimedVm;
public class OverbookingNetworkOperatingSystem extends NetworkOperatingSystem {
public OverbookingNetworkOperatingSystem(String fileName) {
super(fileName);
}
@Override
public boolean deployApplication(List<Vm> vms, List<Middlebox> middleboxes, List<Arc> links) {
Log.printLine(CloudSim.clock() + ": " + getName() + ": Starting deploying application..");
for(Vm vm:vms)
{
TimedVm tvm = (TimedVm) vm;
Log.printLine(CloudSim.clock() + ": " + getName() + ": Trying to Create VM #" + vm.getId()
+ " in " + datacenter.getName() + ", (" + tvm.getStartTime() + "~" +tvm.getFinishTime() + ")");
send(datacenter.getId(), tvm.getStartTime(), CloudSimTags.VM_CREATE_ACK, vm);
if(tvm.getFinishTime() != Double.POSITIVE_INFINITY) {
send(datacenter.getId(), tvm.getFinishTime(), CloudSimTags.VM_DESTROY, vm);
send(this.getId(), tvm.getFinishTime(), CloudSimTags.VM_DESTROY, vm);
}
}
return true;
}
public boolean deployFlow(List<Arc> links) {
for(Arc link:links) {
int srcVm = link.getSrcId();
int dstVm = link.getDstId();
int flowId = link.getFlowId();
SDNHost srchost = findSDNHost(srcVm);
SDNHost dsthost = findSDNHost(dstVm);
if(srchost == null || dsthost == null) {
continue;
}
if(srchost.equals(dsthost)) {
Log.printLine(CloudSim.clock() + ": " + getName() + ": Source SDN Host is same as Destination. Go loopback");
srchost.addVMRoute(srcVm, dstVm, flowId, dsthost);
}
else {
Log.printLine(CloudSim.clock() + ": " + getName() + ": VMs are in different hosts. Create entire routing table (hosts, switches)");
boolean findRoute = buildRoutingTables(srchost, srcVm, dstVm, flowId, null);
if(!findRoute) {
System.err.println("SimpleNetworkOperatingSystem.deployFlow: Could not find route!!" +
NetworkOperatingSystem.debugVmIdName.get(srcVm) + "->"+NetworkOperatingSystem.debugVmIdName.get(dstVm));
}
}
}
// Print all routing tables.
for(Node node:this.topology.getAllNodes()) {
node.printVMRoute();
}
return true;
}
private boolean buildRoutingTables(Node node, int srcVm, int dstVm, int flowId, Node prevNode) {
Collection<Link> links = this.topology.getAdjacentLinks(node);
if(links.size() == 0) {
// No link. Do nothing
}
else if(links.size() == 1) {
// Only one way, no other choice (for Host)
for(Link l:links) {
Node nextHop= l.getHighOrder();
if(nextHop.equals(node))
nextHop= l.getLowOrder();
node.addVMRoute(srcVm, dstVm, flowId, nextHop);
buildRoutingTables(nextHop, srcVm, dstVm, flowId, node);
}
return true;
}
else {
// There are many links. Determine which hop to go.
SDNHost dsthost = findSDNHost(dstVm);
for(Link l:links) {
Node nextHop= l.getHighOrder();
if(nextHop.equals(node))
nextHop= l.getLowOrder();
if(nextHop.equals(prevNode)) {
// NextHop is going back to prev node
continue;
}
else if(nextHop.equals(dsthost)) {
// NextHop is the destination. Just add. No further route finding.
node.addVMRoute(srcVm, dstVm, flowId, nextHop);
return true;
}
else if(nextHop instanceof SDNHost) {
// NextHop is host but no destination. Can't forward
continue;
}
else {
// Nexthop is switch
if(buildRoutingTables(nextHop, srcVm, dstVm, flowId, node)) {
// If the route is right.
node.addVMRoute(srcVm, dstVm, flowId, nextHop);
return true;
}
else
continue;
}
}
}
return false;
}
@Override
protected Middlebox deployMiddlebox(String type,Vm vm) {
return null;
}
@Override
public void processVmCreateAck(SimEvent ev) {
// print the created VM info
TimedVm vm = (TimedVm) ev.getData();
Log.printLine(CloudSim.clock() + ": " + getName() + ": VM Created: " + vm.getId() + " in " + this.findSDNHost(vm.getId()));
deployFlow(this.arcList);
}
@Override
protected Host createHost(int hostId, int ram, long bw, long storage, long pes, double mips) {
LinkedList<Pe> peList = new LinkedList<Pe>();
int peId=0;
for(int i=0;i<pes;i++) peList.add(new Pe(peId++,new PeProvisionerOverbooking(mips)));
RamProvisioner ramPro = new RamProvisionerSimple(ram);
BwProvisioner bwPro = new BwProvisionerOverbooking(bw);
VmScheduler vmScheduler = new VmSchedulerTimeSharedOverbookingEnergy(peList);
Host newHost = new Host(hostId, ramPro, bwPro, storage, peList, vmScheduler);
return newHost;
}
}

View File

@@ -0,0 +1,201 @@
/*
* 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.sdn.overbooking;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.cloudbus.cloudsim.Vm;
import org.cloudbus.cloudsim.provisioners.PeProvisioner;
/**
* The Class PeProvisionerSimple.
*
* @author Anton Beloglazov
* @since CloudSim Toolkit 2.0
*/
public class PeProvisionerOverbooking extends PeProvisioner {
/** The pe table. */
private Map<String, List<Double>> peTable;
public static final double overbookingRatioMips = 4.0; // 10% overbooking allowed for MIPS
/**
* Creates the PeProvisionerSimple object.
*
* @param availableMips the available mips
*
* @pre $none
* @post $none
*/
public PeProvisionerOverbooking(double availableMips) {
super(availableMips);
setAvailableMips(PeProvisionerOverbooking.getOverbookedMips(availableMips));
setPeTable(new HashMap<String, ArrayList<Double>>());
}
/*
* (non-Javadoc)
* @see cloudsim.provisioners.PeProvisioner#allocateMipsForVM(cloudsim.power.VM, int)
*/
@Override
public boolean allocateMipsForVm(Vm vm, double mips) {
return allocateMipsForVm(vm.getUid(), mips);
}
/*
* (non-Javadoc)
* @see cloudsim.provisioners.PeProvisioner#allocateMipsForVm(java.lang.String, double)
*/
@Override
public boolean allocateMipsForVm(String vmUid, double mips) {
if (getAvailableMips() < mips) {
return false;
}
List<Double> allocatedMips;
if (getPeTable().containsKey(vmUid)) {
allocatedMips = getPeTable().get(vmUid);
} else {
allocatedMips = new ArrayList<Double>();
}
allocatedMips.add(mips);
setAvailableMips(getAvailableMips() - mips);
getPeTable().put(vmUid, allocatedMips);
return true;
}
/*
* (non-Javadoc)
* @see cloudsim.provisioners.PeProvisioner#allocateMipsForVM(cloudsim.power.VM,
* java.util.ArrayList)
*/
@Override
public boolean allocateMipsForVm(Vm vm, List<Double> mips) {
int totalMipsToAllocate = 0;
for (double _mips : mips) {
totalMipsToAllocate += _mips;
}
if (getAvailableMips() + getTotalAllocatedMipsForVm(vm) < totalMipsToAllocate) {
return false;
}
setAvailableMips(getAvailableMips() + getTotalAllocatedMipsForVm(vm) - totalMipsToAllocate);
getPeTable().put(vm.getUid(), mips);
return true;
}
/*
* (non-Javadoc)
* @see cloudsim.provisioners.PeProvisioner#deallocateMipsForAllVms()
*/
@Override
public void deallocateMipsForAllVms() {
super.deallocateMipsForAllVms();
setAvailableMips(PeProvisionerOverbooking.getOverbookedMips(getMips())); //Overbooking
getPeTable().clear();
}
/*
* (non-Javadoc)
* @see
* cloudsim.provisioners.PeProvisioner#getAllocatedMipsForVMByVirtualPeId(cloudsim.power.VM,
* int)
*/
@Override
public double getAllocatedMipsForVmByVirtualPeId(Vm vm, int peId) {
if (getPeTable().containsKey(vm.getUid())) {
try {
return getPeTable().get(vm.getUid()).get(peId);
} catch (Exception e) {
}
}
return 0;
}
/*
* (non-Javadoc)
* @see cloudsim.provisioners.PeProvisioner#getAllocatedMipsForVM(cloudsim.power.VM)
*/
@Override
public List<Double> getAllocatedMipsForVm(Vm vm) {
if (getPeTable().containsKey(vm.getUid())) {
return getPeTable().get(vm.getUid());
}
return null;
}
/*
* (non-Javadoc)
* @see cloudsim.provisioners.PeProvisioner#getTotalAllocatedMipsForVM(cloudsim.power.VM)
*/
@Override
public double getTotalAllocatedMipsForVm(Vm vm) {
if (getPeTable().containsKey(vm.getUid())) {
double totalAllocatedMips = 0.0;
for (double mips : getPeTable().get(vm.getUid())) {
totalAllocatedMips += mips;
}
return totalAllocatedMips;
}
return 0;
}
/*
* (non-Javadoc)
* @see cloudsim.provisioners.PeProvisioner#deallocateMipsForVM(cloudsim.power.VM)
*/
@Override
public void deallocateMipsForVm(Vm vm) {
if (getPeTable().containsKey(vm.getUid())) {
for (double mips : getPeTable().get(vm.getUid())) {
setAvailableMips(getAvailableMips() + mips);
}
getPeTable().remove(vm.getUid());
}
}
/**
* Gets the pe table.
*
* @return the peTable
*/
protected Map<String, List<Double>> getPeTable() {
return peTable;
}
/**
* Sets the pe table.
*
* @param peTable the peTable to set
*/
@SuppressWarnings("unchecked")
protected void setPeTable(Map<String, ? extends List<Double>> peTable) {
this.peTable = (Map<String, List<Double>>) peTable;
}
public static double getOverbookedMips(double availableMips) {
double overbookedMips = availableMips * PeProvisionerOverbooking.overbookingRatioMips;
return overbookedMips;
}
}

View File

@@ -0,0 +1,339 @@
package org.cloudbus.cloudsim.sdn.overbooking;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.cloudbus.cloudsim.Host;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.Vm;
import org.cloudbus.cloudsim.VmAllocationPolicy;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.sdn.power.PowerUtilizationMaxHostInterface;
public class VmAllocationPolicyOverbooking extends VmAllocationPolicy implements PowerUtilizationMaxHostInterface {
protected final double hostTotalMips;
protected final double hostTotalBw;
protected final int hostTotalPes;
/** The vm table. */
private Map<String, Host> vmTable;
/** The used pes. */
private Map<String, Integer> usedPes;
/** The free pes. */
private List<Integer> freePes;
private Map<String, Long> usedMips;
private List<Long> freeMips;
private Map<String, Long> usedBw;
private List<Long> freeBw;
/**
* Creates the new VmAllocationPolicySimple object.
*
* @param list the list
* @pre $none
* @post $none
*/
public VmAllocationPolicyOverbooking(List<? extends Host> list) {
super(list);
setFreePes(new ArrayList<Integer>());
setFreeMips(new ArrayList<Long>());
setFreeBw(new ArrayList<Long>());
for (Host host : getHostList()) {
getFreePes().add(host.getNumberOfPes());
getFreeMips().add((long) PeProvisionerOverbooking.getOverbookedMips((host.getTotalMips())));
getFreeBw().add((long) BwProvisionerOverbooking.getOverbookedBw(host.getBw()));
}
hostTotalMips = getHostList().get(0).getTotalMips();
hostTotalBw = getHostList().get(0).getBw();
hostTotalPes = getHostList().get(0).getNumberOfPes();
setVmTable(new HashMap<String, Host>());
setUsedPes(new HashMap<String, Integer>());
setUsedMips(new HashMap<String, Long>());
setUsedBw(new HashMap<String, Long>());
}
protected double convertWeightedMetric(double mipsPercent, double bwPercent) {
double ret = mipsPercent * bwPercent;
return ret;
}
/**
* Allocates a host for a given VM.
*
* @param vm VM specification
* @return $true if the host could be allocated; $false otherwise
* @pre $none
* @post $none
*/
@Override
public boolean allocateHostForVm(Vm vm) {
if (getVmTable().containsKey(vm.getUid())) { // if this vm was not created
return false;
}
int numHosts = getHostList().size();
// 1. Find/Order the best host for this VM by comparing a metric
int requiredPes = vm.getNumberOfPes();
double requiredMips = vm.getCurrentRequestedTotalMips();
long requiredBw = vm.getCurrentRequestedBw();
boolean result = false;
// freeReousrces : Weighted-calculated free resource percentage in each host
double[] freeResources = new double[numHosts];
for (int i = 0; i < numHosts; i++) {
double mipsFreePercent = (double)getFreeMips().get(i) / this.hostTotalMips;
double bwFreePercent = (double)getFreeBw().get(i) / this.hostTotalBw;
freeResources[i] = this.convertWeightedMetric(mipsFreePercent, bwFreePercent);
}
// Find the most full host, with available resource.
for(int tries = 0; result == false && tries < numHosts; tries++) {// we still trying until we find a host or until we try all of them
double lessFree = Double.POSITIVE_INFINITY;
int idx = -1;
// Find the most full host
for (int i = 0; i < numHosts; i++) {
if (freeResources[i] < lessFree) {
lessFree = freeResources[i];
idx = i;
}
}
freeResources[idx] = Double.POSITIVE_INFINITY; // Mark visited
Host host = getHostList().get(idx);
// Check whether the host can hold this VM or not.
if( getFreeMips().get(idx) < requiredMips) {
System.err.format("not enough MIPS. MIPS %d(%.2f) / BW %d (%.2f)\n",
getFreeMips().get(idx),
(double)getFreeMips().get(idx)/requiredMips,
getFreeBw().get(idx),
(double)getFreeBw().get(idx) / requiredBw);
continue;
}
if( getFreeBw().get(idx) < requiredBw) {
System.err.format("not enough BW. MIPS %d(%.2f) / BW %d (%.2f)\n",
getFreeMips().get(idx),
(double)getFreeMips().get(idx)/requiredMips,
getFreeBw().get(idx),
(double)getFreeBw().get(idx) / requiredBw);
continue;
}
result = host.vmCreate(vm);
if (result) { // if vm were succesfully created in the host
getVmTable().put(vm.getUid(), host);
getUsedPes().put(vm.getUid(), requiredPes);
getFreePes().set(idx, getFreePes().get(idx) - requiredPes);
getUsedMips().put(vm.getUid(), (long) requiredMips);
getFreeMips().set(idx, (long) (getFreeMips().get(idx) - requiredMips));
getUsedBw().put(vm.getUid(), (long) requiredBw);
getFreeBw().set(idx, (long) (getFreeBw().get(idx) - requiredBw));
break;
}
}
if(!result) {
System.err.println("VmAllocationPolicy: WARNING:: Cannot create VM!!!!");
}
logMaxNumHostsUsed();
return result;
}
protected int maxNumHostsUsed=0;
public void logMaxNumHostsUsed() {
// Get how many are used
int numHostsUsed=0;
for(int freePes:getFreePes()) {
if(freePes < hostTotalPes) {
numHostsUsed++;
}
}
if(maxNumHostsUsed < numHostsUsed)
maxNumHostsUsed = numHostsUsed;
Log.printLine("Number of online hosts:"+numHostsUsed + ", max was ="+maxNumHostsUsed);
}
public int getMaxNumHostsUsed() { return maxNumHostsUsed;}
/**
* Releases the host used by a VM.
*
* @param vm the vm
* @pre $none
* @post none
*/
@Override
public void deallocateHostForVm(Vm vm) {
Host host = getVmTable().remove(vm.getUid());
if (host != null) {
int idx = getHostList().indexOf(host);
host.vmDestroy(vm);
Integer pes = getUsedPes().remove(vm.getUid());
getFreePes().set(idx, getFreePes().get(idx) + pes);
Long mips = getUsedMips().remove(vm.getUid());
getFreeMips().set(idx, getFreeMips().get(idx) + mips);
Long bw = getUsedBw().remove(vm.getUid());
getFreeBw().set(idx, getFreeBw().get(idx) + bw);
}
}
/**
* Gets the host that is executing the given VM belonging to the given user.
*
* @param vm the vm
* @return the Host with the given vmID and userID; $null if not found
* @pre $none
* @post $none
*/
@Override
public Host getHost(Vm vm) {
return getVmTable().get(vm.getUid());
}
/**
* Gets the host that is executing the given VM belonging to the given user.
*
* @param vmId the vm id
* @param userId the user id
* @return the Host with the given vmID and userID; $null if not found
* @pre $none
* @post $none
*/
@Override
public Host getHost(int vmId, int userId) {
return getVmTable().get(Vm.getUid(userId, vmId));
}
/**
* Gets the vm table.
*
* @return the vm table
*/
public Map<String, Host> getVmTable() {
return vmTable;
}
/**
* Sets the vm table.
*
* @param vmTable the vm table
*/
protected void setVmTable(Map<String, Host> vmTable) {
this.vmTable = vmTable;
}
/**
* Gets the used pes.
*
* @return the used pes
*/
protected Map<String, Integer> getUsedPes() {
return usedPes;
}
/**
* Sets the used pes.
*
* @param usedPes the used pes
*/
protected void setUsedPes(Map<String, Integer> usedPes) {
this.usedPes = usedPes;
}
/**
* Gets the free pes.
*
* @return the free pes
*/
protected List<Integer> getFreePes() {
return freePes;
}
/**
* Sets the free pes.
*
* @param freePes the new free pes
*/
protected void setFreePes(List<Integer> freePes) {
this.freePes = freePes;
}
protected Map<String, Long> getUsedMips() {
return usedMips;
}
protected void setUsedMips(Map<String, Long> usedMips) {
this.usedMips = usedMips;
}
protected Map<String, Long> getUsedBw() {
return usedBw;
}
protected void setUsedBw(Map<String, Long> usedBw) {
this.usedBw = usedBw;
}
protected List<Long> getFreeMips() {
return this.freeMips;
}
protected void setFreeMips(List<Long> freeMips) {
this.freeMips = freeMips;
}
protected List<Long> getFreeBw() {
return this.freeBw;
}
protected void setFreeBw(List<Long> freeBw) {
this.freeBw = freeBw;
}
/*
* (non-Javadoc)
* @see cloudsim.VmAllocationPolicy#optimizeAllocation(double, cloudsim.VmList, double)
*/
@Override
public List<Map<String, Object>> optimizeAllocation(List<? extends Vm> vmList) {
// TODO Auto-generated method stub
return null;
}
/*
* (non-Javadoc)
* @see org.cloudbus.cloudsim.VmAllocationPolicy#allocateHostForVm(org.cloudbus.cloudsim.Vm,
* org.cloudbus.cloudsim.Host)
*/
@Override
public boolean allocateHostForVm(Vm vm, Host host) {
if (host.vmCreate(vm)) { // if vm has been succesfully created in the host
getVmTable().put(vm.getUid(), host);
int requiredPes = vm.getNumberOfPes();
int idx = getHostList().indexOf(host);
getUsedPes().put(vm.getUid(), requiredPes);
getFreePes().set(idx, getFreePes().get(idx) - requiredPes);
Log.formatLine(
"%.2f: VM #" + vm.getId() + " has been allocated to the host #" + host.getId(),
CloudSim.clock());
return true;
}
return false;
}
}

View File

@@ -0,0 +1,99 @@
/*
* 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.sdn.overbooking;
import java.util.ArrayList;
import java.util.List;
import org.cloudbus.cloudsim.Pe;
import org.cloudbus.cloudsim.VmSchedulerTimeSharedOverSubscription;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.sdn.power.PowerUtilizationHistoryEntry;
import org.cloudbus.cloudsim.sdn.power.PowerUtilizationInterface;
/**
* VmSchedulerSpaceShared is a VMM allocation policy that allocates one or more Pe to a VM, and
* doesn't allow sharing of PEs. If there is no free PEs to the VM, allocation fails. Free PEs are
* not allocated to VMs
*
* @author Rodrigo N. Calheiros
* @author Anton Beloglazov
* @since CloudSim Toolkit 1.0
*/
public class VmSchedulerTimeSharedOverbookingEnergy extends VmSchedulerTimeSharedOverSubscription implements PowerUtilizationInterface{
public VmSchedulerTimeSharedOverbookingEnergy(List<? extends Pe> pelist) {
super(pelist);
}
@Override
protected void setAvailableMips(double availableMips) {
super.setAvailableMips(availableMips);
addUtilizationEntry();
}
private List<PowerUtilizationHistoryEntry> utilizationHistories = null;
private static double powerOffDuration = 0; //if host is idle for 1 hours, it's turned off.
public void addUtilizationEntryTermination(double terminatedTime) {
if(this.utilizationHistories != null)
this.utilizationHistories.add(new PowerUtilizationHistoryEntry(terminatedTime, 0));
}
public List<PowerUtilizationHistoryEntry> getUtilizationHisotry() {
return utilizationHistories;
}
public double getUtilizationEnergyConsumption() {
double total=0;
double lastTime=0;
double lastMips=0;
if(this.utilizationHistories == null)
return 0;
for(PowerUtilizationHistoryEntry h:this.utilizationHistories) {
double duration = h.startTime - lastTime;
double utilPercentage = lastMips/ getTotalMips();
double power = calculatePower(utilPercentage);
double energyConsumption = power * duration;
// Assume that the host is turned off when duration is long enough
if(duration > powerOffDuration && lastMips == 0)
energyConsumption = 0;
total += energyConsumption;
lastTime = h.startTime;
lastMips = h.usedMips;
}
return total/3600; // transform to Whatt*hour from What*seconds
}
private double calculatePower(double u) {
double power = 120 + 154 * u;
return power;
}
private void addUtilizationEntry() {
double time = CloudSim.clock();
double totalMips = getTotalMips();
double usingMips = totalMips - this.getAvailableMips();
if(usingMips < 0) {
System.err.println("addUtilizationEntry : using mips is negative, No way!");
}
if(utilizationHistories == null)
utilizationHistories = new ArrayList<PowerUtilizationHistoryEntry>();
this.utilizationHistories.add(new PowerUtilizationHistoryEntry(time, usingMips));
}
private double getTotalMips() {
return this.getPeList().size() * this.getPeCapacity();
}
}

View File

@@ -0,0 +1,21 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn.power;
/**
* To log utilization history, this class holds power utilization information
*
* @author Jungmin Son
* @since CloudSimSDN 1.0
*/
public class PowerUtilizationHistoryEntry {
public double startTime;
public double usedMips;
public PowerUtilizationHistoryEntry(double t, double m) { startTime=t; usedMips=m;}
}

View File

@@ -0,0 +1,25 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn.power;
import java.util.List;
/**
* Interface to manage utilization history.
*
* @author Jungmin Son
* @since CloudSimSDN 1.0
*/
public interface PowerUtilizationInterface {
public void addUtilizationEntryTermination(double terminatedTime);
public List<PowerUtilizationHistoryEntry> getUtilizationHisotry();
public double getUtilizationEnergyConsumption();
}

View File

@@ -0,0 +1,20 @@
/*
* Title: CloudSimSDN
* Description: SDN extension for CloudSim
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2015, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.sdn.power;
/**
* Interface to manage host history.
*
* @author Jungmin Son
* @since CloudSimSDN 1.0
*/
public interface PowerUtilizationMaxHostInterface {
void logMaxNumHostsUsed();
int getMaxNumHostsUsed();
}

View File

@@ -0,0 +1,290 @@
package org.cloudbus.cloudsim.sdn.request;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.apache.commons.math3.distribution.ExponentialDistribution;
import org.apache.commons.math3.distribution.ParetoDistribution;
import org.apache.commons.math3.random.Well19937c;
/* Generate VM requests, for example:
*
{
"nodes" : [
{
"name" : "vm01",
"type" : "vm",
"size" : 1000,
"pes": 1,
"mips" : 30000000,
"ram" : 512,
"bw" : 100000,
"starttime": 1.3,
"endtime" : 20.5,
},
],
"links" : [
{
"name": "l32",
"source" : "vm03" ,
"destination" : "vm02" ,
"bandwidth" : 66000000
},
],
*/
public class VMRequestGenerator {
public static void main(String [] argv) {
int numVms = 100;
String jsonFileName = "virtual2.json";
VMRequestGenerator reqg = new VMRequestGenerator();
List<VMSpec> vms = reqg.generateVMs(numVms);
List<LinkSpec> links = reqg.generateLinks();
reqg.wrtieJSON(vms, links, jsonFileName);
}
class VMSpec {
String name;
String type;
long size;
int pe;
long mips;
int ram;
long bw;
double starttime;
double endtime;
@SuppressWarnings("unchecked")
JSONObject toJSON() {
VMSpec vm = this;
JSONObject obj = new JSONObject();
obj.put("name", vm.name);
obj.put("type", vm.type);
obj.put("size", vm.size);
obj.put("pes", vm.pe);
obj.put("mips", vm.mips);
obj.put("ram", new Integer(vm.ram));
obj.put("bw", vm.bw);
obj.put("starttime", vm.starttime);
obj.put("endtime", vm.endtime);
return obj;
}
}
class LinkSpec {
String name;
String source;
String destination;
Long bw;
public LinkSpec(String name,String source,String destination,Long bw) {
this.name = name;
this.source = source;
this.destination = destination;
this.bw = bw;
}
@SuppressWarnings("unchecked")
JSONObject toJSON() {
LinkSpec link = this;
JSONObject obj = new JSONObject();
obj.put("name", link.name);
obj.put("source", link.source);
obj.put("destination", link.destination);
if(link.bw != null)
obj.put("bw", link.bw);
return obj;
}
}
int vmId = 0;
@SuppressWarnings("unchecked")
public void wrtieJSON(List<VMSpec> vms, List<LinkSpec> links, String jsonFileName) {
JSONObject obj = new JSONObject();
JSONArray vmList = new JSONArray();
JSONArray linkList = new JSONArray();
for(VMSpec vm:vms) {
vmList.add(vm.toJSON());
}
for(LinkSpec link:links) {
linkList.add(link.toJSON());
}
obj.put("nodes", vmList);
obj.put("links", linkList);
try {
FileWriter file = new FileWriter(jsonFileName);
file.write(obj.toJSONString());
file.flush();
file.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(obj);
}
enum VMtype {
WebServer,
AppServer,
DBServer,
Proxy,
Firewall
}
public VMSpec generateVM(long vmSize, int pes, long mips, int vmRam, long bw, double startTime, double endTime) {
VMSpec vm = new VMSpec();
vm.name = "vm"+ String.format("%02d", vmId++);
vm.type = "vm";
vm.size = vmSize;
vm.pe = pes;
vm.mips = mips;
vm.ram = vmRam;
vm.bw = bw;
vm.starttime = startTime;
vm.endtime = endTime;
return vm;
}
public VMSpec generateVM(VMtype vmtype, double startTime, double endTime) {
int pes = 1;
long vmSize = 1000;
long mips=2000;
int vmRam = 512;
long bw=1000000000/10;
switch(vmtype) {
case WebServer:
//m1.large
mips=2000;
pes=2;
break;
case AppServer:
//m2.xlarge
mips=3000L;
pes=8;
break;
case DBServer:
//c1.xlarge
mips=2400L;
pes=8;
break;
case Proxy:
mips=2000;
pes=8;
bw=500000000;
break;
case Firewall:
mips=3000L;
pes=8;
bw=500000000;
break;
}
return generateVM(vmSize, pes, mips, vmRam, bw, startTime, endTime);
}
public List<VMSpec> generateVMGroup(int numVMsInGroup, double startTime, double endTime) {
System.out.printf("Generating VM Group(%d): %f - %f\n", numVMsInGroup, startTime, endTime);
List<VMSpec> vms = new ArrayList<VMSpec>();
switch(numVMsInGroup) {
case 2:
vms.add(this.generateVM(VMtype.WebServer, startTime, endTime));
vms.add(this.generateVM(VMtype.AppServer, startTime, endTime));
break;
case 3:
vms.add(this.generateVM(VMtype.WebServer, startTime, endTime));
vms.add(this.generateVM(VMtype.AppServer, startTime, endTime));
vms.add(this.generateVM(VMtype.DBServer, startTime, endTime));
break;
case 4:
vms.add(this.generateVM(VMtype.WebServer, startTime, endTime));
vms.add(this.generateVM(VMtype.AppServer, startTime, endTime));
vms.add(this.generateVM(VMtype.DBServer, startTime, endTime));
vms.add(this.generateVM(VMtype.Proxy, startTime, endTime));
break;
case 5:
vms.add(this.generateVM(VMtype.WebServer, startTime, endTime));
vms.add(this.generateVM(VMtype.AppServer, startTime, endTime));
vms.add(this.generateVM(VMtype.DBServer, startTime, endTime));
vms.add(this.generateVM(VMtype.Proxy, startTime, endTime));
vms.add(this.generateVM(VMtype.Firewall, startTime, endTime));
break;
default:
System.err.println("Unknown group number"+numVMsInGroup);
break;
}
return vms;
}
private static long seed = 10;
public List<VMSpec> generateVMs(int totalVmNum) {
double lastStartTime = 0;
double startMean = 1800; // sec = 30min
double durScale=14400; // sec = 4 hours
double durShape=1.2;
Random rVmNum = new Random(seed);
ExponentialDistribution rStartTime = new ExponentialDistribution(new Well19937c(seed), startMean, ExponentialDistribution.DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
ParetoDistribution rDuration = new ParetoDistribution(new Well19937c(seed), durScale, durShape);
List<VMSpec> vms = new ArrayList<VMSpec>();
while(this.vmId < totalVmNum) {
int vmsInGroup = rVmNum.nextInt(4)+2;
double duration = Math.floor(rDuration.sample());
vms.addAll(generateVMGroup(vmsInGroup, lastStartTime, lastStartTime+duration));
lastStartTime += Math.floor(rStartTime.sample());
}
return vms;
}
public List<LinkSpec> generateLinks() {
// Dummy links
List<LinkSpec> links = new ArrayList<LinkSpec>();
links.add(new LinkSpec("default", "vm01","vm02", null));
links.add(new LinkSpec("default", "vm02","vm01", null));
links.add(new LinkSpec("default", "vm02","vm03", null));
links.add(new LinkSpec("default", "vm03","vm02", null));
return links;
}
public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
//return value;
}
}