/* * Title: CloudSim Toolkit * Description: CloudSim (Cloud Simulation) Toolkit for Modeling and Simulation of Clouds * Licence: GPL - http://www.gnu.org/copyleft/gpl.html * * Copyright (c) 2009-2012, The University of Melbourne, Australia */ package org.cloudbus.cloudsim.network.datacenter; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.cloudbus.cloudsim.Cloudlet; import org.cloudbus.cloudsim.DatacenterCharacteristics; 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; import org.cloudbus.cloudsim.distributions.UniformDistr; import org.cloudbus.cloudsim.lists.VmList; /** * NetDatacentreBroker represents a broker acting on behalf of Datacenter provider. It hides VM * management, as vm creation, submission of cloudlets to this VMs and destruction of VMs. NOTE- It * is an example only. It work on behalf of a provider not for users. One has to implement * interaction with user broker to this broker. * * @author Saurabh Kumar Garg * @since CloudSim Toolkit 3.0 */ public class NetDatacenterBroker extends SimEntity { // TODO: remove unnecessary variables /** The vm list. */ private List<? extends Vm> vmList; /** The vms created list. */ private List<? extends Vm> vmsCreatedList; /** The cloudlet list. */ private List<? extends NetworkCloudlet> cloudletList; private List<? extends AppCloudlet> appCloudletList; /** The Appcloudlet submitted list. */ private final Map<Integer, Integer> appCloudletRecieved; private List<? extends Cloudlet> cloudletSubmittedList; /** The cloudlet received list. */ private List<? extends Cloudlet> cloudletReceivedList; /** The cloudlets submitted. */ private int cloudletsSubmitted; /** The vms requested. */ private int vmsRequested; /** The vms acks. */ private int vmsAcks; /** The vms destroyed. */ private int vmsDestroyed; /** The datacenter ids list. */ private List<Integer> datacenterIdsList; /** The datacenter requested ids list. */ private List<Integer> datacenterRequestedIdsList; /** The vms to datacenters map. */ private Map<Integer, Integer> vmsToDatacentersMap; /** The datacenter characteristics list. */ private Map<Integer, DatacenterCharacteristics> datacenterCharacteristicsList; public static NetworkDatacenter linkDC; public boolean createvmflag = true; public static int cachedcloudlet = 0; /** * Created a new DatacenterBroker object. * * @param name name to be associated with this entity (as required by Sim_entity class from * simjava package) * * @throws Exception the exception * * @pre name != null * @post $none */ public NetDatacenterBroker(String name) throws Exception { super(name); setVmList(new ArrayList<NetworkVm>()); setVmsCreatedList(new ArrayList<NetworkVm>()); setCloudletList(new ArrayList<NetworkCloudlet>()); setAppCloudletList(new ArrayList<AppCloudlet>()); setCloudletSubmittedList(new ArrayList<Cloudlet>()); setCloudletReceivedList(new ArrayList<Cloudlet>()); appCloudletRecieved = new HashMap<Integer, Integer>(); cloudletsSubmitted = 0; setVmsRequested(0); setVmsAcks(0); setVmsDestroyed(0); setDatacenterIdsList(new LinkedList<Integer>()); setDatacenterRequestedIdsList(new ArrayList<Integer>()); setVmsToDatacentersMap(new HashMap<Integer, Integer>()); setDatacenterCharacteristicsList(new HashMap<Integer, DatacenterCharacteristics>()); } /** * This method is used to send to the broker the list with virtual machines that must be * created. * * @param list the list * * @pre list !=null * @post $none */ public void submitVmList(List<? extends Vm> list) { getVmList().addAll(list); } /** * This method is used to send to the broker the list of cloudlets. * * @param list the list * * @pre list !=null * @post $none */ public void submitCloudletList(List<? extends NetworkCloudlet> list) { getCloudletList().addAll(list); } public void setLinkDC(NetworkDatacenter alinkDC) { linkDC = alinkDC; } /** * Processes events available for this Broker. * * @param ev a SimEvent object * * @pre ev != null * @post $none */ @Override public void processEvent(SimEvent ev) { switch (ev.getTag()) { // Resource characteristics request case CloudSimTags.RESOURCE_CHARACTERISTICS_REQUEST: processResourceCharacteristicsRequest(ev); break; // Resource characteristics answer case CloudSimTags.RESOURCE_CHARACTERISTICS: processResourceCharacteristics(ev); break; // VM Creation answer // A finished cloudlet returned case CloudSimTags.CLOUDLET_RETURN: processCloudletReturn(ev); break; // if the simulation finishes case CloudSimTags.END_OF_SIMULATION: shutdownEntity(); break; case CloudSimTags.NextCycle: if (NetworkConstants.BASE) { createVmsInDatacenterBase(linkDC.getId()); } break; // other unknown tags are processed by this method default: processOtherEvent(ev); break; } } /** * Process the return of a request for the characteristics of a PowerDatacenter. * * @param ev a SimEvent object * * @pre ev != $null * @post $none */ protected void processResourceCharacteristics(SimEvent ev) { DatacenterCharacteristics characteristics = (DatacenterCharacteristics) ev.getData(); getDatacenterCharacteristicsList().put(characteristics.getId(), characteristics); if (getDatacenterCharacteristicsList().size() == getDatacenterIdsList().size()) { setDatacenterRequestedIdsList(new ArrayList<Integer>()); createVmsInDatacenterBase(getDatacenterIdsList().get(0)); } } /** * Process a request for the characteristics of a PowerDatacenter. * * @param ev a SimEvent object * * @pre ev != $null * @post $none */ protected void processResourceCharacteristicsRequest(SimEvent ev) { setDatacenterIdsList(CloudSim.getCloudResourceList()); setDatacenterCharacteristicsList(new HashMap<Integer, DatacenterCharacteristics>()); Log.printLine(CloudSim.clock() + ": " + getName() + ": Cloud Resource List received with " + getDatacenterIdsList().size() + " resource(s)"); for (Integer datacenterId : getDatacenterIdsList()) { sendNow(datacenterId, CloudSimTags.RESOURCE_CHARACTERISTICS, getId()); } } /** * Process the ack received due to a request for VM creation. * * @param ev a SimEvent object * * @pre ev != null * @post $none */ /** * Process a cloudlet return event. * * @param ev a SimEvent object * * @pre ev != $null * @post $none */ protected void processCloudletReturn(SimEvent ev) { Cloudlet cloudlet = (Cloudlet) ev.getData(); getCloudletReceivedList().add(cloudlet); cloudletsSubmitted--; // all cloudlets executed if (getCloudletList().size() == 0 && cloudletsSubmitted == 0 && NetworkConstants.iteration > 10) { Log.printLine(CloudSim.clock() + ": " + getName() + ": All Cloudlets executed. Finishing..."); clearDatacenters(); finishExecution(); } else { // some cloudlets haven't finished yet if (getAppCloudletList().size() > 0 && cloudletsSubmitted == 0) { // all the cloudlets sent finished. It means that some bount // cloudlet is waiting its VM be created clearDatacenters(); createVmsInDatacenterBase(0); } } } /** * Overrides this method when making a new and different type of Broker. This method is called * by {@link #body()} for incoming unknown tags. * * @param ev a SimEvent object * * @pre ev != null * @post $none */ protected void processOtherEvent(SimEvent ev) { if (ev == null) { Log.printLine(getName() + ".processOtherEvent(): " + "Error - an event is null."); return; } Log.printLine(getName() + ".processOtherEvent(): " + "Error - event unknown by this DatacenterBroker."); } /** * Create the virtual machines in a datacenter and submit/schedule cloudlets to them. * * @param datacenterId Id of the chosen PowerDatacenter * * @pre $none * @post $none */ protected void createVmsInDatacenterBase(int datacenterId) { // send as much vms as possible for this datacenter before trying the // next one int requestedVms = 0; // All host will have two VMs (assumption) VM is the minimum unit if (createvmflag) { CreateVMs(datacenterId); createvmflag = false; } // generate Application execution Requests for (int i = 0; i < 100; i++) { this.getAppCloudletList().add( new WorkflowApp(AppCloudlet.APP_Workflow, NetworkConstants.currentAppId, 0, 0, getId())); NetworkConstants.currentAppId++; } int k = 0; // schedule the application on VMs for (AppCloudlet app : this.getAppCloudletList()) { List<Integer> vmids = new ArrayList<Integer>(); int numVms = linkDC.getVmList().size(); UniformDistr ufrnd = new UniformDistr(0, numVms, 5); for (int i = 0; i < app.numbervm; i++) { int vmid = (int) ufrnd.sample(); vmids.add(vmid); } if (vmids != null) { if (!vmids.isEmpty()) { app.createCloudletList(vmids); for (int i = 0; i < app.numbervm; i++) { app.clist.get(i).setUserId(getId()); appCloudletRecieved.put(app.appID, app.numbervm); this.getCloudletSubmittedList().add(app.clist.get(i)); cloudletsSubmitted++; // Sending cloudlet sendNow( getVmsToDatacentersMap().get(this.getVmList().get(0).getId()), CloudSimTags.CLOUDLET_SUBMIT, app.clist.get(i)); } System.out.println("app" + (k++)); } } } setAppCloudletList(new ArrayList<AppCloudlet>()); if (NetworkConstants.iteration < 10) { NetworkConstants.iteration++; this.schedule(getId(), NetworkConstants.nexttime, CloudSimTags.NextCycle); } setVmsRequested(requestedVms); setVmsAcks(0); } private void CreateVMs(int datacenterId) { // two VMs per host int numVM = linkDC.getHostList().size() * NetworkConstants.maxhostVM; for (int i = 0; i < numVM; i++) { int vmid = i; int mips = 1; long size = 10000; // image size (MB) int ram = 512; // vm memory (MB) long bw = 1000; int pesNumber = NetworkConstants.HOST_PEs / NetworkConstants.maxhostVM; String vmm = "Xen"; // VMM name // create VM NetworkVm vm = new NetworkVm( vmid, getId(), mips, pesNumber, ram, bw, size, vmm, new NetworkCloudletSpaceSharedScheduler()); linkDC.processVmCreateNetwork(vm); // add the VM to the vmList getVmList().add(vm); getVmsToDatacentersMap().put(vmid, datacenterId); getVmsCreatedList().add(VmList.getById(getVmList(), vmid)); } } /** * Submit cloudlets to the created VMs. * * @pre $none * @post $none /** Destroy the virtual machines running in datacenters. * * @pre $none * @post $none */ protected void clearDatacenters() { for (Vm vm : getVmsCreatedList()) { Log.printLine(CloudSim.clock() + ": " + getName() + ": Destroying VM #" + vm.getId()); sendNow(getVmsToDatacentersMap().get(vm.getId()), CloudSimTags.VM_DESTROY, vm); } getVmsCreatedList().clear(); } /** * Send an internal event communicating the end of the simulation. * * @pre $none * @post $none */ private void finishExecution() { sendNow(getId(), CloudSimTags.END_OF_SIMULATION); } /* * (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..."); schedule(getId(), 0, CloudSimTags.RESOURCE_CHARACTERISTICS_REQUEST); } /** * Gets the vm list. * * @param <T> the generic type * @return the vm list */ @SuppressWarnings("unchecked") public <T extends Vm> List<T> getVmList() { return (List<T>) vmList; } /** * Sets the vm list. * * @param <T> the generic type * @param vmList the new vm list */ protected <T extends Vm> void setVmList(List<T> vmList) { this.vmList = vmList; } /** * Gets the cloudlet list. * * @param <T> the generic type * @return the cloudlet list */ @SuppressWarnings("unchecked") public <T extends NetworkCloudlet> List<T> getCloudletList() { return (List<T>) cloudletList; } /** * Sets the cloudlet list. * * @param <T> the generic type * @param cloudletList the new cloudlet list */ protected <T extends NetworkCloudlet> void setCloudletList(List<T> cloudletList) { this.cloudletList = cloudletList; } @SuppressWarnings("unchecked") public <T extends AppCloudlet> List<T> getAppCloudletList() { return (List<T>) appCloudletList; } public <T extends AppCloudlet> void setAppCloudletList(List<T> appCloudletList) { this.appCloudletList = appCloudletList; } /** * Gets the cloudlet submitted list. * * @param <T> the generic type * @return the cloudlet submitted list */ @SuppressWarnings("unchecked") public <T extends Cloudlet> List<T> getCloudletSubmittedList() { return (List<T>) cloudletSubmittedList; } /** * Sets the cloudlet submitted list. * * @param <T> the generic type * @param cloudletSubmittedList the new cloudlet submitted list */ protected <T extends Cloudlet> void setCloudletSubmittedList(List<T> cloudletSubmittedList) { this.cloudletSubmittedList = cloudletSubmittedList; } /** * Gets the cloudlet received list. * * @param <T> the generic type * @return the cloudlet received list */ @SuppressWarnings("unchecked") public <T extends Cloudlet> List<T> getCloudletReceivedList() { return (List<T>) cloudletReceivedList; } /** * Sets the cloudlet received list. * * @param <T> the generic type * @param cloudletReceivedList the new cloudlet received list */ protected <T extends Cloudlet> void setCloudletReceivedList(List<T> cloudletReceivedList) { this.cloudletReceivedList = cloudletReceivedList; } /** * Gets the vm list. * * @param <T> the generic type * @return the vm list */ @SuppressWarnings("unchecked") public <T extends Vm> List<T> getVmsCreatedList() { return (List<T>) vmsCreatedList; } /** * Sets the vm list. * * @param <T> the generic type * @param vmsCreatedList the vms created list */ protected <T extends Vm> void setVmsCreatedList(List<T> vmsCreatedList) { this.vmsCreatedList = vmsCreatedList; } /** * Gets the vms requested. * * @return the vms requested */ protected int getVmsRequested() { return vmsRequested; } /** * Sets the vms requested. * * @param vmsRequested the new vms requested */ protected void setVmsRequested(int vmsRequested) { this.vmsRequested = vmsRequested; } /** * Gets the vms acks. * * @return the vms acks */ protected int getVmsAcks() { return vmsAcks; } /** * Sets the vms acks. * * @param vmsAcks the new vms acks */ protected void setVmsAcks(int vmsAcks) { this.vmsAcks = vmsAcks; } /** * Increment vms acks. */ protected void incrementVmsAcks() { vmsAcks++; } /** * Gets the vms destroyed. * * @return the vms destroyed */ protected int getVmsDestroyed() { return vmsDestroyed; } /** * Sets the vms destroyed. * * @param vmsDestroyed the new vms destroyed */ protected void setVmsDestroyed(int vmsDestroyed) { this.vmsDestroyed = vmsDestroyed; } /** * Gets the datacenter ids list. * * @return the datacenter ids list */ protected List<Integer> getDatacenterIdsList() { return datacenterIdsList; } /** * Sets the datacenter ids list. * * @param datacenterIdsList the new datacenter ids list */ protected void setDatacenterIdsList(List<Integer> datacenterIdsList) { this.datacenterIdsList = datacenterIdsList; } /** * Gets the vms to datacenters map. * * @return the vms to datacenters map */ protected Map<Integer, Integer> getVmsToDatacentersMap() { return vmsToDatacentersMap; } /** * Sets the vms to datacenters map. * * @param vmsToDatacentersMap the vms to datacenters map */ protected void setVmsToDatacentersMap(Map<Integer, Integer> vmsToDatacentersMap) { this.vmsToDatacentersMap = vmsToDatacentersMap; } /** * Gets the datacenter characteristics list. * * @return the datacenter characteristics list */ protected Map<Integer, DatacenterCharacteristics> getDatacenterCharacteristicsList() { return datacenterCharacteristicsList; } /** * Sets the datacenter characteristics list. * * @param datacenterCharacteristicsList the datacenter characteristics list */ protected void setDatacenterCharacteristicsList( Map<Integer, DatacenterCharacteristics> datacenterCharacteristicsList) { this.datacenterCharacteristicsList = datacenterCharacteristicsList; } /** * Gets the datacenter requested ids list. * * @return the datacenter requested ids list */ protected List<Integer> getDatacenterRequestedIdsList() { return datacenterRequestedIdsList; } /** * Sets the datacenter requested ids list. * * @param datacenterRequestedIdsList the new datacenter requested ids list */ protected void setDatacenterRequestedIdsList(List<Integer> datacenterRequestedIdsList) { this.datacenterRequestedIdsList = datacenterRequestedIdsList; } }