Implemented Scheduler A and utility classes
authorAndreas Egger <egger.andreas.1@gmail.com>
Tue, 21 May 2013 17:19:40 +0000 (19:19 +0200)
committerAndreas Egger <egger.andreas.1@gmail.com>
Tue, 21 May 2013 17:19:40 +0000 (19:19 +0200)
12 files changed:
src/at/ac/tuwien/lsdc/SchedSimulator.java
src/at/ac/tuwien/lsdc/exception/ActiveApplicationsException.java [new file with mode: 0644]
src/at/ac/tuwien/lsdc/exception/VMsRunningException.java [new file with mode: 0644]
src/at/ac/tuwien/lsdc/management/MachineManager.java
src/at/ac/tuwien/lsdc/sched/AbstractScheduler.java
src/at/ac/tuwien/lsdc/sched/SchedulerA.java
src/at/ac/tuwien/lsdc/sched/SchedulerB.java
src/at/ac/tuwien/lsdc/sched/SchedulerC.java
src/at/ac/tuwien/lsdc/types/PhysicalMachine.java
src/at/ac/tuwien/lsdc/types/SortedApplication.java [new file with mode: 0644]
src/at/ac/tuwien/lsdc/types/SortedPhysicalMachine.java [new file with mode: 0644]
src/at/ac/tuwien/lsdc/types/VirtualMachine.java

