From dc277886280b29a33e83c5138b6a94304af5a026 Mon Sep 17 00:00:00 2001 From: Hc Wang <0x4863@gmail.com> Date: Tue, 19 Mar 2019 09:02:08 +0800 Subject: [PATCH 1/4] Fixed most of the currently discovered typos. --- CONTRIBUTING.md | 2 +- README.md | 2 +- .../config/default_config.properties | 2 +- .../config/default_config.properties | 2 +- .../config/default_config.properties | 2 +- .../config/default_config.properties | 2 +- .../applications/sample_app1/MainApp.java | 2 +- .../applications/sample_app2/MainApp.java | 2 +- .../sample_app2/SampleEdgeOrchestrator.java | 4 +-- .../sample_app2/SampleNetworkModel.java | 14 ++++---- .../applications/sample_app3/MainApp.java | 2 +- .../SampleMobileServerManager.java | 6 ++-- .../sample_app4/FuzzyEdgeOrchestrator.java | 12 +++---- .../FuzzyExperimentalNetworkModel.java | 10 +++--- .../sample_app4/FuzzyMainApp.java | 2 +- .../cloud_server/CloudServerManager.java | 2 +- .../CloudVmAllocationPolicy_Custom.java | 2 +- .../DefaultCloudServerManager.java | 8 ++--- .../boun/edgecloudsim/core/SimManager.java | 2 +- .../boun/edgecloudsim/core/SimSettings.java | 34 +++++++++---------- .../CpuUtilizationModel_Custom.java | 2 +- .../DefaultMobileDeviceManager.java | 6 ++-- .../DefaultMobileServerManager.java | 2 +- .../MobileServerManager.java | 2 +- .../MobileVmAllocationPolicy_Custom.java | 4 +-- .../edge_orchestrator/EdgeOrchestrator.java | 2 +- .../edge_server/DefaultEdgeServerManager.java | 4 +-- .../edge_server/EdgeServerManager.java | 2 +- .../EdgeVmAllocationPolicy_Custom.java | 2 +- .../edgecloudsim/mobility/MobilityModel.java | 2 +- .../mobility/NomadicMobility.java | 4 +-- .../boun/edgecloudsim/network/MM1Queue.java | 10 +++--- .../edgecloudsim/network/NetworkModel.java | 2 +- .../IdleActiveLoadGenerator.java | 2 +- .../task_generator/LoadGeneratorModel.java | 2 +- .../boun/edgecloudsim/utils/PoissonDistr.java | 14 ++++---- .../boun/edgecloudsim/utils/SimLogger.java | 14 ++++---- 37 files changed, 95 insertions(+), 95 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 42df42c..38220c1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,7 +37,7 @@ If you want to specify more things, add additional notes here # How to Contribute to EdgeCloudSim -You can simply follow below steps to contribute to EdgeClouldSim: +You can simply follow below steps to contribute to EdgeCloudSim: 1. Create a working copy (fork the project & clone it) 2. Specify a new remote upstream repository diff --git a/README.md b/README.md index e88f05f..c415f09 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ EdgeCloudSim provides a simulation environment specific to Edge Computing scenar The discussion forum for EdgeCloudSim can be found [here](https://groups.google.com/forum/#!forum/edgecloudsim). We hope to meet with all interested parties in this forum. -Please feel free to join and let us discuss issues, share ideas related to EdgeCloudSim all togerther. +Please feel free to join and let us discuss issues, share ideas related to EdgeCloudSim all together. ## Needed Features diff --git a/scripts/sample_app1/config/default_config.properties b/scripts/sample_app1/config/default_config.properties index a8462a0..8abd908 100644 --- a/scripts/sample_app1/config/default_config.properties +++ b/scripts/sample_app1/config/default_config.properties @@ -10,7 +10,7 @@ min_number_of_mobile_devices=100 max_number_of_mobile_devices=1000 mobile_device_counter_size=100 -wan_propogation_delay=0.1 +wan_propagation_delay=0.1 lan_internal_delay=0.005 wlan_bandwidth=200 wan_bandwidth=15 diff --git a/scripts/sample_app2/config/default_config.properties b/scripts/sample_app2/config/default_config.properties index 3f37780..68c237d 100644 --- a/scripts/sample_app2/config/default_config.properties +++ b/scripts/sample_app2/config/default_config.properties @@ -10,7 +10,7 @@ min_number_of_mobile_devices=200 max_number_of_mobile_devices=2000 mobile_device_counter_size=200 -wan_propogation_delay=0.1 +wan_propagation_delay=0.1 lan_internal_delay=0.005 wlan_bandwidth=0 wan_bandwidth=0 diff --git a/scripts/sample_app3/config/default_config.properties b/scripts/sample_app3/config/default_config.properties index a19a3ac..830d1a6 100644 --- a/scripts/sample_app3/config/default_config.properties +++ b/scripts/sample_app3/config/default_config.properties @@ -10,7 +10,7 @@ min_number_of_mobile_devices=200 max_number_of_mobile_devices=2000 mobile_device_counter_size=200 -wan_propogation_delay=0.1 +wan_propagation_delay=0.1 lan_internal_delay=0.005 wlan_bandwidth=0 wan_bandwidth=0 diff --git a/scripts/sample_app4/config/default_config.properties b/scripts/sample_app4/config/default_config.properties index 027d409..9b58b8d 100644 --- a/scripts/sample_app4/config/default_config.properties +++ b/scripts/sample_app4/config/default_config.properties @@ -10,7 +10,7 @@ min_number_of_mobile_devices=200 max_number_of_mobile_devices=2400 mobile_device_counter_size=200 -wan_propogation_delay=0.1 +wan_propagation_delay=0.1 lan_internal_delay=0.005 wlan_bandwidth=0 wan_bandwidth=0 diff --git a/src/edu/boun/edgecloudsim/applications/sample_app1/MainApp.java b/src/edu/boun/edgecloudsim/applications/sample_app1/MainApp.java index fa17b12..6e47080 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app1/MainApp.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app1/MainApp.java @@ -32,7 +32,7 @@ public class MainApp { //disable console output of cloudsim library Log.disable(); - //enable console ourput and file output of this application + //enable console output and file output of this application SimLogger.enablePrintLog(); int iterationNumber = 1; diff --git a/src/edu/boun/edgecloudsim/applications/sample_app2/MainApp.java b/src/edu/boun/edgecloudsim/applications/sample_app2/MainApp.java index b88a31d..a25df0c 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app2/MainApp.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app2/MainApp.java @@ -32,7 +32,7 @@ public class MainApp { //disable console output of cloudsim library Log.disable(); - //enable console ourput and file output of this application + //enable console output and file output of this application SimLogger.enablePrintLog(); int iterationNumber = 1; diff --git a/src/edu/boun/edgecloudsim/applications/sample_app2/SampleEdgeOrchestrator.java b/src/edu/boun/edgecloudsim/applications/sample_app2/SampleEdgeOrchestrator.java index c1baa03..4d98dd5 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app2/SampleEdgeOrchestrator.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app2/SampleEdgeOrchestrator.java @@ -91,12 +91,12 @@ public class SampleEdgeOrchestrator extends EdgeOrchestrator { result = SimSettings.GENERIC_EDGE_DEVICE_ID; } else { - SimLogger.printLine("Unknow edge orchestrator policy! Terminating simulation..."); + SimLogger.printLine("Unknown edge orchestrator policy! Terminating simulation..."); System.exit(0); } } else { - SimLogger.printLine("Unknow simulation scenario! Terminating simulation..."); + SimLogger.printLine("Unknown simulation scenario! Terminating simulation..."); System.exit(0); } return result; diff --git a/src/edu/boun/edgecloudsim/applications/sample_app2/SampleNetworkModel.java b/src/edu/boun/edgecloudsim/applications/sample_app2/SampleNetworkModel.java index 19ecf6e..6a5c63f 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app2/SampleNetworkModel.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app2/SampleNetworkModel.java @@ -36,7 +36,7 @@ public class SampleNetworkModel extends NetworkModel { private int[] wanClients; private int[] wlanClients; - private double lastMM1QueeuUpdateTime; + private double lastMM1QueueUpdateTime; private double ManPoissonMeanForDownload; //seconds private double ManPoissonMeanForUpload; //seconds @@ -194,7 +194,7 @@ public class SampleNetworkModel extends NetworkModel { SimSettings SS = SimSettings.getInstance(); for(int taskIndex=0; taskIndex 15) ? 0 : result; } @@ -412,8 +412,8 @@ public class SampleNetworkModel extends NetworkModel { } public void updateMM1QueeuModel(){ - double lastInterval = CloudSim.clock() - lastMM1QueeuUpdateTime; - lastMM1QueeuUpdateTime = CloudSim.clock(); + double lastInterval = CloudSim.clock() - lastMM1QueueUpdateTime; + lastMM1QueueUpdateTime = CloudSim.clock(); if(numOfManTaskForDownload != 0){ ManPoissonMeanForDownload = lastInterval / (numOfManTaskForDownload / (double)numberOfMobileDevices); diff --git a/src/edu/boun/edgecloudsim/applications/sample_app3/MainApp.java b/src/edu/boun/edgecloudsim/applications/sample_app3/MainApp.java index e319b99..a27dab9 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app3/MainApp.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app3/MainApp.java @@ -32,7 +32,7 @@ public class MainApp { //disable console output of cloudsim library Log.disable(); - //enable console ourput and file output of this application + //enable console output and file output of this application SimLogger.enablePrintLog(); int iterationNumber = 1; diff --git a/src/edu/boun/edgecloudsim/applications/sample_app3/SampleMobileServerManager.java b/src/edu/boun/edgecloudsim/applications/sample_app3/SampleMobileServerManager.java index 8757969..8e09050 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app3/SampleMobileServerManager.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app3/SampleMobileServerManager.java @@ -65,7 +65,7 @@ public class SampleMobileServerManager extends MobileServerManager{ } @Override - public void createVmList(int brockerId) { + public void createVmList(int brokerId) { //VMs should have unique IDs, so create Mobile VMs after Edge+Cloud VMs int vmCounter=SimSettings.getInstance().getNumOfEdgeVMs() + SimSettings.getInstance().getNumOfCloudVMs(); @@ -82,7 +82,7 @@ public class SampleMobileServerManager extends MobileServerManager{ long bandwidth = 0; //VM Parameters - MobileVM vm = new MobileVM(vmCounter, brockerId, mips, numOfCores, ram, bandwidth, storage, vmm, new CloudletSchedulerTimeShared()); + MobileVM vm = new MobileVM(vmCounter, brokerId, mips, numOfCores, ram, bandwidth, storage, vmm, new CloudletSchedulerTimeShared()); vmList.get(i).add(vm); vmCounter++; } @@ -166,7 +166,7 @@ public class SampleMobileServerManager extends MobileServerManager{ //4. Create Hosts with its id and list of PEs and add them to the list of machines MobileHost host = new MobileHost( //Hosts should have unique IDs, so create Mobile Hosts after Edge+Cloud Hosts - i+SimSettings.getInstance().getNumOfEdgeHosts()+SimSettings.getInstance().getNumOfCoudHost(), + i+SimSettings.getInstance().getNumOfEdgeHosts()+SimSettings.getInstance().getNumOfCouldHost(), new RamProvisionerSimple(ram), new BwProvisionerSimple(bandwidth), //kbps storage, diff --git a/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyEdgeOrchestrator.java b/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyEdgeOrchestrator.java index d4df2f3..188b46f 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyEdgeOrchestrator.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyEdgeOrchestrator.java @@ -96,16 +96,16 @@ public class FuzzyEdgeOrchestrator extends EdgeOrchestrator { for(int hostIndex=0; hostIndex vmArray = SimManager.getInstance().getEdgeServerManager().getVmList(hostIndex); - double totalUtlization=0; + double totalUtilization=0; for(int vmIndex=0; vmIndex()); for(int j = 0; j < SimSettings.getInstance().getNumOfCloudVMsPerHost(); j++){ String vmm = "Xen"; @@ -69,7 +69,7 @@ public class DefaultCloudServerManager extends CloudServerManager{ long bandwidth = 0; //VM Parameters - CloudVM vm = new CloudVM(vmCounter, brockerId, mips, numOfCores, ram, bandwidth, storage, vmm, new CloudletSchedulerTimeShared()); + CloudVM vm = new CloudVM(vmCounter, brokerId, mips, numOfCores, ram, bandwidth, storage, vmm, new CloudletSchedulerTimeShared()); vmList.get(i).add(vm); vmCounter++; } @@ -131,7 +131,7 @@ public class DefaultCloudServerManager extends CloudServerManager{ // 1. We need to create a list to store one or more Machines List hostList = new ArrayList(); - for (int i = 0; i < SimSettings.getInstance().getNumOfCoudHost(); i++) { + for (int i = 0; i < SimSettings.getInstance().getNumOfCouldHost(); i++) { int numOfVMPerHost = SimSettings.getInstance().getNumOfCloudVMsPerHost(); int numOfCores = SimSettings.getInstance().getCoreForCloudVM() * numOfVMPerHost; double mips = SimSettings.getInstance().getMipsForCloudVM() * numOfVMPerHost; diff --git a/src/edu/boun/edgecloudsim/core/SimManager.java b/src/edu/boun/edgecloudsim/core/SimManager.java index 1f0fa3b..e6a3f34 100644 --- a/src/edu/boun/edgecloudsim/core/SimManager.java +++ b/src/edu/boun/edgecloudsim/core/SimManager.java @@ -185,7 +185,7 @@ public class SimManager extends SimEntity { } } - for(int i= 0; i 0){ networkModel.uploadStarted(currentLocation, nextHopId); - schedule(getId(), WlanDelay, REQUEST_RECIVED_BY_EDGE_DEVICE, task); + schedule(getId(), WlanDelay, REQUEST_RECEIVED_BY_EDGE_DEVICE, task); SimLogger.getInstance().taskStarted(task.getCloudletId(), CloudSim.clock()); SimLogger.getInstance().setUploadDelay(task.getCloudletId(), WlanDelay, NETWORK_DELAY_TYPES.WLAN_DELAY); } diff --git a/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/DefaultMobileServerManager.java b/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/DefaultMobileServerManager.java index d8109b6..14b834d 100644 --- a/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/DefaultMobileServerManager.java +++ b/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/DefaultMobileServerManager.java @@ -46,7 +46,7 @@ public class DefaultMobileServerManager extends MobileServerManager{ } @Override - public void createVmList(int brockerId) { + public void createVmList(int brokerId) { //local computation is not supported in default Mobile Device Manager } diff --git a/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/MobileServerManager.java b/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/MobileServerManager.java index b64ba18..c1d5ace 100644 --- a/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/MobileServerManager.java +++ b/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/MobileServerManager.java @@ -69,7 +69,7 @@ public abstract class MobileServerManager { /* * Creates VM List */ - public abstract void createVmList(int brockerId); + public abstract void createVmList(int brokerId); /* * returns average utilization of all VMs diff --git a/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/MobileVmAllocationPolicy_Custom.java b/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/MobileVmAllocationPolicy_Custom.java index 2aae6bb..b7f03b2 100644 --- a/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/MobileVmAllocationPolicy_Custom.java +++ b/src/edu/boun/edgecloudsim/edge_client/mobile_processing_unit/MobileVmAllocationPolicy_Custom.java @@ -58,7 +58,7 @@ public class MobileVmAllocationPolicy_Custom extends VmAllocationPolicy { Host host = getHostList().get(hostIndex); result = host.vmCreate(vm); - if (result) { // if vm were succesfully created in the host + if (result) { // if vm were successfully created in the host getVmTable().put(vm.getUid(), host); createdVmNum++; Log.formatLine("%.2f: Mobile VM #" + vm.getId() + " has been allocated to the host #" + host.getId(),CloudSim.clock()); @@ -72,7 +72,7 @@ public class MobileVmAllocationPolicy_Custom extends VmAllocationPolicy { @Override public boolean allocateHostForVm(Vm vm, Host host) { - if (host.vmCreate(vm)) { // if vm has been succesfully created in the host + if (host.vmCreate(vm)) { // if vm has been successfully created in the host getVmTable().put(vm.getUid(), host); createdVmNum++; diff --git a/src/edu/boun/edgecloudsim/edge_orchestrator/EdgeOrchestrator.java b/src/edu/boun/edgecloudsim/edge_orchestrator/EdgeOrchestrator.java index 7b8e7d5..22af7cc 100644 --- a/src/edu/boun/edgecloudsim/edge_orchestrator/EdgeOrchestrator.java +++ b/src/edu/boun/edgecloudsim/edge_orchestrator/EdgeOrchestrator.java @@ -5,7 +5,7 @@ * EdgeOrchestrator is an abstract class which is used for selecting VM * for each client requests. For those who wants to add a custom * Edge Orchestrator to EdgeCloudSim should extend this class and provide - * a concreate instance via ScenarioFactory + * a concrete instance via ScenarioFactory * * Licence: GPL - http://www.gnu.org/copyleft/gpl.html * Copyright (c) 2017, Bogazici University, Istanbul, Turkey diff --git a/src/edu/boun/edgecloudsim/edge_server/DefaultEdgeServerManager.java b/src/edu/boun/edgecloudsim/edge_server/DefaultEdgeServerManager.java index 7a6b9d0..29fec87 100644 --- a/src/edu/boun/edgecloudsim/edge_server/DefaultEdgeServerManager.java +++ b/src/edu/boun/edgecloudsim/edge_server/DefaultEdgeServerManager.java @@ -63,7 +63,7 @@ public class DefaultEdgeServerManager extends EdgeServerManager{ } } - public void createVmList(int brockerId){ + public void createVmList(int brokerId){ int hostCounter=0; int vmCounter=0; @@ -93,7 +93,7 @@ public class DefaultEdgeServerManager extends EdgeServerManager{ long bandwidth = SimSettings.getInstance().getWlanBandwidth() / (hostNodeList.getLength()+vmNodeList.getLength()); //VM Parameters - EdgeVM vm = new EdgeVM(vmCounter, brockerId, mips, numOfCores, ram, bandwidth, storage, vmm, new CloudletSchedulerTimeShared()); + EdgeVM vm = new EdgeVM(vmCounter, brokerId, mips, numOfCores, ram, bandwidth, storage, vmm, new CloudletSchedulerTimeShared()); vmList.get(hostCounter).add(vm); vmCounter++; } diff --git a/src/edu/boun/edgecloudsim/edge_server/EdgeServerManager.java b/src/edu/boun/edgecloudsim/edge_server/EdgeServerManager.java index 6e2938e..e43b49d 100644 --- a/src/edu/boun/edgecloudsim/edge_server/EdgeServerManager.java +++ b/src/edu/boun/edgecloudsim/edge_server/EdgeServerManager.java @@ -62,7 +62,7 @@ public abstract class EdgeServerManager { /* * Creates VM List */ - public abstract void createVmList(int brockerId); + public abstract void createVmList(int brokerId); /* * returns average utilization of all VMs diff --git a/src/edu/boun/edgecloudsim/edge_server/EdgeVmAllocationPolicy_Custom.java b/src/edu/boun/edgecloudsim/edge_server/EdgeVmAllocationPolicy_Custom.java index 558a3af..2d02b1b 100644 --- a/src/edu/boun/edgecloudsim/edge_server/EdgeVmAllocationPolicy_Custom.java +++ b/src/edu/boun/edgecloudsim/edge_server/EdgeVmAllocationPolicy_Custom.java @@ -84,7 +84,7 @@ public class EdgeVmAllocationPolicy_Custom extends VmAllocationPolicy { Host host = getHostList().get(hostIndex); result = host.vmCreate(vm); - if (result) { // if vm were succesfully created in the host + if (result) { // if vm were successfully created in the host getVmTable().put(vm.getUid(), host); createdVmNum++; Log.formatLine("%.2f: Edge VM #" + vm.getId() + " has been allocated to the host #" + host.getId(),CloudSim.clock()); diff --git a/src/edu/boun/edgecloudsim/mobility/MobilityModel.java b/src/edu/boun/edgecloudsim/mobility/MobilityModel.java index 0168302..a66084b 100644 --- a/src/edu/boun/edgecloudsim/mobility/MobilityModel.java +++ b/src/edu/boun/edgecloudsim/mobility/MobilityModel.java @@ -5,7 +5,7 @@ * MobilityModel is an abstract class which is used for calculating the * location of each mobile devices with respect to the time. For those who * wants to add a custom Mobility Model to EdgeCloudSim should extend - * this class and provide a concreate instance via ScenarioFactory + * this class and provide a concrete instance via ScenarioFactory * * Licence: GPL - http://www.gnu.org/copyleft/gpl.html * Copyright (c) 2017, Bogazici University, Istanbul, Turkey diff --git a/src/edu/boun/edgecloudsim/mobility/NomadicMobility.java b/src/edu/boun/edgecloudsim/mobility/NomadicMobility.java index bed2081..2e6cc8d 100644 --- a/src/edu/boun/edgecloudsim/mobility/NomadicMobility.java +++ b/src/edu/boun/edgecloudsim/mobility/NomadicMobility.java @@ -98,7 +98,7 @@ public class NomadicMobility extends MobilityModel { } } if(!placeFound){ - SimLogger.printLine("impossible is occured! location cannot be assigned to the device!"); + SimLogger.printLine("impossible is occurred! location cannot be assigned to the device!"); System.exit(0); } } @@ -113,7 +113,7 @@ public class NomadicMobility extends MobilityModel { Entry e = treeMap.floorEntry(time); if(e == null){ - SimLogger.printLine("impossible is occured! no location is found for the device '" + deviceId + "' at " + time); + SimLogger.printLine("impossible is occurred! no location is found for the device '" + deviceId + "' at " + time); System.exit(0); } diff --git a/src/edu/boun/edgecloudsim/network/MM1Queue.java b/src/edu/boun/edgecloudsim/network/MM1Queue.java index 5ab1fb0..160bd54 100644 --- a/src/edu/boun/edgecloudsim/network/MM1Queue.java +++ b/src/edu/boun/edgecloudsim/network/MM1Queue.java @@ -122,7 +122,7 @@ public class MM1Queue extends NetworkModel { getHostList().get(0)); //if source device id is the edge server which is located in another location, add internal lan delay - //in our scenasrio, serving wlan ID is equal to the host id, because there is only one host in one place + //in our scenario, serving wlan ID is equal to the host id, because there is only one host in one place if(host.getLocation().getServingWlanId() != accessPointLocation.getServingWlanId()) delay += (SimSettings.getInstance().getInternalLanDelay() * 2); } @@ -150,7 +150,7 @@ public class MM1Queue extends NetworkModel { return deviceCount; } - private double calculateMM1(double propogationDelay, int bandwidth /*Kbps*/, double PoissonMean, double avgTaskSize /*KB*/, int deviceCount){ + private double calculateMM1(double propagationDelay, int bandwidth /*Kbps*/, double PoissonMean, double avgTaskSize /*KB*/, int deviceCount){ double Bps=0, mu=0, lamda=0; avgTaskSize = avgTaskSize * (double)1000; //convert from KB to Byte @@ -160,7 +160,7 @@ public class MM1Queue extends NetworkModel { mu = Bps / avgTaskSize ; //task per seconds double result = (double)1 / (mu-lamda*(double)deviceCount); - result += propogationDelay; + result += propagationDelay; return (result > 5) ? -1 : result; } @@ -182,7 +182,7 @@ public class MM1Queue extends NetworkModel { } private double getWanDownloadDelay(Location accessPointLocation, double time) { - return calculateMM1(SimSettings.getInstance().getWanPropogationDelay(), + return calculateMM1(SimSettings.getInstance().getWanPropagationDelay(), SimSettings.getInstance().getWanBandwidth(), WanPoissonMean, avgTaskOutputSize, @@ -190,7 +190,7 @@ public class MM1Queue extends NetworkModel { } private double getWanUploadDelay(Location accessPointLocation, double time) { - return calculateMM1(SimSettings.getInstance().getWanPropogationDelay(), + return calculateMM1(SimSettings.getInstance().getWanPropagationDelay(), SimSettings.getInstance().getWanBandwidth(), WanPoissonMean, avgTaskInputSize, diff --git a/src/edu/boun/edgecloudsim/network/NetworkModel.java b/src/edu/boun/edgecloudsim/network/NetworkModel.java index 0937d53..e912654 100644 --- a/src/edu/boun/edgecloudsim/network/NetworkModel.java +++ b/src/edu/boun/edgecloudsim/network/NetworkModel.java @@ -5,7 +5,7 @@ * NetworkModel is an abstract class which is used for calculating the * network delay from device to device. For those who wants to add a * custom Network Model to EdgeCloudSim should extend this class and - * provide a concreate instance via ScenarioFactory + * provide a concrete instance via ScenarioFactory * * Licence: GPL - http://www.gnu.org/copyleft/gpl.html * Copyright (c) 2017, Bogazici University, Istanbul, Turkey diff --git a/src/edu/boun/edgecloudsim/task_generator/IdleActiveLoadGenerator.java b/src/edu/boun/edgecloudsim/task_generator/IdleActiveLoadGenerator.java index 5a65ac8..8856e58 100644 --- a/src/edu/boun/edgecloudsim/task_generator/IdleActiveLoadGenerator.java +++ b/src/edu/boun/edgecloudsim/task_generator/IdleActiveLoadGenerator.java @@ -78,7 +78,7 @@ public class IdleActiveLoadGenerator extends LoadGeneratorModel{ double interval = rng.sample(); if(interval <= 0){ - SimLogger.printLine("Impossible is occured! interval is " + interval + " for device " + i + " time " + virtualTime); + SimLogger.printLine("Impossible is occurred! interval is " + interval + " for device " + i + " time " + virtualTime); continue; } //SimLogger.printLine(virtualTime + " -> " + interval + " for device " + i + " time "); diff --git a/src/edu/boun/edgecloudsim/task_generator/LoadGeneratorModel.java b/src/edu/boun/edgecloudsim/task_generator/LoadGeneratorModel.java index 72fd06a..9d518c4 100644 --- a/src/edu/boun/edgecloudsim/task_generator/LoadGeneratorModel.java +++ b/src/edu/boun/edgecloudsim/task_generator/LoadGeneratorModel.java @@ -5,7 +5,7 @@ * LoadGeneratorModel is an abstract class which is used for * deciding task generation pattern via a task list. For those who * wants to add a custom Load Generator Model to EdgeCloudSim should - * extend this class and provide a concreate instance via ScenarioFactory + * extend this class and provide a concrete instance via ScenarioFactory * * Licence: GPL - http://www.gnu.org/copyleft/gpl.html * Copyright (c) 2017, Bogazici University, Istanbul, Turkey diff --git a/src/edu/boun/edgecloudsim/utils/PoissonDistr.java b/src/edu/boun/edgecloudsim/utils/PoissonDistr.java index 84b60a5..9e3dc98 100644 --- a/src/edu/boun/edgecloudsim/utils/PoissonDistr.java +++ b/src/edu/boun/edgecloudsim/utils/PoissonDistr.java @@ -1,8 +1,8 @@ /* * Title: EdgeCloudSim - Poisson Distribution - * + * * Description: Wrapper class for colt Poisson Distribution - * + * * Licence: GPL - http://www.gnu.org/copyleft/gpl.html * Copyright (c) 2017, Bogazici University, Istanbul, Turkey */ @@ -22,18 +22,18 @@ public class PoissonDistr { /** * Creates a new exponential number generator. - * + * * @param mean the mean for the distribution. */ public PoissonDistr(double mean) { engine = new MersenneTwister(new Date()); poisson = new Poisson(mean, engine); - + //always sleep for some milliseconds in order not to have same seed for iterative PoissonDistr contruction try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException e) { - SimLogger.printLine("impossible is occured! Poisson random number cannot be created!"); + SimLogger.printLine("impossible is occurred! Poisson random number cannot be created!"); e.printStackTrace(); System.exit(0); } @@ -41,10 +41,10 @@ public class PoissonDistr { /** * Generate a new random number. - * + * * @return the next random number in the sequence */ - public double sample() { + public double sample() { return poisson.nextDouble(); } } diff --git a/src/edu/boun/edgecloudsim/utils/SimLogger.java b/src/edu/boun/edgecloudsim/utils/SimLogger.java index 0478e2d..b6563ff 100644 --- a/src/edu/boun/edgecloudsim/utils/SimLogger.java +++ b/src/edu/boun/edgecloudsim/utils/SimLogger.java @@ -31,7 +31,7 @@ import edu.boun.edgecloudsim.utils.SimLogger.NETWORK_ERRORS; public class SimLogger { public static enum TASK_STATUS { - CREATED, UPLOADING, PROCESSING, DOWNLOADING, COMLETED, REJECTED_DUE_TO_VM_CAPACITY, REJECTED_DUE_TO_BANDWIDTH, UNFINISHED_DUE_TO_BANDWIDTH, UNFINISHED_DUE_TO_MOBILITY + CREATED, UPLOADING, PROCESSING, DOWNLOADING, COMPLETED, REJECTED_DUE_TO_VM_CAPACITY, REJECTED_DUE_TO_BANDWIDTH, UNFINISHED_DUE_TO_BANDWIDTH, UNFINISHED_DUE_TO_MOBILITY } public static enum NETWORK_ERRORS { @@ -264,7 +264,7 @@ public class SimLogger { if (value.isInWarmUpPeriod()) continue; - if (value.getStatus() == SimLogger.TASK_STATUS.COMLETED) { + if (value.getStatus() == SimLogger.TASK_STATUS.COMPLETED) { completedTask[value.getTaskType()]++; if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) @@ -298,7 +298,7 @@ public class SimLogger { failedTaskOnEdge[value.getTaskType()]++; } - if (value.getStatus() == SimLogger.TASK_STATUS.COMLETED) { + if (value.getStatus() == SimLogger.TASK_STATUS.COMPLETED) { cost[value.getTaskType()] += value.getCost(); serviceTime[value.getTaskType()] += value.getServiceTime(); networkDelay[value.getTaskType()] += value.getNetworkDelay(); @@ -705,9 +705,9 @@ class LogItem { private double cpuCost; private boolean isInWarmUpPeriod; - LogItem(int _taskType, int _taskLenght, int _taskInputType, int _taskOutputSize) { + LogItem(int _taskType, int _taskLength, int _taskInputType, int _taskOutputSize) { taskType = _taskType; - taskLenght = _taskLenght; + taskLenght = _taskLength; taskInputType = _taskInputType; taskOutputSize = _taskOutputSize; networkError = NETWORK_ERRORS.NONE; @@ -757,7 +757,7 @@ class LogItem { public void taskEnded(double time) { taskEndTime = time; - status = SimLogger.TASK_STATUS.COMLETED; + status = SimLogger.TASK_STATUS.COMPLETED; } public void taskRejectedDueToVMCapacity(double time, int _vmType) { @@ -881,7 +881,7 @@ class LogItem { + taskOutputSize + SimSettings.DELIMITER + taskStartTime + SimSettings.DELIMITER + taskEndTime + SimSettings.DELIMITER; - if (status == SimLogger.TASK_STATUS.COMLETED){ + if (status == SimLogger.TASK_STATUS.COMPLETED){ result += getNetworkDelay() + SimSettings.DELIMITER; result += getNetworkDelay(NETWORK_DELAY_TYPES.WLAN_DELAY) + SimSettings.DELIMITER; result += getNetworkDelay(NETWORK_DELAY_TYPES.MAN_DELAY) + SimSettings.DELIMITER; From 08341c3681a62bdceb5963b1833ab46746dadc8e Mon Sep 17 00:00:00 2001 From: Cagatay Sonmez Date: Fri, 30 Oct 2020 11:06:09 +0300 Subject: [PATCH 2/4] some minor backward compatible, major backward incompatible changes and code formatting (beautification) Minor Modifications: * Indentation issues are fixed * Typo errors in source code and comments are fixed * Misspelled parameters in plotTaskFailureReason.m are corrected * sim_results folder is added to .gitignore file Backward compatible changes * The exit code of the application when there is an error is changed from 0 to 1 * Default constructors are added for Location.java, LoadGeneratorModel.java, MobilityModel.java, EdgeOrchestrator.java (this change request coming from a developer) * public TaskProperty(int mobileDeviceId, double startTime, ExponentialDistribution[] expRngList) is added to TaskProperty.java (this change request coming from a developer to create a task without task type) * double getCreationTime() function is added to Task.java * void reconfigureMips(double mips) function is added to EdgeVM (for future usage) * gsm_propagation_delay variable is added to config file. SimSettings class is also modified accordingly. You can use it if you have cellular network access in your scenario. * wlan_range, northern_bound, southern_bound, eastern_bound, western_bound variables are added to config file; and relevant functions are added to SimSettings class. (this change request coming from a developer) Backward incompatible changes! * location_check_interval variable name is changed to location_check_interval in config.properties file. Please update your config files accordingly (remove 'vm_' part) * Major modifications are applied in SimLogger class to decrease time complexity. Now the basic results are kept in the memory and saved to the files at the end of the simulation. As a result of this change, the signature of the SimLogger.addLog () function had to be changed. You must add the mobile device id as the first argument. Please update your MobileDeviceManager class accordingly (add task.getCloudletId () as the first argument). --- .gitignore | 3 + .../config/default_config.properties | 2 +- .../sample_app1/matlab/plotGenericResult.m | 2 +- .../matlab/plotTaskFailureReason.m | 32 +- .../config/default_config.properties | 2 +- .../matlab/plotTaskFailureReason.m | 40 +- .../config/default_config.properties | 2 +- .../matlab/plotTaskFailureReason.m | 24 +- .../config/default_config.properties | 2 +- .../matlab/plotTaskFailureReason.m | 40 +- .../applications/sample_app2/MainApp.java | 22 +- .../SampleMobileDeviceManager.java | 3 +- .../SampleMobileDeviceManager.java | 3 +- .../SampleMobileServerManager.java | 2 +- .../FuzzyExperimentalNetworkModel.java | 4 +- .../sample_app4/FuzzyMobileDeviceManager.java | 3 +- .../edgecloudsim/cloud_server/CloudVM.java | 14 +- .../CloudVmAllocationPolicy_Custom.java | 2 +- .../DefaultCloudServerManager.java | 4 +- .../boun/edgecloudsim/core/SimManager.java | 11 +- .../boun/edgecloudsim/core/SimSettings.java | 429 ++++++----- .../CpuUtilizationModel_Custom.java | 2 +- .../DefaultMobileDeviceManager.java | 9 +- .../boun/edgecloudsim/edge_client/Task.java | 7 + .../mobile_processing_unit/MobileHost.java | 2 +- .../edge_orchestrator/EdgeOrchestrator.java | 9 +- .../boun/edgecloudsim/edge_server/EdgeVM.java | 19 + .../EdgeVmAllocationPolicy_Custom.java | 2 +- .../edgecloudsim/mobility/MobilityModel.java | 6 + .../mobility/NomadicMobility.java | 4 +- .../boun/edgecloudsim/network/MM1Queue.java | 74 +- .../edgecloudsim/network/NetworkModel.java | 32 +- .../IdleActiveLoadGenerator.java | 2 +- .../task_generator/LoadGeneratorModel.java | 6 + src/edu/boun/edgecloudsim/utils/Location.java | 6 + .../boun/edgecloudsim/utils/PoissonDistr.java | 42 +- .../boun/edgecloudsim/utils/SimLogger.java | 713 ++++++++++++------ src/edu/boun/edgecloudsim/utils/SimUtils.java | 35 +- .../boun/edgecloudsim/utils/TaskProperty.java | 118 +-- 39 files changed, 1089 insertions(+), 645 deletions(-) diff --git a/.gitignore b/.gitignore index af5efaf..0e113b8 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,9 @@ Desktop.ini # bin folder bin +# simulation output folder +sim_results + # eclipse's files .settings .classpath diff --git a/scripts/sample_app1/config/default_config.properties b/scripts/sample_app1/config/default_config.properties index 8abd908..f1c9f28 100644 --- a/scripts/sample_app1/config/default_config.properties +++ b/scripts/sample_app1/config/default_config.properties @@ -2,7 +2,7 @@ simulation_time=30 warm_up_period=3 vm_load_check_interval=0.1 -vm_location_check_interval=0.1 +location_check_interval=0.1 file_log_enabled=true deep_file_log_enabled=false diff --git a/scripts/sample_app1/matlab/plotGenericResult.m b/scripts/sample_app1/matlab/plotGenericResult.m index be15845..9e92ba8 100644 --- a/scripts/sample_app1/matlab/plotGenericResult.m +++ b/scripts/sample_app1/matlab/plotGenericResult.m @@ -21,7 +21,7 @@ function [] = plotGenericResult(rowOfset, columnOfset, yLabel, appType, calculat for j=1:numOfMobileDevices try mobileDeviceNumber = startOfMobileDeviceLoop + stepOfMobileDeviceLoop * (j-1); - filePath = strcat(folderPath,'\ite',int2str(s),'\SIMRESULT_',char(scenarioType(i)),'_NEXT_FIT_',int2str(mobileDeviceNumber),'DEVICES_',appType,'_GENERIC.log') + filePath = strcat(folderPath,'\ite',int2str(s),'\SIMRESULT_',char(scenarioType(i)),'_NEXT_FIT_',int2str(mobileDeviceNumber),'DEVICES_',appType,'_GENERIC.log'); readData = dlmread(filePath,';',rowOfset,0); value = readData(1,columnOfset); diff --git a/scripts/sample_app1/matlab/plotTaskFailureReason.m b/scripts/sample_app1/matlab/plotTaskFailureReason.m index d8f2c8e..54f94bb 100644 --- a/scripts/sample_app1/matlab/plotTaskFailureReason.m +++ b/scripts/sample_app1/matlab/plotTaskFailureReason.m @@ -1,27 +1,27 @@ function [] = plotTaskFailureReason() plotGenericResult(1, 10, 'Failed Task due to VM Capacity (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(1, 11, 'Failed Task due to Mobility (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(5, 5, 'Failed Tasks due to WLAN failure (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(5, 7, 'Failed Tasks due to WAN failure (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); end \ No newline at end of file diff --git a/scripts/sample_app2/config/default_config.properties b/scripts/sample_app2/config/default_config.properties index 68c237d..75e9047 100644 --- a/scripts/sample_app2/config/default_config.properties +++ b/scripts/sample_app2/config/default_config.properties @@ -2,7 +2,7 @@ simulation_time=30 warm_up_period=3 vm_load_check_interval=0.1 -vm_location_check_interval=0.1 +location_check_interval=0.1 file_log_enabled=true deep_file_log_enabled=false diff --git a/scripts/sample_app2/matlab/plotTaskFailureReason.m b/scripts/sample_app2/matlab/plotTaskFailureReason.m index 4e71b7f..a808001 100644 --- a/scripts/sample_app2/matlab/plotTaskFailureReason.m +++ b/scripts/sample_app2/matlab/plotTaskFailureReason.m @@ -1,33 +1,33 @@ function [] = plotTaskFailureReason() plotGenericResult(1, 10, 'Failed Task due to VM Capacity (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(1, 11, 'Failed Task due to Mobility (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(5, 5, 'Failed Tasks due to WLAN failure (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(5, 5, {'Failed Tasks due to WLAN failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(5, 6, 'Failed Tasks due to MAN failure (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(5, 6, {'Failed Tasks due to MAN failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(5, 6, {'Failed Tasks due to MAN failure';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(5, 6, {'Failed Tasks due to MAN failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(5, 6, {'Failed Tasks due to MAN failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(5, 6, {'Failed Tasks due to MAN failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(5, 6, {'Failed Tasks due to MAN failure';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(5, 6, {'Failed Tasks due to MAN failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(5, 6, {'Failed Tasks due to MAN failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(5, 7, 'Failed Tasks due to WAN failure (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(5, 7, {'Failed Tasks due to WAN failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); end \ No newline at end of file diff --git a/scripts/sample_app3/config/default_config.properties b/scripts/sample_app3/config/default_config.properties index 830d1a6..7c4fe34 100644 --- a/scripts/sample_app3/config/default_config.properties +++ b/scripts/sample_app3/config/default_config.properties @@ -2,7 +2,7 @@ simulation_time=33 warm_up_period=3 vm_load_check_interval=0.1 -vm_location_check_interval=0.1 +location_check_interval=0.1 file_log_enabled=true deep_file_log_enabled=false diff --git a/scripts/sample_app3/matlab/plotTaskFailureReason.m b/scripts/sample_app3/matlab/plotTaskFailureReason.m index e6216a0..daa6991 100644 --- a/scripts/sample_app3/matlab/plotTaskFailureReason.m +++ b/scripts/sample_app3/matlab/plotTaskFailureReason.m @@ -1,20 +1,20 @@ function [] = plotTaskFailureReason() plotGenericResult(1, 10, 'Failed Task due to VM Capacity (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(1, 11, 'Failed Task due to Mobility (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(1, 11, {'Failed Task due to Mobility';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(1, 4, 'Failed Tasks due to Network failure (%)', 'ALL_APPS', 'percentage_for_failed'); - plotGenericResult(1, 4, {'Failed Tasks due to Network failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); - plotGenericResult(1, 4, {'Failed Tasks due to Network failure';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); - plotGenericResult(1, 4, {'Failed Tasks due to Network failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); - plotGenericResult(1, 4, {'Failed Tasks due to Network failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); + plotGenericResult(1, 4, {'Failed Tasks due to Network failure';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); + plotGenericResult(1, 4, {'Failed Tasks due to Network failure';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); + plotGenericResult(1, 4, {'Failed Tasks due to Network failure';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); + plotGenericResult(1, 4, {'Failed Tasks due to Network failure';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); end \ No newline at end of file diff --git a/scripts/sample_app4/config/default_config.properties b/scripts/sample_app4/config/default_config.properties index 9b58b8d..879a804 100644 --- a/scripts/sample_app4/config/default_config.properties +++ b/scripts/sample_app4/config/default_config.properties @@ -2,7 +2,7 @@ simulation_time=33 warm_up_period=3 vm_load_check_interval=0.1 -vm_location_check_interval=0.1 +location_check_interval=0.1 file_log_enabled=true deep_file_log_enabled=false diff --git a/scripts/sample_app4/matlab/plotTaskFailureReason.m b/scripts/sample_app4/matlab/plotTaskFailureReason.m index 2bd25b8..0bfee09 100755 --- a/scripts/sample_app4/matlab/plotTaskFailureReason.m +++ b/scripts/sample_app4/matlab/plotTaskFailureReason.m @@ -1,31 +1,31 @@ function [] = plotTaskFailureReason() plotGenericResult(1, 10, 'Failed Task due to VM Capacity (%)', 'ALL_APPS', 'percentage_for_failed'); -% plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); -% plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); -% plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); -% plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); +% plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); +% plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); +% plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); +% plotGenericResult(1, 10, {'Failed Task due to VM Capacity';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(1, 11, 'Average Failed Task due to Mobility (%)', 'ALL_APPS', 'percentage_for_failed'); -% plotGenericResult(1, 11, {'Failed Task due to VM Capacity';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); -% plotGenericResult(1, 11, {'Failed Task due to VM Capacity';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); -% plotGenericResult(1, 11, {'Failed Task due to VM Capacity';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); -% plotGenericResult(1, 11, {'Failed Task due to VM Capacity';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); +% plotGenericResult(1, 11, {'Failed Task due to VM Capacity';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); +% plotGenericResult(1, 11, {'Failed Task due to VM Capacity';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); +% plotGenericResult(1, 11, {'Failed Task due to VM Capacity';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); +% plotGenericResult(1, 11, {'Failed Task due to VM Capacity';'for Heavy Computation App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(5, 4, 'Failed Tasks due to WLAN failure (%)', 'ALL_APPS', 'percentage_for_failed'); -% plotGenericResult(5, 4, {'Failed Tasks due to WLAN';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); -% plotGenericResult(5, 4, {'Failed Tasks due to WLAN';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); -% plotGenericResult(5, 4, {'Failed Tasks due to WLAN';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); -% plotGenericResult(5, 4, {'Failed Tasks due to WLAN';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); +% plotGenericResult(5, 4, {'Failed Tasks due to WLAN';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); +% plotGenericResult(5, 4, {'Failed Tasks due to WLAN';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); +% plotGenericResult(5, 4, {'Failed Tasks due to WLAN';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); +% plotGenericResult(5, 4, {'Failed Tasks due to WLAN';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(5, 5, 'Failed Tasks due to MAN failure (%)', 'ALL_APPS', 'percentage_for_failed'); -% plotGenericResult(5, 5, {'Failed Tasks due to MAN';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); -% plotGenericResult(5, 5, {'Failed Tasks due to MAN';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); -% plotGenericResult(5, 5, {'Failed Tasks due to MAN';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); -% plotGenericResult(5, 5, {'Failed Tasks due to MAN';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); +% plotGenericResult(5, 5, {'Failed Tasks due to MAN';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); +% plotGenericResult(5, 5, {'Failed Tasks due to MAN';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); +% plotGenericResult(5, 5, {'Failed Tasks due to MAN';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); +% plotGenericResult(5, 5, {'Failed Tasks due to MAN';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); plotGenericResult(5, 6, 'Failed Tasks due to WAN failure (%)', 'ALL_APPS', 'percentage_for_failed'); -% plotGenericResult(5, 6, {'Failed Tasks due to WAN';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'for_failed'); -% plotGenericResult(5, 6, {'Failed Tasks due to WAN';'for Health App (%)'}, 'HEALTH_APP', 'for_failed'); -% plotGenericResult(5, 6, {'Failed Tasks due to WAN';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'for_failed'); -% plotGenericResult(5, 6, {'Failed Tasks due to WAN';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'for_failed'); +% plotGenericResult(5, 6, {'Failed Tasks due to WAN';'for Augmented Reality App (%)'}, 'AUGMENTED_REALITY', 'percentage_for_failed'); +% plotGenericResult(5, 6, {'Failed Tasks due to WAN';'for Health App (%)'}, 'HEALTH_APP', 'percentage_for_failed'); +% plotGenericResult(5, 6, {'Failed Tasks due to WAN';'for Infotainment App (%)'}, 'INFOTAINMENT_APP', 'percentage_for_failed'); +% plotGenericResult(5, 6, {'Failed Tasks due to WAN';'for Heavy Comp. App (%)'}, 'HEAVY_COMP_APP', 'percentage_for_failed'); end diff --git a/src/edu/boun/edgecloudsim/applications/sample_app2/MainApp.java b/src/edu/boun/edgecloudsim/applications/sample_app2/MainApp.java index a25df0c..8ee4f43 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app2/MainApp.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app2/MainApp.java @@ -24,17 +24,17 @@ import edu.boun.edgecloudsim.utils.SimLogger; import edu.boun.edgecloudsim.utils.SimUtils; public class MainApp { - + /** * Creates main() to run this example */ public static void main(String[] args) { //disable console output of cloudsim library Log.disable(); - + //enable console output and file output of this application SimLogger.enablePrintLog(); - + int iterationNumber = 1; String configFile = ""; String outputFolder = ""; @@ -61,12 +61,12 @@ public class MainApp { SimLogger.printLine("cannot initialize simulation settings!"); System.exit(0); } - + if(SS.getFileLoggingEnabled()){ SimLogger.enableFileLog(); SimUtils.cleanOutputFolder(outputFolder); } - + DateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); Date SimulationStartDate = Calendar.getInstance().getTime(); String now = df.format(SimulationStartDate); @@ -88,7 +88,7 @@ public class MainApp { SimLogger.printLine("Scenario: " + simScenario + " - Policy: " + orchestratorPolicy + " - #iteration: " + iterationNumber); SimLogger.printLine("Duration: " + SS.getSimulationTime()/60 + " min (warm up period: "+ SS.getWarmUpPeriod()/60 +" min) - #devices: " + j); SimLogger.getInstance().simStarted(outputFolder,"SIMRESULT_" + simScenario + "_" + orchestratorPolicy + "_" + j + "DEVICES"); - + try { // First step: Initialize the CloudSim package. It should be called @@ -96,16 +96,16 @@ public class MainApp { int num_user = 2; // number of grid users Calendar calendar = Calendar.getInstance(); boolean trace_flag = false; // mean trace events - + // Initialize the CloudSim library CloudSim.init(num_user, calendar, trace_flag, 0.01); - + // Generate EdgeCloudsim Scenario Factory ScenarioFactory sampleFactory = new SampleScenarioFactory(j,SS.getSimulationTime(), orchestratorPolicy, simScenario); - + // Generate EdgeCloudSim Simulation Manager SimManager manager = new SimManager(sampleFactory, j, simScenario, orchestratorPolicy); - + // Start simulation manager.startSimulation(); } @@ -115,7 +115,7 @@ public class MainApp { e.printStackTrace(); System.exit(0); } - + Date ScenarioEndDate = Calendar.getInstance().getTime(); now = df.format(ScenarioEndDate); SimLogger.printLine("Scenario finished at " + now + ". It took " + SimUtils.getTimeDifference(ScenarioStartDate,ScenarioEndDate)); diff --git a/src/edu/boun/edgecloudsim/applications/sample_app2/SampleMobileDeviceManager.java b/src/edu/boun/edgecloudsim/applications/sample_app2/SampleMobileDeviceManager.java index 4d808e1..fe0a776 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app2/SampleMobileDeviceManager.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app2/SampleMobileDeviceManager.java @@ -298,7 +298,8 @@ public class SampleMobileDeviceManager extends MobileDeviceManager { task.setSubmittedLocation(currentLocation); //add related task to log list - SimLogger.getInstance().addLog(task.getCloudletId(), + SimLogger.getInstance().addLog(task.getMobileDeviceId(), + task.getCloudletId(), task.getTaskType(), (int)task.getCloudletLength(), (int)task.getCloudletFileSize(), diff --git a/src/edu/boun/edgecloudsim/applications/sample_app3/SampleMobileDeviceManager.java b/src/edu/boun/edgecloudsim/applications/sample_app3/SampleMobileDeviceManager.java index 6eebe35..2d1cf1f 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app3/SampleMobileDeviceManager.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app3/SampleMobileDeviceManager.java @@ -191,7 +191,8 @@ public class SampleMobileDeviceManager extends MobileDeviceManager { task.setSubmittedLocation(currentLocation); //add related task to log list - SimLogger.getInstance().addLog(task.getCloudletId(), + SimLogger.getInstance().addLog(task.getMobileDeviceId(), + task.getCloudletId(), task.getTaskType(), (int)task.getCloudletLength(), (int)task.getCloudletFileSize(), diff --git a/src/edu/boun/edgecloudsim/applications/sample_app3/SampleMobileServerManager.java b/src/edu/boun/edgecloudsim/applications/sample_app3/SampleMobileServerManager.java index 8e09050..da6e7a7 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app3/SampleMobileServerManager.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app3/SampleMobileServerManager.java @@ -166,7 +166,7 @@ public class SampleMobileServerManager extends MobileServerManager{ //4. Create Hosts with its id and list of PEs and add them to the list of machines MobileHost host = new MobileHost( //Hosts should have unique IDs, so create Mobile Hosts after Edge+Cloud Hosts - i+SimSettings.getInstance().getNumOfEdgeHosts()+SimSettings.getInstance().getNumOfCouldHost(), + i+SimSettings.getInstance().getNumOfEdgeHosts()+SimSettings.getInstance().getNumOfCloudHost(), new RamProvisionerSimple(ram), new BwProvisionerSimple(bandwidth), //kbps storage, diff --git a/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyExperimentalNetworkModel.java b/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyExperimentalNetworkModel.java index 0422db4..7b137fe 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyExperimentalNetworkModel.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyExperimentalNetworkModel.java @@ -357,7 +357,7 @@ public class FuzzyExperimentalNetworkModel extends NetworkModel { return getWanDownloadDelay(accessPointLocation, dataSize); } - private double calculateMM1(double propogationDelay, double bandwidth /*Kbps*/, double PoissonMean, double avgTaskSize /*KB*/, int deviceCount){ + private double calculateMM1(double propagationDelay, double bandwidth /*Kbps*/, double PoissonMean, double avgTaskSize /*KB*/, int deviceCount){ double mu=0, lamda=0; avgTaskSize = avgTaskSize * 8; //convert from KB to Kb @@ -369,7 +369,7 @@ public class FuzzyExperimentalNetworkModel extends NetworkModel { if(result < 0) return 0; - result += propogationDelay; + result += propagationDelay; return (result > 15) ? 0 : result; } diff --git a/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyMobileDeviceManager.java b/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyMobileDeviceManager.java index e3eb421..951230e 100644 --- a/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyMobileDeviceManager.java +++ b/src/edu/boun/edgecloudsim/applications/sample_app4/FuzzyMobileDeviceManager.java @@ -286,7 +286,8 @@ public class FuzzyMobileDeviceManager extends MobileDeviceManager { task.setSubmittedLocation(currentLocation); //add related task to log list - SimLogger.getInstance().addLog(task.getCloudletId(), + SimLogger.getInstance().addLog(task.getMobileDeviceId(), + task.getCloudletId(), task.getTaskType(), (int)task.getCloudletLength(), (int)task.getCloudletFileSize(), diff --git a/src/edu/boun/edgecloudsim/cloud_server/CloudVM.java b/src/edu/boun/edgecloudsim/cloud_server/CloudVM.java index 6c71349..5702e07 100644 --- a/src/edu/boun/edgecloudsim/cloud_server/CloudVM.java +++ b/src/edu/boun/edgecloudsim/cloud_server/CloudVM.java @@ -20,7 +20,7 @@ import edu.boun.edgecloudsim.core.SimSettings; public class CloudVM extends Vm { private SimSettings.VM_TYPES type; - + public CloudVM(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); @@ -32,15 +32,15 @@ public class CloudVM extends Vm { return type; } - /** - * dynamically reconfigures the mips value of a VM in CloudSim - * - * @param mips new mips value for this VM. - */ + /** + * dynamically reconfigures the mips value of a VM in CloudSim + * + * @param mips new mips value for this VM. + */ public void reconfigureMips(double mips){ super.setMips(mips); super.getHost().getVmScheduler().deallocatePesForVm(this); - + List mipsShareAllocated = new ArrayList(); for(int i= 0; i()); for(int j = 0; j < SimSettings.getInstance().getNumOfCloudVMsPerHost(); j++){ String vmm = "Xen"; @@ -131,7 +131,7 @@ public class DefaultCloudServerManager extends CloudServerManager{ // 1. We need to create a list to store one or more Machines List hostList = new ArrayList(); - for (int i = 0; i < SimSettings.getInstance().getNumOfCouldHost(); i++) { + for (int i = 0; i < SimSettings.getInstance().getNumOfCloudHost(); i++) { int numOfVMPerHost = SimSettings.getInstance().getNumOfCloudVMsPerHost(); int numOfCores = SimSettings.getInstance().getCoreForCloudVM() * numOfVMPerHost; double mips = SimSettings.getInstance().getMipsForCloudVM() * numOfVMPerHost; diff --git a/src/edu/boun/edgecloudsim/core/SimManager.java b/src/edu/boun/edgecloudsim/core/SimManager.java index e6a3f34..750df1f 100644 --- a/src/edu/boun/edgecloudsim/core/SimManager.java +++ b/src/edu/boun/edgecloudsim/core/SimManager.java @@ -16,7 +16,6 @@ import java.io.IOException; import java.util.List; import org.cloudbus.cloudsim.Host; -import org.cloudbus.cloudsim.Log; import org.cloudbus.cloudsim.core.CloudSim; import org.cloudbus.cloudsim.core.SimEntity; import org.cloudbus.cloudsim.core.SimEvent; @@ -185,7 +184,7 @@ public class SimManager extends SimEntity { } } - for(int i = 0; i= 0 && index < taskLookUpTable.length) + result = taskLookUpTable[index]; + + return result; + } + public String getTaskName(int taskType) { return taskNames[taskType]; } - + private void isAttributePresent(Element element, String key) { - String value = element.getAttribute(key); - if (value.isEmpty() || value == null){ - throw new IllegalArgumentException("Attribute '" + key + "' is not found in '" + element.getNodeName() +"'"); - } + String value = element.getAttribute(key); + if (value.isEmpty() || value == null){ + throw new IllegalArgumentException("Attribute '" + key + "' is not found in '" + element.getNodeName() +"'"); + } } private void isElementPresent(Element element, String key) { try { String value = element.getElementsByTagName(key).item(0).getTextContent(); - if (value.isEmpty() || value == null){ - throw new IllegalArgumentException("Element '" + key + "' is not found in '" + element.getNodeName() +"'"); - } + if (value.isEmpty() || value == null){ + throw new IllegalArgumentException("Element '" + key + "' is not found in '" + element.getNodeName() +"'"); + } } catch (Exception e) { throw new IllegalArgumentException("Element '" + key + "' is not found in '" + element.getNodeName() +"'"); } } - + + private Boolean checkElement(Element element, String key) { + Boolean result = true; + try { + String value = element.getElementsByTagName(key).item(0).getTextContent(); + if (value.isEmpty() || value == null){ + result = false; + } + } catch (Exception e) { + result = false; + } + + return result; + } + private void parseApplicationsXML(String filePath) { Document doc = null; @@ -519,64 +617,55 @@ public class SimSettings { doc = dBuilder.parse(devicesFile); doc.getDocumentElement().normalize(); + String mandatoryAttributes[] = { + "usage_percentage", //usage percentage [0-100] + "prob_cloud_selection", //prob. of selecting cloud [0-100] + "poisson_interarrival", //poisson mean (sec) + "active_period", //active period (sec) + "idle_period", //idle period (sec) + "data_upload", //avg data upload (KB) + "data_download", //avg data download (KB) + "task_length", //avg task length (MI) + "required_core", //required # of core + "vm_utilization_on_edge", //vm utilization on edge vm [0-100] + "vm_utilization_on_cloud", //vm utilization on cloud vm [0-100] + "vm_utilization_on_mobile", //vm utilization on mobile vm [0-100] + "delay_sensitivity"}; //delay_sensitivity [0-1] + + String optionalAttributes[] = { + "max_delay_requirement"}; //maximum delay requirement (sec) + NodeList appList = doc.getElementsByTagName("application"); - taskLookUpTable = new double[appList.getLength()][13]; + taskLookUpTable = new double[appList.getLength()] + [mandatoryAttributes.length + optionalAttributes.length]; + taskNames = new String[appList.getLength()]; for (int i = 0; i < appList.getLength(); i++) { Node appNode = appList.item(i); - + Element appElement = (Element) appNode; isAttributePresent(appElement, "name"); - isElementPresent(appElement, "usage_percentage"); - isElementPresent(appElement, "prob_cloud_selection"); - isElementPresent(appElement, "poisson_interarrival"); - isElementPresent(appElement, "active_period"); - isElementPresent(appElement, "idle_period"); - isElementPresent(appElement, "data_upload"); - isElementPresent(appElement, "data_download"); - isElementPresent(appElement, "task_length"); - isElementPresent(appElement, "required_core"); - isElementPresent(appElement, "vm_utilization_on_edge"); - isElementPresent(appElement, "vm_utilization_on_cloud"); - isElementPresent(appElement, "vm_utilization_on_mobile"); - isElementPresent(appElement, "delay_sensitivity"); - String taskName = appElement.getAttribute("name"); taskNames[i] = taskName; - - double usage_percentage = Double.parseDouble(appElement.getElementsByTagName("usage_percentage").item(0).getTextContent()); - double prob_cloud_selection = Double.parseDouble(appElement.getElementsByTagName("prob_cloud_selection").item(0).getTextContent()); - double poisson_interarrival = Double.parseDouble(appElement.getElementsByTagName("poisson_interarrival").item(0).getTextContent()); - double active_period = Double.parseDouble(appElement.getElementsByTagName("active_period").item(0).getTextContent()); - double idle_period = Double.parseDouble(appElement.getElementsByTagName("idle_period").item(0).getTextContent()); - double data_upload = Double.parseDouble(appElement.getElementsByTagName("data_upload").item(0).getTextContent()); - double data_download = Double.parseDouble(appElement.getElementsByTagName("data_download").item(0).getTextContent()); - double task_length = Double.parseDouble(appElement.getElementsByTagName("task_length").item(0).getTextContent()); - double required_core = Double.parseDouble(appElement.getElementsByTagName("required_core").item(0).getTextContent()); - double vm_utilization_on_edge = Double.parseDouble(appElement.getElementsByTagName("vm_utilization_on_edge").item(0).getTextContent()); - double vm_utilization_on_cloud = Double.parseDouble(appElement.getElementsByTagName("vm_utilization_on_cloud").item(0).getTextContent()); - double vm_utilization_on_mobile = Double.parseDouble(appElement.getElementsByTagName("vm_utilization_on_mobile").item(0).getTextContent()); - double delay_sensitivity = Double.parseDouble(appElement.getElementsByTagName("delay_sensitivity").item(0).getTextContent()); - - taskLookUpTable[i][0] = usage_percentage; //usage percentage [0-100] - taskLookUpTable[i][1] = prob_cloud_selection; //prob. of selecting cloud [0-100] - taskLookUpTable[i][2] = poisson_interarrival; //poisson mean (sec) - taskLookUpTable[i][3] = active_period; //active period (sec) - taskLookUpTable[i][4] = idle_period; //idle period (sec) - taskLookUpTable[i][5] = data_upload; //avg data upload (KB) - taskLookUpTable[i][6] = data_download; //avg data download (KB) - taskLookUpTable[i][7] = task_length; //avg task length (MI) - taskLookUpTable[i][8] = required_core; //required # of core - taskLookUpTable[i][9] = vm_utilization_on_edge; //vm utilization on edge vm [0-100] - taskLookUpTable[i][10] = vm_utilization_on_cloud; //vm utilization on cloud vm [0-100] - taskLookUpTable[i][11] = vm_utilization_on_mobile; //vm utilization on mobile vm [0-100] - taskLookUpTable[i][12] = delay_sensitivity; //delay_sensitivity [0-1] + + for(int m=0; m mipsShareAllocated = new ArrayList(); + for(int i= 0; i edge orchestrator to edge device @@ -103,7 +103,7 @@ public class MM1Queue extends NetworkModel { double delay = 0; Location accessPointLocation = SimManager.getInstance().getMobilityModel().getLocation(destDeviceId,CloudSim.clock()); - + //cloud server to mobile device if(sourceDeviceId == SimSettings.CLOUD_DATACENTER_ID){ double wlanDelay = getWlanDownloadDelay(accessPointLocation, CloudSim.clock()); @@ -114,57 +114,57 @@ public class MM1Queue extends NetworkModel { //edge device (wifi access point) to mobile device else{ delay = getWlanDownloadDelay(accessPointLocation, CloudSim.clock()); - + EdgeHost host = (EdgeHost)(SimManager. getInstance(). getEdgeServerManager(). getDatacenterList().get(sourceDeviceId). getHostList().get(0)); - + //if source device id is the edge server which is located in another location, add internal lan delay //in our scenario, serving wlan ID is equal to the host id, because there is only one host in one place if(host.getLocation().getServingWlanId() != accessPointLocation.getServingWlanId()) delay += (SimSettings.getInstance().getInternalLanDelay() * 2); } - + return delay; } - + public int getMaxNumOfClientsInPlace(){ return maxNumOfClientsInPlace; } - + private int getDeviceCount(Location deviceLocation, double time){ int deviceCount = 0; - + for(int i=0; i 5) ? -1 : result; } - + private double getWlanDownloadDelay(Location accessPointLocation, double time) { return calculateMM1(0, SimSettings.getInstance().getWlanBandwidth(), @@ -172,7 +172,7 @@ public class MM1Queue extends NetworkModel { avgTaskOutputSize, getDeviceCount(accessPointLocation, time)); } - + private double getWlanUploadDelay(Location accessPointLocation, double time) { return calculateMM1(0, SimSettings.getInstance().getWlanBandwidth(), @@ -180,7 +180,7 @@ public class MM1Queue extends NetworkModel { avgTaskInputSize, getDeviceCount(accessPointLocation, time)); } - + private double getWanDownloadDelay(Location accessPointLocation, double time) { return calculateMM1(SimSettings.getInstance().getWanPropagationDelay(), SimSettings.getInstance().getWanBandwidth(), @@ -188,7 +188,7 @@ public class MM1Queue extends NetworkModel { avgTaskOutputSize, getDeviceCount(accessPointLocation, time)); } - + private double getWanUploadDelay(Location accessPointLocation, double time) { return calculateMM1(SimSettings.getInstance().getWanPropagationDelay(), SimSettings.getInstance().getWanBandwidth(), @@ -200,24 +200,24 @@ public class MM1Queue extends NetworkModel { @Override public void uploadStarted(Location accessPointLocation, int destDeviceId) { // TODO Auto-generated method stub - + } @Override public void uploadFinished(Location accessPointLocation, int destDeviceId) { // TODO Auto-generated method stub - + } @Override public void downloadStarted(Location accessPointLocation, int sourceDeviceId) { // TODO Auto-generated method stub - + } @Override public void downloadFinished(Location accessPointLocation, int sourceDeviceId) { // TODO Auto-generated method stub - + } } diff --git a/src/edu/boun/edgecloudsim/network/NetworkModel.java b/src/edu/boun/edgecloudsim/network/NetworkModel.java index e912654..6b56888 100644 --- a/src/edu/boun/edgecloudsim/network/NetworkModel.java +++ b/src/edu/boun/edgecloudsim/network/NetworkModel.java @@ -24,26 +24,26 @@ public abstract class NetworkModel { numberOfMobileDevices=_numberOfMobileDevices; simScenario = _simScenario; }; - + /** - * initializes custom network model - */ + * initializes custom network model + */ public abstract void initialize(); - - /** - * calculates the upload delay from source to destination device - */ + + /** + * calculates the upload delay from source to destination device + */ public abstract double getUploadDelay(int sourceDeviceId, int destDeviceId, Task task); - - /** - * calculates the download delay from source to destination device - */ + + /** + * calculates the download delay from source to destination device + */ public abstract double getDownloadDelay(int sourceDeviceId, int destDeviceId, Task task); - - /** - * Mobile device manager should inform network manager about the network operation - * This information may be important for some network delay models - */ + + /** + * Mobile device manager should inform network manager about the network operation + * This information may be important for some network delay models + */ public abstract void uploadStarted(Location accessPointLocation, int destDeviceId); public abstract void uploadFinished(Location accessPointLocation, int destDeviceId); public abstract void downloadStarted(Location accessPointLocation, int sourceDeviceId); diff --git a/src/edu/boun/edgecloudsim/task_generator/IdleActiveLoadGenerator.java b/src/edu/boun/edgecloudsim/task_generator/IdleActiveLoadGenerator.java index 8856e58..4130a4b 100644 --- a/src/edu/boun/edgecloudsim/task_generator/IdleActiveLoadGenerator.java +++ b/src/edu/boun/edgecloudsim/task_generator/IdleActiveLoadGenerator.java @@ -59,7 +59,7 @@ public class IdleActiveLoadGenerator extends LoadGeneratorModel{ } } if(randomTaskType == -1){ - SimLogger.printLine("Impossible is occured! no random task type!"); + SimLogger.printLine("Impossible is occurred! no random task type!"); continue; } diff --git a/src/edu/boun/edgecloudsim/task_generator/LoadGeneratorModel.java b/src/edu/boun/edgecloudsim/task_generator/LoadGeneratorModel.java index 9d518c4..feaaba8 100644 --- a/src/edu/boun/edgecloudsim/task_generator/LoadGeneratorModel.java +++ b/src/edu/boun/edgecloudsim/task_generator/LoadGeneratorModel.java @@ -29,6 +29,12 @@ public abstract class LoadGeneratorModel { simScenario=_simScenario; }; + /* + * Default Constructor: Creates an empty LoadGeneratorModel + */ + public LoadGeneratorModel() { + } + /* * each task has a virtual start time * it will be used while generating task diff --git a/src/edu/boun/edgecloudsim/utils/Location.java b/src/edu/boun/edgecloudsim/utils/Location.java index 9c322cf..f25e3b7 100644 --- a/src/edu/boun/edgecloudsim/utils/Location.java +++ b/src/edu/boun/edgecloudsim/utils/Location.java @@ -21,6 +21,12 @@ public class Location { yPos = _yPos; } + /* + * Default Constructor: Creates an empty Location + */ + public Location() { + } + @Override public boolean equals(Object other){ boolean result = false; diff --git a/src/edu/boun/edgecloudsim/utils/PoissonDistr.java b/src/edu/boun/edgecloudsim/utils/PoissonDistr.java index 9e3dc98..7821a54 100644 --- a/src/edu/boun/edgecloudsim/utils/PoissonDistr.java +++ b/src/edu/boun/edgecloudsim/utils/PoissonDistr.java @@ -1,8 +1,8 @@ /* * Title: EdgeCloudSim - Poisson Distribution - * + * * Description: Wrapper class for colt Poisson Distribution - * + * * Licence: GPL - http://www.gnu.org/copyleft/gpl.html * Copyright (c) 2017, Bogazici University, Istanbul, Turkey */ @@ -20,31 +20,31 @@ public class PoissonDistr { Poisson poisson; RandomEngine engine; - /** - * Creates a new exponential number generator. - * - * @param mean the mean for the distribution. - */ - public PoissonDistr(double mean) { + /** + * Creates a new exponential number generator. + * + * @param mean the mean for the distribution. + */ + public PoissonDistr(double mean) { engine = new MersenneTwister(new Date()); poisson = new Poisson(mean, engine); - - //always sleep for some milliseconds in order not to have same seed for iterative PoissonDistr contruction + + //always sleep for some milliseconds in order not to have same seed for iterative PoissonDistr construction try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException e) { - SimLogger.printLine("impossible is occurred! Poisson random number cannot be created!"); + SimLogger.printLine("impossible is occurred! Poisson random number cannot be created!"); e.printStackTrace(); - System.exit(0); + System.exit(1); } - } + } - /** - * Generate a new random number. - * - * @return the next random number in the sequence - */ - public double sample() { - return poisson.nextDouble(); - } + /** + * Generate a new random number. + * + * @return the next random number in the sequence + */ + public double sample() { + return poisson.nextDouble(); + } } diff --git a/src/edu/boun/edgecloudsim/utils/SimLogger.java b/src/edu/boun/edgecloudsim/utils/SimLogger.java index b6563ff..ff5d22a 100644 --- a/src/edu/boun/edgecloudsim/utils/SimLogger.java +++ b/src/edu/boun/edgecloudsim/utils/SimLogger.java @@ -8,6 +8,21 @@ * If you need more results or another file format, you should modify * this class. * + * IMPORTANT NOTES: + * EdgeCloudSim is designed to perform file logging operations with + * a low memory consumption. Deep file logging is performed whenever + * a task is completed. This may cause too many file IO operation and + * increase the time consumption! + * + * The basic results are kept in the memory, and saved to the files + * at the end of the simulation. So, basic file logging does + * bring too much overhead to the time complexity. + * + * In the earlier versions (v3 and older), EdgeCloudSim keeps all the + * task results in the memory and save them to the files when the + * simulation ends. Since this approach increases memory consumption + * too much, we sacrificed the time complexity. + * * Licence: GPL - http://www.gnu.org/copyleft/gpl.html * Copyright (c) 2017, Bogazici University, Istanbul, Turkey */ @@ -31,21 +46,88 @@ import edu.boun.edgecloudsim.utils.SimLogger.NETWORK_ERRORS; public class SimLogger { public static enum TASK_STATUS { - CREATED, UPLOADING, PROCESSING, DOWNLOADING, COMPLETED, REJECTED_DUE_TO_VM_CAPACITY, REJECTED_DUE_TO_BANDWIDTH, UNFINISHED_DUE_TO_BANDWIDTH, UNFINISHED_DUE_TO_MOBILITY + CREATED, UPLOADING, PROCESSING, DOWNLOADING, COMLETED, + REJECTED_DUE_TO_VM_CAPACITY, REJECTED_DUE_TO_BANDWIDTH, + UNFINISHED_DUE_TO_BANDWIDTH, UNFINISHED_DUE_TO_MOBILITY, + REJECTED_DUE_TO_WLAN_COVERAGE } public static enum NETWORK_ERRORS { - LAN_ERROR, MAN_ERROR, WAN_ERROR, NONE + LAN_ERROR, MAN_ERROR, WAN_ERROR, GSM_ERROR, NONE } + private long startTime; + private long endTime; private static boolean fileLogEnabled; private static boolean printLogEnabled; private String filePrefix; private String outputFolder; private Map taskMap; private LinkedList vmLoadList; + private LinkedList apDelayList; private static SimLogger singleton = new SimLogger(); + + private int numOfAppTypes; + + private File successFile = null, failFile = null; + private FileWriter successFW = null, failFW = null; + private BufferedWriter successBW = null, failBW = null; + + // extract following values for each app type. + // last index is average of all app types + private int[] uncompletedTask = null; + private int[] uncompletedTaskOnCloud = null; + private int[] uncompletedTaskOnEdge = null; + private int[] uncompletedTaskOnMobile = null; + + private int[] completedTask = null; + private int[] completedTaskOnCloud = null; + private int[] completedTaskOnEdge = null; + private int[] completedTaskOnMobile = null; + + private int[] failedTask = null; + private int[] failedTaskOnCloud = null; + private int[] failedTaskOnEdge = null; + private int[] failedTaskOnMobile = null; + + private double[] networkDelay = null; + private double[] gsmDelay = null; + private double[] wanDelay = null; + private double[] manDelay = null; + private double[] lanDelay = null; + + private double[] gsmUsage = null; + private double[] wanUsage = null; + private double[] manUsage = null; + private double[] lanUsage = null; + + private double[] serviceTime = null; + private double[] serviceTimeOnCloud = null; + private double[] serviceTimeOnEdge = null; + private double[] serviceTimeOnMobile = null; + + private double[] processingTime = null; + private double[] processingTimeOnCloud = null; + private double[] processingTimeOnEdge = null; + private double[] processingTimeOnMobile = null; + + private int[] failedTaskDueToVmCapacity = null; + private int[] failedTaskDueToVmCapacityOnCloud = null; + private int[] failedTaskDueToVmCapacityOnEdge = null; + private int[] failedTaskDueToVmCapacityOnMobile = null; + + private double[] cost = null; + private double[] QoE = null; + private int[] failedTaskDuetoBw = null; + private int[] failedTaskDuetoLanBw = null; + private int[] failedTaskDuetoManBw = null; + private int[] failedTaskDuetoWanBw = null; + private int[] failedTaskDuetoGsmBw = null; + private int[] failedTaskDuetoMobility = null; + private int[] refectedTaskDuetoWlanRange = null; + + private double[] orchestratorOverhead = null; /* * A private Constructor prevents any other class from instantiating. @@ -72,9 +154,17 @@ public class SimLogger { return fileLogEnabled; } + public static void disableFileLog() { + fileLogEnabled = false; + } + public static void disablePrintLog() { printLogEnabled = false; } + + public String getOutputFolder() { + return outputFolder; + } private void appendToFile(BufferedWriter bw, String line) throws IOException { bw.write(line); @@ -92,16 +182,93 @@ public class SimLogger { } public void simStarted(String outFolder, String fileName) { + startTime = System.currentTimeMillis(); filePrefix = fileName; outputFolder = outFolder; taskMap = new HashMap(); vmLoadList = new LinkedList(); + apDelayList = new LinkedList(); + + numOfAppTypes = SimSettings.getInstance().getTaskLookUpTable().length; + + if (SimSettings.getInstance().getDeepFileLoggingEnabled()) { + try { + successFile = new File(outputFolder, filePrefix + "_SUCCESS.log"); + successFW = new FileWriter(successFile, true); + successBW = new BufferedWriter(successFW); + + failFile = new File(outputFolder, filePrefix + "_FAIL.log"); + failFW = new FileWriter(failFile, true); + failBW = new BufferedWriter(failFW); + + appendToFile(successBW, "#auto generated file!"); + appendToFile(failBW, "#auto generated file!"); + } catch (IOException e) { + e.printStackTrace(); + System.exit(1); + } + } + + // extract following values for each app type. + // last index is average of all app types + uncompletedTask = new int[numOfAppTypes + 1]; + uncompletedTaskOnCloud = new int[numOfAppTypes + 1]; + uncompletedTaskOnEdge = new int[numOfAppTypes + 1]; + uncompletedTaskOnMobile = new int[numOfAppTypes + 1]; + + completedTask = new int[numOfAppTypes + 1]; + completedTaskOnCloud = new int[numOfAppTypes + 1]; + completedTaskOnEdge = new int[numOfAppTypes + 1]; + completedTaskOnMobile = new int[numOfAppTypes + 1]; + + failedTask = new int[numOfAppTypes + 1]; + failedTaskOnCloud = new int[numOfAppTypes + 1]; + failedTaskOnEdge = new int[numOfAppTypes + 1]; + failedTaskOnMobile = new int[numOfAppTypes + 1]; + + networkDelay = new double[numOfAppTypes + 1]; + gsmDelay = new double[numOfAppTypes + 1]; + wanDelay = new double[numOfAppTypes + 1]; + manDelay = new double[numOfAppTypes + 1]; + lanDelay = new double[numOfAppTypes + 1]; + + gsmUsage = new double[numOfAppTypes + 1]; + wanUsage = new double[numOfAppTypes + 1]; + manUsage = new double[numOfAppTypes + 1]; + lanUsage = new double[numOfAppTypes + 1]; + + serviceTime = new double[numOfAppTypes + 1]; + serviceTimeOnCloud = new double[numOfAppTypes + 1]; + serviceTimeOnEdge = new double[numOfAppTypes + 1]; + serviceTimeOnMobile = new double[numOfAppTypes + 1]; + + processingTime = new double[numOfAppTypes + 1]; + processingTimeOnCloud = new double[numOfAppTypes + 1]; + processingTimeOnEdge = new double[numOfAppTypes + 1]; + processingTimeOnMobile = new double[numOfAppTypes + 1]; + + failedTaskDueToVmCapacity = new int[numOfAppTypes + 1]; + failedTaskDueToVmCapacityOnCloud = new int[numOfAppTypes + 1]; + failedTaskDueToVmCapacityOnEdge = new int[numOfAppTypes + 1]; + failedTaskDueToVmCapacityOnMobile = new int[numOfAppTypes + 1]; + + cost = new double[numOfAppTypes + 1]; + QoE = new double[numOfAppTypes + 1]; + failedTaskDuetoBw = new int[numOfAppTypes + 1]; + failedTaskDuetoLanBw = new int[numOfAppTypes + 1]; + failedTaskDuetoManBw = new int[numOfAppTypes + 1]; + failedTaskDuetoWanBw = new int[numOfAppTypes + 1]; + failedTaskDuetoGsmBw = new int[numOfAppTypes + 1]; + failedTaskDuetoMobility = new int[numOfAppTypes + 1]; + refectedTaskDuetoWlanRange = new int[numOfAppTypes + 1]; + + orchestratorOverhead = new double[numOfAppTypes + 1]; } - public void addLog(int taskId, int taskType, int taskLenght, int taskInputType, - int taskOutputSize) { + public void addLog(int deviceId, int taskId, int taskType, + int taskLenght, int taskInputType, int taskOutputSize) { // printLine(taskId+"->"+taskStartTime); - taskMap.put(taskId, new LogItem(taskType, taskLenght, taskInputType, taskOutputSize)); + taskMap.put(taskId, new LogItem(deviceId, taskType, taskLenght, taskInputType, taskOutputSize)); } public void taskStarted(int taskId, double time) { @@ -126,34 +293,57 @@ public class SimLogger { public void taskEnded(int taskId, double time) { taskMap.get(taskId).taskEnded(time); + recordLog(taskId); } public void rejectedDueToVMCapacity(int taskId, double time, int vmType) { taskMap.get(taskId).taskRejectedDueToVMCapacity(time, vmType); + recordLog(taskId); } + public void rejectedDueToWlanCoverage(int taskId, double time, int vmType) { + taskMap.get(taskId).taskRejectedDueToWlanCoverage(time, vmType); + recordLog(taskId); + } + public void rejectedDueToBandwidth(int taskId, double time, int vmType, NETWORK_DELAY_TYPES delayType) { taskMap.get(taskId).taskRejectedDueToBandwidth(time, vmType, delayType); + recordLog(taskId); } public void failedDueToBandwidth(int taskId, double time, NETWORK_DELAY_TYPES delayType) { taskMap.get(taskId).taskFailedDueToBandwidth(time, delayType); + recordLog(taskId); } public void failedDueToMobility(int taskId, double time) { taskMap.get(taskId).taskFailedDueToMobility(time); + recordLog(taskId); + } + + public void setQoE(int taskId, double QoE){ + taskMap.get(taskId).setQoE(QoE); + } + + public void setOrchestratorOverhead(int taskId, double overhead){ + taskMap.get(taskId).setOrchestratorOverhead(overhead); } public void addVmUtilizationLog(double time, double loadOnEdge, double loadOnCloud, double loadOnMobile) { - vmLoadList.add(new VmLoadLogItem(time, loadOnEdge, loadOnCloud, loadOnMobile)); + if(SimSettings.getInstance().getLocationLogInterval() != 0) + vmLoadList.add(new VmLoadLogItem(time, loadOnEdge, loadOnCloud, loadOnMobile)); } + public void addApDelayLog(double time, double[] apUploadDelays, double[] apDownloadDelays) { + if(SimSettings.getInstance().getApDelayLogInterval() != 0) + apDelayList.add(new ApDelayLogItem(time, apUploadDelays, apDownloadDelays)); + } + public void simStopped() throws IOException { - int numOfAppTypes = SimSettings.getInstance().getTaskLookUpTable().length; - - File successFile = null, failFile = null, vmLoadFile = null, locationFile = null; - FileWriter successFW = null, failFW = null, vmLoadFW = null, locationFW = null; - BufferedWriter successBW = null, failBW = null, vmLoadBW = null, locationBW = null; + endTime = System.currentTimeMillis(); + File vmLoadFile = null, locationFile = null, apUploadDelayFile = null, apDownloadDelayFile = null; + FileWriter vmLoadFW = null, locationFW = null, apUploadDelayFW = null, apDownloadDelayFW = null; + BufferedWriter vmLoadBW = null, locationBW = null, apUploadDelayBW = null, apDownloadDelayBW = null; // Save generic results to file for each app type. last index is average // of all app types @@ -161,66 +351,8 @@ public class SimLogger { FileWriter[] genericFWs = new FileWriter[numOfAppTypes + 1]; BufferedWriter[] genericBWs = new BufferedWriter[numOfAppTypes + 1]; - // extract following values for each app type. last index is average of - // all app types - int[] uncompletedTask = new int[numOfAppTypes + 1]; - int[] uncompletedTaskOnCloud = new int[numOfAppTypes + 1]; - int[] uncompletedTaskOnEdge = new int[numOfAppTypes + 1]; - int[] uncompletedTaskOnMobile = new int[numOfAppTypes + 1]; - - int[] completedTask = new int[numOfAppTypes + 1]; - int[] completedTaskOnCloud = new int[numOfAppTypes + 1]; - int[] completedTaskOnEdge = new int[numOfAppTypes + 1]; - int[] completedTaskOnMobile = new int[numOfAppTypes + 1]; - - int[] failedTask = new int[numOfAppTypes + 1]; - int[] failedTaskOnCloud = new int[numOfAppTypes + 1]; - int[] failedTaskOnEdge = new int[numOfAppTypes + 1]; - int[] failedTaskOnMobile = new int[numOfAppTypes + 1]; - - double[] networkDelay = new double[numOfAppTypes + 1]; - double[] wanDelay = new double[numOfAppTypes + 1]; - double[] manDelay = new double[numOfAppTypes + 1]; - double[] lanDelay = new double[numOfAppTypes + 1]; - - double[] wanUsage = new double[numOfAppTypes + 1]; - double[] manUsage = new double[numOfAppTypes + 1]; - double[] lanUsage = new double[numOfAppTypes + 1]; - - double[] serviceTime = new double[numOfAppTypes + 1]; - double[] serviceTimeOnCloud = new double[numOfAppTypes + 1]; - double[] serviceTimeOnEdge = new double[numOfAppTypes + 1]; - double[] serviceTimeOnMobile = new double[numOfAppTypes + 1]; - - double[] processingTime = new double[numOfAppTypes + 1]; - double[] processingTimeOnCloud = new double[numOfAppTypes + 1]; - double[] processingTimeOnEdge = new double[numOfAppTypes + 1]; - double[] processingTimeOnMobile = new double[numOfAppTypes + 1]; - - int[] failedTaskDueToVmCapacity = new int[numOfAppTypes + 1]; - int[] failedTaskDueToVmCapacityOnCloud = new int[numOfAppTypes + 1]; - int[] failedTaskDueToVmCapacityOnEdge = new int[numOfAppTypes + 1]; - int[] failedTaskDueToVmCapacityOnMobile = new int[numOfAppTypes + 1]; - - double[] cost = new double[numOfAppTypes + 1]; - int[] failedTaskDuetoBw = new int[numOfAppTypes + 1]; - int[] failedTaskDuetoLanBw = new int[numOfAppTypes + 1]; - int[] failedTaskDuetoManBw = new int[numOfAppTypes + 1]; - int[] failedTaskDuetoWanBw = new int[numOfAppTypes + 1]; - int[] failedTaskDuetoMobility = new int[numOfAppTypes + 1]; - // open all files and prepare them for write if (fileLogEnabled) { - if (SimSettings.getInstance().getDeepFileLoggingEnabled()) { - successFile = new File(outputFolder, filePrefix + "_SUCCESS.log"); - successFW = new FileWriter(successFile, true); - successBW = new BufferedWriter(successFW); - - failFile = new File(outputFolder, filePrefix + "_FAIL.log"); - failFW = new FileWriter(failFile, true); - failBW = new BufferedWriter(failFW); - } - vmLoadFile = new File(outputFolder, filePrefix + "_VM_LOAD.log"); vmLoadFW = new FileWriter(vmLoadFile, true); vmLoadBW = new BufferedWriter(vmLoadFW); @@ -229,12 +361,19 @@ public class SimLogger { locationFW = new FileWriter(locationFile, true); locationBW = new BufferedWriter(locationFW); + apUploadDelayFile = new File(outputFolder, filePrefix + "_AP_UPLOAD_DELAY.log"); + apUploadDelayFW = new FileWriter(apUploadDelayFile, true); + apUploadDelayBW = new BufferedWriter(apUploadDelayFW); + + apDownloadDelayFile = new File(outputFolder, filePrefix + "_AP_DOWNLOAD_DELAY.log"); + apDownloadDelayFW = new FileWriter(apDownloadDelayFile, true); + apDownloadDelayBW = new BufferedWriter(apDownloadDelayFW); + for (int i = 0; i < numOfAppTypes + 1; i++) { String fileName = "ALL_APPS_GENERIC.log"; if (i < numOfAppTypes) { - // if related app is not used in this simulation, just - // discard it + // if related app is not used in this simulation, just discard it if (SimSettings.getInstance().getTaskLookUpTable()[i][0] == 0) continue; @@ -247,121 +386,23 @@ public class SimLogger { appendToFile(genericBWs[i], "#auto generated file!"); } - if (SimSettings.getInstance().getDeepFileLoggingEnabled()) { - appendToFile(successBW, "#auto generated file!"); - appendToFile(failBW, "#auto generated file!"); - } - appendToFile(vmLoadBW, "#auto generated file!"); appendToFile(locationBW, "#auto generated file!"); + appendToFile(apUploadDelayBW, "#auto generated file!"); + appendToFile(apDownloadDelayBW, "#auto generated file!"); } - // extract the result of each task and write it to the file if required + //the tasks in the map is not completed yet! for (Map.Entry entry : taskMap.entrySet()) { - Integer key = entry.getKey(); LogItem value = entry.getValue(); - if (value.isInWarmUpPeriod()) - continue; - - if (value.getStatus() == SimLogger.TASK_STATUS.COMPLETED) { - completedTask[value.getTaskType()]++; - - if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) - completedTaskOnCloud[value.getTaskType()]++; - else if (value.getVmType() == SimSettings.VM_TYPES.MOBILE_VM.ordinal()) - completedTaskOnMobile[value.getTaskType()]++; - else - completedTaskOnEdge[value.getTaskType()]++; - } - else if(value.getStatus() == SimLogger.TASK_STATUS.CREATED || - value.getStatus() == SimLogger.TASK_STATUS.UPLOADING || - value.getStatus() == SimLogger.TASK_STATUS.PROCESSING || - value.getStatus() == SimLogger.TASK_STATUS.DOWNLOADING) - { - uncompletedTask[value.getTaskType()]++; - if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) - uncompletedTaskOnCloud[value.getTaskType()]++; - else if (value.getVmType() == SimSettings.VM_TYPES.MOBILE_VM.ordinal()) - uncompletedTaskOnMobile[value.getTaskType()]++; - else - uncompletedTaskOnEdge[value.getTaskType()]++; - } - else { - failedTask[value.getTaskType()]++; - - if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) - failedTaskOnCloud[value.getTaskType()]++; - else if (value.getVmType() == SimSettings.VM_TYPES.MOBILE_VM.ordinal()) - failedTaskOnMobile[value.getTaskType()]++; - else - failedTaskOnEdge[value.getTaskType()]++; - } - - if (value.getStatus() == SimLogger.TASK_STATUS.COMPLETED) { - cost[value.getTaskType()] += value.getCost(); - serviceTime[value.getTaskType()] += value.getServiceTime(); - networkDelay[value.getTaskType()] += value.getNetworkDelay(); - processingTime[value.getTaskType()] += (value.getServiceTime() - value.getNetworkDelay()); - - if(value.getNetworkDelay(NETWORK_DELAY_TYPES.WLAN_DELAY) != 0) { - lanUsage[value.getTaskType()]++; - lanDelay[value.getTaskType()] += value.getNetworkDelay(NETWORK_DELAY_TYPES.WLAN_DELAY); - } - if(value.getNetworkDelay(NETWORK_DELAY_TYPES.MAN_DELAY) != 0) { - manUsage[value.getTaskType()]++; - manDelay[value.getTaskType()] += value.getNetworkDelay(NETWORK_DELAY_TYPES.MAN_DELAY); - } - if(value.getNetworkDelay(NETWORK_DELAY_TYPES.WAN_DELAY) != 0) { - wanUsage[value.getTaskType()]++; - wanDelay[value.getTaskType()] += value.getNetworkDelay(NETWORK_DELAY_TYPES.WAN_DELAY); - } - - - if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) { - serviceTimeOnCloud[value.getTaskType()] += value.getServiceTime(); - processingTimeOnCloud[value.getTaskType()] += (value.getServiceTime() - value.getNetworkDelay()); - } - else if (value.getVmType() == SimSettings.VM_TYPES.MOBILE_VM.ordinal()) { - serviceTimeOnMobile[value.getTaskType()] += value.getServiceTime(); - processingTimeOnMobile[value.getTaskType()] += value.getServiceTime(); - } - else { - serviceTimeOnEdge[value.getTaskType()] += value.getServiceTime(); - processingTimeOnEdge[value.getTaskType()] += (value.getServiceTime() - value.getNetworkDelay()); - } - - if (fileLogEnabled && SimSettings.getInstance().getDeepFileLoggingEnabled()) - appendToFile(successBW, value.toString(key)); - } else if (value.getStatus() == SimLogger.TASK_STATUS.REJECTED_DUE_TO_VM_CAPACITY) { - failedTaskDueToVmCapacity[value.getTaskType()]++; - - if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) - failedTaskDueToVmCapacityOnCloud[value.getTaskType()]++; - else if (value.getVmType() == SimSettings.VM_TYPES.MOBILE_VM.ordinal()) - failedTaskDueToVmCapacityOnMobile[value.getTaskType()]++; - else - failedTaskDueToVmCapacityOnEdge[value.getTaskType()]++; - - if (fileLogEnabled && SimSettings.getInstance().getDeepFileLoggingEnabled()) - appendToFile(failBW, value.toString(key)); - } else if (value.getStatus() == SimLogger.TASK_STATUS.REJECTED_DUE_TO_BANDWIDTH - || value.getStatus() == SimLogger.TASK_STATUS.UNFINISHED_DUE_TO_BANDWIDTH) { - failedTaskDuetoBw[value.getTaskType()]++; - if (value.getNetworkError() == NETWORK_ERRORS.LAN_ERROR) - failedTaskDuetoLanBw[value.getTaskType()]++; - else if (value.getNetworkError() == NETWORK_ERRORS.MAN_ERROR) - failedTaskDuetoManBw[value.getTaskType()]++; - else if (value.getNetworkError() == NETWORK_ERRORS.WAN_ERROR) - failedTaskDuetoWanBw[value.getTaskType()]++; - - if (fileLogEnabled && SimSettings.getInstance().getDeepFileLoggingEnabled()) - appendToFile(failBW, value.toString(key)); - } else if (value.getStatus() == SimLogger.TASK_STATUS.UNFINISHED_DUE_TO_MOBILITY) { - failedTaskDuetoMobility[value.getTaskType()]++; - if (fileLogEnabled && SimSettings.getInstance().getDeepFileLoggingEnabled()) - appendToFile(failBW, value.toString(key)); - } + uncompletedTask[value.getTaskType()]++; + if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) + uncompletedTaskOnCloud[value.getTaskType()]++; + else if (value.getVmType() == SimSettings.VM_TYPES.MOBILE_VM.ordinal()) + uncompletedTaskOnMobile[value.getTaskType()]++; + else + uncompletedTaskOnEdge[value.getTaskType()]++; } // calculate total values @@ -384,10 +425,12 @@ public class SimLogger { lanDelay[numOfAppTypes] = DoubleStream.of(lanDelay).sum(); manDelay[numOfAppTypes] = DoubleStream.of(manDelay).sum(); wanDelay[numOfAppTypes] = DoubleStream.of(wanDelay).sum(); + gsmDelay[numOfAppTypes] = DoubleStream.of(gsmDelay).sum(); lanUsage[numOfAppTypes] = DoubleStream.of(lanUsage).sum(); manUsage[numOfAppTypes] = DoubleStream.of(manUsage).sum(); wanUsage[numOfAppTypes] = DoubleStream.of(wanUsage).sum(); + gsmUsage[numOfAppTypes] = DoubleStream.of(gsmUsage).sum(); serviceTime[numOfAppTypes] = DoubleStream.of(serviceTime).sum(); serviceTimeOnCloud[numOfAppTypes] = DoubleStream.of(serviceTimeOnCloud).sum(); @@ -405,12 +448,17 @@ public class SimLogger { failedTaskDueToVmCapacityOnMobile[numOfAppTypes] = IntStream.of(failedTaskDueToVmCapacityOnMobile).sum(); cost[numOfAppTypes] = DoubleStream.of(cost).sum(); + QoE[numOfAppTypes] = DoubleStream.of(QoE).sum(); failedTaskDuetoBw[numOfAppTypes] = IntStream.of(failedTaskDuetoBw).sum(); + failedTaskDuetoGsmBw[numOfAppTypes] = IntStream.of(failedTaskDuetoGsmBw).sum(); failedTaskDuetoWanBw[numOfAppTypes] = IntStream.of(failedTaskDuetoWanBw).sum(); failedTaskDuetoManBw[numOfAppTypes] = IntStream.of(failedTaskDuetoManBw).sum(); failedTaskDuetoLanBw[numOfAppTypes] = IntStream.of(failedTaskDuetoLanBw).sum(); failedTaskDuetoMobility[numOfAppTypes] = IntStream.of(failedTaskDuetoMobility).sum(); + refectedTaskDuetoWlanRange[numOfAppTypes] = IntStream.of(refectedTaskDuetoWlanRange).sum(); + orchestratorOverhead[numOfAppTypes] = DoubleStream.of(orchestratorOverhead).sum(); + // calculate server load double totalVmLoadOnEdge = 0; double totalVmLoadOnCloud = 0; @@ -419,39 +467,47 @@ public class SimLogger { totalVmLoadOnEdge += entry.getEdgeLoad(); totalVmLoadOnCloud += entry.getCloudLoad(); totalVmLoadOnMobile += entry.getMobileLoad(); - if (fileLogEnabled) + if (fileLogEnabled && SimSettings.getInstance().getVmLoadLogInterval() != 0) appendToFile(vmLoadBW, entry.toString()); } if (fileLogEnabled) { - // write location info to file - for (int t = 1; t < (SimSettings.getInstance().getSimulationTime() - / SimSettings.getInstance().getVmLocationLogInterval()); t++) { - int[] locationInfo = new int[SimSettings.getInstance().getNumOfPlaceTypes()]; - Double time = t * SimSettings.getInstance().getVmLocationLogInterval(); + // write location info to file for each location + // assuming each location has only one access point + double locationLogInterval = SimSettings.getInstance().getLocationLogInterval(); + if(locationLogInterval != 0) { + for (int t = 1; t < (SimSettings.getInstance().getSimulationTime() / locationLogInterval); t++) { + int[] locationInfo = new int[SimSettings.getInstance().getNumOfEdgeDatacenters()]; + Double time = t * SimSettings.getInstance().getLocationLogInterval(); + + if (time < SimSettings.CLIENT_ACTIVITY_START_TIME) + continue; - if (time < SimSettings.getInstance().getWarmUpPeriod()) - continue; + for (int i = 0; i < SimManager.getInstance().getNumOfMobileDevice(); i++) { + Location loc = SimManager.getInstance().getMobilityModel().getLocation(i, time); + locationInfo[loc.getServingWlanId()]++; + } - for (int i = 0; i < SimManager.getInstance().getNumOfMobileDevice(); i++) { + locationBW.write(time.toString()); + for (int i = 0; i < locationInfo.length; i++) + locationBW.write(SimSettings.DELIMITER + locationInfo[i]); - Location loc = SimManager.getInstance().getMobilityModel().getLocation(i, time); - int placeTypeIndex = loc.getPlaceTypeIndex(); - locationInfo[placeTypeIndex]++; + locationBW.newLine(); + } + } + + // write delay info to file for each access point + if(SimSettings.getInstance().getApDelayLogInterval() != 0) { + for (ApDelayLogItem entry : apDelayList) { + appendToFile(apUploadDelayBW, entry.getUploadStat()); + appendToFile(apDownloadDelayBW, entry.getDownloadStat()); } - - locationBW.write(time.toString()); - for (int i = 0; i < locationInfo.length; i++) - locationBW.write(SimSettings.DELIMITER + locationInfo[i]); - - locationBW.newLine(); } for (int i = 0; i < numOfAppTypes + 1; i++) { if (i < numOfAppTypes) { - // if related app is not used in this simulation, just - // discard it + // if related app is not used in this simulation, just discard it if (SimSettings.getInstance().getTaskLookUpTable()[i][0] == 0) continue; } @@ -465,6 +521,8 @@ public class SimLogger { double _vmLoadOnClould = (vmLoadList.size() == 0) ? 0.0 : (totalVmLoadOnCloud / (double) vmLoadList.size()); double _vmLoadOnMobile = (vmLoadList.size() == 0) ? 0.0 : (totalVmLoadOnMobile / (double) vmLoadList.size()); double _cost = (completedTask[i] == 0) ? 0.0 : (cost[i] / (double) completedTask[i]); + double _QoE1 = (completedTask[i] == 0) ? 0.0 : (QoE[i] / (double) completedTask[i]); + double _QoE2 = (completedTask[i] == 0) ? 0.0 : (QoE[i] / (double) (failedTask[i] + completedTask[i])); double _lanDelay = (lanUsage[i] == 0) ? 0.0 : (lanDelay[i] / (double) lanUsage[i]); @@ -472,7 +530,9 @@ public class SimLogger { : (manDelay[i] / (double) manUsage[i]); double _wanDelay = (wanUsage[i] == 0) ? 0.0 : (wanDelay[i] / (double) wanUsage[i]); - + double _gsmDelay = (gsmUsage[i] == 0) ? 0.0 + : (gsmDelay[i] / (double) gsmUsage[i]); + // write generic results String genericResult1 = Integer.toString(completedTask[i]) + SimSettings.DELIMITER + Integer.toString(failedTask[i]) + SimSettings.DELIMITER @@ -484,7 +544,10 @@ public class SimLogger { + Double.toString(0) + SimSettings.DELIMITER + Double.toString(_cost) + SimSettings.DELIMITER + Integer.toString(failedTaskDueToVmCapacity[i]) + SimSettings.DELIMITER - + Integer.toString(failedTaskDuetoMobility[i]); + + Integer.toString(failedTaskDuetoMobility[i]) + SimSettings.DELIMITER + + Double.toString(_QoE1) + SimSettings.DELIMITER + + Double.toString(_QoE2) + SimSettings.DELIMITER + + Integer.toString(refectedTaskDuetoWlanRange[i]); // check if the divisor is zero in order to avoid division by zero problem double _serviceTimeOnEdge = (completedTaskOnEdge[i] == 0) ? 0.0 @@ -534,16 +597,48 @@ public class SimLogger { String genericResult5 = Double.toString(_lanDelay) + SimSettings.DELIMITER + Double.toString(_manDelay) + SimSettings.DELIMITER + Double.toString(_wanDelay) + SimSettings.DELIMITER - + 0 + SimSettings.DELIMITER //for future use + + Double.toString(_gsmDelay) + SimSettings.DELIMITER + Integer.toString(failedTaskDuetoLanBw[i]) + SimSettings.DELIMITER + Integer.toString(failedTaskDuetoManBw[i]) + SimSettings.DELIMITER - + Integer.toString(failedTaskDuetoWanBw[i]); + + Integer.toString(failedTaskDuetoWanBw[i]) + SimSettings.DELIMITER + + Integer.toString(failedTaskDuetoGsmBw[i]); + + //performance related values + double _orchestratorOverhead = orchestratorOverhead[i] / (double) (failedTask[i] + completedTask[i]); + + String genericResult6 = Long.toString((endTime-startTime)/60) + SimSettings.DELIMITER + + Double.toString(_orchestratorOverhead); + appendToFile(genericBWs[i], genericResult1); appendToFile(genericBWs[i], genericResult2); appendToFile(genericBWs[i], genericResult3); appendToFile(genericBWs[i], genericResult4); appendToFile(genericBWs[i], genericResult5); + + //append performance related values only to ALL_ALLPS file + if(i == numOfAppTypes) { + appendToFile(genericBWs[i], genericResult6); + } + else { + printLine(SimSettings.getInstance().getTaskName(i)); + printLine("# of tasks (Edge/Cloud): " + + (failedTask[i] + completedTask[i]) + "(" + + (failedTaskOnEdge[i] + completedTaskOnEdge[i]) + "/" + + (failedTaskOnCloud[i]+ completedTaskOnCloud[i]) + ")" ); + + printLine("# of failed tasks (Edge/Cloud): " + + failedTask[i] + "(" + + failedTaskOnEdge[i] + "/" + + failedTaskOnCloud[i] + ")"); + + printLine("# of completed tasks (Edge/Cloud): " + + completedTask[i] + "(" + + completedTaskOnEdge[i] + "/" + + completedTaskOnCloud[i] + ")"); + + printLine("---------------------------------------"); + } } // close open files @@ -553,6 +648,8 @@ public class SimLogger { } vmLoadBW.close(); locationBW.close(); + apUploadDelayBW.close(); + apDownloadDelayBW.close(); for (int i = 0; i < numOfAppTypes + 1; i++) { if (i < numOfAppTypes) { // if related app is not used in this simulation, just @@ -562,6 +659,7 @@ public class SimLogger { } genericBWs[i].close(); } + } // printout important results @@ -595,12 +693,14 @@ public class SimLogger { + failedTaskDueToVmCapacityOnCloud[numOfAppTypes] + "/" + failedTaskDueToVmCapacityOnMobile[numOfAppTypes] + ")"); - printLine("# of failed tasks due to Mobility/Network(WLAN/MAN/WAN): " + printLine("# of failed tasks due to Mobility/WLAN Range/Network(WLAN/MAN/WAN/GSM): " + failedTaskDuetoMobility[numOfAppTypes] + + "/" + refectedTaskDuetoWlanRange[numOfAppTypes] + "/" + failedTaskDuetoBw[numOfAppTypes] + "(" + failedTaskDuetoLanBw[numOfAppTypes] + "/" + failedTaskDuetoManBw[numOfAppTypes] - + "/" + failedTaskDuetoWanBw[numOfAppTypes] + ")"); + + "/" + failedTaskDuetoWanBw[numOfAppTypes] + + "/" + failedTaskDuetoGsmBw[numOfAppTypes] + ")"); printLine("percentage of failed tasks: " + String.format("%.6f", ((double) failedTask[numOfAppTypes] * (double) 100) @@ -634,18 +734,128 @@ public class SimLogger { + ", " + "MAN delay: " + String.format("%.6f", manDelay[numOfAppTypes] / (double) manUsage[numOfAppTypes]) + ", " + "WAN delay: " - + String.format("%.6f", wanDelay[numOfAppTypes] / (double) wanUsage[numOfAppTypes]) + ")"); + + String.format("%.6f", wanDelay[numOfAppTypes] / (double) wanUsage[numOfAppTypes]) + + ", " + "GSM delay: " + + String.format("%.6f", gsmDelay[numOfAppTypes] / (double) gsmUsage[numOfAppTypes]) + ")"); printLine("average server utilization Edge/Cloud/Mobile: " + String.format("%.6f", totalVmLoadOnEdge / (double) vmLoadList.size()) + "/" + String.format("%.6f", totalVmLoadOnCloud / (double) vmLoadList.size()) + "/" + String.format("%.6f", totalVmLoadOnMobile / (double) vmLoadList.size())); - + printLine("average cost: " + cost[numOfAppTypes] / completedTask[numOfAppTypes] + "$"); + printLine("average overhead: " + orchestratorOverhead[numOfAppTypes] / (failedTask[numOfAppTypes] + completedTask[numOfAppTypes]) + " ns"); + printLine("average QoE (for all): " + QoE[numOfAppTypes] / (failedTask[numOfAppTypes] + completedTask[numOfAppTypes]) + "%"); + printLine("average QoE (for executed): " + QoE[numOfAppTypes] / completedTask[numOfAppTypes] + "%"); // clear related collections (map list etc.) taskMap.clear(); vmLoadList.clear(); + apDelayList.clear(); + } + + private void recordLog(int taskId){ + LogItem value = taskMap.remove(taskId); + + if (value.isInWarmUpPeriod()) + return; + + if (value.getStatus() == SimLogger.TASK_STATUS.COMLETED) { + completedTask[value.getTaskType()]++; + + if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) + completedTaskOnCloud[value.getTaskType()]++; + else if (value.getVmType() == SimSettings.VM_TYPES.MOBILE_VM.ordinal()) + completedTaskOnMobile[value.getTaskType()]++; + else + completedTaskOnEdge[value.getTaskType()]++; + } + else { + failedTask[value.getTaskType()]++; + + if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) + failedTaskOnCloud[value.getTaskType()]++; + else if (value.getVmType() == SimSettings.VM_TYPES.MOBILE_VM.ordinal()) + failedTaskOnMobile[value.getTaskType()]++; + else + failedTaskOnEdge[value.getTaskType()]++; + } + + if (value.getStatus() == SimLogger.TASK_STATUS.COMLETED) { + cost[value.getTaskType()] += value.getCost(); + QoE[value.getTaskType()] += value.getQoE(); + serviceTime[value.getTaskType()] += value.getServiceTime(); + networkDelay[value.getTaskType()] += value.getNetworkDelay(); + processingTime[value.getTaskType()] += (value.getServiceTime() - value.getNetworkDelay()); + orchestratorOverhead[value.getTaskType()] += value.getOrchestratorOverhead(); + + if(value.getNetworkDelay(NETWORK_DELAY_TYPES.WLAN_DELAY) != 0) { + lanUsage[value.getTaskType()]++; + lanDelay[value.getTaskType()] += value.getNetworkDelay(NETWORK_DELAY_TYPES.WLAN_DELAY); + } + if(value.getNetworkDelay(NETWORK_DELAY_TYPES.MAN_DELAY) != 0) { + manUsage[value.getTaskType()]++; + manDelay[value.getTaskType()] += value.getNetworkDelay(NETWORK_DELAY_TYPES.MAN_DELAY); + } + if(value.getNetworkDelay(NETWORK_DELAY_TYPES.WAN_DELAY) != 0) { + wanUsage[value.getTaskType()]++; + wanDelay[value.getTaskType()] += value.getNetworkDelay(NETWORK_DELAY_TYPES.WAN_DELAY); + } + if(value.getNetworkDelay(NETWORK_DELAY_TYPES.GSM_DELAY) != 0) { + gsmUsage[value.getTaskType()]++; + gsmDelay[value.getTaskType()] += value.getNetworkDelay(NETWORK_DELAY_TYPES.GSM_DELAY); + } + + if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) { + serviceTimeOnCloud[value.getTaskType()] += value.getServiceTime(); + processingTimeOnCloud[value.getTaskType()] += (value.getServiceTime() - value.getNetworkDelay()); + } + else if (value.getVmType() == SimSettings.VM_TYPES.MOBILE_VM.ordinal()) { + serviceTimeOnMobile[value.getTaskType()] += value.getServiceTime(); + processingTimeOnMobile[value.getTaskType()] += value.getServiceTime(); + } + else { + serviceTimeOnEdge[value.getTaskType()] += value.getServiceTime(); + processingTimeOnEdge[value.getTaskType()] += (value.getServiceTime() - value.getNetworkDelay()); + } + } else if (value.getStatus() == SimLogger.TASK_STATUS.REJECTED_DUE_TO_VM_CAPACITY) { + failedTaskDueToVmCapacity[value.getTaskType()]++; + + if (value.getVmType() == SimSettings.VM_TYPES.CLOUD_VM.ordinal()) + failedTaskDueToVmCapacityOnCloud[value.getTaskType()]++; + else if (value.getVmType() == SimSettings.VM_TYPES.MOBILE_VM.ordinal()) + failedTaskDueToVmCapacityOnMobile[value.getTaskType()]++; + else + failedTaskDueToVmCapacityOnEdge[value.getTaskType()]++; + } else if (value.getStatus() == SimLogger.TASK_STATUS.REJECTED_DUE_TO_BANDWIDTH + || value.getStatus() == SimLogger.TASK_STATUS.UNFINISHED_DUE_TO_BANDWIDTH) { + failedTaskDuetoBw[value.getTaskType()]++; + if (value.getNetworkError() == NETWORK_ERRORS.LAN_ERROR) + failedTaskDuetoLanBw[value.getTaskType()]++; + else if (value.getNetworkError() == NETWORK_ERRORS.MAN_ERROR) + failedTaskDuetoManBw[value.getTaskType()]++; + else if (value.getNetworkError() == NETWORK_ERRORS.WAN_ERROR) + failedTaskDuetoWanBw[value.getTaskType()]++; + else if (value.getNetworkError() == NETWORK_ERRORS.GSM_ERROR) + failedTaskDuetoGsmBw[value.getTaskType()]++; + } else if (value.getStatus() == SimLogger.TASK_STATUS.UNFINISHED_DUE_TO_MOBILITY) { + failedTaskDuetoMobility[value.getTaskType()]++; + } else if (value.getStatus() == SimLogger.TASK_STATUS.REJECTED_DUE_TO_WLAN_COVERAGE) { + refectedTaskDuetoWlanRange[value.getTaskType()]++;; + } + + //if deep file logging is enabled, record every task result + if (SimSettings.getInstance().getDeepFileLoggingEnabled()){ + try { + if (value.getStatus() == SimLogger.TASK_STATUS.COMLETED) + appendToFile(successBW, value.toString(taskId)); + else + appendToFile(failBW, value.toString(taskId)); + } catch (IOException e) { + e.printStackTrace(); + System.exit(1); + } + } } } @@ -682,9 +892,38 @@ class VmLoadLogItem { } } +class ApDelayLogItem { + private double time; + private double apUploadDelays[]; + double[] apDownloadDelays; + + ApDelayLogItem(double _time, double[] _apUploadDelays, double[] _apDownloadDelays){ + time = _time; + apUploadDelays = _apUploadDelays; + apDownloadDelays = _apDownloadDelays; + } + + public String getUploadStat() { + String result = Double.toString(time); + for(int i=0; i0) result += diffInDays + ((diffInDays>1 == true) ? " Days " : " Day "); if(diffInHours>0) @@ -79,7 +82,7 @@ public class SimUtils { result += diffInSeconds % 60 + ((diffInSeconds>1 == true) ? " Seconds" : " Second"); if(diffInMilli>0 && result.isEmpty()) result += diffInMilli + ((diffInMilli>1 == true) ? " Milli Seconds" : " Milli Second"); - + return result; } } diff --git a/src/edu/boun/edgecloudsim/utils/TaskProperty.java b/src/edu/boun/edgecloudsim/utils/TaskProperty.java index fe77a11..e5b9a70 100644 --- a/src/edu/boun/edgecloudsim/utils/TaskProperty.java +++ b/src/edu/boun/edgecloudsim/utils/TaskProperty.java @@ -15,59 +15,69 @@ import org.apache.commons.math3.distribution.ExponentialDistribution; import edu.boun.edgecloudsim.core.SimSettings; public class TaskProperty { - private double startTime; - private long length, inputFileSize, outputFileSize; - private int taskType; - private int pesNumber; - private int mobileDeviceId; - - public TaskProperty(double _startTime, int _mobileDeviceId, int _taskType, int _pesNumber, long _length, long _inputFileSize, long _outputFileSize) { - startTime=_startTime; - mobileDeviceId=_mobileDeviceId; - taskType=_taskType; - pesNumber = _pesNumber; - length = _length; - outputFileSize = _inputFileSize; - inputFileSize = _outputFileSize; - } - - public TaskProperty(int _mobileDeviceId, int _taskType, double _startTime, ExponentialDistribution[][] expRngList) { - mobileDeviceId=_mobileDeviceId; - startTime=_startTime; - taskType=_taskType; - - inputFileSize = (long)expRngList[_taskType][0].sample(); - outputFileSize =(long)expRngList[_taskType][1].sample(); - length = (long)expRngList[_taskType][2].sample(); - - pesNumber = (int)SimSettings.getInstance().getTaskLookUpTable()[_taskType][8]; - } - - public double getStartTime(){ - return startTime; - } - - public long getLength(){ - return length; - } - - public long getInputFileSize(){ - return inputFileSize; - } - - public long getOutputFileSize(){ - return outputFileSize; - } + private double startTime; + private long length, inputFileSize, outputFileSize; + private int taskType; + private int pesNumber; + private int mobileDeviceId; - public int getTaskType(){ - return taskType; - } - - public int getPesNumber(){ - return pesNumber; - } - - public int getMobileDeviceId(){ - return mobileDeviceId; - } + public TaskProperty(double _startTime, int _mobileDeviceId, int _taskType, int _pesNumber, long _length, long _inputFileSize, long _outputFileSize) { + startTime=_startTime; + mobileDeviceId=_mobileDeviceId; + taskType=_taskType; + pesNumber = _pesNumber; + length = _length; + outputFileSize = _inputFileSize; + inputFileSize = _outputFileSize; + } + + public TaskProperty(int _mobileDeviceId, int _taskType, double _startTime, ExponentialDistribution[][] expRngList) { + mobileDeviceId=_mobileDeviceId; + startTime=_startTime; + taskType=_taskType; + + inputFileSize = (long)expRngList[_taskType][0].sample(); + outputFileSize =(long)expRngList[_taskType][1].sample(); + length = (long)expRngList[_taskType][2].sample(); + + pesNumber = (int)SimSettings.getInstance().getTaskLookUpTable()[_taskType][8]; + } + + public TaskProperty(int mobileDeviceId, double startTime, ExponentialDistribution[] expRngList) { + this.mobileDeviceId = mobileDeviceId; + this.startTime = startTime; + taskType = 0; + inputFileSize = (long)expRngList[0].sample(); + outputFileSize = (long)expRngList[1].sample(); + length = (long) expRngList[2].sample(); + pesNumber = (int)SimSettings.getInstance().getTaskLookUpTable()[0][8]; + } + + public double getStartTime(){ + return startTime; + } + + public long getLength(){ + return length; + } + + public long getInputFileSize(){ + return inputFileSize; + } + + public long getOutputFileSize(){ + return outputFileSize; + } + + public int getTaskType(){ + return taskType; + } + + public int getPesNumber(){ + return pesNumber; + } + + public int getMobileDeviceId(){ + return mobileDeviceId; + } } From 6660de75b2b0561661ff297c791ee2ad6750f757 Mon Sep 17 00:00:00 2001 From: Cagatay Sonmez Date: Fri, 30 Oct 2020 12:57:07 +0300 Subject: [PATCH 3/4] Sample application 5 used in IEEE Transactions on Intelligent Transportation Systems is added. --- README.md | 4 + doc/images/sample_app5/ml_details.png | Bin 0 -> 88787 bytes doc/images/sample_app5/ml_stages.png | Bin 0 -> 28435 bytes doc/images/sample_app5/road.png | Bin 0 -> 31060 bytes doc/images/sample_app5/vec_architecture.png | Bin 0 -> 76967 bytes lib/mtj-1.0.4.jar | Bin 0 -> 268984 bytes lib/weka.jar | Bin 0 -> 11143484 bytes scripts/sample_app5/.gitignore | 1 + scripts/sample_app5/ai_trainer/.gitignore | 1 + scripts/sample_app5/ai_trainer/README.md | 23 + .../ai_trainer/WekaModelCreator.java | 208 +++ scripts/sample_app5/ai_trainer/config.json | 10 + .../sample_app5/ai_trainer/data_convertor.py | 133 ++ .../ai_trainer/generate_training_data.sh | 14 + .../ai_trainer/generate_weka_models.sh | 4 + .../ai_trainer/json-simple-1.1.1.jar | Bin 0 -> 23737 bytes scripts/sample_app5/compile.sh | 4 + scripts/sample_app5/config/applications.xml | 51 + .../config/default_config.properties | 53 + scripts/sample_app5/config/edge_devices.xml | 1364 +++++++++++++++++ .../config/weka/lr_cloud_gsm.model | Bin 0 -> 4645 bytes .../config/weka/lr_cloud_rsu.model | Bin 0 -> 4645 bytes scripts/sample_app5/config/weka/lr_edge.model | Bin 0 -> 4493 bytes .../config/weka/mlp_cloud_gsm.model | Bin 0 -> 9286 bytes .../config/weka/mlp_cloud_rsu.model | Bin 0 -> 9286 bytes .../sample_app5/config/weka/mlp_edge.model | Bin 0 -> 10583 bytes scripts/sample_app5/matlab/getConfiguration.m | 60 + scripts/sample_app5/matlab/plotApDelay.m | 113 ++ .../sample_app5/matlab/plotAvgFailedTask.m | 8 + .../sample_app5/matlab/plotAvgNetworkDelay.m | 11 + .../matlab/plotAvgProcessingTime.m | 9 + scripts/sample_app5/matlab/plotAvgQoE.m | 8 + .../sample_app5/matlab/plotAvgServiceTime.m | 9 + .../sample_app5/matlab/plotAvgVmUtilization.m | 7 + .../sample_app5/matlab/plotDelayReasonAsBar.m | 91 ++ scripts/sample_app5/matlab/plotGenericLine.m | 198 +++ scripts/sample_app5/matlab/plotGenericPie.m | 78 + .../sample_app5/matlab/plotGenericScatter.m | 96 ++ scripts/sample_app5/matlab/plotLocation.m | 66 + .../matlab/plotTaskFailureReason.m | 15 + .../sample_app5/matlab/plotTimeComplexity.m | 7 + scripts/sample_app5/run_scenarios.sh | 75 + scripts/sample_app5/runner.sh | 25 + scripts/sample_app5/simulation.list | 1 + scripts/sample_app5/stop_scenarios.sh | 15 + .../applications/sample_app4/README.md | 8 +- .../sample_app5/GameTheoryHelper.java | 74 + .../sample_app5/MultiArmedBanditHelper.java | 115 ++ .../OrchestratorStatisticLogger.java | 193 +++ .../OrchestratorTrainerLogger.java | 227 +++ .../applications/sample_app5/README.md | 55 + .../VehicularCpuUtilizationModel.java | 67 + .../VehicularEdgeOrchestrator.java | 465 ++++++ .../VehicularEdgeServerManager.java | 222 +++ .../sample_app5/VehicularLoadGenerator.java | 102 ++ .../sample_app5/VehicularMainApp.java | 150 ++ .../VehicularMobileDeviceManager.java | 569 +++++++ .../VehicularMobileServerManager.java | 184 +++ .../sample_app5/VehicularMobilityModel.java | 112 ++ .../sample_app5/VehicularNetworkModel.java | 487 ++++++ .../sample_app5/VehicularScenarioFactory.java | 78 + .../applications/sample_app5/WekaWrapper.java | 219 +++ 62 files changed, 6084 insertions(+), 5 deletions(-) create mode 100644 doc/images/sample_app5/ml_details.png create mode 100644 doc/images/sample_app5/ml_stages.png create mode 100644 doc/images/sample_app5/road.png create mode 100644 doc/images/sample_app5/vec_architecture.png create mode 100644 lib/mtj-1.0.4.jar create mode 100644 lib/weka.jar create mode 100644 scripts/sample_app5/.gitignore create mode 100644 scripts/sample_app5/ai_trainer/.gitignore create mode 100644 scripts/sample_app5/ai_trainer/README.md create mode 100644 scripts/sample_app5/ai_trainer/WekaModelCreator.java create mode 100644 scripts/sample_app5/ai_trainer/config.json create mode 100644 scripts/sample_app5/ai_trainer/data_convertor.py create mode 100644 scripts/sample_app5/ai_trainer/generate_training_data.sh create mode 100644 scripts/sample_app5/ai_trainer/generate_weka_models.sh create mode 100644 scripts/sample_app5/ai_trainer/json-simple-1.1.1.jar create mode 100644 scripts/sample_app5/compile.sh create mode 100644 scripts/sample_app5/config/applications.xml create mode 100644 scripts/sample_app5/config/default_config.properties create mode 100644 scripts/sample_app5/config/edge_devices.xml create mode 100644 scripts/sample_app5/config/weka/lr_cloud_gsm.model create mode 100644 scripts/sample_app5/config/weka/lr_cloud_rsu.model create mode 100644 scripts/sample_app5/config/weka/lr_edge.model create mode 100644 scripts/sample_app5/config/weka/mlp_cloud_gsm.model create mode 100644 scripts/sample_app5/config/weka/mlp_cloud_rsu.model create mode 100644 scripts/sample_app5/config/weka/mlp_edge.model create mode 100644 scripts/sample_app5/matlab/getConfiguration.m create mode 100644 scripts/sample_app5/matlab/plotApDelay.m create mode 100644 scripts/sample_app5/matlab/plotAvgFailedTask.m create mode 100644 scripts/sample_app5/matlab/plotAvgNetworkDelay.m create mode 100644 scripts/sample_app5/matlab/plotAvgProcessingTime.m create mode 100644 scripts/sample_app5/matlab/plotAvgQoE.m create mode 100644 scripts/sample_app5/matlab/plotAvgServiceTime.m create mode 100644 scripts/sample_app5/matlab/plotAvgVmUtilization.m create mode 100644 scripts/sample_app5/matlab/plotDelayReasonAsBar.m create mode 100644 scripts/sample_app5/matlab/plotGenericLine.m create mode 100644 scripts/sample_app5/matlab/plotGenericPie.m create mode 100644 scripts/sample_app5/matlab/plotGenericScatter.m create mode 100644 scripts/sample_app5/matlab/plotLocation.m create mode 100644 scripts/sample_app5/matlab/plotTaskFailureReason.m create mode 100644 scripts/sample_app5/matlab/plotTimeComplexity.m create mode 100644 scripts/sample_app5/run_scenarios.sh create mode 100644 scripts/sample_app5/runner.sh create mode 100644 scripts/sample_app5/simulation.list create mode 100644 scripts/sample_app5/stop_scenarios.sh create mode 100644 src/edu/boun/edgecloudsim/applications/sample_app5/GameTheoryHelper.java create mode 100644 src/edu/boun/edgecloudsim/applications/sample_app5/MultiArmedBanditHelper.java create mode 100644 src/edu/boun/edgecloudsim/applications/sample_app5/OrchestratorStatisticLogger.java create mode 100644 src/edu/boun/edgecloudsim/applications/sample_app5/OrchestratorTrainerLogger.java create mode 100644 src/edu/boun/edgecloudsim/applications/sample_app5/README.md create mode 100644 src/edu/boun/edgecloudsim/applications/sample_app5/VehicularCpuUtilizationModel.java create mode 100644 src/edu/boun/edgecloudsim/applications/sample_app5/VehicularEdgeOrchestrator.java create mode 100644 src/edu/boun/edgecloudsim/applications/sample_app5/VehicularEdgeServerManager.java create mode 100644 src/edu/boun/edgecloudsim/applications/sample_app5/VehicularLoadGenerator.java create mode 100644 src/edu/boun/edgecloudsim/applications/sample_app5/VehicularMainApp.java create mode 100644 src/edu/boun/edgecloudsim/applications/sample_app5/VehicularMobileDeviceManager.java create mode 100644 src/edu/boun/edgecloudsim/applications/sample_app5/VehicularMobileServerManager.java create mode 100644 src/edu/boun/edgecloudsim/applications/sample_app5/VehicularMobilityModel.java create mode 100644 src/edu/boun/edgecloudsim/applications/sample_app5/VehicularNetworkModel.java create mode 100644 src/edu/boun/edgecloudsim/applications/sample_app5/VehicularScenarioFactory.java create mode 100644 src/edu/boun/edgecloudsim/applications/sample_app5/WekaWrapper.java diff --git a/README.md b/README.md index c415f09..204153d 100644 --- a/README.md +++ b/README.md @@ -112,3 +112,7 @@ You can plot lots of graphics by using the result of EdgeCloudSim. Some examples **[2]** C. Sonmez, A. Ozgovde and C. Ersoy, "[Performance evaluation of single-tier and two-tier cloudlet assisted applications](http://ieeexplore.ieee.org/document/7962674/)," *2017 IEEE International Conference on Communications Workshops (ICC Workshops)*, Paris, 2017, pp. 302-307. **[3]** Sonmez C, Ozgovde A, Ersoy C. "[EdgeCloudSim: An environment for performance evaluation of Edge Computing systems](https://onlinelibrary.wiley.com/doi/abs/10.1002/ett.3493)," *Transactions on Emerging Telecommunications Technologies*, 2018;e3493. + +**[4]** C. Sonmez, A. Ozgovde and C. Ersoy, "[Fuzzy Workload Orchestration for Edge Computing](https://ieeexplore.ieee.org/abstract/document/8651335/)," in *IEEE Transactions on Network and Service Management*, vol. 16, no. 2, pp. 769-782, June 2019. + +**[5]** C. Sonmez, A. Ozgovde and C. Ersoy, "[Machine Learning-Based Workload Orchestrator for Vehicular Edge Computing](https://ieeexplore.ieee.org/abstract/document/9208723/)," in *IEEE Transactions on Intelligent Transportation Systems*, doi: 10.1109/TITS.2020.3024233. diff --git a/doc/images/sample_app5/ml_details.png b/doc/images/sample_app5/ml_details.png new file mode 100644 index 0000000000000000000000000000000000000000..1e1384c7f53fba48ad197baada6166d4a2925d5b GIT binary patch literal 88787 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