You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ts...@apache.org on 2012/12/22 22:03:04 UTC

[6/8] Simulator: moving hypervisor simulator into plugin

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/d6083ce5/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java
new file mode 100644
index 0000000..8177cda
--- /dev/null
+++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java
@@ -0,0 +1,615 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.agent.manager;
+
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import com.cloud.agent.api.*;
+import com.cloud.agent.api.routing.*;
+import com.cloud.network.router.VirtualRouter;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.check.CheckSshAnswer;
+import com.cloud.agent.api.check.CheckSshCommand;
+import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
+import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.simulator.MockHost;
+import com.cloud.simulator.MockSecurityRulesVO;
+import com.cloud.simulator.MockVMVO;
+import com.cloud.simulator.MockVm;
+import com.cloud.simulator.dao.MockHostDao;
+import com.cloud.simulator.dao.MockSecurityRulesDao;
+import com.cloud.simulator.dao.MockVMDao;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VirtualMachine.State;
+
+@Local(value = { MockVmManager.class })
+public class MockVmManagerImpl implements MockVmManager {
+    private static final Logger s_logger = Logger.getLogger(MockVmManagerImpl.class);
+
+	@Inject MockVMDao _mockVmDao = null;
+	@Inject MockAgentManager _mockAgentMgr = null;
+	@Inject MockHostDao _mockHostDao = null;
+	@Inject MockSecurityRulesDao _mockSecurityDao = null;
+	private Map<String, Map<String, Ternary<String, Long, Long>>> _securityRules = new ConcurrentHashMap<String, Map<String, Ternary<String, Long, Long>>>();
+
+	public MockVmManagerImpl() {
+	}
+
+	@Override
+    public boolean configure(String name, Map<String, Object> params)
+            throws ConfigurationException {
+
+	    return true;
+	}
+
+    public String startVM(String vmName, NicTO[] nics,
+		int cpuHz, long ramSize,
+		String bootArgs, String hostGuid) {
+
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		MockHost host = null;
+		MockVm vm = null;
+		try {
+			txn.start();
+			host = _mockHostDao.findByGuid(hostGuid);
+			if (host == null) {
+				return "can't find host";
+			}
+
+			vm = _mockVmDao.findByVmName(vmName);
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Unable to start VM " + vmName, ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+        if(vm == null) {
+            int vncPort = 0;
+            if(vncPort < 0)
+                return "Unable to allocate VNC port";
+            vm = new MockVMVO();
+            vm.setCpu(cpuHz);
+            vm.setMemory(ramSize);
+            vm.setState(State.Running);
+            vm.setName(vmName);
+            vm.setVncPort(vncPort);
+            vm.setHostId(host.getId());
+            if(vmName.startsWith("s-")) {
+		vm.setType("SecondaryStorageVm");
+            } else if (vmName.startsWith("v-")) {
+		vm.setType("ConsoleProxy");
+            } else if (vmName.startsWith("r-")) {
+		vm.setType("DomainRouter");
+            } else if (vmName.startsWith("i-")) {
+		vm.setType("User");
+            }
+            txn = Transaction.open(Transaction.SIMULATOR_DB);
+			try {
+				txn.start();
+				vm = _mockVmDao.persist((MockVMVO) vm);
+				txn.commit();
+			} catch (Exception ex) {
+				txn.rollback();
+				throw new CloudRuntimeException("unable to save vm to db " + vm.getName(), ex);
+			} finally {
+				txn.close();
+                txn = Transaction.open(Transaction.CLOUD_DB);
+                txn.close();
+			}
+        } else {
+            if(vm.getState() == State.Stopped) {
+                vm.setState(State.Running);
+                txn = Transaction.open(Transaction.SIMULATOR_DB);
+			try {
+				txn.start();
+				_mockVmDao.update(vm.getId(), (MockVMVO)vm);
+				txn.commit();
+			} catch (Exception ex) {
+				txn.rollback();
+				throw new CloudRuntimeException("unable to update vm " + vm.getName(), ex);
+			} finally {
+				txn.close();
+                    txn = Transaction.open(Transaction.CLOUD_DB);
+                    txn.close();
+			}
+            }
+        }
+
+        if (vm.getState() == State.Running && vmName.startsWith("s-")) {
+            String prvIp = null;
+            String prvMac = null;
+            String prvNetMask = null;
+
+            for (NicTO nic : nics) {
+                if (nic.getType() == TrafficType.Management) {
+                    prvIp = nic.getIp();
+                    prvMac = nic.getMac();
+                    prvNetMask = nic.getNetmask();
+                }
+            }
+            long dcId = 0;
+            long podId = 0;
+            String name = null;
+            String vmType = null;
+            String url = null;
+            String[] args = bootArgs.trim().split(" ");
+            for (String arg : args) {
+                String[] params = arg.split("=");
+                if (params.length < 1) {
+                    continue;
+                }
+
+                if (params[0].equalsIgnoreCase("zone")) {
+                    dcId = Long.parseLong(params[1]);
+                } else if (params[0].equalsIgnoreCase("name")) {
+                    name = params[1];
+                } else if (params[0].equalsIgnoreCase("type")) {
+                    vmType = params[1];
+                } else if (params[0].equalsIgnoreCase("url")) {
+                    url = params[1];
+                } else if (params[0].equalsIgnoreCase("pod")) {
+                    podId = Long.parseLong(params[1]);
+                }
+            }
+
+            _mockAgentMgr.handleSystemVMStart(vm.getId(), prvIp, prvMac, prvNetMask, dcId, podId, name, vmType, url);
+        }
+
+        return null;
+    }
+
+	public boolean rebootVM(String vmName) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			MockVm vm = _mockVmDao.findByVmName(vmName);
+			if (vm != null) {
+				vm.setState(State.Running);
+				_mockVmDao.update(vm.getId(), (MockVMVO) vm);
+
+			}
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("unable to reboot vm " + vmName, ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+		return true;
+	}
+
+	@Override
+	public Map<String, MockVMVO> getVms(String hostGuid) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			List<MockVMVO> vms = _mockVmDao.findByHostGuid(hostGuid);
+			Map<String, MockVMVO> vmMap = new HashMap<String, MockVMVO>();
+			for (MockVMVO vm : vms) {
+				vmMap.put(vm.getName(), vm);
+			}
+			txn.commit();
+			return vmMap;
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("unable to fetch vms  from host " + hostGuid, ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+	}
+
+    @Override
+    public CheckRouterAnswer checkRouter(CheckRouterCommand cmd) {
+        String router_name = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        int router_id = Integer.parseInt(router_name.split("-")[1]);
+        if (router_id % 2 == 0) {
+            s_logger.debug("Found even routerId, making it MASTER in RvR");
+            CheckRouterAnswer ans = new CheckRouterAnswer(cmd, "Status: MASTER & Bumped: NO", true);
+            ans.setState(VirtualRouter.RedundantState.MASTER);
+            return ans;
+        } else {
+            s_logger.debug("Found odd routerId, making it BACKUP in RvR");
+            CheckRouterAnswer ans = new CheckRouterAnswer(cmd, "Status: MASTER & Bumped: NO", true);
+            ans.setState(VirtualRouter.RedundantState.BACKUP);
+            return ans;
+        }
+    }
+
+    @Override
+    public Answer bumpPriority(BumpUpPriorityCommand cmd) {
+        String router_name = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        int router_id = Integer.parseInt(router_name.split("-")[1]);
+        if (router_id % 2 == 0) {
+            return new Answer(cmd, true, "Status: MASTER & Bumped: YES");
+        } else {
+            return new Answer(cmd, true, "Status: BACKUP & Bumped: YES");
+        }
+
+    }
+
+    @Override
+	public Map<String, State> getVmStates(String hostGuid) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			Map<String, State> states = new HashMap<String, State>();
+			List<MockVMVO> vms = _mockVmDao.findByHostGuid(hostGuid);
+			if (vms.isEmpty()) {
+				txn.commit();
+				return states;
+			}
+			for (MockVm vm : vms) {
+				states.put(vm.getName(), vm.getState());
+			}
+			txn.commit();
+			return states;
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("unable to fetch vms  from host " + hostGuid, ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+	}
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public String getName() {
+        return this.getClass().getSimpleName();
+    }
+
+    @Override
+    public Answer getVmStats(GetVmStatsCommand cmd) {
+        HashMap<String, VmStatsEntry> vmStatsNameMap = new HashMap<String, VmStatsEntry>();
+        List<String> vmNames = cmd.getVmNames();
+        for (String vmName : vmNames) {
+            VmStatsEntry entry = new VmStatsEntry(0, 0, 0, 0, "vm");
+            entry.setNetworkReadKBs(32768); // default values 256 KBps
+            entry.setNetworkWriteKBs(16384);
+            entry.setCPUUtilization(10);
+            entry.setNumCPUs(1);
+            vmStatsNameMap.put(vmName, entry);
+        }
+        return new GetVmStatsAnswer(cmd, vmStatsNameMap);
+    }
+
+    @Override
+	public CheckVirtualMachineAnswer checkVmState(CheckVirtualMachineCommand cmd) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			MockVMVO vm = _mockVmDao.findByVmName(cmd.getVmName());
+			if (vm == null) {
+				return new CheckVirtualMachineAnswer(cmd, "can't find vm:" + cmd.getVmName());
+			}
+
+			txn.commit();
+			return new CheckVirtualMachineAnswer(cmd, vm.getState(), vm.getVncPort());
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("unable to fetch vm state " + cmd.getVmName(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+	}
+
+    @Override
+    public Answer startVM(StartCommand cmd, SimulatorInfo info) {
+        VirtualMachineTO vm = cmd.getVirtualMachine();
+        String result = startVM(vm.getName(), vm.getNics(), vm.getCpus()* vm.getSpeed(), vm.getMaxRam(), vm.getBootArgs(), info.getHostUuid());
+        if (result != null) {
+            return new StartAnswer(cmd, result);
+        } else {
+            return new StartAnswer(cmd);
+        }
+    }
+
+    @Override
+    public CheckSshAnswer checkSshCommand(CheckSshCommand cmd) {
+        return new CheckSshAnswer(cmd);
+    }
+
+    @Override
+    public Answer SetStaticNatRules(SetStaticNatRulesCommand cmd) {
+        return new Answer(cmd);
+    }
+
+    @Override
+    public Answer SetPortForwardingRules(SetPortForwardingRulesCommand cmd) {
+        return new Answer(cmd);
+    }
+
+    @Override
+    public Answer SetFirewallRules(SetFirewallRulesCommand cmd) {
+	return new Answer(cmd);
+    }
+
+
+    @Override
+    public NetworkUsageAnswer getNetworkUsage(NetworkUsageCommand cmd) {
+        return new NetworkUsageAnswer(cmd, null, 100L, 100L);
+    }
+
+    @Override
+	public MigrateAnswer Migrate(MigrateCommand cmd, SimulatorInfo info) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			String vmName = cmd.getVmName();
+			String destGuid = cmd.getHostGuid();
+			MockVMVO vm = _mockVmDao.findByVmNameAndHost(vmName, info.getHostUuid());
+			if (vm == null) {
+				return new MigrateAnswer(cmd, false, "can;t find vm:" + vmName + " on host:" + info.getHostUuid(), null);
+			}
+
+			MockHost destHost = _mockHostDao.findByGuid(destGuid);
+			if (destHost == null) {
+				return new MigrateAnswer(cmd, false, "can;t find host:" + info.getHostUuid(), null);
+			}
+			vm.setHostId(destHost.getId());
+			_mockVmDao.update(vm.getId(), vm);
+			txn.commit();
+			return new MigrateAnswer(cmd, true, null, 0);
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("unable to migrate vm " + cmd.getVmName(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+	}
+
+    @Override
+    public Answer IpAssoc(IpAssocCommand cmd) {
+        return new Answer(cmd);
+    }
+
+    @Override
+    public Answer LoadBalancerConfig(LoadBalancerConfigCommand cmd) {
+        return new Answer(cmd);
+    }
+
+    @Override
+    public Answer AddDhcpEntry(DhcpEntryCommand cmd) {
+        return new Answer(cmd);
+    }
+
+    @Override
+    public Answer setVmData(VmDataCommand cmd) {
+        return new Answer(cmd);
+    }
+
+    @Override
+	public Answer CleanupNetworkRules(CleanupNetworkRulesCmd cmd, SimulatorInfo info) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			List<MockSecurityRulesVO> rules = _mockSecurityDao.findByHost(info.getHostUuid());
+			for (MockSecurityRulesVO rule : rules) {
+				MockVMVO vm = _mockVmDao.findByVmNameAndHost(rule.getVmName(), info.getHostUuid());
+				if (vm == null) {
+					_mockSecurityDao.remove(rule.getId());
+				}
+			}
+			txn.commit();
+			return new Answer(cmd);
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("unable to clean up rules", ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+	}
+
+    @Override
+	public Answer stopVM(StopCommand cmd) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			String vmName = cmd.getVmName();
+			MockVm vm = _mockVmDao.findByVmName(vmName);
+			if (vm != null) {
+				vm.setState(State.Stopped);
+				_mockVmDao.update(vm.getId(), (MockVMVO) vm);
+			}
+
+			if (vmName.startsWith("s-")) {
+				_mockAgentMgr.handleSystemVMStop(vm.getId());
+			}
+			txn.commit();
+			return new StopAnswer(cmd, null, new Integer(0), true);
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("unable to stop vm " + cmd.getVmName(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+	}
+
+    @Override
+	public Answer rebootVM(RebootCommand cmd) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			MockVm vm = _mockVmDao.findByVmName(cmd.getVmName());
+			if (vm != null) {
+				vm.setState(State.Running);
+				_mockVmDao.update(vm.getId(), (MockVMVO) vm);
+			}
+			txn.commit();
+			return new RebootAnswer(cmd, "Rebooted " + cmd.getVmName(), true);
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("unable to stop vm " + cmd.getVmName(), ex);
+		} finally {
+			txn.close();
+			txn = Transaction.open(Transaction.CLOUD_DB);
+			txn.close();
+		}
+	}
+
+    @Override
+    public Answer getVncPort(GetVncPortCommand cmd) {
+          return new GetVncPortAnswer(cmd, 0);
+    }
+
+    @Override
+    public Answer CheckConsoleProxyLoad(CheckConsoleProxyLoadCommand cmd) {
+        return Answer.createUnsupportedCommandAnswer(cmd);
+    }
+
+    @Override
+    public Answer WatchConsoleProxyLoad(WatchConsoleProxyLoadCommand cmd) {
+        return Answer.createUnsupportedCommandAnswer(cmd);
+    }
+
+    @Override
+    public GetDomRVersionAnswer getDomRVersion(GetDomRVersionCmd cmd) {
+	return new GetDomRVersionAnswer(cmd, null, null, null);
+    }
+
+    @Override
+    public SecurityGroupRuleAnswer AddSecurityGroupRules(SecurityGroupRulesCmd cmd, SimulatorInfo info) {
+        if (!info.isEnabled()) {
+		return new SecurityGroupRuleAnswer(cmd, false, "Disabled", SecurityGroupRuleAnswer.FailureReason.CANNOT_BRIDGE_FIREWALL);
+        }
+
+        Map<String, Ternary<String,Long, Long>> rules = _securityRules.get(info.getHostUuid());
+
+        if (rules == null) {
+            logSecurityGroupAction(cmd, null);
+            rules = new ConcurrentHashMap<String, Ternary<String, Long, Long>>();
+            rules.put(cmd.getVmName(), new Ternary<String,Long, Long>(cmd.getSignature(), cmd.getVmId(), cmd.getSeqNum()));
+            _securityRules.put(info.getHostUuid(), rules);
+        } else {
+            logSecurityGroupAction(cmd, rules.get(cmd.getVmName()));
+            rules.put(cmd.getVmName(), new Ternary<String, Long,Long>(cmd.getSignature(), cmd.getVmId(), cmd.getSeqNum()));
+        }
+
+        return new SecurityGroupRuleAnswer(cmd);
+    }
+
+    private boolean logSecurityGroupAction(SecurityGroupRulesCmd cmd, Ternary<String,Long, Long> rule) {
+        String action = ", do nothing";
+        String reason = ", reason=";
+        Long currSeqnum = rule == null? null: rule.third();
+        String currSig = rule == null? null: rule.first();
+        boolean updateSeqnoAndSig = false;
+        if (currSeqnum != null) {
+            if (cmd.getSeqNum() > currSeqnum) {
+                s_logger.info("New seqno received: " + cmd.getSeqNum() + " curr=" + currSeqnum);
+                updateSeqnoAndSig = true;
+                if (!cmd.getSignature().equals(currSig)) {
+                    s_logger.info("New seqno received: " + cmd.getSeqNum() + " curr=" + currSeqnum
+                            + " new signature received:" + cmd.getSignature()  + " curr=" + currSig + ", updated iptables");
+                    action = ", updated iptables";
+                    reason = reason + "seqno_increased_sig_changed";
+                } else {
+                    s_logger.info("New seqno received: " + cmd.getSeqNum() + " curr=" + currSeqnum
+                            + " no change in signature:" + cmd.getSignature() +  ", do nothing");
+                    reason = reason + "seqno_increased_sig_same";
+                }
+            } else if (cmd.getSeqNum() < currSeqnum) {
+                s_logger.info("Older seqno received: " + cmd.getSeqNum() + " curr=" + currSeqnum + ", do nothing");
+                reason = reason + "seqno_decreased";
+            } else {
+                if (!cmd.getSignature().equals(currSig)) {
+                    s_logger.info("Identical seqno received: " + cmd.getSeqNum()
+                            + " new signature received:" + cmd.getSignature()  + " curr=" + currSig + ", updated iptables");
+                    action = ", updated iptables";
+                    reason = reason + "seqno_same_sig_changed";
+                    updateSeqnoAndSig = true;
+                } else {
+                    s_logger.info("Identical seqno received: " + cmd.getSeqNum() + " curr=" + currSeqnum
+                            + " no change in signature:" + cmd.getSignature() +  ", do nothing");
+                    reason = reason + "seqno_same_sig_same";
+                }
+            }
+        } else {
+            s_logger.info("New seqno received: " + cmd.getSeqNum() + " old=null");
+            updateSeqnoAndSig = true;
+            action = ", updated iptables";
+            reason = ", seqno_new";
+        }
+        s_logger.info("Programmed network rules for vm " + cmd.getVmName() + " seqno=" + cmd.getSeqNum()
+                + " signature=" + cmd.getSignature()
+                + " guestIp=" + cmd.getGuestIp() + ", numIngressRules="
+                + cmd.getIngressRuleSet().length + ", numEgressRules="
+                + cmd.getEgressRuleSet().length + " total cidrs=" + cmd.getTotalNumCidrs() + action + reason);
+        return updateSeqnoAndSig;
+    }
+
+    @Override
+    public Answer SavePassword(SavePasswordCommand cmd) {
+        return new Answer(cmd);
+    }
+
+    @Override
+    public HashMap<String, Pair<Long, Long>> syncNetworkGroups(SimulatorInfo info) {
+        HashMap<String, Pair<Long, Long>> maps = new HashMap<String, Pair<Long, Long>>();
+
+        Map<String, Ternary<String, Long, Long>> rules = _securityRules.get(info.getHostUuid());
+        if (rules == null) {
+            return maps;
+        }
+        for (Map.Entry<String,Ternary<String, Long, Long>> rule : rules.entrySet()) {
+            maps.put(rule.getKey(), new Pair<Long, Long>(rule.getValue().second(), rule.getValue().third()));
+        }
+        return maps;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/d6083ce5/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorInfo.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorInfo.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorInfo.java
new file mode 100644
index 0000000..c084730
--- /dev/null
+++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorInfo.java
@@ -0,0 +1,59 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.agent.manager;
+
+public class SimulatorInfo {
+	private boolean enabled;
+	private int timeout;
+	private String hostUuid;
+
+	public SimulatorInfo(boolean enabled, int timeout, String hostUuid) {
+		this.enabled = enabled;
+		this.timeout = timeout;
+		this.hostUuid = hostUuid;
+	}
+
+	public SimulatorInfo() {
+		this.enabled = true;
+		this.timeout = -1;
+		this.hostUuid = null;
+	}
+
+	public boolean isEnabled() {
+		return this.enabled;
+	}
+
+	public int getTimeout() {
+		return this.timeout;
+	}
+
+	public String getHostUuid() {
+		return this.hostUuid;
+	}
+
+	public void setEnabled(boolean enabled) {
+		this.enabled = enabled;
+	}
+
+	public void setTimeout(int timeout) {
+		this.timeout = timeout;
+	}
+
+	public void setHostUuid(String hostUuid) {
+		this.hostUuid = hostUuid;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/d6083ce5/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManager.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManager.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManager.java
new file mode 100755
index 0000000..ff8c32c
--- /dev/null
+++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManager.java
@@ -0,0 +1,65 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.agent.manager;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.StoragePoolInfo;
+import com.cloud.simulator.MockVMVO;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.Manager;
+import com.cloud.vm.VirtualMachine.State;
+
+public interface SimulatorManager extends Manager {
+	public static final String Name = "simulator manager";
+
+	public enum AgentType {
+		Computing(0), // not used anymore
+		Routing(1),
+		Storage(2);
+
+		int value;
+
+		AgentType(int value) {
+			this.value = value;
+		}
+
+		public int value() {
+			return value;
+		}
+	}
+
+    MockVmManager getVmMgr();
+
+    MockStorageManager getStorageMgr();
+
+    MockAgentManager getAgentMgr();
+
+    Answer simulate(Command cmd, String hostGuid);
+    StoragePoolInfo getLocalStorage(String hostGuid);
+
+    boolean configureSimulator(Long zoneId, Long podId, Long clusterId, Long hostId, String command, String values);
+    public HashMap<String, Pair<Long, Long>> syncNetworkGroups(String hostGuid);
+
+    Map<String, State> getVmStates(String hostGuid);
+
+	Map<String, MockVMVO> getVms(String hostGuid);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/d6083ce5/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java
new file mode 100644
index 0000000..a32da34
--- /dev/null
+++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java
@@ -0,0 +1,336 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.agent.manager;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import com.cloud.agent.api.*;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.check.CheckSshCommand;
+import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
+import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
+import com.cloud.agent.api.routing.DhcpEntryCommand;
+import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
+import com.cloud.agent.api.routing.SavePasswordCommand;
+import com.cloud.agent.api.routing.SetFirewallRulesCommand;
+import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
+import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
+import com.cloud.agent.api.routing.VmDataCommand;
+import com.cloud.agent.api.storage.CopyVolumeCommand;
+import com.cloud.agent.api.storage.CreateCommand;
+import com.cloud.agent.api.storage.DeleteTemplateCommand;
+import com.cloud.agent.api.storage.DestroyCommand;
+import com.cloud.agent.api.storage.DownloadCommand;
+import com.cloud.agent.api.storage.DownloadProgressCommand;
+import com.cloud.agent.api.storage.ListTemplateCommand;
+import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
+import com.cloud.simulator.MockConfigurationVO;
+import com.cloud.simulator.MockHost;
+import com.cloud.simulator.MockVMVO;
+import com.cloud.simulator.dao.MockConfigurationDao;
+import com.cloud.simulator.dao.MockHostDao;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.db.ConnectionConcierge;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VirtualMachine.State;
+@Local(value = { SimulatorManager.class })
+public class SimulatorManagerImpl implements SimulatorManager {
+    private static final Logger s_logger = Logger.getLogger(SimulatorManagerImpl.class);
+    @Inject
+    MockVmManager _mockVmMgr = null;
+    @Inject
+    MockStorageManager _mockStorageMgr = null;
+    @Inject
+    MockAgentManager _mockAgentMgr = null;
+    @Inject
+    MockConfigurationDao _mockConfigDao = null;
+    @Inject
+    MockHostDao _mockHost = null;
+    private ConnectionConcierge _concierge;
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+    /*
+        try {
+            Connection conn = Transaction.getStandaloneSimulatorConnection();
+            conn.setAutoCommit(true);
+            _concierge = new ConnectionConcierge("SimulatorConnection", conn, true);
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to get a db connection to simulator", e);
+        }
+	*/
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public String getName() {
+        return this.getClass().getSimpleName();
+    }
+
+    @Override
+    public MockVmManager getVmMgr() {
+        return _mockVmMgr;
+    }
+
+    @Override
+    public MockStorageManager getStorageMgr() {
+        return _mockStorageMgr;
+    }
+
+    @Override
+    public MockAgentManager getAgentMgr() {
+        return _mockAgentMgr;
+    }
+
+    @DB
+    @Override
+    public Answer simulate(Command cmd, String hostGuid) {
+        Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+ //       txn.transitToUserManagedConnection(_concierge.conn());
+
+        try {
+            MockHost host = _mockHost.findByGuid(hostGuid);
+            String cmdName = cmd.toString();
+            int index = cmdName.lastIndexOf(".");
+            if (index != -1) {
+		cmdName = cmdName.substring(index + 1);
+            }
+            MockConfigurationVO config = _mockConfigDao.findByNameBottomUP(host.getDataCenterId(), host.getPodId(), host.getClusterId(), host.getId(), cmdName);
+
+            SimulatorInfo info = new SimulatorInfo();
+            info.setHostUuid(hostGuid);
+
+            if (config != null) {
+                Map<String, String> configParameters = config.getParameters();
+                for (Map.Entry<String, String> entry : configParameters.entrySet()) {
+			if (entry.getKey().equalsIgnoreCase("enabled")) {
+				info.setEnabled(Boolean.parseBoolean(entry.getValue()));
+			} else if (entry.getKey().equalsIgnoreCase("timeout")) {
+				try {
+					info.setTimeout(Integer.valueOf(entry.getValue()));
+				} catch (NumberFormatException e) {
+					s_logger.debug("invalid timeout parameter: " + e.toString());
+				}
+			} else if (entry.getKey().equalsIgnoreCase("wait")) {
+				try {
+					int wait = Integer.valueOf(entry.getValue());
+					Thread.sleep(wait * 1000);
+				} catch (NumberFormatException e) {
+					s_logger.debug("invalid timeout parameter: " + e.toString());
+				} catch (InterruptedException e) {
+					s_logger.debug("thread is interrupted: " + e.toString());
+				}
+			}
+                }
+            }
+
+            if (cmd instanceof GetHostStatsCommand) {
+                return _mockAgentMgr.getHostStatistic((GetHostStatsCommand)cmd);
+            } else if (cmd instanceof CheckHealthCommand) {
+                return _mockAgentMgr.checkHealth((CheckHealthCommand)cmd);
+            } else if (cmd instanceof PingTestCommand) {
+                return _mockAgentMgr.pingTest((PingTestCommand)cmd);
+            } else if (cmd instanceof PrepareForMigrationCommand) {
+		return _mockAgentMgr.prepareForMigrate((PrepareForMigrationCommand)cmd);
+            } else if (cmd instanceof MigrateCommand) {
+                return _mockVmMgr.Migrate((MigrateCommand)cmd, info);
+            } else if (cmd instanceof StartCommand) {
+                return _mockVmMgr.startVM((StartCommand)cmd, info);
+            } else if (cmd instanceof CheckSshCommand) {
+                return _mockVmMgr.checkSshCommand((CheckSshCommand)cmd);
+            } else if (cmd instanceof CheckVirtualMachineCommand) {
+		return _mockVmMgr.checkVmState((CheckVirtualMachineCommand)cmd);
+            } else if (cmd instanceof SetStaticNatRulesCommand) {
+                return _mockVmMgr.SetStaticNatRules((SetStaticNatRulesCommand)cmd);
+            } else if (cmd instanceof SetFirewallRulesCommand) {
+		return _mockVmMgr.SetFirewallRules((SetFirewallRulesCommand)cmd);
+            } else if (cmd instanceof SetPortForwardingRulesCommand) {
+                return _mockVmMgr.SetPortForwardingRules((SetPortForwardingRulesCommand)cmd);
+            } else if (cmd instanceof NetworkUsageCommand) {
+                return _mockVmMgr.getNetworkUsage((NetworkUsageCommand)cmd);
+            } else if (cmd instanceof IpAssocCommand) {
+                return _mockVmMgr.IpAssoc((IpAssocCommand)cmd);
+            } else if (cmd instanceof LoadBalancerConfigCommand) {
+                return _mockVmMgr.LoadBalancerConfig((LoadBalancerConfigCommand)cmd);
+            } else if (cmd instanceof DhcpEntryCommand) {
+                return _mockVmMgr.AddDhcpEntry((DhcpEntryCommand)cmd);
+            } else if (cmd instanceof VmDataCommand) {
+                return _mockVmMgr.setVmData((VmDataCommand)cmd);
+            } else if (cmd instanceof CleanupNetworkRulesCmd) {
+                return _mockVmMgr.CleanupNetworkRules((CleanupNetworkRulesCmd)cmd, info);
+            } else if (cmd instanceof CheckNetworkCommand) {
+		return _mockAgentMgr.checkNetworkCommand((CheckNetworkCommand) cmd);
+            }else if (cmd instanceof StopCommand) {
+                return _mockVmMgr.stopVM((StopCommand)cmd);
+            } else if (cmd instanceof RebootCommand) {
+                return _mockVmMgr.rebootVM((RebootCommand)cmd);
+            } else if (cmd instanceof GetVncPortCommand) {
+                return _mockVmMgr.getVncPort((GetVncPortCommand)cmd);
+            } else if (cmd instanceof CheckConsoleProxyLoadCommand) {
+                return _mockVmMgr.CheckConsoleProxyLoad((CheckConsoleProxyLoadCommand)cmd);
+            } else if (cmd instanceof WatchConsoleProxyLoadCommand) {
+                return _mockVmMgr.WatchConsoleProxyLoad((WatchConsoleProxyLoadCommand)cmd);
+            } else if (cmd instanceof SecurityGroupRulesCmd) {
+                return _mockVmMgr.AddSecurityGroupRules((SecurityGroupRulesCmd)cmd, info);
+            } else if (cmd instanceof SavePasswordCommand) {
+                return _mockVmMgr.SavePassword((SavePasswordCommand)cmd);
+            } else if (cmd instanceof PrimaryStorageDownloadCommand) {
+                return _mockStorageMgr.primaryStorageDownload((PrimaryStorageDownloadCommand)cmd);
+            } else if (cmd instanceof CreateCommand) {
+                return _mockStorageMgr.createVolume((CreateCommand)cmd);
+            } else if (cmd instanceof AttachVolumeCommand) {
+                return _mockStorageMgr.AttachVolume((AttachVolumeCommand)cmd);
+            } else if (cmd instanceof AttachIsoCommand) {
+                return _mockStorageMgr.AttachIso((AttachIsoCommand)cmd);
+            } else if (cmd instanceof DeleteStoragePoolCommand) {
+                return _mockStorageMgr.DeleteStoragePool((DeleteStoragePoolCommand)cmd);
+            } else if (cmd instanceof ModifyStoragePoolCommand) {
+                return _mockStorageMgr.ModifyStoragePool((ModifyStoragePoolCommand)cmd);
+            } else if (cmd instanceof CreateStoragePoolCommand) {
+                return _mockStorageMgr.CreateStoragePool((CreateStoragePoolCommand)cmd);
+            } else if (cmd instanceof SecStorageSetupCommand) {
+                return _mockStorageMgr.SecStorageSetup((SecStorageSetupCommand)cmd);
+            } else if (cmd instanceof ListTemplateCommand) {
+                return _mockStorageMgr.ListTemplates((ListTemplateCommand)cmd);
+            } else if (cmd instanceof DestroyCommand) {
+                return _mockStorageMgr.Destroy((DestroyCommand)cmd);
+            } else if (cmd instanceof DownloadProgressCommand) {
+                return _mockStorageMgr.DownloadProcess((DownloadProgressCommand)cmd);
+            } else if (cmd instanceof DownloadCommand) {
+                return _mockStorageMgr.Download((DownloadCommand)cmd);
+            } else if (cmd instanceof GetStorageStatsCommand) {
+                return _mockStorageMgr.GetStorageStats((GetStorageStatsCommand)cmd);
+            } else if (cmd instanceof ManageSnapshotCommand) {
+                return _mockStorageMgr.ManageSnapshot((ManageSnapshotCommand)cmd);
+            } else if (cmd instanceof BackupSnapshotCommand) {
+                return _mockStorageMgr.BackupSnapshot((BackupSnapshotCommand)cmd, info);
+            } else if (cmd instanceof DeleteSnapshotBackupCommand) {
+                return _mockStorageMgr.DeleteSnapshotBackup((DeleteSnapshotBackupCommand)cmd);
+            } else if (cmd instanceof CreateVolumeFromSnapshotCommand) {
+                return _mockStorageMgr.CreateVolumeFromSnapshot((CreateVolumeFromSnapshotCommand)cmd);
+            } else if (cmd instanceof DeleteTemplateCommand) {
+                return _mockStorageMgr.DeleteTemplate((DeleteTemplateCommand)cmd);
+            } else if (cmd instanceof SecStorageVMSetupCommand) {
+                return _mockStorageMgr.SecStorageVMSetup((SecStorageVMSetupCommand)cmd);
+            } else if (cmd instanceof CreatePrivateTemplateFromSnapshotCommand) {
+                return _mockStorageMgr.CreatePrivateTemplateFromSnapshot((CreatePrivateTemplateFromSnapshotCommand)cmd);
+            } else if (cmd instanceof ComputeChecksumCommand) {
+                return _mockStorageMgr.ComputeChecksum((ComputeChecksumCommand)cmd);
+            } else if (cmd instanceof CreatePrivateTemplateFromVolumeCommand) {
+                return _mockStorageMgr.CreatePrivateTemplateFromVolume((CreatePrivateTemplateFromVolumeCommand)cmd);
+            } else if (cmd instanceof MaintainCommand) {
+                return _mockAgentMgr.maintain((MaintainCommand)cmd);
+            } else if (cmd instanceof GetVmStatsCommand) {
+                return _mockVmMgr.getVmStats((GetVmStatsCommand)cmd);
+            } else if (cmd instanceof CheckRouterCommand) {
+                return _mockVmMgr.checkRouter((CheckRouterCommand) cmd);
+            } else if (cmd instanceof BumpUpPriorityCommand) {
+                return _mockVmMgr.bumpPriority((BumpUpPriorityCommand) cmd);
+            } else if (cmd instanceof GetDomRVersionCmd) {
+		return _mockVmMgr.getDomRVersion((GetDomRVersionCmd) cmd);
+            } else if (cmd instanceof ClusterSyncCommand) {
+		return new Answer(cmd);
+		//return new ClusterSyncAnswer(((ClusterSyncCommand) cmd).getClusterId(), this.getVmStates(hostGuid));
+            } else if (cmd instanceof CopyVolumeCommand) {
+		return _mockStorageMgr.CopyVolume((CopyVolumeCommand) cmd);
+            } else {
+                return Answer.createUnsupportedCommandAnswer(cmd);
+            }
+        } catch(Exception e) {
+            s_logger.error("Failed execute cmd: " + e.toString());
+            txn.rollback();
+            return new Answer(cmd, false, e.toString());
+        } finally {
+            txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+        }
+    }
+
+    @Override
+    public StoragePoolInfo getLocalStorage(String hostGuid) {
+        return _mockStorageMgr.getLocalStorage(hostGuid);
+    }
+
+    @Override
+    public Map<String, State> getVmStates(String hostGuid) {
+	return _mockVmMgr.getVmStates(hostGuid);
+    }
+
+    @Override
+    public Map<String, MockVMVO> getVms(String hostGuid) {
+	return _mockVmMgr.getVms(hostGuid);
+    }
+
+    @Override
+    public HashMap<String, Pair<Long, Long>> syncNetworkGroups(String hostGuid) {
+	SimulatorInfo info = new SimulatorInfo();
+	info.setHostUuid(hostGuid);
+	return _mockVmMgr.syncNetworkGroups(info);
+    }
+
+    @Override
+	public boolean configureSimulator(Long zoneId, Long podId, Long clusterId, Long hostId, String command,
+			String values) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			MockConfigurationVO config = _mockConfigDao.findByCommand(zoneId, podId, clusterId, hostId, command);
+			if (config == null) {
+				config = new MockConfigurationVO();
+				config.setClusterId(clusterId);
+				config.setDataCenterId(zoneId);
+				config.setPodId(podId);
+				config.setHostId(hostId);
+				config.setName(command);
+				config.setValues(values);
+				_mockConfigDao.persist(config);
+				txn.commit();
+			} else {
+				config.setValues(values);
+				_mockConfigDao.update(config.getId(), config);
+				txn.commit();
+			}
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Unable to configure simulator because of " + ex.getMessage(), ex);
+		} finally {
+			txn.close();
+		}
+		return true;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/d6083ce5/plugins/hypervisors/simulator/src/com/cloud/api/commands/ConfigureSimulator.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/api/commands/ConfigureSimulator.java b/plugins/hypervisors/simulator/src/com/cloud/api/commands/ConfigureSimulator.java
new file mode 100755
index 0000000..60ce82e
--- /dev/null
+++ b/plugins/hypervisors/simulator/src/com/cloud/api/commands/ConfigureSimulator.java
@@ -0,0 +1,82 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.api.commands;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.manager.SimulatorManager;
+import com.cloud.api.ApiConstants;
+import com.cloud.api.BaseCmd;
+import com.cloud.api.Implementation;
+import com.cloud.api.Parameter;
+import com.cloud.api.ServerApiException;
+import com.cloud.api.response.SuccessResponse;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.server.ManagementService;
+import com.cloud.user.Account;
+import com.cloud.utils.component.ComponentLocator;
+
+@Implementation(description="configure simulator", responseObject=SuccessResponse.class)
+public class ConfigureSimulator extends BaseCmd {
+    public static final Logger s_logger = Logger.getLogger(ConfigureSimulator.class.getName());
+    private static final String s_name = "configuresimulatorresponse";
+
+    @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, description="configure range: in a zone")
+    private Long zoneId;
+
+    @Parameter(name=ApiConstants.POD_ID, type=CommandType.LONG, description="configure range: in a pod")
+    private Long podId;
+
+    @Parameter(name=ApiConstants.CLUSTER_ID, type=CommandType.LONG, description="configure range: in a cluster")
+    private Long clusterId;
+
+    @Parameter(name=ApiConstants.HOST_ID, type=CommandType.LONG, description="configure range: in a host")
+    private Long hostId;
+
+    @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="which command needs to be configured")
+    private String command;
+
+    @Parameter(name=ApiConstants.VALUE, type=CommandType.STRING, required=true, description="configuration options for this command, which is seperated by ;")
+    private String values;
+
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException {
+        ComponentLocator locator = ComponentLocator.getLocator(ManagementService.Name);
+        SimulatorManager _simMgr = locator.getManager(SimulatorManager.class);
+        boolean result = _simMgr.configureSimulator(zoneId, podId, clusterId, hostId, command, values);
+        if (!result) {
+            throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to configure simulator");
+        }
+
+        SuccessResponse response = new SuccessResponse(getCommandName());
+        this.setResponseObject(response);
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/d6083ce5/plugins/hypervisors/simulator/src/com/cloud/configuration/SimulatorComponentLibrary.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/configuration/SimulatorComponentLibrary.java b/plugins/hypervisors/simulator/src/com/cloud/configuration/SimulatorComponentLibrary.java
new file mode 100644
index 0000000..9fd5258
--- /dev/null
+++ b/plugins/hypervisors/simulator/src/com/cloud/configuration/SimulatorComponentLibrary.java
@@ -0,0 +1,50 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.configuration;
+
+import com.cloud.agent.manager.MockAgentManagerImpl;
+import com.cloud.agent.manager.MockStorageManagerImpl;
+import com.cloud.agent.manager.MockVmManagerImpl;
+import com.cloud.agent.manager.SimulatorManagerImpl;
+import com.cloud.simulator.dao.MockConfigurationDaoImpl;
+import com.cloud.simulator.dao.MockHostDaoImpl;
+import com.cloud.simulator.dao.MockSecStorageDaoImpl;
+import com.cloud.simulator.dao.MockSecurityRulesDaoImpl;
+import com.cloud.simulator.dao.MockStoragePoolDaoImpl;
+import com.cloud.simulator.dao.MockVMDaoImpl;
+import com.cloud.simulator.dao.MockVolumeDaoImpl;
+
+public class SimulatorComponentLibrary extends PremiumComponentLibrary {
+	  @Override
+	    protected void populateManagers() {
+	        addManager("VM Manager", MockVmManagerImpl.class);
+	        addManager("agent manager", MockAgentManagerImpl.class);
+	        addManager("storage manager", MockStorageManagerImpl.class);
+	        addManager("SimulatorManager", SimulatorManagerImpl.class);
+	    }
+
+	    @Override
+	    protected void populateDaos() {
+	        addDao("mock Host", MockHostDaoImpl.class);
+	        addDao("mock secondary storage", MockSecStorageDaoImpl.class);
+	        addDao("mock storage pool", MockStoragePoolDaoImpl.class);
+	        addDao("mock vm", MockVMDaoImpl.class);
+	        addDao("mock volume", MockVolumeDaoImpl.class);
+	        addDao("mock config", MockConfigurationDaoImpl.class);
+	        addDao("mock security rules", MockSecurityRulesDaoImpl.class);
+	    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/d6083ce5/plugins/hypervisors/simulator/src/com/cloud/resource/AgentResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentResourceBase.java b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentResourceBase.java
new file mode 100644
index 0000000..808ca07
--- /dev/null
+++ b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentResourceBase.java
@@ -0,0 +1,284 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.resource;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.manager.MockAgentManager;
+import com.cloud.agent.manager.MockStorageManager;
+import com.cloud.agent.manager.MockVmManager;
+import com.cloud.agent.manager.SimulatorManager;
+import com.cloud.agent.manager.SimulatorManager.AgentType;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.simulator.MockHost;
+import com.cloud.utils.component.ComponentLocator;
+
+public class AgentResourceBase implements ServerResource {
+	private static final Logger s_logger = Logger
+			.getLogger(AgentResourceBase.class);
+
+	protected String _name;
+	private List<String> _warnings = new LinkedList<String>();
+	private List<String> _errors = new LinkedList<String>();
+
+	private transient IAgentControl _agentControl;
+
+	protected long _instanceId;
+
+	private Type _type;
+
+	private transient ComponentLocator _locator = null;
+	protected transient SimulatorManager _simMgr;
+	protected MockHost agentHost = null;
+	protected boolean stopped = false;
+	protected String hostGuid = null;
+
+
+	public AgentResourceBase(long instanceId, AgentType agentType, SimulatorManager simMgr, String hostGuid) {
+	    _instanceId = instanceId;
+
+		if(s_logger.isDebugEnabled()) {
+			s_logger.info("New Routing host instantiated with guid:" + hostGuid);
+		}
+
+		if (agentType == AgentType.Routing) {
+			_type = Host.Type.Routing;
+		} else {
+			_type = Host.Type.Storage;
+		}
+
+		this.hostGuid = hostGuid;
+	}
+
+	protected MockVmManager getVmMgr() {
+	    return _simMgr.getVmMgr();
+	}
+
+	protected MockStorageManager getStorageMgr() {
+	    return _simMgr.getStorageMgr();
+	}
+
+	protected MockAgentManager getAgentMgr() {
+	    return _simMgr.getAgentMgr();
+	}
+
+	protected long getInstanceId() {
+	    return _instanceId;
+	}
+
+	public AgentResourceBase() {
+		if(s_logger.isDebugEnabled()) {
+			s_logger.debug("Deserializing simulated agent on reconnect");
+		}
+
+	}
+
+	@Override
+	public String getName() {
+		return _name;
+	}
+
+	public void setName(String name) {
+		_name = name;
+	}
+
+	@Override
+	public boolean configure(String name, Map<String, Object> params)
+			throws ConfigurationException {
+	    hostGuid = (String)params.get("guid");
+	    _locator = ComponentLocator.getLocator("management-server");
+        _simMgr = _locator.getManager(SimulatorManager.class);
+
+	    agentHost = getAgentMgr().getHost(hostGuid);
+	    return true;
+	}
+
+
+	private void reconnect(MockHost host) {
+		if(s_logger.isDebugEnabled()) {
+			s_logger.debug("Reconfiguring existing simulated host w/ name: " + host.getName() + " and guid: " + host.getGuid());
+		}
+		this.agentHost = host;
+	}
+
+
+	@Override
+	public void disconnected() {
+	    this.stopped = true;
+	}
+
+	protected void recordWarning(String msg, Throwable th) {
+		String str = getLogStr(msg, th);
+		synchronized (_warnings) {
+			_warnings.add(str);
+		}
+	}
+
+	protected void recordWarning(String msg) {
+		recordWarning(msg, null);
+	}
+
+	protected List<String> getWarnings() {
+		synchronized (this) {
+			List<String> results = _warnings;
+			_warnings = new ArrayList<String>();
+			return results;
+		}
+	}
+
+	protected List<String> getErrors() {
+		synchronized (this) {
+			List<String> result = _errors;
+			_errors = new ArrayList<String>();
+			return result;
+		}
+	}
+
+	protected void recordError(String msg, Throwable th) {
+		String str = getLogStr(msg, th);
+		synchronized (_errors) {
+			_errors.add(str);
+		}
+	}
+
+	protected void recordError(String msg) {
+		recordError(msg, null);
+	}
+
+	protected Answer createErrorAnswer(Command cmd, String msg, Throwable th) {
+		StringWriter writer = new StringWriter();
+		if (msg != null) {
+			writer.append(msg);
+		}
+		writer.append("===>Stack<===");
+		th.printStackTrace(new PrintWriter(writer));
+		return new Answer(cmd, false, writer.toString());
+	}
+
+	protected String createErrorDetail(String msg, Throwable th) {
+		StringWriter writer = new StringWriter();
+		if (msg != null) {
+			writer.append(msg);
+		}
+		writer.append("===>Stack<===");
+		th.printStackTrace(new PrintWriter(writer));
+		return writer.toString();
+	}
+
+	protected String getLogStr(String msg, Throwable th) {
+		StringWriter writer = new StringWriter();
+		writer.append(new Date().toString()).append(": ").append(msg);
+		if (th != null) {
+			writer.append("\n  Exception: ");
+			th.printStackTrace(new PrintWriter(writer));
+		}
+		return writer.toString();
+	}
+
+	@Override
+	public boolean start() {
+		return true;
+	}
+
+	@Override
+	public boolean stop() {
+	    this.stopped = true;
+		return true;
+	}
+
+	@Override
+	public IAgentControl getAgentControl() {
+		return _agentControl;
+	}
+
+	@Override
+	public void setAgentControl(IAgentControl agentControl) {
+		_agentControl = agentControl;
+	}
+
+	protected String findScript(String script) {
+		s_logger.debug("Looking for " + script + " in the classpath");
+		URL url = ClassLoader.getSystemResource(script);
+		File file = null;
+		if (url == null) {
+			file = new File("./" + script);
+			s_logger.debug("Looking for " + script + " in "
+					+ file.getAbsolutePath());
+			if (!file.exists()) {
+				return null;
+			}
+		} else {
+			file = new File(url.getFile());
+		}
+		return file.getAbsolutePath();
+	}
+
+
+	@Override
+	public Answer executeRequest(Command cmd) {
+		return null;
+	}
+
+	@Override
+	public PingCommand getCurrentStatus(long id) {
+		return null;
+	}
+
+	@Override
+	public Type getType() {
+		return _type;
+	}
+
+	public void setType(Host.Type _type) {
+		this._type = _type;
+	}
+
+	@Override
+	public StartupCommand[] initialize() {
+		return null;
+	}
+
+	public SimulatorManager getSimulatorManager() {
+		return _simMgr;
+	}
+
+	public void setSimulatorManager(SimulatorManager simMgr) {
+		_simMgr = simMgr;
+	}
+
+	public boolean isStopped() {
+	    return this.stopped;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/d6083ce5/plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java
new file mode 100644
index 0000000..f35e432
--- /dev/null
+++ b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java
@@ -0,0 +1,363 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.resource;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckVirtualMachineAnswer;
+import com.cloud.agent.api.CheckVirtualMachineCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingRoutingWithNwGroupsCommand;
+import com.cloud.agent.api.PrepareForMigrationAnswer;
+import com.cloud.agent.api.PrepareForMigrationCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.ShutdownCommand;
+import com.cloud.agent.api.StartAnswer;
+import com.cloud.agent.api.StartCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.agent.api.StartupStorageCommand;
+import com.cloud.agent.api.StopAnswer;
+import com.cloud.agent.api.StopCommand;
+import com.cloud.agent.api.StoragePoolInfo;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.manager.SimulatorManager;
+import com.cloud.agent.manager.SimulatorManager.AgentType;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.Networks.RouterPrivateIpStrategy;
+import com.cloud.simulator.MockVMVO;
+import com.cloud.storage.Storage.StorageResourceType;
+import com.cloud.storage.template.TemplateInfo;
+import com.cloud.utils.Pair;
+import com.cloud.vm.VirtualMachine.State;
+
+public class AgentRoutingResource extends AgentStorageResource {
+    private static final Logger s_logger = Logger.getLogger(AgentRoutingResource.class);
+
+    protected Map<String, State> _vms = new HashMap<String, State>();
+    private Map<String, Pair<Long, Long>> _runningVms = new HashMap<String, Pair<Long, Long>>();
+    long usedCpu = 0;
+    long usedMem = 0;
+    long totalCpu;
+    long totalMem;
+    protected String _mountParent;
+
+
+    public AgentRoutingResource(long instanceId, AgentType agentType, SimulatorManager simMgr, String hostGuid) {
+        super(instanceId, agentType, simMgr, hostGuid);
+    }
+
+    public AgentRoutingResource() {
+        setType(Host.Type.Routing);
+    }
+
+    @Override
+    public Answer executeRequest(Command cmd) {
+        try {
+            if (cmd instanceof StartCommand) {
+                return execute((StartCommand) cmd);
+            } else if (cmd instanceof StopCommand) {
+                return execute((StopCommand) cmd);
+            } else if (cmd instanceof CheckVirtualMachineCommand) {
+                return execute((CheckVirtualMachineCommand) cmd);
+            } else if (cmd instanceof ReadyCommand) {
+                return new ReadyAnswer((ReadyCommand)cmd);
+            } else if (cmd instanceof ShutdownCommand) {
+                return execute((ShutdownCommand)cmd);
+            } else {
+                return _simMgr.simulate(cmd, hostGuid);
+            }
+        } catch (IllegalArgumentException e) {
+            return new Answer(cmd, false, e.getMessage());
+        }
+    }
+
+    @Override
+    public Type getType() {
+        return Host.Type.Routing;
+    }
+
+    @Override
+    public PingCommand getCurrentStatus(long id) {
+        if (isStopped()) {
+            return null;
+        }
+        synchronized (_vms) {
+		if (_vms.size() == 0) {
+			//load vms state from database
+			_vms.putAll(_simMgr.getVmStates(hostGuid));
+		}
+        }
+        final HashMap<String, State> newStates = sync();
+        HashMap<String, Pair<Long, Long>> nwGrpStates = _simMgr.syncNetworkGroups(hostGuid);
+        return new PingRoutingWithNwGroupsCommand(getType(), id, newStates, nwGrpStates);
+    }
+
+    @Override
+    public StartupCommand[] initialize() {
+        synchronized (_vms) {
+            _vms.clear();
+        }
+        Map<String, State> changes = _simMgr.getVmStates(this.hostGuid);
+        Map<String, MockVMVO> vmsMaps = _simMgr.getVms(this.hostGuid);
+        totalCpu = agentHost.getCpuCount() * agentHost.getCpuSpeed();
+        totalMem = agentHost.getMemorySize();
+        for (Map.Entry<String, MockVMVO> entry : vmsMaps.entrySet()) {
+		MockVMVO vm = entry.getValue();
+		usedCpu += vm.getCpu();
+		usedMem += vm.getMemory();
+		_runningVms.put(entry.getKey(), new Pair<Long, Long>(Long.valueOf(vm.getCpu()), vm.getMemory()));
+        }
+
+        List<Object> info = getHostInfo();
+
+        StartupRoutingCommand cmd = new StartupRoutingCommand((Integer) info.get(0), (Long) info.get(1), (Long) info.get(2), (Long) info.get(4), (String) info.get(3), HypervisorType.Simulator,
+                RouterPrivateIpStrategy.HostLocal);
+        cmd.setStateChanges(changes);
+
+        Map<String, String> hostDetails = new HashMap<String, String>();
+        hostDetails.put(RouterPrivateIpStrategy.class.getCanonicalName(), RouterPrivateIpStrategy.DcGlobal.toString());
+
+        cmd.setHostDetails(hostDetails);
+        cmd.setAgentTag("agent-simulator");
+        cmd.setPrivateIpAddress(agentHost.getPrivateIpAddress());
+        cmd.setPrivateNetmask(agentHost.getPrivateNetMask());
+        cmd.setPrivateMacAddress(agentHost.getPrivateMacAddress());
+        cmd.setStorageIpAddress(agentHost.getStorageIpAddress());
+        cmd.setStorageNetmask(agentHost.getStorageNetMask());
+        cmd.setStorageMacAddress(agentHost.getStorageMacAddress());
+        cmd.setStorageIpAddressDeux(agentHost.getStorageIpAddress());
+        cmd.setStorageNetmaskDeux(agentHost.getStorageNetMask());
+        cmd.setStorageMacAddressDeux(agentHost.getStorageIpAddress());
+
+        cmd.setName(agentHost.getName());
+        cmd.setGuid(agentHost.getGuid());
+        cmd.setVersion(agentHost.getVersion());
+        cmd.setAgentTag("agent-simulator");
+        cmd.setDataCenter(String.valueOf(agentHost.getDataCenterId()));
+        cmd.setPod(String.valueOf(agentHost.getPodId()));
+        cmd.setCluster(String.valueOf(agentHost.getClusterId()));
+
+        StartupStorageCommand ssCmd = initializeLocalSR();
+
+        return new StartupCommand[] { cmd, ssCmd };
+    }
+
+    private StartupStorageCommand initializeLocalSR() {
+        Map<String, TemplateInfo> tInfo = new HashMap<String, TemplateInfo>();
+
+        StoragePoolInfo poolInfo = _simMgr.getLocalStorage(hostGuid);
+
+        StartupStorageCommand cmd = new StartupStorageCommand(poolInfo.getHostPath(), poolInfo.getPoolType(), poolInfo.getCapacityBytes(), tInfo);
+
+        cmd.setPoolInfo(poolInfo);
+        cmd.setGuid(agentHost.getGuid());
+        cmd.setResourceType(StorageResourceType.STORAGE_POOL);
+        return cmd;
+    }
+
+	protected synchronized Answer execute(StartCommand cmd)
+			throws IllegalArgumentException {
+		VirtualMachineTO vmSpec = cmd.getVirtualMachine();
+		String vmName = vmSpec.getName();
+		if (this.totalCpu < (vmSpec.getCpus() * vmSpec.getSpeed() + this.usedCpu) ||
+			this.totalMem < (vmSpec.getMaxRam() + this.usedMem)) {
+			return new StartAnswer(cmd, "Not enough resource to start the vm");
+		}
+		State state = State.Stopped;
+		synchronized (_vms) {
+			_vms.put(vmName, State.Starting);
+		}
+
+		try {
+		    Answer result = _simMgr.simulate(cmd, hostGuid);
+		    if (!result.getResult()) {
+		        return new StartAnswer(cmd, result.getDetails());
+		    }
+
+		    this.usedCpu += vmSpec.getCpus() * vmSpec.getSpeed();
+		    this.usedMem += vmSpec.getMaxRam();
+		    _runningVms.put(vmName, new Pair<Long, Long>(Long.valueOf(vmSpec.getCpus() * vmSpec.getSpeed()), vmSpec.getMaxRam()));
+		    state = State.Running;
+
+		} finally {
+		    synchronized (_vms) {
+		        _vms.put(vmName, state);
+		    }
+		}
+
+		return new StartAnswer(cmd);
+
+	}
+
+	protected synchronized StopAnswer execute(StopCommand cmd) {
+
+		StopAnswer answer = null;
+		String vmName = cmd.getVmName();
+
+		State state = null;
+		synchronized (_vms) {
+			state = _vms.get(vmName);
+			_vms.put(vmName, State.Stopping);
+		}
+		try {
+		    Answer result = _simMgr.simulate(cmd, hostGuid);
+
+		    if (!result.getResult()) {
+		        return new StopAnswer(cmd, result.getDetails(), false);
+		    }
+
+			answer = new StopAnswer(cmd, null, 0, true);
+			Pair<Long, Long> data = _runningVms.get(vmName);
+			if (data != null) {
+				this.usedCpu -= data.first();
+				this.usedMem -= data.second();
+			}
+			state = State.Stopped;
+
+		} finally {
+			synchronized (_vms) {
+				_vms.put(vmName, state);
+			}
+		}
+
+        return answer;
+	}
+
+    protected CheckVirtualMachineAnswer execute(final CheckVirtualMachineCommand cmd) {
+        final String vmName = cmd.getVmName();
+        CheckVirtualMachineAnswer result = (CheckVirtualMachineAnswer)_simMgr.simulate(cmd, hostGuid);
+        State state = result.getState();
+        if (state == State.Running) {
+            synchronized (_vms) {
+                _vms.put(vmName, State.Running);
+            }
+        }
+        return result;
+    }
+
+    protected List<Object> getHostInfo() {
+        ArrayList<Object> info = new ArrayList<Object>();
+        long speed = agentHost.getCpuSpeed();
+        long cpus = agentHost.getCpuCount();
+        long ram = agentHost.getMemorySize();
+        long dom0Ram = agentHost.getMemorySize()/10;
+
+        info.add((int) cpus);
+        info.add(speed);
+        info.add(ram);
+        info.add(agentHost.getCapabilities());
+        info.add(dom0Ram);
+
+        return info;
+    }
+
+    protected HashMap<String, State> sync() {
+        Map<String, State> newStates;
+        Map<String, State> oldStates = null;
+
+        HashMap<String, State> changes = new HashMap<String, State>();
+
+        synchronized (_vms) {
+            oldStates = new HashMap<String, State>(_vms.size());
+            oldStates.putAll(_vms);
+            newStates = new HashMap<String, State>(_vms.size());
+            newStates.putAll(_vms);
+
+            for (Map.Entry<String, State> entry : newStates.entrySet()) {
+                String vm = entry.getKey();
+
+                State newState = entry.getValue();
+                State oldState = oldStates.remove(vm);
+
+                if (s_logger.isTraceEnabled()) {
+                    s_logger.trace("VM " + vm + ": has state " + newState + " and we have state " + (oldState != null ? oldState.toString() : "null"));
+                }
+
+                if (oldState == null) {
+                    _vms.put(vm, newState);
+                    changes.put(vm, newState);
+                } else if (oldState == State.Starting) {
+                    if (newState == State.Running) {
+                        _vms.put(vm, newState);
+                    } else if (newState == State.Stopped) {
+                        s_logger.debug("Ignoring vm " + vm + " because of a lag in starting the vm.");
+                    }
+                } else if (oldState == State.Stopping) {
+                    if (newState == State.Stopped) {
+                        _vms.put(vm, newState);
+                    } else if (newState == State.Running) {
+                        s_logger.debug("Ignoring vm " + vm + " because of a lag in stopping the vm. ");
+                    }
+                } else if (oldState != newState) {
+                    _vms.put(vm, newState);
+                    changes.put(vm, newState);
+                }
+            }
+
+            for (Map.Entry<String, State> entry : oldStates.entrySet()) {
+                String vm = entry.getKey();
+                State oldState = entry.getValue();
+
+                if (s_logger.isTraceEnabled()) {
+                    s_logger.trace("VM " + vm + " is now missing from simulator agent so reporting stopped");
+                }
+
+                if (oldState == State.Stopping) {
+                    s_logger.debug("Ignoring VM " + vm + " in transition state stopping.");
+                    _vms.remove(vm);
+                } else if (oldState == State.Starting) {
+                    s_logger.debug("Ignoring VM " + vm + " in transition state starting.");
+                } else if (oldState == State.Stopped) {
+                    _vms.remove(vm);
+                } else {
+                    changes.put(entry.getKey(), State.Stopped);
+                }
+            }
+        }
+
+        return changes;
+    }
+
+    private Answer execute(ShutdownCommand cmd) {
+        this.stopped = true;
+        return new Answer(cmd);
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        if (!super.configure(name, params)) {
+            s_logger.warn("Base class was unable to configure");
+            return false;
+        }
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/d6083ce5/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java
new file mode 100644
index 0000000..1125eeb
--- /dev/null
+++ b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java
@@ -0,0 +1,117 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.resource;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingStorageCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupSecondaryStorageCommand;
+import com.cloud.agent.api.StartupStorageCommand;
+import com.cloud.agent.api.storage.ssCommand;
+import com.cloud.agent.manager.SimulatorManager;
+import com.cloud.agent.manager.SimulatorManager.AgentType;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.storage.resource.SecondaryStorageResource;
+import com.cloud.vm.SecondaryStorageVm;
+
+
+public class AgentStorageResource extends AgentResourceBase implements SecondaryStorageResource {
+    private static final Logger s_logger = Logger.getLogger(AgentStorageResource.class);
+
+    final protected String _parent = "/mnt/SecStorage";
+    protected String _role;
+
+    public AgentStorageResource(long instanceId, AgentType agentType, SimulatorManager simMgr, String hostGuid) {
+        super(instanceId, agentType, simMgr, hostGuid);
+    }
+
+    public AgentStorageResource() {
+        setType(Host.Type.SecondaryStorage);
+    }
+
+    @Override
+    public Answer executeRequest(Command cmd) {
+        if (cmd instanceof ReadyCommand) {
+            return new ReadyAnswer((ReadyCommand)cmd);
+        } else {
+            return _simMgr.simulate(cmd, hostGuid);
+        }
+	}
+
+    @Override
+    public PingCommand getCurrentStatus(long id) {
+        if (isStopped()) {
+            return null;
+        }
+        return new PingStorageCommand(Host.Type.Storage, id, new HashMap<String, Boolean>());
+    }
+
+    @Override
+    public Type getType() {
+	if(SecondaryStorageVm.Role.templateProcessor.toString().equals(_role))
+		return Host.Type.SecondaryStorage;
+	return Host.Type.SecondaryStorageCmdExecutor;
+    }
+
+    @Override
+    public StartupCommand[] initialize() {
+	StartupSecondaryStorageCommand cmd = new StartupSecondaryStorageCommand();
+
+        cmd.setPrivateIpAddress(agentHost.getPrivateIpAddress());
+        cmd.setPrivateNetmask(agentHost.getPrivateNetMask());
+        cmd.setPrivateMacAddress(agentHost.getPrivateMacAddress());
+        cmd.setStorageIpAddress(agentHost.getStorageIpAddress());
+        cmd.setStorageNetmask(agentHost.getStorageNetMask());
+        cmd.setStorageMacAddress(agentHost.getStorageMacAddress());
+        cmd.setPublicIpAddress(agentHost.getPublicIpAddress());
+
+        cmd.setName(agentHost.getName());
+        cmd.setAgentTag("agent-simulator");
+        cmd.setVersion(agentHost.getVersion());
+        cmd.setDataCenter(String.valueOf(agentHost.getDataCenterId()));
+        cmd.setPod(String.valueOf(agentHost.getPodId()));
+        cmd.setGuid(agentHost.getGuid());
+        return new StartupCommand[] { cmd };
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        if (!super.configure(name, params)) {
+            s_logger.warn("Base class was unable to configure");
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public String getRootDir(ssCommand cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}