index 83256c025a03198a4c5d86b0cb294211f891101e..90bc3e6856bf7b7d316f6c837318cd4d80b01ef0 100644 (file)
@@ -57,11 +57,11 @@ public class SchedSimulator {
                AbstractScheduler scheduler;
                switch (schedulerType) {
                case A:
-                       scheduler = new SchedulerA(schedulerLog,schedulerType,scenario);
+                       scheduler = new SchedulerA(schedulerLog, schedulerType, scenario, numPMs, numCloudPartners);
                case B:
-                       scheduler = new SchedulerB(schedulerLog,schedulerType,scenario);
+                       scheduler = new SchedulerB(schedulerLog, schedulerType, scenario, numPMs, numCloudPartners);
                default:
-                       scheduler = new SchedulerC(schedulerLog,schedulerType,scenario);
+                       scheduler = new SchedulerC(schedulerLog, schedulerType, scenario, numPMs, numCloudPartners);
                }
                ScenarioData data = scheduler.initAndStart(apps);
                CSVLogger logger = new CSVLogger(generalLog);
diff --git a/src/at/ac/tuwien/lsdc/exception/ActiveApplicationsException.java b/src/at/ac/tuwien/lsdc/exception/ActiveApplicationsException.java
new file mode 100644 (file)
index 0000000..1de3c8d
--- /dev/null
@@ -0,0 +1,8 @@
+package at.ac.tuwien.lsdc.exception;
+
+public class ActiveApplicationsException extends Exception {
+
+       public ActiveApplicationsException(String msg) {
+               super(msg);
+       }
+}
diff --git a/src/at/ac/tuwien/lsdc/exception/VMsRunningException.java b/src/at/ac/tuwien/lsdc/exception/VMsRunningException.java
new file mode 100644 (file)
index 0000000..113e7ee
--- /dev/null
@@ -0,0 +1,8 @@
+package at.ac.tuwien.lsdc.exception;
+
+public class VMsRunningException extends Exception {
+
+       public VMsRunningException(String message) {
+               super(message);
+       }
+}
index 49bf3404001b0779f7397a8834223d30cf838c3d..133faa7b2681b522513cf332032dc62af6ee95ba 100644 (file)
@@ -1,16 +1,75 @@
 package at.ac.tuwien.lsdc.management;
 
+import java.util.Collection;
 import java.util.HashMap;
+import java.util.List;
 
+import at.ac.tuwien.lsdc.exception.VMsRunningException;
 import at.ac.tuwien.lsdc.types.PhysicalMachine;
 
+/**
+ * This class is responsible to start and stop PMs & VMs
+ * also it will be used to put an application on a VM
+ * move an application and get utilization data
+ * 
+ */
 public class MachineManager {
-       // this class is responsible to start and stop PMs & VMs
-       // also it will be used to put an application on a VM
-       // move an application and get utilization data
 
        private HashMap<Integer, PhysicalMachine> PMs = new HashMap<Integer, PhysicalMachine>();
+       
+       private int maxPMs;
+       
+       public MachineManager(int maxPMs) {
+               this.maxPMs = maxPMs;
+       }
+       
+       
+       /**
+        * Start a physical machine
+        * @return the PM that was started, null if all machines already running
+        */
+       public PhysicalMachine startPhysicalMachine() {
+               if(PMs.size() < maxPMs) {
+                       PhysicalMachine pm = new PhysicalMachine();
+                       PMs.put(pm.getId(), pm);
+                       pm.start();
+                       return pm;
+               }
+               return null;
+       }
+       
+       /**
+        * Stops a physical machine with the given id
+        * @param id the id of the PM to stop
+        * @throws VMsRunningException is thrown when there are still VMs running on this PM
+        */
+       public void stopPhysicalMachine(int id) throws VMsRunningException {
+               if(PMs.containsKey(id)) {
+                       PMs.get(id).stop();
+                       PMs.remove(id);
+               }
+       }
+       
+       /**
+        * Returns all running physical machines
+        * @return the currently active PMs
+        */
+       public Collection<PhysicalMachine> getPMs () {
+               return PMs.values();
+       }
+       
+       /**
+        * Returns the maximum number of available physical machines
+        * @return the maximum number of PMs
+        */
+       public int getMaxPMs() {
+               return maxPMs;
+       }
 
+       /**
+        * Gets the total power consumption summed up from each PM
+        * @return the total power consumption
+        */
        public double getTotalConsumption() {
                double consumption = 0;
                for (PhysicalMachine pm : PMs.values()) {
index 7c336decff1386121df05f79386fcd6beef7a98d..4a9f84e43ac47c3416b2fd3396e637ef4edd4a22 100644 (file)
@@ -10,12 +10,16 @@ import java.util.Map;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import at.ac.tuwien.lsdc.federation.Federation;
+import at.ac.tuwien.lsdc.management.MachineManager;
 import at.ac.tuwien.lsdc.types.Application;
 import at.ac.tuwien.lsdc.types.ScenarioData;
 import at.ac.tuwien.lsdc.types.ScenarioType;
 import at.ac.tuwien.lsdc.types.SchedulerData;
 import at.ac.tuwien.lsdc.types.SchedulerEvent;
+import at.ac.tuwien.lsdc.types.SchedulerEvent.EventType;
 import at.ac.tuwien.lsdc.types.SchedulerType;
+import at.ac.tuwien.lsdc.types.VirtualMachine.VMType;
 import at.ac.tuwien.lsdc.util.CSVLogger;
 
 public abstract class AbstractScheduler {
@@ -31,13 +35,21 @@ public abstract class AbstractScheduler {
        protected int numCurrInSourced;
        protected int numCurrOutSourced;
        
-       File schedulerLog;
-       CSVLogger logger;
+       protected MachineManager machineManager;
+       protected Federation federation;
+       protected File schedulerLog;
+       protected CSVLogger logger;
+       protected VMType VMType;
 
        // this map saves the following Type of Events:
        // start of an Application, end of an Application
        // (start outSourced, end outSourced, start inSourced, end inSourced)
        protected HashMap<Long, LinkedList<SchedulerEvent>> eventMap;
+       
+//     // this map saves the following Type of Events:
+//     // start of an Application, end of an Application
+//     // (start outSourced, end outSourced, start inSourced, end inSourced)
+//     protected HashMap<Long, LinkedList<SchedulerEvent>> endEventMap;
 
        // Scheduler has an internal Time "Abstraction"
        // at every point in time it checks for Events in his "EventList"
@@ -48,10 +60,12 @@ public abstract class AbstractScheduler {
        // it is updated with every added "EndEvent"
        protected long endTime;
 
-       public AbstractScheduler(File schedulerLog, SchedulerType schedulerType, ScenarioType scenario) throws IOException {
+       public AbstractScheduler(File schedulerLog, SchedulerType schedulerType, ScenarioType scenario, int numPMs, int numCloudPartners) throws IOException {
                this.schedulerLog = schedulerLog;
                this.schedulerType = schedulerType;
                this.scenario = scenario;
+               this.machineManager = new MachineManager(numPMs);
+               this.federation = new Federation(numCloudPartners);
                this.eventMap = new HashMap<Long,LinkedList<SchedulerEvent>>();
                this.logger = new CSVLogger(schedulerLog);
        }
@@ -59,10 +73,9 @@ public abstract class AbstractScheduler {
        // Initialize Scheduler with Data from CSV
        // CSV will be parsed and sent as List<Application> to Scheduler
        public ScenarioData initAndStart(LinkedList<Application> apps) {
-               for (Application a : apps) {
-                       //System.out.println(a);
-                       // read start timestamp
-                       // save event in map
+               for (Application app : apps) {
+                       insertStartEvent(app.getTimestamp(), app);
+                       insertStopEvent(app.getTimestamp() + app.getDuration(), app);
                }
                startScheduling();
                try {
@@ -72,6 +85,43 @@ public abstract class AbstractScheduler {
                }
                return doEndLogging();
        }
+       
+       /**
+        * Insert a start event into the map, at timestamp when the application should start
+        * @param timestamp the timestamp when the application should start
+        * @param app the application to start
+        */
+       private void insertStartEvent(long timestamp, Application app) {
+               SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.startApplication, app);
+               if(!eventMap.containsKey(timestamp)) {
+                       LinkedList<SchedulerEvent> list = new LinkedList<SchedulerEvent>();
+                       list.add(evt);
+                       eventMap.put(timestamp, list);
+               } else {
+                       LinkedList<SchedulerEvent> list = eventMap.get(timestamp);
+                       list.add(evt);
+               }
+       }
+       
+       /**
+        * Insert a stop event into the map, at timestamp when the application should stop
+        * @param timestamp the timestamp when the application should stop
+        * @param app the application to stop
+        */
+       private void insertStopEvent(long timestamp, Application app) {
+               SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.endApplication, app);
+               if(!eventMap.containsKey(timestamp)) {
+                       LinkedList<SchedulerEvent> list = new LinkedList<SchedulerEvent>();
+                       list.add(evt);
+                       eventMap.put(timestamp, list);
+               } else {
+                       LinkedList<SchedulerEvent> list = eventMap.get(timestamp);
+                       list.add(evt);
+               }
+               if(endTime < timestamp) {
+                       endTime = timestamp;
+               }
+       }
 
        protected void startScheduling() {
                while (true) {
@@ -79,6 +129,7 @@ public abstract class AbstractScheduler {
                        handleEvents(events);
                        doStateLogging();
                        //advance Time to next Event
+                       currTime++;
                        if (currTime == endTime) {
                                // reached last Event, Scheduler will shut down
                                break;
index 91588d2b5b9ad7ea90391b8d223d518db2747113..4ce79c9b0ec4948a8f22371b6aa3528ae495bd78 100644 (file)
@@ -2,23 +2,130 @@ package at.ac.tuwien.lsdc.sched;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.Iterator;
 import java.util.LinkedList;
+import java.util.List;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import edu.emory.mathcs.backport.java.util.Collections;
+
+import at.ac.tuwien.lsdc.exception.ActiveApplicationsException;
+import at.ac.tuwien.lsdc.types.Application;
+import at.ac.tuwien.lsdc.types.PhysicalMachine;
 import at.ac.tuwien.lsdc.types.ScenarioType;
 import at.ac.tuwien.lsdc.types.SchedulerEvent;
+import at.ac.tuwien.lsdc.types.SchedulerEvent.EventType;
 import at.ac.tuwien.lsdc.types.SchedulerType;
+import at.ac.tuwien.lsdc.types.SortedApplication;
+import at.ac.tuwien.lsdc.types.SortedPhysicalMachine;
+import at.ac.tuwien.lsdc.types.VirtualMachine;
 
 
 public class SchedulerA extends AbstractScheduler {
 
-       public SchedulerA(File logFile, SchedulerType schedulerType, ScenarioType scenario) throws IOException {
-               super(logFile, schedulerType, scenario);
+       private static final Logger log = LoggerFactory.getLogger(SchedulerA.class);
+       
+       public SchedulerA(File logFile, SchedulerType schedulerType, ScenarioType scenario, int numPMs, int numCloudPartners) throws IOException {
+               super(logFile, schedulerType, scenario, numPMs, numCloudPartners);
+               this.VMType = VMType.NonResizable;
        }
 
        @Override
        protected void handleEvents(LinkedList<SchedulerEvent> events) {
-               // TODO Auto-generated method stub
                
+               for(SchedulerEvent evt : events) {
+                       if(evt.getType() == EventType.endApplication) {
+                               VirtualMachine vm = evt.getApp().getRunningOn();
+                               vm.stopApplication(evt.getApp());
+                               PhysicalMachine pm = vm.getRunningOn();
+                               try {
+                                       pm.stopVirtualMachine(vm);
+                               } catch (ActiveApplicationsException e) {
+                                       log.warn("VM "+vm.getId()+"could not be stopped, "+e.getMessage());
+                               }
+                       }
+               }
+               
+               // sorting applications by amount of resources (descending)
+               List<SortedApplication> sortedApps = sortApps(events);
+                               
+               for(Iterator<SortedApplication> iter = sortedApps.iterator(); iter.hasNext(); ) {
+                       boolean appDeployed = false;
+                       Application app = iter.next().getApp();
+                       
+                       if(machineManager.getPMs().size() == 0) {
+                               PhysicalMachine pm = machineManager.startPhysicalMachine();
+                               boolean enoughResources = pm.checkVM(app.getSize(), app.getRam(), app.getCpu());
+                               
+                               if(enoughResources) {
+                                       pm.startVirtualMachine(app.getSize(), app.getRam(), app.getCpu(), VMType);
+                                       appDeployed = true;
+                                       log.debug("Application "+app.toString()+" started on new pm "+pm.getId());
+                               }
+                               else {
+                                       log.warn("Application "+app.toString()+" cannot be run on empty pm "+pm.getId());
+                               }
+                       }
+                       else {
+                               // sorting physical machines by resource utilization (descending)
+                               List<SortedPhysicalMachine> sortedPMs = sortPMs();
+                               
+                               for(Iterator<SortedPhysicalMachine> it = sortedPMs.iterator(); iter.hasNext(); ) {
+                                       PhysicalMachine pm = it.next().getPm();
+                                       boolean enoughResources = pm.checkVM(app.getSize(), app.getRam(), app.getCpu());
+                                       
+                                       if(enoughResources) {
+                                               VirtualMachine vm = pm.startVirtualMachine(app.getSize(), app.getRam(), app.getCpu(), VMType);
+                                               vm.startApplication(app);
+                                               appDeployed = true;
+                                               log.debug("Application "+app.toString()+" started on new pm "+pm.getId());
+                                               break;
+                                       }
+                               }
+                               if(!appDeployed  &&  (machineManager.getPMs().size() < machineManager.getMaxPMs())) {
+                                       
+                                       PhysicalMachine pm = machineManager.startPhysicalMachine();
+                                       boolean enoughResources = pm.checkVM(app.getSize(), app.getRam(), app.getCpu());
+                                       
+                                       if(enoughResources) {
+                                               VirtualMachine vm = pm.startVirtualMachine(app.getSize(), app.getRam(), app.getCpu(), VMType);
+                                               vm.startApplication(app);
+                                               appDeployed = true;
+                                               log.debug("Application "+app.toString()+" started on new pm "+pm.getId());
+                                       }
+                                       else {
+                                               log.warn("Application "+app.toString()+" cannot be run on empty pm "+pm.getId());
+                                       }
+                               }
+                       }
+                       if(!appDeployed) 
+                               log.warn("Application "+app.toString()+" could not be deployed on any pm");
+               }
+       }
+       
+       // sorting applications by amount of resources (descending)
+       private List<SortedApplication> sortApps(LinkedList<SchedulerEvent> events) {
+               List<SortedApplication> sortedApps = new LinkedList<SortedApplication>();
+               for(SchedulerEvent evt : events) {
+                       if(evt.getType() == EventType.startApplication)
+                               sortedApps.add(new SortedApplication(evt.getApp()));
+               }
+               Collections.sort(sortedApps);
+               Collections.reverse(sortedApps);
+               return sortedApps;
+       }
+       
+       // sorting physical machines by resource utilization (descending)
+       private List<SortedPhysicalMachine> sortPMs() {
+               List<SortedPhysicalMachine> sortedPMs = new LinkedList<SortedPhysicalMachine>();
+               for(PhysicalMachine pm  : machineManager.getPMs())
+                       sortedPMs.add(new SortedPhysicalMachine(pm));
+               
+               Collections.sort(sortedPMs);
+               Collections.reverse(sortedPMs);
+               return sortedPMs;
        }
 
 }
index 4e54be12979ff70cb3fe2ba72276f75af372cd84..892067aa5d31e0ab9f09a1c46aa3bc42520e32bb 100644 (file)
@@ -11,8 +11,8 @@ import at.ac.tuwien.lsdc.types.SchedulerType;
 
 public class SchedulerB extends AbstractScheduler {
 
-       public SchedulerB(File logFile, SchedulerType schedulerType, ScenarioType scenario) throws IOException {
-               super(logFile, schedulerType, scenario);
+       public SchedulerB(File logFile, SchedulerType schedulerType, ScenarioType scenario, int numPMs, int numCloudPartners) throws IOException {
+               super(logFile, schedulerType, scenario, numPMs, numCloudPartners);
        }
 
        @Override
index cc21496d64e1561f858f4e085e71e47144345d4f..910886ce09055a935d798ac2023361100d256ebe 100644 (file)
@@ -11,8 +11,8 @@ import at.ac.tuwien.lsdc.types.SchedulerType;
 
 public class SchedulerC extends AbstractScheduler {
 
-       public SchedulerC(File logFile, SchedulerType schedulerType, ScenarioType scenario) throws IOException {
-               super(logFile,schedulerType,scenario);
+       public SchedulerC(File logFile, SchedulerType schedulerType, ScenarioType scenario, int numPMs, int numCloudPartners) throws IOException {
+               super(logFile, schedulerType, scenario, numPMs, numCloudPartners);
        }
 
        @Override
index 94897971de83c14406b5cfbdb414b5a9d0dbe038..9de683fa09e44bca4222cbdb1f55c6b82fabe379 100644 (file)
@@ -2,6 +2,10 @@ package at.ac.tuwien.lsdc.types;
 
 import java.util.HashMap;
 
+import at.ac.tuwien.lsdc.exception.ActiveApplicationsException;
+import at.ac.tuwien.lsdc.exception.VMsRunningException;
+import at.ac.tuwien.lsdc.types.VirtualMachine.VMType;
+
 public class PhysicalMachine {
 
        private static int count = 0;
@@ -36,9 +40,10 @@ public class PhysicalMachine {
                running = true;
        }
 
-       public void stop() {
-               // TODO: anything else we need to do? maybe implement a stop method in
-               // VirtualMachine and call it on every VM
+       public void stop() throws VMsRunningException {
+               if(VMs.size() > 0)
+                       throw new VMsRunningException("PM cannot be stopped. Some VMs still running");
+               
                VMs = new HashMap<Integer, VirtualMachine>();
                size = 0;
                RAM = 0;
@@ -47,38 +52,35 @@ public class PhysicalMachine {
        }
 
        public double getConsumption() {
-               return 200 + 0.3 * CPU;
+               return 200 + 0.3 * (CPU - initialCPU);
        }
 
-       public int startVirtualMachine(int size, int RAM, int CPU) {
-               if (checkVM(size, RAM, CPU)) {
-                       VirtualMachine vm = new VirtualMachine(size, RAM, CPU, this);
+       public VirtualMachine startVirtualMachine(int sz, int ram, int cpu, VMType type) {
+               if (checkVM(sz, ram, cpu)) {
+                       VirtualMachine vm = new VirtualMachine(sz, ram, cpu, this, type);
                        VMs.put(vm.getId(), vm);
                        size = size + vm.getSize();
                        RAM = RAM + vm.getRAM();
                        CPU = CPU + vm.getCPU();
-                       return vm.getId();
+                       return vm;
                } else
-                       return -1;
+                       return null;
        }
 
-       public boolean stopVirtualMachine(VirtualMachine vm) {
+       public void stopVirtualMachine(VirtualMachine vm) throws ActiveApplicationsException {
                if (VMs.containsKey(vm.getId())) {
                        if (vm.getApplications().size() != 0) {
-                               // apps must be migrated before stopping a VM
-                               return false;
+                               throw new ActiveApplicationsException("Applications must be migrated before stopping a vm, vm id "+vm.getId());
                        } else {
                                VMs.remove(vm.getId());
                                size = size - vm.getSize();
                                RAM = RAM - vm.getRAM();
                                CPU = CPU - vm.getCPU();
-                               return true;
                        }
-               } else
-                       return false;
+               }
        }
 
-       private boolean checkVM(int size, int RAM, int CPU) {
+       public boolean checkVM(int size, int RAM, int CPU) {
                return (size <= availableSize()) && (RAM <= availableRAM())
                                && (CPU <= availableCPU());
        }
@@ -94,6 +96,22 @@ public class PhysicalMachine {
        private int availableCPU() {
                return maxCPU - CPU;
        }
+       
+       public double getSizeUtilization() {
+               return ((double)(size - initialSize) / (maxSize - initialSize)) * 100;
+       }
+       
+       public double getRamUtilization() {
+               return ((double)(RAM - initialRAM) / (maxRAM - initialRAM)) * 100;
+       }
+       
+       public double getCpuUtilization() {
+               return ((double)(CPU - initialCPU) / (maxCPU - initialCPU)) * 100;
+       }
+       
+       public double getAverageUtilization() {
+               return (getSizeUtilization() + getRamUtilization() + getCpuUtilization()) / 3.0;
+       }
 
        public int getId() {
                return id;
diff --git a/src/at/ac/tuwien/lsdc/types/SortedApplication.java b/src/at/ac/tuwien/lsdc/types/SortedApplication.java
new file mode 100644 (file)
index 0000000..ff052a3
--- /dev/null
@@ -0,0 +1,38 @@
+package at.ac.tuwien.lsdc.types;
+
+public class SortedApplication implements Comparable<SortedApplication> {
+
+       
+       private Application app;
+       final int BEFORE = -1;
+       final int EQUAL = 0;
+       final int AFTER = 1;
+       
+       public SortedApplication(Application app) {
+               this.app = app;
+       }
+
+       @Override
+       public int compareTo(SortedApplication other) {
+               if (this == other)
+                       return EQUAL;
+               
+               if(getResourceDifference(other) < 0)
+                       return BEFORE;
+               else if(getResourceDifference(other) > 0)
+                       return AFTER;
+               else
+                       return EQUAL;
+       }
+       
+       public Application getApp() {
+               return app;
+       }
+       
+       public int getResourceDifference(SortedApplication other) {
+               return  app.getSize() - other.getApp().getSize()  +
+                               app.getRam() - other.getApp().getRam()  +
+                               app.getCpu() - other.getApp().getCpu();
+       }
+       
+}
diff --git a/src/at/ac/tuwien/lsdc/types/SortedPhysicalMachine.java b/src/at/ac/tuwien/lsdc/types/SortedPhysicalMachine.java
new file mode 100644 (file)
index 0000000..6d61fbf
--- /dev/null
@@ -0,0 +1,32 @@
+package at.ac.tuwien.lsdc.types;
+
+public class SortedPhysicalMachine implements Comparable<SortedPhysicalMachine> {
+
+       private PhysicalMachine pm;
+       final int BEFORE = -1;
+       final int EQUAL = 0;
+       final int AFTER = 1;
+       
+       public SortedPhysicalMachine(PhysicalMachine pm) {
+               this.pm = pm;
+       }
+       
+       @Override
+       public int compareTo(SortedPhysicalMachine other) {
+               if(this == other)
+                       return EQUAL;
+               
+               if(pm.getAverageUtilization() < other.getPm().getAverageUtilization())
+                       return BEFORE;
+               else if(pm.getAverageUtilization() > other.getPm().getAverageUtilization())
+                       return AFTER;
+               else
+                       return EQUAL;
+       }
+
+       
+       public PhysicalMachine getPm() {
+               return pm;
+       }
+       
+}
index 766e55cfa3bd8002c16dd09d2eaf98838a7c7396..ae9c6806ead2f3dfdfadbc595ae6c297a27ed28e 100644 (file)
@@ -5,6 +5,11 @@ import java.util.HashMap;
 
 public class VirtualMachine {
 
+       public enum VMType {
+               Resizable, NonResizable
+       }
+       
+       
        private static int count = 0;
 
        private PhysicalMachine runningOn;
@@ -20,18 +25,24 @@ public class VirtualMachine {
        private int size;
        private int RAM;
        private int CPU;
+       
+       private VMType type;
 
-       public VirtualMachine(int size, int RAM, int CPU, PhysicalMachine pm) {
+       public VirtualMachine(int size, int RAM, int CPU, PhysicalMachine pm, VMType type) {
                this.id = count;
                count++;
                this.size = size + initialSize;
                this.RAM = RAM + initialRAM;
                this.CPU = CPU + initialCPU;
                this.runningOn = pm;
+               this.type = type;
        }
 
        public boolean startApplication(Application app) {
-               if (checkApp(app)) {
+               if (enoughResources(app)) {
+                       applications.put(app.getID(), app);
+                       return true;
+               } else if (type == VMType.Resizable  &&  runningOn.checkVM(app.getSize(), app.getRam(), app.getCpu())) {
                        applications.put(app.getID(), app);
                        size = size + app.getSize();
                        RAM = RAM + app.getRam();
@@ -52,7 +63,7 @@ public class VirtualMachine {
                        return false;
        }
 
-       private boolean checkApp(Application app) {
+       private boolean enoughResources(Application app) {
                return (app.getSize() <= availableSize())
                                && (app.getRam() <= availableRAM())
                                && (app.getCpu() <= availableCPU());