Commit ecd0ad0b authored by rodrigo.calheiros's avatar rodrigo.calheiros

Classes related to federation were removed, as they were not properly supported.

parent fe5ec634
/*
* 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-2010, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim;
import java.util.List;
/**
* This class represents the coordinator of a federation of clouds.
* It interacts with other clouds coordinators in order to exchange
* virtual machines and user applicatoins, if required.
*
* @author Rodrigo N. Calheiros
* @since CloudSim Toolkit 1.0
*/
public abstract class CloudCoordinator {
/** The datacenter. */
protected FederatedDatacenter datacenter;
/** The federation. */
protected List<Integer> federation;
/**
* Defines the FederatedDataCenter this coordinator works for.
*
* @param datacenter FederatedDataCenter associated to this coordinator.
*
* @pre $none
* @post $none
*/
public void setDatacenter(FederatedDatacenter datacenter){
this.datacenter = datacenter;
}
/**
* Informs about the other data centers that are part of the federation.
*
* @param federationList List of DataCenters ids that are part of the federation
*
* @pre federationList != null
* @post $none
*/
public void setFederation(List<Integer> federationList) {
this.federation = federationList;
}
/**
* This method is periodically called by the FederatedDataCenter to
* makethe coordinator update the sensors measuring in order to decide
* if modification in the data center must be processed. This modification
* requires migration of virtual machines and/or user applications from
* one data center to another.
*
* @pre $none
* @post $none
*/
public void updateDatacenter() {
for (Sensor<Double> s : this.datacenter.getSensors()) {
int result = s.monitor();
if (result != 0) {
migrate(s, result);
}
}
}
/**
* Implements a specific migration policy to be deployed by the cloud coordinator.
*
* @param result the result vof the last measurement:
* -1 if the measurement fell below the lower threshold
* +1 if the measurement fell above the higher threshold
* @param sensor the sensor
*
* @pre sensor != null
* @post $none
*/
protected abstract void migrate(Sensor<Double> sensor,int result);
}
\ No newline at end of file
/*
* 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-2010, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.core.CloudSimTags;
import org.cloudbus.cloudsim.core.SimEntity;
import org.cloudbus.cloudsim.core.SimEvent;
/**
* PowerDatacenter class is a CloudResource whose hostList
* are virtualized. It deals with processing of VM queries (i.e., handling
* of VMs) instead of processing Cloudlet-related queries. So, even though an
* AllocPolicy will be instantiated (in the init() method of the superclass,
* it will not be used, as processing of cloudlets are handled by the CloudletScheduler
* and processing of VirtualMachines are handled by the VmAllocationPolicy.
*
* @author Rodrigo N. Calheiros
* @since CloudSim Toolkit 1.0
*/
public class FederatedDatacenter extends SimEntity {
private static final int COORDINATOR_CALL = 46789;
/** The characteristics. */
private DatacenterCharacteristics characteristics;
/** The regional cis name. */
private String regionalCisName;
/** The vm provisioner. */
private VmAllocationPolicy vmAllocationPolicy;
/** The last process time. */
private double lastProcessTime;
/** The debts. */
private Map<Integer, Double> debts;
/** The storage list. */
private List<Storage> storageList;
/** The vm list. */
private List<? extends Vm> vmList;
protected CloudCoordinator coordinator;
protected List<Integer> federationList;
protected List<Sensor<Double>> sensorsList;
private int delay = 60*60;
/**
* Allocates a new PowerDatacenter object.
*
* @param name the name to be associated with this entity (as
* required by Sim_entity class from simjava package)
* @param characteristics an object of DatacenterCharacteristics
* @param storageList a LinkedList of storage elements, for data simulation
* @param vmAllocationPolicy the vmAllocationPolicy
*
* @throws Exception This happens when one of the following scenarios occur:
* <ul>
* <li> creating this entity before initializing CloudSim package
* <li> this entity name is <tt>null</tt> or empty
* <li> this entity has <tt>zero</tt> number of PEs (Processing
* Elements). <br>
* No PEs mean the Cloudlets can't be processed.
* A CloudResource must contain one or more Machines.
* A Machine must contain one or more PEs.
* </ul>
*
* @pre name != null
* @pre resource != null
* @post $none
*/
public FederatedDatacenter(String name, DatacenterCharacteristics characteristics, VmAllocationPolicy vmAllocationPolicy, List<Storage> storageList, double schedulingInterval, CloudCoordinator coordinator) throws Exception {
super(name);
this.coordinator=coordinator;
coordinator.setDatacenter(this);
this.sensorsList = new LinkedList<Sensor<Double>>();
setCharacteristics(characteristics);
setVmAllocationPolicy(vmAllocationPolicy);
setLastProcessTime(0.0);
setDebts(new HashMap<Integer,Double>());
setStorageList(storageList);
setVmList(new ArrayList<Vm>());
// If this resource doesn't have any PEs then no useful at all
if (getCharacteristics().getPesNumber() == 0) {
throw new Exception(super.getName() + " : Error - this entity has no PEs. Therefore, can't process any Cloudlets.");
}
// stores id of this class
getCharacteristics().setId(super.getId());
}
/**
* Overrides this method when making a new and different type of resource.
* This method is called by {@link #body()} to register other type to
* GIS entity. In doing so, you
* need to create a new child class extending from
* gridsim.CloudInformationService.
* <br>
* <b>NOTE:</b> You do not need to override {@link #body()} method, if
* you use this method.
*
* @pre $none
* @post $none
*/
protected void registerOtherEntity() {
// empty. This should be override by a child class
}
/**
* Processes events or services that are available for this PowerDatacenter.
*
* @param ev a Sim_event object
*
* @pre ev != null
* @post $none
*/
@Override
public void processEvent(SimEvent ev) {
int srcId = -1;
switch (ev.getTag()) {
// Resource characteristics inquiry
case CloudSimTags.RESOURCE_CHARACTERISTICS:
srcId = ((Integer) ev.getData()).intValue();
sendNow(srcId, ev.getTag(), getCharacteristics());
break;
// Resource dynamic info inquiry
case CloudSimTags.RESOURCE_DYNAMICS:
srcId = ((Integer) ev.getData()).intValue();
sendNow(srcId, ev.getTag(), 0);
break;
case CloudSimTags.RESOURCE_NUM_PE:
srcId = ((Integer) ev.getData()).intValue();
int numPE = getCharacteristics().getPesNumber();
sendNow(srcId, ev.getTag(), numPE);
break;
case CloudSimTags.RESOURCE_NUM_FREE_PE:
srcId = ((Integer) ev.getData()).intValue();
int freePesNumber = getCharacteristics().getFreePesNumber();
sendNow(srcId, ev.getTag(), freePesNumber);
break;
// New Cloudlet arrives
case CloudSimTags.CLOUDLET_SUBMIT:
processCloudletSubmit(ev, false);
break;
// New Cloudlet arrives, but the sender asks for an ack
case CloudSimTags.CLOUDLET_SUBMIT_ACK:
processCloudletSubmit(ev, true);
break;
// Cancels a previously submitted Cloudlet
case CloudSimTags.CLOUDLET_CANCEL:
processCloudlet(ev, CloudSimTags.CLOUDLET_CANCEL);
break;
// Pauses a previously submitted Cloudlet
case CloudSimTags.CLOUDLET_PAUSE:
processCloudlet(ev, CloudSimTags.CLOUDLET_PAUSE);
break;
// Pauses a previously submitted Cloudlet, but the sender
// asks for an acknowledgement
case CloudSimTags.CLOUDLET_PAUSE_ACK:
processCloudlet(ev, CloudSimTags.CLOUDLET_PAUSE_ACK);
break;
// Resumes a previously submitted Cloudlet
case CloudSimTags.CLOUDLET_RESUME:
processCloudlet(ev, CloudSimTags.CLOUDLET_RESUME);
break;
// Resumes a previously submitted Cloudlet, but the sender
// asks for an acknowledgement
case CloudSimTags.CLOUDLET_RESUME_ACK:
processCloudlet(ev, CloudSimTags.CLOUDLET_RESUME_ACK);
break;
// Moves a previously submitted Cloudlet to a different resource
case CloudSimTags.CLOUDLET_MOVE:
processCloudletMove((int[]) ev.getData(), CloudSimTags.CLOUDLET_MOVE);
break;
// Moves a previously submitted Cloudlet to a different resource
case CloudSimTags.CLOUDLET_MOVE_ACK:
processCloudletMove((int[]) ev.getData(), CloudSimTags.CLOUDLET_MOVE_ACK);
break;
// Checks the status of a Cloudlet
case CloudSimTags.CLOUDLET_STATUS:
processCloudletStatus(ev);
break;
// Ping packet
case CloudSimTags.INFOPKT_SUBMIT:
processPingRequest(ev);
break;
case CloudSimTags.VM_CREATE:
processVmCreate(ev, false);
break;
case CloudSimTags.VM_CREATE_ACK:
processVmCreate(ev, true);
break;
case CloudSimTags.VM_DESTROY:
processVmDestroy(ev, false);
break;
case CloudSimTags.VM_DESTROY_ACK:
processVmDestroy(ev, true);
break;
case CloudSimTags.VM_MIGRATE:
processVmMigrate(ev, false);
break;
case CloudSimTags.VM_MIGRATE_ACK:
processVmMigrate(ev, true);
break;
case CloudSimTags.VM_DATA_ADD:
processDataAdd(ev, false);
break;
case CloudSimTags.VM_DATA_ADD_ACK:
processDataAdd(ev, true);
break;
case CloudSimTags.VM_DATA_DEL:
processDataDelete(ev, false);
break;
case CloudSimTags.VM_DATA_DEL_ACK:
processDataDelete(ev, true);
break;
case CloudSimTags.VM_DATACENTER_EVENT:
updateCloudletProcessing();
checkCloudletCompletion();
break;
case COORDINATOR_CALL:
processCoordinatorCall();
break;
// other unknown tags are processed by this method
default:
processOtherEvent(ev);
break;
}
}
private void processCoordinatorCall() {
updateCloudletProcessing();
checkCloudletCompletion();
coordinator.updateDatacenter();
send(getId(), delay, COORDINATOR_CALL);
}
/**
* Process data del.
*
* @param ev the ev
* @param ack the ack
*/
protected void processDataDelete(SimEvent ev, boolean ack) {
if (ev == null) {
return;
}
Object[] data = (Object[]) ev.getData();
if (data == null) {
return;
}
String filename = (String) data[0];
int req_source = ((Integer) data[1]).intValue();
int tag = -1;
// check if this file can be deleted (do not delete is right now)
int msg = deleteFileFromStorage(filename);
if (msg == DataCloudTags.FILE_DELETE_SUCCESSFUL) {
tag = DataCloudTags.CTLG_DELETE_MASTER;
} else { // if an error occured, notify user
tag = DataCloudTags.FILE_DELETE_MASTER_RESULT;
}
if (ack){
// send back to sender
Object pack[] = new Object[2];
pack[0] = filename;
pack[1] = Integer.valueOf(msg);
sendNow(req_source, tag, pack);
}
}
/**
* Process data add.
*
* @param ev the ev
* @param ack the ack
*/
protected void processDataAdd(SimEvent ev, boolean ack) {
if (ev == null) {
return;
}
Object[] pack = (Object[]) ev.getData();
if (pack == null) {
return;
}
File file = (File) pack[0]; // get the file
file.setMasterCopy(true); // set the file into a master copy
int sentFrom = ((Integer) pack[1]).intValue(); // get sender ID
/****** // DEBUG
Log.printLine(super.get_name() + ".addMasterFile(): " +
file.getName() + " from " + CloudSim.getEntityName(sentFrom));
*******/
Object[] data = new Object[3];
data[0] = file.getName();
int msg = addFile(file); // add the file
double debit;
if (getDebts().containsKey(sentFrom)) {
debit = getDebts().get(sentFrom);
} else {
debit = 0.0;
}
debit += getCharacteristics().getCostPerBw() * file.getSize();
getDebts().put(sentFrom, debit);
if (ack) {
data[1] = Integer.valueOf(-1); // no sender id
data[2] = Integer.valueOf(msg); // the result of adding a master file
sendNow(sentFrom, DataCloudTags.FILE_ADD_MASTER_RESULT, data);
}
}
/**
* Processes a ping request.
*
* @param ev a Sim_event object
*
* @pre ev != null
* @post $none
*/
protected void processPingRequest(SimEvent ev) {
InfoPacket pkt = (InfoPacket) ev.getData();
pkt.setTag(CloudSimTags.INFOPKT_RETURN);
pkt.setDestId(pkt.getSrcId());
// sends back to the sender
sendNow(pkt.getSrcId(), CloudSimTags.INFOPKT_RETURN, pkt);
}
/**
* Process the event for an User/Broker who wants to know the status of a Cloudlet.
* This PowerDatacenter will then send the status back to the User/Broker.
*
* @param ev a Sim_event object
*
* @pre ev != null
* @post $none
*/
protected void processCloudletStatus(SimEvent ev) {
int cloudletId = 0;
int userId = 0;
int vmId = 0;
int status = -1;
try{
// if a sender using cloudletXXX() methods
int data[] = (int[]) ev.getData();
cloudletId = data[0];
userId = data[1];
vmId = data[2];
status = getVmAllocationPolicy().getHost(vmId, userId).getVm(userId, vmId).getCloudletScheduler().getCloudletStatus(cloudletId);
}
// if a sender using normal send() methods
catch (ClassCastException c) {
try {
Cloudlet cl = (Cloudlet) ev.getData();
cloudletId = cl.getCloudletId();
userId = cl.getUserId();
status = getVmAllocationPolicy().getHost(vmId, userId).getVm(userId, vmId).getCloudletScheduler().getCloudletStatus(cloudletId);
}
catch (Exception e) {
Log.printLine(getName() +
": Error in processing CloudSimTags.CLOUDLET_STATUS");
Log.printLine( e.getMessage() );
return;
}
}
catch (Exception e) {
Log.printLine(getName() +
": Error in processing CloudSimTags.CLOUDLET_STATUS");
Log.printLine( e.getMessage() );
return;
}
int[] array = new int[3];
array[0] = getId();
array[1] = cloudletId;
array[2] = status;
int tag = CloudSimTags.CLOUDLET_STATUS;
send(userId, CloudSimTags.SCHEDULE_NOW, tag, array);
}
/**
* Here all the method related to VM requests will be received and forwarded to the related method.
*
* @param ev the received event
*
* @pre $none
* @post $none
*/
protected void processOtherEvent(SimEvent ev) {
if (ev == null){
Log.printLine(getName() + ".processOtherEvent(): Error - an event is null.");
}
}
/**
* Process the event for an User/Broker who wants to create a VM
* in this PowerDatacenter. This PowerDatacenter will then send the status back to
* the User/Broker.
*
* @param ev a Sim_event object
* @param ack the ack
*
* @pre ev != null
* @post $none
*/
protected void processVmCreate(SimEvent ev, boolean ack) {
Vm vm = (Vm) ev.getData();
boolean result = getVmAllocationPolicy().allocateHostForVm(vm);
if (ack) {
int[] data = new int[3];
data[0] = getId();
data[1] = vm.getId();
if (result) {
data[2] = CloudSimTags.TRUE;
} else {
data[2] = CloudSimTags.FALSE;
}
sendNow(vm.getUserId(), CloudSimTags.VM_CREATE_ACK, data);
}
if (result) {
double amount = 0.0;
if (getDebts().containsKey(vm.getUserId())) {
amount = getDebts().get(vm.getUserId());
}
amount += getCharacteristics().getCostPerMem() * vm.getRam();
amount += getCharacteristics().getCostPerStorage() * vm.getSize();
getDebts().put(vm.getUserId(), amount);
getVmList().add(vm);
vm.updateVmProcessing(CloudSim.clock(), getVmAllocationPolicy().getHost(vm).getVmScheduler().getAllocatedMipsForVm(vm));
}
}
/**
* Process the event for an User/Broker who wants to destroy a VM
* previously created in this PowerDatacenter. This PowerDatacenter may send,
* upon request, the status back to the User/Broker.
*
* @param ev a Sim_event object
* @param ack the ack
*
* @pre ev != null
* @post $none
*/
protected void processVmDestroy(SimEvent ev, boolean ack) {
Vm vm = (Vm) ev.getData();
getVmAllocationPolicy().deallocateHostForVm(vm);
if (ack) {
int[] data = new int[3];
data[0] = getId();
data[1] = vm.getId();
data[2] = CloudSimTags.TRUE;
sendNow(vm.getUserId(), CloudSimTags.VM_DESTROY_ACK, data);
}
getVmList().remove(vm);
}
/**
* Process the event for an User/Broker who wants to migrate a VM.
* This PowerDatacenter will then send the status back to the User/Broker.
* @param ev a Sim_event object
* @pre ev != null
* @post $none
*/
protected void processVmMigrate(SimEvent ev, boolean ack) {
Object tmp = ev.getData();
if (!(tmp instanceof Map<?, ?>)) {
throw new ClassCastException("The data object must be Map<String, Object>");
}
@SuppressWarnings("unchecked")
Map<String, Object> migrate = (HashMap<String, Object>) tmp;
Vm vm = (Vm) migrate.get("vm");
Host host = (Host) migrate.get("host");
boolean result = host.vmCreate(vm);
if (!result) {
Log.printLine("Allocation with best effort...");
// VM allocation may fail, because utilization may change due to migration delay
result = host.vmCreate(vm);
}
if (ack) {
int[] data = new int[3];
data[0] = getId();
data[1] = vm.getId();
if (result) {
data[2] = CloudSimTags.TRUE;
} else {
data[2] = CloudSimTags.FALSE;
}
sendNow(ev.getSource(), CloudSimTags.VM_CREATE_ACK, data);
}
double amount=0.0;
if (debts.containsKey(vm.getUserId())) {
amount = debts.get(vm.getUserId());
}
amount += getCharacteristics().getCostPerMem() * vm.getRam();
amount += getCharacteristics().getCostPerStorage() * vm.getSize();
debts.put(vm.getUserId(), amount);
Log.formatLine("%.2f: Migration of VM #%d to Host #%d is completed", CloudSim.clock(), vm.getId(), host.getId());
vm.setInMigration(false);
}
/**
* Processes a Cloudlet based on the event type.
*
* @param ev a Sim_event object
* @param type event type
*
* @pre ev != null
* @pre type > 0
* @post $none
*/
protected void processCloudlet(SimEvent ev, int type) {
int cloudletId = 0;
int userId = 0;
int vmId = 0;
try {
// if a sender using cloudletXXX() methods
int data[] = (int[]) ev.getData();
cloudletId = data[0];
userId = data[1];
vmId = data[2];
}
// if a sender using normal send() methods
catch (ClassCastException c) {
try {
Cloudlet cl = (Cloudlet) ev.getData();
cloudletId = cl.getCloudletId();
userId = cl.getUserId();
vmId = cl.getVmId();
} catch (Exception e) {
Log.printLine(super.getName() + ": Error in processing Cloudlet");
Log.printLine(e.getMessage());
return;
}
} catch (Exception e) {
Log.printLine(super.getName() + ": Error in processing a Cloudlet.");
Log.printLine( e.getMessage() );
return;
}
// begins executing ....
switch (type) {
case CloudSimTags.CLOUDLET_CANCEL:
processCloudletCancel(cloudletId, userId, vmId);
break;
case CloudSimTags.CLOUDLET_PAUSE:
processCloudletPause(cloudletId, userId, vmId, false);
break;
case CloudSimTags.CLOUDLET_PAUSE_ACK:
processCloudletPause(cloudletId, userId, vmId, true);
break;
case CloudSimTags.CLOUDLET_RESUME:
processCloudletResume(cloudletId, userId, vmId, false);
break;
case CloudSimTags.CLOUDLET_RESUME_ACK:
processCloudletResume(cloudletId, userId, vmId, true);
break;
default:
break;
}
}
/**
* Process the event for an User/Broker who wants to move a Cloudlet.
*
* @param receivedData information about the migration
* @param type event tag
*
* @pre receivedData != null
* @pre type > 0
* @post $none
*/
protected void processCloudletMove(int[] receivedData, int type) {
updateCloudletProcessing();
int[] array = receivedData;
int cloudletId = array[0];
int userId = array[1];
int vmId = array[2];
int vmDestId = array[3];
int destId = array[4];
//get the cloudlet
Cloudlet cl = getVmAllocationPolicy().getHost(vmId, userId).getVm(userId, vmId).getCloudletScheduler().cloudletCancel(cloudletId);
boolean failed=false;
if (cl == null) {// cloudlet doesn't exist
failed = true;
} else {
// has the cloudlet already finished?
if (cl.getCloudletStatus() == Cloudlet.SUCCESS) {// if yes, send it back to user
int[] data = new int[3];
data[0] = this.getId();
data[1] = cloudletId;
data[2] = 0;
sendNow(cl.getUserId(), CloudSimTags.CLOUDLET_SUBMIT_ACK, data);
sendNow(cl.getUserId(), CloudSimTags.CLOUDLET_RETURN, cl);
}
// prepare cloudlet for migration
cl.setVmId(vmDestId);
// the cloudlet will migrate from one vm to another does the destination VM exist?
if (destId == this.getId()) {
Vm vm = getVmAllocationPolicy().getHost(vmDestId, userId).getVm(userId, vmDestId);
if (vm == null) {
failed = true;
} else {
double fileTransferTime = predictFileTransferTime(cl.getRequiredFiles()); // time to transfer the files
vm.getCloudletScheduler().cloudletSubmit(cl, fileTransferTime);
}
} else {// the cloudlet will migrate from one resource to another
int tag = ((type == CloudSimTags.CLOUDLET_MOVE_ACK) ? CloudSimTags.CLOUDLET_SUBMIT_ACK : CloudSimTags.CLOUDLET_SUBMIT);
sendNow(destId, tag, cl);
}
}
if (type == CloudSimTags.CLOUDLET_MOVE_ACK) {// send ACK if requested
int[] data = new int[3];
data[0] = this.getId();
data[1] = cloudletId;
if (failed) {
data[2] = 0;
} else {
data[2] = 1;
}
sendNow(cl.getUserId(), CloudSimTags.CLOUDLET_SUBMIT_ACK, data);
}
}
/**
* Processes a Cloudlet submission.
*
* @param ev a SimEvent object
* @param ack an acknowledgement
*
* @pre ev != null
* @post $none
*/
protected void processCloudletSubmit(SimEvent ev, boolean ack) {
updateCloudletProcessing();
try {
// gets the Cloudlet object
Cloudlet cl = (Cloudlet) ev.getData();
// checks whether this Cloudlet has finished or not
if (cl.isFinished()){
String name = CloudSim.getEntityName(cl.getUserId());
Log.printLine(getName()+": Warning - Cloudlet #"+cl.getCloudletId()+" owned by "+name+" is already completed/finished.");
Log.printLine("Therefore, it is not being executed again");
Log.printLine();
// NOTE: If a Cloudlet has finished, then it won't be processed.
// So, if ack is required, this method sends back a result.
// If ack is not required, this method don't send back a result.
// Hence, this might cause CloudSim to be hanged since waiting
// for this Cloudlet back.
if (ack) {
int[] data = new int[3];
data[0] = getId();
data[1] = cl.getCloudletId();
data[2] = CloudSimTags.FALSE;
// unique tag = operation tag
int tag = CloudSimTags.CLOUDLET_SUBMIT_ACK;
sendNow(cl.getUserId(), tag, data);
}
sendNow(cl.getUserId(), CloudSimTags.CLOUDLET_RETURN, cl);
return;
}
// process this Cloudlet to this CloudResource
cl.setResourceParameter(getId(), getCharacteristics().getCostPerSecond(), getCharacteristics().getCostPerBw());
int userId = cl.getUserId();
int vmId = cl.getVmId();
double fileTransferTime = predictFileTransferTime(cl.getRequiredFiles()); //time to transfer the files
Host host = getVmAllocationPolicy().getHost(vmId, userId);
Vm vm = host.getVm(vmId, userId);
CloudletScheduler scheduler = vm.getCloudletScheduler();
double estimatedFinishTime = scheduler.cloudletSubmit(cl,fileTransferTime);
//if (estimatedFinishTime > 0.0 && estimatedFinishTime < getSchedulingInterval()) { //if this cloudlet is in the exec queue
if (estimatedFinishTime > 0.0) { //if this cloudlet is in the exec queue
//double estimatedFinishTime = (cl.getCloudletTotalLength()/(capacity*cl.getPesNumber())); //time to process the cloudlet
//Log.printLine(estimatedFinishTime+"="+gl.getCloudletLength()+"/("+capacity+"*"+gl.getNumPE()+")");
estimatedFinishTime += fileTransferTime;
estimatedFinishTime -= CloudSim.clock();
//Log.printLine(CloudSim.clock()+": Next event set to "+estimatedFinishTime);
send(getId(), estimatedFinishTime, CloudSimTags.VM_DATACENTER_EVENT);
}
if (ack) {
int[] data = new int[3];
data[0] = getId();
data[1] = cl.getCloudletId();
data[2] = CloudSimTags.TRUE;
// unique tag = operation tag
int tag = CloudSimTags.CLOUDLET_SUBMIT_ACK;
sendNow(cl.getUserId(), tag, data);
}
}
catch (ClassCastException c) {
Log.printLine(getName() + ".processCloudletSubmit(): " + "ClassCastException error.");
c.printStackTrace();
}
catch (Exception e) {
Log.printLine(getName() + ".processCloudletSubmit(): " + "Exception error.");
e.printStackTrace();
}
checkCloudletCompletion();
}
/**
* Predict file transfer time.
*
* @param requiredFiles the required files
*
* @return the double
*/
protected double predictFileTransferTime(List<String> requiredFiles) {
double time=0.0;
Iterator<String> iter = requiredFiles.iterator();
while(iter.hasNext()){
String fileName = iter.next();
for (int i = 0; i < getStorageList().size(); i++) {
Storage tempStorage = getStorageList().get(i);
File tempFile = tempStorage.getFile(fileName);
if (tempFile != null) {
time+=tempFile.getSize()/tempStorage.getMaxTransferRate();
break;
}
}
}
return time;
}
/**
* Processes a Cloudlet resume request.
*
* @param cloudletId resuming cloudlet ID
* @param userId ID of the cloudlet's owner
* @param ack $true if an ack is requested after operation
* @param vmId the vm id
*
* @pre $none
* @post $none
*/
protected void processCloudletResume(int cloudletId, int userId, int vmId, boolean ack) {
double eventTime = getVmAllocationPolicy().getHost(vmId,userId).getVm(userId, vmId).getCloudletScheduler().cloudletResume(cloudletId);
boolean status = false;
if (eventTime > 0.0) { //if this cloudlet is in the exec queue
status = true;
if (eventTime > CloudSim.clock()) {
schedule(getId(), eventTime, CloudSimTags.VM_DATACENTER_EVENT);
}
}
if (ack) {
int[] data = new int[3];
data[0] = getId();
data[1] = cloudletId;
if (status) {
data[2] = CloudSimTags.TRUE;
} else {
data[2] = CloudSimTags.FALSE;
}
sendNow(userId, CloudSimTags.CLOUDLET_RESUME_ACK, data);
}
}
/**
* Processes a Cloudlet pause request.
*
* @param cloudletId resuming cloudlet ID
* @param userId ID of the cloudlet's owner
* @param ack $true if an ack is requested after operation
* @param vmId the vm id
*
* @pre $none
* @post $none
*/
protected void processCloudletPause(int cloudletId, int userId, int vmId, boolean ack) {
boolean status = getVmAllocationPolicy().getHost(vmId,userId).getVm(userId, vmId).getCloudletScheduler().cloudletPause(cloudletId);
if (ack) {
int[] data = new int[3];
data[0] = getId();
data[1] = cloudletId;
if (status) {
data[2] = CloudSimTags.TRUE;
} else {
data[2] = CloudSimTags.FALSE;
}
sendNow(userId, CloudSimTags.CLOUDLET_PAUSE_ACK, data);
}
}
/**
* Processes a Cloudlet cancel request.
*
* @param cloudletId resuming cloudlet ID
* @param userId ID of the cloudlet's owner
* @param vmId the vm id
*
* @pre $none
* @post $none
*/
protected void processCloudletCancel(int cloudletId, int userId, int vmId) {
Cloudlet cl = getVmAllocationPolicy().getHost(vmId,userId).getVm(userId, vmId).getCloudletScheduler().cloudletCancel(cloudletId);
sendNow(userId, CloudSimTags.CLOUDLET_CANCEL, cl);
}
/**
* Updates processing of each cloudlet running in this PowerDatacenter. It is necessary because
* Hosts and VirtualMachines are simple objects, not entities. So, they don't receive events
* and updating cloudlets inside them must be called from the outside.
*
* @pre $none
* @post $none
*/
protected void updateCloudletProcessing() {
//Log.printLine(CloudSim.clock()+": PowerDatacenter #"+this.get_id()+": updating cloudlet processing.......................................");
//if some time passed since last processing
if (CloudSim.clock() > this.getLastProcessTime()) {
List<? extends Host> list = getVmAllocationPolicy().getHostList();
double smallerTime = Double.MAX_VALUE;
//for each host...
for (int i = 0; i < list.size(); i++) {
Host host = list.get(i);
double time = host.updateVmsProcessing(CloudSim.clock());//inform VMs to update processing
//what time do we expect that the next cloudlet will finish?
if (time < smallerTime) {
smallerTime = time;
}
}
//schedules an event to the next time, if valid
//if (smallerTime > CloudSim.clock() + 0.01 && smallerTime != Double.MAX_VALUE && smallerTime < getSchedulingInterval()) {
if (smallerTime > CloudSim.clock() + 0.01 && smallerTime != Double.MAX_VALUE) {
schedule(getId(), (smallerTime - CloudSim.clock()), CloudSimTags.VM_DATACENTER_EVENT);
}
setLastProcessTime(CloudSim.clock());
}
}
/**
* Verifies if some cloudlet inside this PowerDatacenter already finished.
* If yes, send it to the User/Broker
*
* @pre $none
* @post $none
*/
protected void checkCloudletCompletion() {
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) {
sendNow(cl.getUserId(), CloudSimTags.CLOUDLET_RETURN, cl);
}
}
}
}
}
/**
* Adds a file into the resource's storage before the experiment starts.
* If the file is a master file, then it will be registered to the RC when
* the experiment begins.
*
* @param file a DataCloud file
*
* @return a tag number denoting whether this operation is a success or not
*
* @see CloudSim.datagrid.DataCloudTags#FILE_ADD_SUCCESSFUL
* @see CloudSim.datagrid.DataCloudTags#FILE_ADD_ERROR_EMPTY
*/
public int addFile(File file) {
if (file == null) {
return DataCloudTags.FILE_ADD_ERROR_EMPTY;
}
if (contains(file.getName()) == true) {
return DataCloudTags.FILE_ADD_ERROR_EXIST_READ_ONLY;
}
// check storage space first
if (getStorageList().size() <= 0) {
return DataCloudTags.FILE_ADD_ERROR_STORAGE_FULL;
}
Storage tempStorage = null;
int msg = DataCloudTags.FILE_ADD_ERROR_STORAGE_FULL;
for (int i = 0; i < getStorageList().size(); i++) {
tempStorage = getStorageList().get(i);
if (tempStorage.getAvailableSpace() >= file.getSize()) {
tempStorage.addFile(file);
msg = DataCloudTags.FILE_ADD_SUCCESSFUL;
break;
}
}
return msg;
}
/**
* Checks whether the resource has the given file.
*
* @param file a file to be searched
*
* @return <tt>true</tt> if successful, <tt>false</tt> otherwise
*/
protected boolean contains(File file) {
if (file == null) {
return false;
}
return contains( file.getName() );
}
/**
* Checks whether the resource has the given file.
*
* @param fileName a file name to be searched
*
* @return <tt>true</tt> if successful, <tt>false</tt> otherwise
*/
protected boolean contains(String fileName) {
if (fileName == null || fileName.length() == 0) {
return false;
}
Iterator<Storage> it = getStorageList().iterator();
Storage storage = null;
boolean result = false;
while (it.hasNext()) {
storage = it.next();
if (storage.contains(fileName) == true) {
result = true;
break;
}
}
return result;
}
/**
* Deletes the file from the storage. Also, check whether it is
* possible to delete the file from the storage.
*
* @param fileName the name of the file to be deleted
*
* @return the error message as defined in
* {@link CloudSim.datagrid.DataCloudTags}
*
* @see CloudSim.datagrid.DataCloudTags#FILE_DELETE_SUCCESSFUL
* @see CloudSim.datagrid.DataCloudTags#FILE_DELETE_ERROR_ACCESS_DENIED
* @see CloudSim.datagrid.DataCloudTags#FILE_DELETE_ERROR
*/
private int deleteFileFromStorage(String fileName) {
Storage tempStorage = null;
File tempFile = null;
int msg = DataCloudTags.FILE_DELETE_ERROR;
for (int i = 0; i < getStorageList().size(); i++) {
tempStorage = getStorageList().get(i);
tempFile = tempStorage.getFile(fileName);
tempStorage.deleteFile(fileName, tempFile);
msg = DataCloudTags.FILE_DELETE_SUCCESSFUL;
} // end for
return msg;
}
/**
* Prints the debts.
*/
public void printDebts() {
Log.printLine("*****PowerDatacenter: "+this.getName()+"*****");
Log.printLine("User id\t\tDebt");
Set<Integer> keys = getDebts().keySet();
Iterator<Integer> iter = keys.iterator();
while (iter.hasNext()) {
int key = iter.next();
double value = getDebts().get(key);
DecimalFormat df = new DecimalFormat("#.##");
Log.printLine(key+"\t\t"+df.format(value));
}
Log.printLine("**********************************");
}
/* (non-Javadoc)
* @see cloudsim.core.SimEntity#shutdownEntity()
*/
@Override
public void shutdownEntity() {
Log.printLine(getName() + " is shutting down...");
}
/* (non-Javadoc)
* @see cloudsim.core.SimEntity#startEntity()
*/
@Override
public void startEntity() {
Log.printLine(getName() + " is starting...");
// this resource should register to regional GIS.
// However, if not specified, then register to system GIS (the
// default CloudInformationService) entity.
int gisID = CloudSim.getEntityId(regionalCisName);
if (gisID == -1) {
gisID = CloudSim.getCloudInfoServiceEntityId();
}
//schedule an internal event for coordinator
send(getId(), delay, COORDINATOR_CALL);
// send the registration to GIS
sendNow(gisID, CloudSimTags.REGISTER_RESOURCE, getId());
// Below method is for a child class to override
registerOtherEntity();
}
/**
* Gets the host list.
*
* @return the host list
*/
// protected HostList2<? extends Host> getHostList() {
// return (HostList2<Host>) getCharacteristics().getHostList();
// }
@SuppressWarnings("unchecked")
public <T extends Host> List<T> getHostList() {
return (List<T>) getCharacteristics().getHostList();
}
/**
* Gets the characteristics.
*
* @return the characteristics
*/
protected DatacenterCharacteristics getCharacteristics() {
return characteristics;
}
/**
* Sets the characteristics.
*
* @param characteristics the new characteristics
*/
protected void setCharacteristics(DatacenterCharacteristics characteristics) {
this.characteristics = characteristics;
}
/**
* Gets the regional cis name.
*
* @return the regional cis name
*/
protected String getRegionalCisName() {
return regionalCisName;
}
/**
* Sets the regional cis name.
*
* @param regionalCisName the new regional cis name
*/
protected void setRegionalCisName(String regionalCisName) {
this.regionalCisName = regionalCisName;
}
/**
* Gets the vm provisioner.
*
* @return the vm provisioner
*/
protected VmAllocationPolicy getVmAllocationPolicy() {
return vmAllocationPolicy;
}
/**
* Sets the vm provisioner.
*
* @param vmAllocationPolicy the new vm provisioner
*/
protected void setVmAllocationPolicy(VmAllocationPolicy vmAllocationPolicy) {
this.vmAllocationPolicy = vmAllocationPolicy;
}
/**
* Gets the last process time.
*
* @return the last process time
*/
protected double getLastProcessTime() {
return lastProcessTime;
}
/**
* Sets the last process time.
*
* @param lastProcessTime the new last process time
*/
protected void setLastProcessTime(double lastProcessTime) {
this.lastProcessTime = lastProcessTime;
}
/**
* Gets the debts.
*
* @return the debts
*/
protected Map<Integer, Double> getDebts() {
return debts;
}
/**
* Sets the debts.
*
* @param debts the debts
*/
protected void setDebts(Map<Integer, Double> debts) {
this.debts = debts;
}
/**
* Gets the storage list.
*
* @return the storage list
*/
protected List<Storage> getStorageList() {
return storageList;
}
/**
* Sets the storage list.
*
* @param storageList the new storage list
*/
protected void setStorageList(List<Storage> storageList) {
this.storageList = storageList;
}
/**
* Gets the vm list.
*
* @return the vm list
*/
@SuppressWarnings("unchecked")
public <T extends Vm> List<T> getVmList() {
return (List<T>) vmList;
}
/**
* Sets the vm list.
*
* @param vmList the new vm list
*/
protected <T extends Vm> void setVmList(List<T> vmList) {
this.vmList = vmList;
}
public void addSensor(Sensor<Double> sensor){
sensor.setDatacenter(this);
this.sensorsList.add(sensor);
}
public List<Sensor<Double>> getSensors(){
return this.sensorsList;
}
}
/*
* 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-2010, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim;
/**
* This interface must be implemented by sensors to
* specific data center features.
*
* @author Rodrigo N. Calheiros
* @since CloudSim Toolkit 1.0
*/
public interface Sensor<T extends Number> {
/**
* Sets the data center the sensor monitors
* @param dataCenter data center monitored by this sensor
*/
void setDatacenter(FederatedDatacenter datacenter);
/**
* Updates internal measurement of the monitored feature
* @return -1 if current measurements falls below the minumum threshold,
* +1 if measurement falls above the maximum threshold,
* 0 if the measurement is within the specified interval
*/
int monitor();
/**
* Sets the upper limit of the feature monitored by the sensor
* @param value maximum value allowed to this sensor
*/
void setUpperThreshold(T value);
/**
* Sets the lower limit of the feature monitored by the sensor
* @param value minimum value allowed to this sensor
*/
void setLowerThreshold(T value);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment