/* * Copyright (c) 2010-2012 Thiago T. Sá * * This file is part of CloudReports. * * CloudReports is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * CloudReports is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * For more information about your rights as a user of CloudReports, * refer to the LICENSE file or see <http://www.gnu.org/licenses/>. */ package cloudreports.extensions; import cloudreports.extensions.vmallocationpolicies.VmAllocationPolicyExtensible; import cloudreports.models.Migration; import cloudreports.simulation.Simulation; import java.util.List; import java.util.Map; import org.cloudbus.cloudsim.*; import org.cloudbus.cloudsim.core.CloudSim; import org.cloudbus.cloudsim.core.CloudSimTags; import org.cloudbus.cloudsim.core.predicates.PredicateType; import org.cloudbus.cloudsim.power.PowerHost; /** * This is a subtype of CloudSim's PowerDatacenter class that implements some * functionalities needed to collect simulation data and generate reports. * * @author Thiago T. Sá * @since 1.0 */ public class PowerDatacenter extends org.cloudbus.cloudsim.power.PowerDatacenter { /** The period between data collections. */ private double monitoringInterval; /** The last time data was collected. */ private double lastMonitoringTime; /** * A new constructor that sets the monitoring interval and the last monitoring * time and uses its base class constructor to initialize the power datacenter. * * @param name the name of the datacenter. * @param characteristics the characteristics of the datacenter. * @param vmAllocationPolicy the virtual machine allocation policy. * @param storageList a list of storage systems. * @param schedulingInterval the period used for scheduling. * @param monitoringInterval the period between data collection. * @since 1.0 */ public PowerDatacenter(String name, DatacenterCharacteristics characteristics, VmAllocationPolicy vmAllocationPolicy, List<Storage> storageList, double schedulingInterval, double monitoringInterval) throws Exception { super(name,characteristics,vmAllocationPolicy,storageList, schedulingInterval); this.monitoringInterval = monitoringInterval; this.lastMonitoringTime = 0; } /** * An overridden version of the method that adds data collection * functionalities. * * @since 1.0 */ @Override protected void updateCloudletProcessing() { if (getCloudletSubmitted() == -1 || getCloudletSubmitted() == CloudSim.clock()) { CloudSim.cancelAll(getId(), new PredicateType(CloudSimTags.VM_DATACENTER_EVENT)); schedule(getId(), getSchedulingInterval(), CloudSimTags.VM_DATACENTER_EVENT); return; } double currentTime = CloudSim.clock(); double timeframePower = 0.0; // if some time passed since last processing if (currentTime > getLastProcessTime()) { double timeDiff = currentTime - getLastProcessTime(); double minTime = Double.MAX_VALUE; Log.printLine("\n"); for (PowerHost host : this.<PowerHost>getHostList()) { double hostPower = 0.0; if (host.getUtilizationOfCpu() > 0) { try { hostPower = host.getPower() * timeDiff; timeframePower += hostPower; } catch (Exception e) { e.printStackTrace(); } } } for (PowerHost host : this.<PowerHost>getHostList()) { double time = host.updateVmsProcessing(currentTime); // inform VMs to update processing if (time < minTime) { minTime = time; } } setPower(getPower() + timeframePower); if((currentTime - this.lastMonitoringTime) >= this.getMonitoringInterval()) { this.lastMonitoringTime = currentTime; if (!isDisableMigrations()) { //Get VM migration list according to active policies List<Migration> migrationList = ((VmAllocationPolicyExtensible) getVmAllocationPolicy()).getListOfMigrationsToBeExecuted(getVmList()); for (Migration migration : migrationList) { Vm vm = migration.getVm(); PowerHost targetHost = (PowerHost) migration.getTargetHost(); PowerHost oldHost = (PowerHost) migration.getSourceHost(); migration.setTime(CloudSim.clock()); targetHost.addMigratingInVm(vm); if (oldHost == null) { Log.formatLine("%.2f: Migration of VM #%d to Host #%d has started", CloudSim.clock(), vm.getId(), targetHost.getId()); } else { Log.formatLine("%.2f: Migration of VM #%d from Host #%d to Host #%d has started", CloudSim.clock(), vm.getId(), oldHost.getId(), targetHost.getId()); } incrementMigrationCount(); vm.setInMigration(true); /** VM migration delay = RAM / bandwidth + C (C = 10 sec) **/ send(getId(), vm.getRam() / ((double) vm.getBw() / 8000) + 10, CloudSimTags.VM_MIGRATE, migration.getMigrationMap()); } if(!migrationList.isEmpty()) Simulation.getDataCollector().flushMigrations(migrationList); } //Collect monitored used resources Simulation.getDataCollector().collectMonitoredUsedResources(); } // schedules an event to the next time if (minTime != Double.MAX_VALUE) { CloudSim.cancelAll(getId(), new PredicateType(CloudSimTags.VM_DATACENTER_EVENT)); send(getId(), getSchedulingInterval(), CloudSimTags.VM_DATACENTER_EVENT); } setLastProcessTime(currentTime); Simulation.getDataCollector().collectData(); } } /** * Gets the debts of this datacenter. * * @return the debts of this datacenter. */ @Override public Map<Integer, Double> getDebts() { return super.getDebts(); } /** * Gets the monitoring interval of this datacenter. * * @return the period between data collections. */ public double getMonitoringInterval() { return monitoringInterval; } }