You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bh...@apache.org on 2012/12/24 01:57:38 UTC

[14/50] [abbrv] 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/MockAgentManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java
new file mode 100755
index 0000000..cb99297
--- /dev/null
+++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java
@@ -0,0 +1,468 @@
+// 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.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.PatternSyntaxException;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckHealthCommand;
+import com.cloud.agent.api.CheckNetworkAnswer;
+import com.cloud.agent.api.CheckNetworkCommand;
+import com.cloud.agent.api.GetHostStatsAnswer;
+import com.cloud.agent.api.GetHostStatsCommand;
+import com.cloud.agent.api.HostStatsEntry;
+import com.cloud.agent.api.MaintainAnswer;
+import com.cloud.agent.api.PingTestCommand;
+import com.cloud.agent.api.PrepareForMigrationAnswer;
+import com.cloud.agent.api.PrepareForMigrationCommand;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.host.Host;
+import com.cloud.resource.AgentResourceBase;
+import com.cloud.resource.AgentRoutingResource;
+import com.cloud.resource.AgentStorageResource;
+import com.cloud.resource.ResourceManager;
+import com.cloud.simulator.MockHost;
+import com.cloud.simulator.MockHostVO;
+import com.cloud.simulator.MockVMVO;
+import com.cloud.simulator.dao.MockHostDao;
+import com.cloud.simulator.dao.MockVMDao;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+
+@Local(value = { MockAgentManager.class })
+public class MockAgentManagerImpl implements MockAgentManager {
+	private static final Logger s_logger = Logger.getLogger(MockAgentManagerImpl.class);
+	@Inject
+	HostPodDao _podDao = null;
+	@Inject
+	MockHostDao _mockHostDao = null;
+	@Inject
+	MockVMDao _mockVmDao = null;
+	@Inject
+	SimulatorManager _simulatorMgr = null;
+	@Inject
+	AgentManager _agentMgr = null;
+	@Inject
+	MockStorageManager _storageMgr = null;
+	@Inject
+	ResourceManager _resourceMgr;
+	private SecureRandom random;
+	private Map<String, AgentResourceBase> _resources = new ConcurrentHashMap<String, AgentResourceBase>();
+	private ThreadPoolExecutor _executor;
+
+	private Pair<String, Long> getPodCidr(long podId, long dcId) {
+		try {
+
+			HashMap<Long, List<Object>> podMap = _podDao.getCurrentPodCidrSubnets(dcId, 0);
+			List<Object> cidrPair = podMap.get(podId);
+			String cidrAddress = (String) cidrPair.get(0);
+			Long cidrSize = (Long) cidrPair.get(1);
+			return new Pair<String, Long>(cidrAddress, cidrSize);
+		} catch (PatternSyntaxException e) {
+			s_logger.error("Exception while splitting pod cidr");
+			return null;
+		} catch (IndexOutOfBoundsException e) {
+			s_logger.error("Invalid pod cidr. Please check");
+			return null;
+		}
+	}
+
+	private String getIpAddress(long instanceId, long dcId, long podId) {
+		Pair<String, Long> cidr = this.getPodCidr(podId, dcId);
+		return NetUtils.long2Ip(NetUtils.ip2Long(cidr.first()) + instanceId);
+	}
+
+	private String getMacAddress(long dcId, long podId, long clusterId, int instanceId) {
+		return NetUtils.long2Mac((dcId << 40 + podId << 32 + clusterId << 24 + instanceId));
+	}
+
+	public synchronized int getNextAgentId(long cidrSize) {
+		return random.nextInt((int) cidrSize);
+	}
+
+	@Override
+	@DB
+	public Map<AgentResourceBase, Map<String, String>> createServerResources(Map<String, Object> params) {
+
+		Map<String, String> args = new HashMap<String, String>();
+		Map<AgentResourceBase, Map<String, String>> newResources = new HashMap<AgentResourceBase, Map<String, String>>();
+		AgentResourceBase agentResource;
+		long cpuCore = Long.parseLong((String) params.get("cpucore"));
+		long cpuSpeed = Long.parseLong((String) params.get("cpuspeed"));
+		long memory = Long.parseLong((String) params.get("memory"));
+		long localStorageSize = Long.parseLong((String) params.get("localstorage"));
+		synchronized (this) {
+			long dataCenterId = Long.parseLong((String) params.get("zone"));
+			long podId = Long.parseLong((String) params.get("pod"));
+			long clusterId = Long.parseLong((String) params.get("cluster"));
+			long cidrSize = getPodCidr(podId, dataCenterId).second();
+
+			int agentId = getNextAgentId(cidrSize);
+			String ipAddress = getIpAddress(agentId, dataCenterId, podId);
+			String macAddress = getMacAddress(dataCenterId, podId, clusterId, agentId);
+			MockHostVO mockHost = new MockHostVO();
+			mockHost.setDataCenterId(dataCenterId);
+			mockHost.setPodId(podId);
+			mockHost.setClusterId(clusterId);
+			mockHost.setCapabilities("hvm");
+			mockHost.setCpuCount(cpuCore);
+			mockHost.setCpuSpeed(cpuSpeed);
+			mockHost.setMemorySize(memory);
+			String guid = UUID.randomUUID().toString();
+			mockHost.setGuid(guid);
+			mockHost.setName("SimulatedAgent." + guid);
+			mockHost.setPrivateIpAddress(ipAddress);
+			mockHost.setPublicIpAddress(ipAddress);
+			mockHost.setStorageIpAddress(ipAddress);
+			mockHost.setPrivateMacAddress(macAddress);
+			mockHost.setPublicMacAddress(macAddress);
+			mockHost.setStorageMacAddress(macAddress);
+			mockHost.setVersion(this.getClass().getPackage().getImplementationVersion());
+			mockHost.setResource("com.cloud.agent.AgentRoutingResource");
+
+			Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+			try {
+				txn.start();
+				mockHost = _mockHostDao.persist(mockHost);
+				txn.commit();
+			} catch (Exception ex) {
+				txn.rollback();
+				s_logger.error("Error while configuring mock agent " + ex.getMessage());
+				throw new CloudRuntimeException("Error configuring agent", ex);
+			} finally {
+				txn.close();
+                txn = Transaction.open(Transaction.CLOUD_DB);
+                txn.close();
+			}
+
+			_storageMgr.getLocalStorage(guid, localStorageSize);
+
+			agentResource = new AgentRoutingResource();
+			if (agentResource != null) {
+				try {
+					params.put("guid", mockHost.getGuid());
+					agentResource.start();
+					agentResource.configure(mockHost.getName(), params);
+
+					newResources.put(agentResource, args);
+				} catch (ConfigurationException e) {
+					s_logger.error("error while configuring server resource" + e.getMessage());
+				}
+			}
+		}
+		return newResources;
+	}
+
+	@Override
+	public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+		try {
+			random = SecureRandom.getInstance("SHA1PRNG");
+			_executor = new ThreadPoolExecutor(1, 5, 1, TimeUnit.DAYS, new LinkedBlockingQueue<Runnable>(),
+					new NamedThreadFactory("Simulator-Agent-Mgr"));
+			// ComponentLocator locator = ComponentLocator.getCurrentLocator();
+			// _simulatorMgr = (SimulatorManager)
+			// locator.getComponent(SimulatorManager.Name);
+		} catch (NoSuchAlgorithmException e) {
+			s_logger.debug("Failed to initialize random:" + e.toString());
+			return false;
+		}
+		return true;
+	}
+
+	@Override
+	public boolean handleSystemVMStart(long vmId, String privateIpAddress, String privateMacAddress,
+			String privateNetMask, long dcId, long podId, String name, String vmType, String url) {
+		_executor.execute(new SystemVMHandler(vmId, privateIpAddress, privateMacAddress, privateNetMask, dcId, podId,
+				name, vmType, _simulatorMgr, url));
+		return true;
+	}
+
+	@Override
+	public boolean handleSystemVMStop(long vmId) {
+		_executor.execute(new SystemVMHandler(vmId));
+		return true;
+	}
+
+	private class SystemVMHandler implements Runnable {
+		private long vmId;
+		private String privateIpAddress;
+		private String privateMacAddress;
+		private String privateNetMask;
+		private long dcId;
+		private long podId;
+		private String guid;
+		private String name;
+		private String vmType;
+		private SimulatorManager mgr;
+		private String mode;
+		private String url;
+
+		public SystemVMHandler(long vmId, String privateIpAddress, String privateMacAddress, String privateNetMask,
+				long dcId, long podId, String name, String vmType, SimulatorManager mgr, String url) {
+			this.vmId = vmId;
+			this.privateIpAddress = privateIpAddress;
+			this.privateMacAddress = privateMacAddress;
+			this.privateNetMask = privateNetMask;
+			this.dcId = dcId;
+			this.guid = "SystemVM-" + UUID.randomUUID().toString();
+			this.name = name;
+			this.vmType = vmType;
+			this.mgr = mgr;
+			this.mode = "Start";
+			this.url = url;
+			this.podId = podId;
+		}
+
+		public SystemVMHandler(long vmId) {
+			this.vmId = vmId;
+			this.mode = "Stop";
+		}
+
+		@Override
+		@DB
+		public void run() {
+
+			Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+			try {
+				if (this.mode.equalsIgnoreCase("Stop")) {
+					txn.start();
+					MockHost host = _mockHostDao.findByVmId(this.vmId);
+					if (host != null) {
+						String guid = host.getGuid();
+						if (guid != null) {
+							AgentResourceBase res = _resources.get(guid);
+							if (res != null) {
+								res.stop();
+								_resources.remove(guid);
+							}
+						}
+					}
+					txn.commit();
+					return;
+				}
+			} catch (Exception ex) {
+				txn.rollback();
+				throw new CloudRuntimeException("Unable to get host " + guid + " due to " + ex.getMessage(), ex);
+			} finally {
+				txn.close();
+                txn = Transaction.open(Transaction.CLOUD_DB);
+                txn.close();
+			}
+
+			String resource = null;
+			if (vmType.equalsIgnoreCase("secstorage")) {
+				resource = "com.cloud.agent.AgentStorageResource";
+			}
+			MockHostVO mockHost = new MockHostVO();
+			mockHost.setDataCenterId(this.dcId);
+			mockHost.setPodId(this.podId);
+			mockHost.setCpuCount(DEFAULT_HOST_CPU_CORES);
+			mockHost.setCpuSpeed(DEFAULT_HOST_SPEED_MHZ);
+			mockHost.setMemorySize(DEFAULT_HOST_MEM_SIZE);
+			mockHost.setGuid(this.guid);
+			mockHost.setName(name);
+			mockHost.setPrivateIpAddress(this.privateIpAddress);
+			mockHost.setPublicIpAddress(this.privateIpAddress);
+			mockHost.setStorageIpAddress(this.privateIpAddress);
+			mockHost.setPrivateMacAddress(this.privateMacAddress);
+			mockHost.setPublicMacAddress(this.privateMacAddress);
+			mockHost.setStorageMacAddress(this.privateMacAddress);
+			mockHost.setVersion(this.getClass().getPackage().getImplementationVersion());
+			mockHost.setResource(resource);
+			mockHost.setVmId(vmId);
+			Transaction simtxn = Transaction.open(Transaction.SIMULATOR_DB);
+			try {
+				simtxn.start();
+				mockHost = _mockHostDao.persist(mockHost);
+				simtxn.commit();
+			} catch (Exception ex) {
+				simtxn.rollback();
+				throw new CloudRuntimeException("Unable to persist host " + mockHost.getGuid() + " due to "
+						+ ex.getMessage(), ex);
+			} finally {
+				simtxn.close();
+                simtxn = Transaction.open(Transaction.CLOUD_DB);
+                simtxn.close();
+			}
+
+			if (vmType.equalsIgnoreCase("secstorage")) {
+				AgentStorageResource storageResource = new AgentStorageResource();
+				try {
+					Map<String, Object> params = new HashMap<String, Object>();
+					Map<String, String> details = new HashMap<String, String>();
+					params.put("guid", this.guid);
+					details.put("guid", this.guid);
+					storageResource.configure("secondaryStorage", params);
+					storageResource.start();
+					// on the simulator the ssvm is as good as a direct
+					// agent
+					_resourceMgr.addHost(mockHost.getDataCenterId(), storageResource, Host.Type.SecondaryStorageVM,
+							details);
+					_resources.put(this.guid, storageResource);
+				} catch (ConfigurationException e) {
+					s_logger.debug("Failed to load secondary storage resource: " + e.toString());
+					return;
+				}
+			}
+		}
+	}
+
+	@Override
+	public MockHost getHost(String guid) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			MockHost _host = _mockHostDao.findByGuid(guid);
+			txn.commit();
+			if (_host != null) {
+				return _host;
+			} else {
+				s_logger.error("Host with guid " + guid + " was not found");
+				return null;
+			}
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Unable to get host " + guid + " due to " + ex.getMessage(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+	}
+
+	@Override
+	public GetHostStatsAnswer getHostStatistic(GetHostStatsCommand cmd) {
+		String hostGuid = cmd.getHostGuid();
+		MockHost host = null;
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			host = _mockHostDao.findByGuid(hostGuid);
+			txn.commit();
+			if (host == null) {
+				return null;
+			}
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Unable to get host " + hostGuid + " due to " + ex.getMessage(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+		Transaction vmtxn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			vmtxn.start();
+			List<MockVMVO> vms = _mockVmDao.findByHostId(host.getId());
+			vmtxn.commit();
+			double usedMem = 0.0;
+			double usedCpu = 0.0;
+			for (MockVMVO vm : vms) {
+				usedMem += vm.getMemory();
+				usedCpu += vm.getCpu();
+			}
+
+			HostStatsEntry hostStats = new HostStatsEntry();
+			hostStats.setTotalMemoryKBs(host.getMemorySize());
+			hostStats.setFreeMemoryKBs(host.getMemorySize() - usedMem);
+			hostStats.setNetworkReadKBs(32768);
+			hostStats.setNetworkWriteKBs(16384);
+			hostStats.setCpuUtilization(usedCpu / (host.getCpuCount() * host.getCpuSpeed()));
+			hostStats.setEntityType("simulator-host");
+			hostStats.setHostId(cmd.getHostId());
+			return new GetHostStatsAnswer(cmd, hostStats);
+		} catch (Exception ex) {
+			vmtxn.rollback();
+			throw new CloudRuntimeException("Unable to get Vms on host " + host.getGuid() + " due to "
+					+ ex.getMessage(), ex);
+		} finally {
+			vmtxn.close();
+            vmtxn = Transaction.open(Transaction.CLOUD_DB);
+            vmtxn.close();
+		}
+	}
+
+	@Override
+	public Answer checkHealth(CheckHealthCommand cmd) {
+		return new Answer(cmd);
+	}
+
+	@Override
+	public Answer pingTest(PingTestCommand cmd) {
+		return new Answer(cmd);
+	}
+
+	@Override
+	public PrepareForMigrationAnswer prepareForMigrate(PrepareForMigrationCommand cmd) {
+		VirtualMachineTO vm = cmd.getVirtualMachine();
+		if (s_logger.isDebugEnabled()) {
+			s_logger.debug("Preparing host for migrating " + vm);
+		}
+		return new PrepareForMigrationAnswer(cmd);
+	}
+
+	@Override
+	public boolean start() {
+		return true;
+	}
+
+	@Override
+	public boolean stop() {
+		return true;
+	}
+
+	@Override
+	public String getName() {
+		return this.getClass().getSimpleName();
+	}
+
+	@Override
+	public MaintainAnswer maintain(com.cloud.agent.api.MaintainCommand cmd) {
+		return new MaintainAnswer(cmd);
+	}
+
+	@Override
+	public Answer checkNetworkCommand(CheckNetworkCommand cmd) {
+		if (s_logger.isDebugEnabled()) {
+			s_logger.debug("Checking if network name setup is done on the resource");
+		}
+		return new CheckNetworkAnswer(cmd, true, "Network Setup check by names is done");
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/d6083ce5/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java
new file mode 100644
index 0000000..fc8aacc
--- /dev/null
+++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java
@@ -0,0 +1,91 @@
+// 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 com.cloud.agent.api.Answer;
+import com.cloud.agent.api.AttachIsoCommand;
+import com.cloud.agent.api.AttachVolumeAnswer;
+import com.cloud.agent.api.AttachVolumeCommand;
+import com.cloud.agent.api.BackupSnapshotCommand;
+import com.cloud.agent.api.ComputeChecksumCommand;
+import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
+import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
+import com.cloud.agent.api.CreateStoragePoolCommand;
+import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
+import com.cloud.agent.api.DeleteSnapshotBackupCommand;
+import com.cloud.agent.api.DeleteStoragePoolCommand;
+import com.cloud.agent.api.GetStorageStatsAnswer;
+import com.cloud.agent.api.GetStorageStatsCommand;
+import com.cloud.agent.api.ManageSnapshotCommand;
+import com.cloud.agent.api.ModifyStoragePoolCommand;
+import com.cloud.agent.api.SecStorageSetupCommand;
+import com.cloud.agent.api.SecStorageVMSetupCommand;
+import com.cloud.agent.api.StoragePoolInfo;
+import com.cloud.agent.api.storage.CopyVolumeAnswer;
+import com.cloud.agent.api.storage.CopyVolumeCommand;
+import com.cloud.agent.api.storage.CreateAnswer;
+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.PrimaryStorageDownloadAnswer;
+import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
+import com.cloud.utils.component.Manager;
+
+public interface MockStorageManager extends Manager {
+    public static final long DEFAULT_HOST_STORAGE_SIZE = 1 * 1024 * 1024 * 1024 * 1024L; //1T
+    public static final long DEFAULT_TEMPLATE_SIZE = 1 * 1000 * 1000 * 1000L; //1G
+
+	public PrimaryStorageDownloadAnswer primaryStorageDownload(PrimaryStorageDownloadCommand cmd);
+
+	public CreateAnswer createVolume(CreateCommand cmd);
+	public AttachVolumeAnswer AttachVolume(AttachVolumeCommand cmd);
+	public Answer AttachIso(AttachIsoCommand cmd);
+
+	public Answer DeleteStoragePool(DeleteStoragePoolCommand cmd);
+	public Answer ModifyStoragePool(ModifyStoragePoolCommand cmd);
+	public Answer CreateStoragePool(CreateStoragePoolCommand cmd);
+
+	public Answer SecStorageSetup(SecStorageSetupCommand cmd);
+	public Answer ListTemplates(ListTemplateCommand cmd);
+	public Answer Destroy(DestroyCommand cmd);
+	public Answer Download(DownloadCommand cmd);
+	public Answer DownloadProcess(DownloadProgressCommand cmd);
+	public GetStorageStatsAnswer GetStorageStats(GetStorageStatsCommand cmd);
+	public Answer ManageSnapshot(ManageSnapshotCommand cmd);
+	public Answer BackupSnapshot(BackupSnapshotCommand cmd, SimulatorInfo info);
+	public Answer DeleteSnapshotBackup(DeleteSnapshotBackupCommand cmd);
+	public Answer CreateVolumeFromSnapshot(CreateVolumeFromSnapshotCommand cmd);
+	public Answer DeleteTemplate(DeleteTemplateCommand cmd);
+	public Answer SecStorageVMSetup(SecStorageVMSetupCommand cmd);
+
+	public void preinstallTemplates(String url, long zoneId);
+
+    StoragePoolInfo getLocalStorage(String hostGuid);
+
+    public Answer CreatePrivateTemplateFromSnapshot(CreatePrivateTemplateFromSnapshotCommand cmd);
+
+    public Answer ComputeChecksum(ComputeChecksumCommand cmd);
+
+    public Answer CreatePrivateTemplateFromVolume(CreatePrivateTemplateFromVolumeCommand cmd);
+
+    StoragePoolInfo getLocalStorage(String hostGuid, Long storageSize);
+
+	CopyVolumeAnswer CopyVolume(CopyVolumeCommand cmd);
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/d6083ce5/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java
new file mode 100644
index 0000000..9bf4192
--- /dev/null
+++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java
@@ -0,0 +1,1298 @@
+// 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.io.File;
+import java.math.BigInteger;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.AttachIsoCommand;
+import com.cloud.agent.api.AttachVolumeAnswer;
+import com.cloud.agent.api.AttachVolumeCommand;
+import com.cloud.agent.api.BackupSnapshotAnswer;
+import com.cloud.agent.api.BackupSnapshotCommand;
+import com.cloud.agent.api.ComputeChecksumCommand;
+import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
+import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
+import com.cloud.agent.api.CreateStoragePoolCommand;
+import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer;
+import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
+import com.cloud.agent.api.DeleteSnapshotBackupCommand;
+import com.cloud.agent.api.DeleteStoragePoolCommand;
+import com.cloud.agent.api.GetStorageStatsAnswer;
+import com.cloud.agent.api.GetStorageStatsCommand;
+import com.cloud.agent.api.ManageSnapshotAnswer;
+import com.cloud.agent.api.ManageSnapshotCommand;
+import com.cloud.agent.api.ModifyStoragePoolAnswer;
+import com.cloud.agent.api.ModifyStoragePoolCommand;
+import com.cloud.agent.api.SecStorageSetupAnswer;
+import com.cloud.agent.api.SecStorageSetupCommand;
+import com.cloud.agent.api.SecStorageVMSetupCommand;
+import com.cloud.agent.api.StoragePoolInfo;
+import com.cloud.agent.api.storage.CopyVolumeAnswer;
+import com.cloud.agent.api.storage.CopyVolumeCommand;
+import com.cloud.agent.api.storage.CreateAnswer;
+import com.cloud.agent.api.storage.CreateCommand;
+import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
+import com.cloud.agent.api.storage.DeleteTemplateCommand;
+import com.cloud.agent.api.storage.DestroyCommand;
+import com.cloud.agent.api.storage.DownloadAnswer;
+import com.cloud.agent.api.storage.DownloadCommand;
+import com.cloud.agent.api.storage.DownloadProgressCommand;
+import com.cloud.agent.api.storage.ListTemplateAnswer;
+import com.cloud.agent.api.storage.ListTemplateCommand;
+import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
+import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
+import com.cloud.agent.api.to.StorageFilerTO;
+import com.cloud.agent.api.to.VolumeTO;
+import com.cloud.simulator.MockHost;
+import com.cloud.simulator.MockSecStorageVO;
+import com.cloud.simulator.MockStoragePoolVO;
+import com.cloud.simulator.MockVMVO;
+import com.cloud.simulator.MockVm;
+import com.cloud.simulator.MockVolumeVO;
+import com.cloud.simulator.MockVolumeVO.MockVolumeType;
+import com.cloud.simulator.dao.MockHostDao;
+import com.cloud.simulator.dao.MockSecStorageDao;
+import com.cloud.simulator.dao.MockStoragePoolDao;
+import com.cloud.simulator.dao.MockVMDao;
+import com.cloud.simulator.dao.MockVolumeDao;
+import com.cloud.storage.Storage;
+import com.cloud.storage.VMTemplateStorageResourceAssoc;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.storage.template.TemplateInfo;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.VirtualMachine.State;
+
+@Local(value = { MockStorageManager.class })
+public class MockStorageManagerImpl implements MockStorageManager {
+	private static final Logger s_logger = Logger.getLogger(MockStorageManagerImpl.class);
+	@Inject
+	MockStoragePoolDao _mockStoragePoolDao = null;
+	@Inject
+	MockSecStorageDao _mockSecStorageDao = null;
+	@Inject
+	MockVolumeDao _mockVolumeDao = null;
+	@Inject
+	MockVMDao _mockVMDao = null;
+	@Inject
+	MockHostDao _mockHostDao = null;
+
+	private MockVolumeVO findVolumeFromSecondary(String path, String ssUrl, MockVolumeType type) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			String volumePath = path.replaceAll(ssUrl, "");
+			MockSecStorageVO secStorage = _mockSecStorageDao.findByUrl(ssUrl);
+			if (secStorage == null) {
+				return null;
+			}
+			volumePath = secStorage.getMountPoint() + volumePath;
+			volumePath = volumePath.replaceAll("//", "/");
+			MockVolumeVO volume = _mockVolumeDao.findByStoragePathAndType(volumePath);
+			txn.commit();
+			if (volume == null) {
+				return null;
+			}
+			return volume;
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Unable to find volume " + path + " on secondary " + ssUrl, ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+	}
+
+	@Override
+	public PrimaryStorageDownloadAnswer primaryStorageDownload(PrimaryStorageDownloadCommand cmd) {
+		MockVolumeVO template = findVolumeFromSecondary(cmd.getUrl(), cmd.getSecondaryStorageUrl(),
+				MockVolumeType.TEMPLATE);
+		if (template == null) {
+			return new PrimaryStorageDownloadAnswer("Can't find primary storage");
+		}
+
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		MockStoragePoolVO primaryStorage = null;
+		try {
+			txn.start();
+			primaryStorage = _mockStoragePoolDao.findByUuid(cmd.getPoolUuid());
+			txn.commit();
+			if (primaryStorage == null) {
+				return new PrimaryStorageDownloadAnswer("Can't find primary storage");
+			}
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when finding primary storagee " + cmd.getPoolUuid(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+		String volumeName = UUID.randomUUID().toString();
+		MockVolumeVO newVolume = new MockVolumeVO();
+		newVolume.setName(volumeName);
+		newVolume.setPath(primaryStorage.getMountPoint() + volumeName);
+		newVolume.setPoolId(primaryStorage.getId());
+		newVolume.setSize(template.getSize());
+		newVolume.setType(MockVolumeType.VOLUME);
+		txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			_mockVolumeDao.persist(newVolume);
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when saving volume " + newVolume, ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+		return new PrimaryStorageDownloadAnswer(newVolume.getPath(), newVolume.getSize());
+	}
+
+	@Override
+	public CreateAnswer createVolume(CreateCommand cmd) {
+		StorageFilerTO sf = cmd.getPool();
+		DiskProfile dskch = cmd.getDiskCharacteristics();
+		MockStoragePoolVO storagePool = null;
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			storagePool = _mockStoragePoolDao.findByUuid(sf.getUuid());
+			txn.commit();
+			if (storagePool == null) {
+				return new CreateAnswer(cmd, "Failed to find storage pool: " + sf.getUuid());
+			}
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when finding storage " + sf.getUuid(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+		String volumeName = UUID.randomUUID().toString();
+		MockVolumeVO volume = new MockVolumeVO();
+		volume.setPoolId(storagePool.getId());
+		volume.setName(volumeName);
+		volume.setPath(storagePool.getMountPoint() + volumeName);
+		volume.setSize(dskch.getSize());
+		volume.setType(MockVolumeType.VOLUME);
+		txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			volume = _mockVolumeDao.persist(volume);
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when saving volume " + volume, ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+		VolumeTO volumeTo = new VolumeTO(cmd.getVolumeId(), dskch.getType(), sf.getType(), sf.getUuid(),
+				volume.getName(), storagePool.getMountPoint(), volume.getPath(), volume.getSize(), null);
+
+		return new CreateAnswer(cmd, volumeTo);
+	}
+
+	@Override
+	public AttachVolumeAnswer AttachVolume(AttachVolumeCommand cmd) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			String poolid = cmd.getPoolUuid();
+			String volumeName = cmd.getVolumeName();
+			MockVolumeVO volume = _mockVolumeDao.findByStoragePathAndType(cmd.getVolumePath());
+			if (volume == null) {
+				return new AttachVolumeAnswer(cmd, "Can't find volume:" + volumeName + "on pool:" + poolid);
+			}
+
+			String vmName = cmd.getVmName();
+			MockVMVO vm = _mockVMDao.findByVmName(vmName);
+			if (vm == null) {
+				return new AttachVolumeAnswer(cmd, "can't vm :" + vmName);
+			}
+			txn.commit();
+
+			return new AttachVolumeAnswer(cmd, cmd.getDeviceId());
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when attaching volume " + cmd.getVolumeName() + " to VM "
+					+ cmd.getVmName(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+	}
+
+	@Override
+	public Answer AttachIso(AttachIsoCommand cmd) {
+		MockVolumeVO iso = findVolumeFromSecondary(cmd.getIsoPath(), cmd.getStoreUrl(), MockVolumeType.ISO);
+		if (iso == null) {
+			return new Answer(cmd, false, "Failed to find the iso: " + cmd.getIsoPath() + "on secondary storage "
+					+ cmd.getStoreUrl());
+		}
+
+		String vmName = cmd.getVmName();
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		MockVMVO vm = null;
+		try {
+			txn.start();
+			vm = _mockVMDao.findByVmName(vmName);
+			txn.commit();
+			if (vm == null) {
+				return new Answer(cmd, false, "can't vm :" + vmName);
+			}
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when attaching iso to vm " + vm.getName(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+		return new Answer(cmd);
+	}
+
+	@Override
+	public Answer DeleteStoragePool(DeleteStoragePoolCommand cmd) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			MockStoragePoolVO storage = _mockStoragePoolDao.findByUuid(cmd.getPool().getUuid());
+			if (storage == null) {
+				return new Answer(cmd, false, "can't find storage pool:" + cmd.getPool().getUuid());
+			}
+			_mockStoragePoolDao.remove(storage.getId());
+			txn.commit();
+			return new Answer(cmd);
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when deleting storage pool " + cmd.getPool().getPath(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+	}
+
+	@Override
+	public ModifyStoragePoolAnswer ModifyStoragePool(ModifyStoragePoolCommand cmd) {
+		StorageFilerTO sf = cmd.getPool();
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		MockStoragePoolVO storagePool = null;
+		try {
+			txn.start();
+			storagePool = _mockStoragePoolDao.findByUuid(sf.getUuid());
+			if (storagePool == null) {
+				storagePool = new MockStoragePoolVO();
+				storagePool.setUuid(sf.getUuid());
+				storagePool.setMountPoint("/mnt/" + sf.getUuid() + File.separator);
+
+				Long size = DEFAULT_HOST_STORAGE_SIZE;
+				String path = sf.getPath();
+				int index = path.lastIndexOf("/");
+				if (index != -1) {
+					path = path.substring(index + 1);
+					if (path != null) {
+						String values[] = path.split("=");
+						if (values.length > 1 && values[0].equalsIgnoreCase("size")) {
+							size = Long.parseLong(values[1]);
+						}
+					}
+				}
+				storagePool.setCapacity(size);
+				storagePool.setStorageType(sf.getType());
+				storagePool = _mockStoragePoolDao.persist(storagePool);
+			}
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when modifying storage pool " + cmd.getPool().getPath(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+		return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap<String, TemplateInfo>());
+	}
+
+	@Override
+	public Answer CreateStoragePool(CreateStoragePoolCommand cmd) {
+		StorageFilerTO sf = cmd.getPool();
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		MockStoragePoolVO storagePool = null;
+		try {
+			txn.start();
+			storagePool = _mockStoragePoolDao.findByUuid(sf.getUuid());
+			if (storagePool == null) {
+				storagePool = new MockStoragePoolVO();
+				storagePool.setUuid(sf.getUuid());
+				storagePool.setMountPoint("/mnt/" + sf.getUuid() + File.separator);
+
+				Long size = DEFAULT_HOST_STORAGE_SIZE;
+				String path = sf.getPath();
+				int index = path.lastIndexOf("/");
+				if (index != -1) {
+					path = path.substring(index + 1);
+					if (path != null) {
+						String values[] = path.split("=");
+						if (values.length > 1 && values[0].equalsIgnoreCase("size")) {
+							size = Long.parseLong(values[1]);
+						}
+					}
+				}
+				storagePool.setCapacity(size);
+				storagePool.setStorageType(sf.getType());
+				storagePool = _mockStoragePoolDao.persist(storagePool);
+			}
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when creating storage pool " + cmd.getPool().getPath(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+		return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap<String, TemplateInfo>());
+	}
+
+	@Override
+	public Answer SecStorageSetup(SecStorageSetupCommand cmd) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		MockSecStorageVO storage = null;
+		try {
+			txn.start();
+			storage = _mockSecStorageDao.findByUrl(cmd.getSecUrl());
+			if (storage == null) {
+				return new Answer(cmd, false, "can't find the storage");
+			}
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when setting up sec storage" + cmd.getSecUrl(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+		return new SecStorageSetupAnswer(storage.getMountPoint());
+	}
+
+	@Override
+	public Answer ListTemplates(ListTemplateCommand cmd) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		MockSecStorageVO storage = null;
+		try {
+			txn.start();
+			storage = _mockSecStorageDao.findByUrl(cmd.getSecUrl());
+			if (storage == null) {
+				return new Answer(cmd, false, "Failed to get secondary storage");
+			}
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when finding sec storage " + cmd.getSecUrl(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+		txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			List<MockVolumeVO> templates = _mockVolumeDao.findByStorageIdAndType(storage.getId(),
+					MockVolumeType.TEMPLATE);
+
+			Map<String, TemplateInfo> templateInfos = new HashMap<String, TemplateInfo>();
+			for (MockVolumeVO template : templates) {
+				templateInfos.put(template.getName(), new TemplateInfo(template.getName(), template.getPath()
+						.replaceAll(storage.getMountPoint(), ""), template.getSize(), template.getSize(), true, false));
+			}
+			txn.commit();
+			return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos);
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when finding template on sec storage " + storage.getId(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+	}
+
+	@Override
+	public Answer Destroy(DestroyCommand cmd) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			MockVolumeVO volume = _mockVolumeDao.findByStoragePathAndType(cmd.getVolume().getPath());
+			if (volume != null) {
+				_mockVolumeDao.remove(volume.getId());
+			}
+
+			if (cmd.getVmName() != null) {
+				MockVm vm = _mockVMDao.findByVmName(cmd.getVmName());
+				vm.setState(State.Expunging);
+				if (vm != null) {
+					MockVMVO vmVo = _mockVMDao.createForUpdate(vm.getId());
+					_mockVMDao.update(vm.getId(), vmVo);
+				}
+			}
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when destroying volume " + cmd.getVolume().getPath(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+		return new Answer(cmd);
+	}
+
+	@Override
+	public DownloadAnswer Download(DownloadCommand cmd) {
+		MockSecStorageVO ssvo = null;
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			ssvo = _mockSecStorageDao.findByUrl(cmd.getSecUrl());
+			if (ssvo == null) {
+				return new DownloadAnswer("can't find secondary storage",
+						VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
+			}
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error accessing secondary storage " + cmd.getSecUrl(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+		MockVolumeVO volume = new MockVolumeVO();
+		volume.setPoolId(ssvo.getId());
+		volume.setName(cmd.getName());
+		volume.setPath(ssvo.getMountPoint() + cmd.getName());
+		volume.setSize(0);
+		volume.setType(MockVolumeType.TEMPLATE);
+		volume.setStatus(Status.DOWNLOAD_IN_PROGRESS);
+		txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			volume = _mockVolumeDao.persist(volume);
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when saving volume " + volume, ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+		return new DownloadAnswer(String.valueOf(volume.getId()), 0, "Downloading", Status.DOWNLOAD_IN_PROGRESS,
+				cmd.getName(), cmd.getName(), volume.getSize(), volume.getSize(), null);
+	}
+
+	@Override
+	public DownloadAnswer DownloadProcess(DownloadProgressCommand cmd) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			String volumeId = cmd.getJobId();
+			MockVolumeVO volume = _mockVolumeDao.findById(Long.parseLong(volumeId));
+			if (volume == null) {
+				return new DownloadAnswer("Can't find the downloading volume", Status.ABANDONED);
+			}
+
+			long size = Math.min(volume.getSize() + DEFAULT_TEMPLATE_SIZE / 5, DEFAULT_TEMPLATE_SIZE);
+			volume.setSize(size);
+
+			double volumeSize = volume.getSize();
+			double pct = volumeSize / DEFAULT_TEMPLATE_SIZE;
+			if (pct >= 1.0) {
+				volume.setStatus(Status.DOWNLOADED);
+				_mockVolumeDao.update(volume.getId(), volume);
+				txn.commit();
+				return new DownloadAnswer(cmd.getJobId(), 100, cmd,
+						com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED, volume.getPath(),
+						volume.getName());
+			} else {
+				_mockVolumeDao.update(volume.getId(), volume);
+				txn.commit();
+				return new DownloadAnswer(cmd.getJobId(), (int) (pct * 100.0), cmd,
+						com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS, volume.getPath(),
+						volume.getName());
+			}
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error during download job " + cmd.getJobId(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+	}
+
+	@Override
+	public GetStorageStatsAnswer GetStorageStats(GetStorageStatsCommand cmd) {
+		String uuid = cmd.getStorageId();
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			if (uuid == null) {
+				String secUrl = cmd.getSecUrl();
+				MockSecStorageVO secondary = _mockSecStorageDao.findByUrl(secUrl);
+				if (secondary == null) {
+					return new GetStorageStatsAnswer(cmd, "Can't find the secondary storage:" + secUrl);
+				}
+				Long totalUsed = _mockVolumeDao.findTotalStorageId(secondary.getId());
+				txn.commit();
+				return new GetStorageStatsAnswer(cmd, secondary.getCapacity(), totalUsed);
+			} else {
+				MockStoragePoolVO pool = _mockStoragePoolDao.findByUuid(uuid);
+				if (pool == null) {
+					return new GetStorageStatsAnswer(cmd, "Can't find the pool");
+				}
+				Long totalUsed = _mockVolumeDao.findTotalStorageId(pool.getId());
+				if (totalUsed == null) {
+					totalUsed = 0L;
+				}
+				txn.commit();
+				return new GetStorageStatsAnswer(cmd, pool.getCapacity(), totalUsed);
+			}
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("DBException during storage stats collection for pool " + uuid, ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+	}
+
+	@Override
+	public ManageSnapshotAnswer ManageSnapshot(ManageSnapshotCommand cmd) {
+		String volPath = cmd.getVolumePath();
+		MockVolumeVO volume = null;
+		MockStoragePoolVO storagePool = null;
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			volume = _mockVolumeDao.findByStoragePathAndType(volPath);
+			if (volume == null) {
+				return new ManageSnapshotAnswer(cmd, false, "Can't find the volume");
+			}
+			storagePool = _mockStoragePoolDao.findById(volume.getPoolId());
+			if (storagePool == null) {
+				return new ManageSnapshotAnswer(cmd, false, "Can't find the storage pooll");
+			}
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Unable to perform snapshot", ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+		String mountPoint = storagePool.getMountPoint();
+		MockVolumeVO snapshot = new MockVolumeVO();
+
+		snapshot.setName(cmd.getSnapshotName());
+		snapshot.setPath(mountPoint + cmd.getSnapshotName());
+		snapshot.setSize(volume.getSize());
+		snapshot.setPoolId(storagePool.getId());
+		snapshot.setType(MockVolumeType.SNAPSHOT);
+		snapshot.setStatus(Status.DOWNLOADED);
+		txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			snapshot = _mockVolumeDao.persist(snapshot);
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when saving snapshot " + snapshot, ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+		return new ManageSnapshotAnswer(cmd, snapshot.getId(), snapshot.getPath(), true, "");
+	}
+
+	@Override
+	public BackupSnapshotAnswer BackupSnapshot(BackupSnapshotCommand cmd, SimulatorInfo info) {
+		// emulate xenserver backupsnapshot, if the base volume is deleted, then
+		// backupsnapshot failed
+		MockVolumeVO volume = null;
+		MockVolumeVO snapshot = null;
+		MockSecStorageVO secStorage = null;
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			volume = _mockVolumeDao.findByStoragePathAndType(cmd.getVolumePath());
+			if (volume == null) {
+				return new BackupSnapshotAnswer(cmd, false, "Can't find base volume: " + cmd.getVolumePath(), null,
+						true);
+			}
+			String snapshotPath = cmd.getSnapshotUuid();
+			snapshot = _mockVolumeDao.findByStoragePathAndType(snapshotPath);
+			if (snapshot == null) {
+				return new BackupSnapshotAnswer(cmd, false, "can't find snapshot" + snapshotPath, null, true);
+			}
+
+			String secStorageUrl = cmd.getSecondaryStorageUrl();
+			secStorage = _mockSecStorageDao.findByUrl(secStorageUrl);
+			if (secStorage == null) {
+				return new BackupSnapshotAnswer(cmd, false, "can't find sec storage" + snapshotPath, null, true);
+			}
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when backing up snapshot");
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+		MockVolumeVO newsnapshot = new MockVolumeVO();
+		String name = UUID.randomUUID().toString();
+		newsnapshot.setName(name);
+		newsnapshot.setPath(secStorage.getMountPoint() + name);
+		newsnapshot.setPoolId(secStorage.getId());
+		newsnapshot.setSize(snapshot.getSize());
+		newsnapshot.setStatus(Status.DOWNLOADED);
+		newsnapshot.setType(MockVolumeType.SNAPSHOT);
+		txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			snapshot = _mockVolumeDao.persist(snapshot);
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when backing up snapshot " + newsnapshot, ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+		return new BackupSnapshotAnswer(cmd, true, null, newsnapshot.getName(), true);
+	}
+
+	@Override
+	public Answer DeleteSnapshotBackup(DeleteSnapshotBackupCommand cmd) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			MockVolumeVO backSnapshot = _mockVolumeDao.findByName(cmd.getSnapshotUuid());
+			if (backSnapshot == null) {
+				return new Answer(cmd, false, "can't find the backupsnapshot: " + cmd.getSnapshotUuid());
+			}
+			_mockVolumeDao.remove(backSnapshot.getId());
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when deleting snapshot");
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+		return new Answer(cmd);
+	}
+
+	@Override
+	public CreateVolumeFromSnapshotAnswer CreateVolumeFromSnapshot(CreateVolumeFromSnapshotCommand cmd) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		MockVolumeVO backSnapshot = null;
+		MockStoragePoolVO primary = null;
+		try {
+			txn.start();
+			backSnapshot = _mockVolumeDao.findByName(cmd.getSnapshotUuid());
+			if (backSnapshot == null) {
+				return new CreateVolumeFromSnapshotAnswer(cmd, false, "can't find the backupsnapshot: "
+						+ cmd.getSnapshotUuid(), null);
+			}
+
+			primary = _mockStoragePoolDao.findByUuid(cmd.getPrimaryStoragePoolNameLabel());
+			if (primary == null) {
+				return new CreateVolumeFromSnapshotAnswer(cmd, false, "can't find the primary storage: "
+						+ cmd.getPrimaryStoragePoolNameLabel(), null);
+			}
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when creating volume from snapshot", ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+		String uuid = UUID.randomUUID().toString();
+		MockVolumeVO volume = new MockVolumeVO();
+
+		volume.setName(uuid);
+		volume.setPath(primary.getMountPoint() + uuid);
+		volume.setPoolId(primary.getId());
+		volume.setSize(backSnapshot.getSize());
+		volume.setStatus(Status.DOWNLOADED);
+		volume.setType(MockVolumeType.VOLUME);
+		txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			_mockVolumeDao.persist(volume);
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when creating volume from snapshot " + volume, ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+		return new CreateVolumeFromSnapshotAnswer(cmd, true, null, volume.getPath());
+	}
+
+	@Override
+	public Answer DeleteTemplate(DeleteTemplateCommand cmd) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			MockVolumeVO template = _mockVolumeDao.findByStoragePathAndType(cmd.getTemplatePath());
+			if (template == null) {
+				return new Answer(cmd, false, "can't find template:" + cmd.getTemplatePath());
+			}
+			_mockVolumeDao.remove(template.getId());
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when deleting template");
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+		return new Answer(cmd);
+	}
+
+	@Override
+	public Answer SecStorageVMSetup(SecStorageVMSetupCommand cmd) {
+		return new Answer(cmd);
+	}
+
+	@Override
+	public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+		// TODO Auto-generated method stub
+		return true;
+	}
+
+	@Override
+	public boolean start() {
+		// TODO Auto-generated method stub
+		return true;
+	}
+
+	@Override
+	public boolean stop() {
+		// TODO Auto-generated method stub
+		return true;
+	}
+
+	@Override
+	public String getName() {
+		return this.getClass().getSimpleName();
+	}
+
+	@Override
+	public void preinstallTemplates(String url, long zoneId) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		MockSecStorageVO storage = null;
+		try {
+			txn.start();
+			storage = _mockSecStorageDao.findByUrl(url);
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Unable to find sec storage at " + url, ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+		if (storage == null) {
+			storage = new MockSecStorageVO();
+			URI uri;
+			try {
+				uri = new URI(url);
+			} catch (URISyntaxException e) {
+				return;
+			}
+
+			String nfsHost = uri.getHost();
+			String nfsPath = uri.getPath();
+			String path = nfsHost + ":" + nfsPath;
+			String dir = "/mnt/" + UUID.nameUUIDFromBytes(path.getBytes()).toString() + File.separator;
+
+			storage.setUrl(url);
+			storage.setCapacity(DEFAULT_HOST_STORAGE_SIZE);
+
+			storage.setMountPoint(dir);
+			txn = Transaction.open(Transaction.SIMULATOR_DB);
+			try {
+				txn.start();
+				storage = _mockSecStorageDao.persist(storage);
+				txn.commit();
+			} catch (Exception ex) {
+				txn.rollback();
+				throw new CloudRuntimeException("Error when saving storage " + storage, ex);
+			} finally {
+				txn.close();
+                txn = Transaction.open(Transaction.CLOUD_DB);
+                txn.close();
+			}
+
+			// preinstall default templates into secondary storage
+			long defaultTemplateSize = 2 * 1024 * 1024 * 1024L;
+			MockVolumeVO template = new MockVolumeVO();
+			template.setName("simulator-domR");
+			template.setPath(storage.getMountPoint() + "template/tmpl/1/9/" + UUID.randomUUID().toString());
+			template.setPoolId(storage.getId());
+			template.setSize(defaultTemplateSize);
+			template.setType(MockVolumeType.TEMPLATE);
+			template.setStatus(Status.DOWNLOADED);
+			txn = Transaction.open(Transaction.SIMULATOR_DB);
+			try {
+				txn.start();
+				template = _mockVolumeDao.persist(template);
+				txn.commit();
+			} catch (Exception ex) {
+				txn.rollback();
+				throw new CloudRuntimeException("Error when saving template " + template, ex);
+			} finally {
+				txn.close();
+                txn = Transaction.open(Transaction.CLOUD_DB);
+                txn.close();
+			}
+
+			template = new MockVolumeVO();
+			template.setName("simulator-Centos");
+			template.setPath(storage.getMountPoint() + "template/tmpl/1/10/" + UUID.randomUUID().toString());
+			template.setPoolId(storage.getId());
+			template.setSize(defaultTemplateSize);
+			template.setType(MockVolumeType.TEMPLATE);
+			template.setStatus(Status.DOWNLOADED);
+			txn = Transaction.open(Transaction.SIMULATOR_DB);
+			try {
+				txn.start();
+				template = _mockVolumeDao.persist(template);
+				txn.commit();
+			} catch (Exception ex) {
+				txn.rollback();
+				throw new CloudRuntimeException("Error when saving template " + template, ex);
+			} finally {
+				txn.close();
+                txn = Transaction.open(Transaction.CLOUD_DB);
+                txn.close();
+			}
+		}
+
+	}
+
+	@Override
+	public StoragePoolInfo getLocalStorage(String hostGuid) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		MockHost host = null;
+		MockStoragePoolVO storagePool = null;
+		try {
+			txn.start();
+			host = _mockHostDao.findByGuid(hostGuid);
+			storagePool = _mockStoragePoolDao.findByHost(hostGuid);
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Unable to find host " + hostGuid, ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+		if (storagePool == null) {
+			String uuid = UUID.randomUUID().toString();
+			storagePool = new MockStoragePoolVO();
+			storagePool.setUuid(uuid);
+			storagePool.setMountPoint("/mnt/" + uuid + File.separator);
+			storagePool.setCapacity(DEFAULT_HOST_STORAGE_SIZE);
+			storagePool.setHostGuid(hostGuid);
+			storagePool.setStorageType(StoragePoolType.Filesystem);
+			txn = Transaction.open(Transaction.SIMULATOR_DB);
+			try {
+				txn.start();
+				storagePool = _mockStoragePoolDao.persist(storagePool);
+				txn.commit();
+			} catch (Exception ex) {
+				txn.rollback();
+				throw new CloudRuntimeException("Error when saving storagePool " + storagePool, ex);
+			} finally {
+				txn.close();
+                txn = Transaction.open(Transaction.CLOUD_DB);
+                txn.close();
+			}
+		}
+		return new StoragePoolInfo(storagePool.getUuid(), host.getPrivateIpAddress(), storagePool.getMountPoint(),
+				storagePool.getMountPoint(), storagePool.getPoolType(), storagePool.getCapacity(), 0);
+	}
+
+	@Override
+	public StoragePoolInfo getLocalStorage(String hostGuid, Long storageSize) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		MockHost host = null;
+		try {
+			txn.start();
+			host = _mockHostDao.findByGuid(hostGuid);
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Unable to find host " + hostGuid, ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+		if (storageSize == null) {
+			storageSize = DEFAULT_HOST_STORAGE_SIZE;
+		}
+		txn = Transaction.open(Transaction.SIMULATOR_DB);
+		MockStoragePoolVO storagePool = null;
+		try {
+			txn.start();
+			storagePool = _mockStoragePoolDao.findByHost(hostGuid);
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when finding storagePool " + storagePool, ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+		if (storagePool == null) {
+			String uuid = UUID.randomUUID().toString();
+			storagePool = new MockStoragePoolVO();
+			storagePool.setUuid(uuid);
+			storagePool.setMountPoint("/mnt/" + uuid + File.separator);
+			storagePool.setCapacity(storageSize);
+			storagePool.setHostGuid(hostGuid);
+			storagePool.setStorageType(StoragePoolType.Filesystem);
+			txn = Transaction.open(Transaction.SIMULATOR_DB);
+			try {
+				txn.start();
+				storagePool = _mockStoragePoolDao.persist(storagePool);
+				txn.commit();
+			} catch (Exception ex) {
+				txn.rollback();
+				throw new CloudRuntimeException("Error when saving storagePool " + storagePool, ex);
+			} finally {
+				txn.close();
+                txn = Transaction.open(Transaction.CLOUD_DB);
+                txn.close();
+			}
+		}
+		return new StoragePoolInfo(storagePool.getUuid(), host.getPrivateIpAddress(), storagePool.getMountPoint(),
+				storagePool.getMountPoint(), storagePool.getPoolType(), storagePool.getCapacity(), 0);
+	}
+
+	@Override
+	public CreatePrivateTemplateAnswer CreatePrivateTemplateFromSnapshot(CreatePrivateTemplateFromSnapshotCommand cmd) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		MockVolumeVO snapshot = null;
+		MockSecStorageVO sec = null;
+		try {
+			txn.start();
+			String snapshotUUId = cmd.getSnapshotUuid();
+			snapshot = _mockVolumeDao.findByName(snapshotUUId);
+			if (snapshot == null) {
+				snapshotUUId = cmd.getSnapshotName();
+				snapshot = _mockVolumeDao.findByName(snapshotUUId);
+				if (snapshot == null) {
+					return new CreatePrivateTemplateAnswer(cmd, false, "can't find snapshot:" + snapshotUUId);
+				}
+			}
+
+			sec = _mockSecStorageDao.findByUrl(cmd.getSecondaryStorageUrl());
+			if (sec == null) {
+				return new CreatePrivateTemplateAnswer(cmd, false, "can't find secondary storage");
+			}
+			txn.commit();
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+		MockVolumeVO template = new MockVolumeVO();
+		String uuid = UUID.randomUUID().toString();
+		template.setName(uuid);
+		template.setPath(sec.getMountPoint() + uuid);
+		template.setPoolId(sec.getId());
+		template.setSize(snapshot.getSize());
+		template.setStatus(Status.DOWNLOADED);
+		template.setType(MockVolumeType.TEMPLATE);
+		txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			template = _mockVolumeDao.persist(template);
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when saving template " + template, ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+		return new CreatePrivateTemplateAnswer(cmd, true, "", template.getName(), template.getSize(),
+				template.getSize(), template.getName(), ImageFormat.QCOW2);
+	}
+
+	@Override
+	public Answer ComputeChecksum(ComputeChecksumCommand cmd) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			MockVolumeVO volume = _mockVolumeDao.findByName(cmd.getTemplatePath());
+			if (volume == null) {
+				return new Answer(cmd, false, "cant' find volume:" + cmd.getTemplatePath());
+			}
+			String md5 = null;
+			try {
+				MessageDigest md = MessageDigest.getInstance("md5");
+				md5 = String.format("%032x", new BigInteger(1, md.digest(cmd.getTemplatePath().getBytes())));
+			} catch (NoSuchAlgorithmException e) {
+				s_logger.debug("failed to gernerate md5:" + e.toString());
+			}
+			txn.commit();
+			return new Answer(cmd, true, md5);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+	}
+
+	@Override
+	public CreatePrivateTemplateAnswer CreatePrivateTemplateFromVolume(CreatePrivateTemplateFromVolumeCommand cmd) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		MockVolumeVO volume = null;
+		MockSecStorageVO sec = null;
+		try {
+			txn.start();
+			volume = _mockVolumeDao.findByStoragePathAndType(cmd.getVolumePath());
+			if (volume == null) {
+				return new CreatePrivateTemplateAnswer(cmd, false, "cant' find volume" + cmd.getVolumePath());
+			}
+
+			sec = _mockSecStorageDao.findByUrl(cmd.getSecondaryStorageUrl());
+			if (sec == null) {
+				return new CreatePrivateTemplateAnswer(cmd, false, "can't find secondary storage");
+			}
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Error when creating private template from volume");
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+		MockVolumeVO template = new MockVolumeVO();
+		String uuid = UUID.randomUUID().toString();
+		template.setName(uuid);
+		template.setPath(sec.getMountPoint() + uuid);
+		template.setPoolId(sec.getId());
+		template.setSize(volume.getSize());
+		template.setStatus(Status.DOWNLOADED);
+		template.setType(MockVolumeType.TEMPLATE);
+		txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			template = _mockVolumeDao.persist(template);
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Encountered " + ex.getMessage() + " when persisting template "
+					+ template.getName(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+		return new CreatePrivateTemplateAnswer(cmd, true, "", template.getName(), template.getSize(),
+				template.getSize(), template.getName(), ImageFormat.QCOW2);
+	}
+
+	@Override
+	public CopyVolumeAnswer CopyVolume(CopyVolumeCommand cmd) {
+		Transaction txn = Transaction.open(Transaction.SIMULATOR_DB);
+		boolean toSecondaryStorage = cmd.toSecondaryStorage();
+		MockSecStorageVO sec = null;
+		MockStoragePoolVO primaryStorage = null;
+		try {
+			txn.start();
+			sec = _mockSecStorageDao.findByUrl(cmd.getSecondaryStorageURL());
+			if (sec == null) {
+				return new CopyVolumeAnswer(cmd, false, "can't find secondary storage", null, null);
+			}
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Encountered " + ex.getMessage() + " when accessing secondary at "
+					+ cmd.getSecondaryStorageURL(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+		txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			primaryStorage = _mockStoragePoolDao.findByUuid(cmd.getPool().getUuid());
+			if (primaryStorage == null) {
+				return new CopyVolumeAnswer(cmd, false, "Can't find primary storage", null, null);
+			}
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Encountered " + ex.getMessage() + " when accessing primary at "
+					+ cmd.getPool(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+		MockVolumeVO volume = null;
+		txn = Transaction.open(Transaction.SIMULATOR_DB);
+		try {
+			txn.start();
+			volume = _mockVolumeDao.findByStoragePathAndType(cmd.getVolumePath());
+			if (volume == null) {
+				return new CopyVolumeAnswer(cmd, false, "cant' find volume" + cmd.getVolumePath(), null, null);
+			}
+			txn.commit();
+		} catch (Exception ex) {
+			txn.rollback();
+			throw new CloudRuntimeException("Encountered " + ex.getMessage() + " when accessing volume at "
+					+ cmd.getVolumePath(), ex);
+		} finally {
+			txn.close();
+            txn = Transaction.open(Transaction.CLOUD_DB);
+            txn.close();
+		}
+
+		String name = UUID.randomUUID().toString();
+		if (toSecondaryStorage) {
+			MockVolumeVO vol = new MockVolumeVO();
+			vol.setName(name);
+			vol.setPath(sec.getMountPoint() + name);
+			vol.setPoolId(sec.getId());
+			vol.setSize(volume.getSize());
+			vol.setStatus(Status.DOWNLOADED);
+			vol.setType(MockVolumeType.VOLUME);
+			txn = Transaction.open(Transaction.SIMULATOR_DB);
+			try {
+				txn.start();
+				vol = _mockVolumeDao.persist(vol);
+				txn.commit();
+			} catch (Exception ex) {
+				txn.rollback();
+				throw new CloudRuntimeException("Encountered " + ex.getMessage() + " when persisting volume "
+						+ vol.getName(), ex);
+			} finally {
+				txn.close();
+                txn = Transaction.open(Transaction.CLOUD_DB);
+                txn.close();
+			}
+			return new CopyVolumeAnswer(cmd, true, null, sec.getMountPoint(), vol.getPath());
+		} else {
+			MockVolumeVO vol = new MockVolumeVO();
+			vol.setName(name);
+			vol.setPath(primaryStorage.getMountPoint() + name);
+			vol.setPoolId(primaryStorage.getId());
+			vol.setSize(volume.getSize());
+			vol.setStatus(Status.DOWNLOADED);
+			vol.setType(MockVolumeType.VOLUME);
+			txn = Transaction.open(Transaction.SIMULATOR_DB);
+			try {
+				txn.start();
+				vol = _mockVolumeDao.persist(vol);
+				txn.commit();
+			} catch (Exception ex) {
+				txn.rollback();
+				throw new CloudRuntimeException("Encountered " + ex.getMessage() + " when persisting volume "
+						+ vol.getName(), ex);
+			} finally {
+				txn.close();
+                txn = Transaction.open(Transaction.CLOUD_DB);
+                txn.close();
+			}
+			return new CopyVolumeAnswer(cmd, true, null, primaryStorage.getMountPoint(), vol.getPath());
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/d6083ce5/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManager.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManager.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManager.java
new file mode 100644
index 0000000..82f600d
--- /dev/null
+++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManager.java
@@ -0,0 +1,83 @@
+// 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.Map;
+
+import com.cloud.agent.api.*;
+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.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.simulator.MockVMVO;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.Manager;
+import com.cloud.vm.VirtualMachine.State;
+
+public interface MockVmManager extends Manager {
+    public Answer stopVM(StopCommand cmd);
+	public Answer rebootVM(RebootCommand cmd);
+
+    public Answer checkVmState(CheckVirtualMachineCommand cmd);
+    public Map<String, State> getVmStates(String hostGuid);
+    public Answer getVncPort(GetVncPortCommand cmd);
+
+	Answer startVM(StartCommand cmd, SimulatorInfo info);
+
+	Answer getVmStats(GetVmStatsCommand cmd);
+    public CheckSshAnswer checkSshCommand(CheckSshCommand cmd);
+
+    Answer SetStaticNatRules(SetStaticNatRulesCommand cmd);
+
+    Answer SetPortForwardingRules(SetPortForwardingRulesCommand cmd);
+
+    Answer SetFirewallRules(SetFirewallRulesCommand cmd);
+
+    Answer getNetworkUsage(NetworkUsageCommand cmd);
+
+    Answer IpAssoc(IpAssocCommand cmd);
+
+    Answer LoadBalancerConfig(LoadBalancerConfigCommand cmd);
+
+    Answer AddDhcpEntry(DhcpEntryCommand cmd);
+
+    Answer setVmData(VmDataCommand cmd);
+    Answer CleanupNetworkRules(CleanupNetworkRulesCmd cmd, SimulatorInfo info);
+
+    Answer CheckConsoleProxyLoad(CheckConsoleProxyLoadCommand cmd);
+    Answer WatchConsoleProxyLoad(WatchConsoleProxyLoadCommand cmd);
+
+    Answer SavePassword(SavePasswordCommand cmd);
+    HashMap<String, Pair<Long, Long>> syncNetworkGroups(SimulatorInfo info);
+    SecurityGroupRuleAnswer AddSecurityGroupRules(SecurityGroupRulesCmd cmd, SimulatorInfo info);
+	MigrateAnswer Migrate(MigrateCommand cmd, SimulatorInfo info);
+	GetDomRVersionAnswer getDomRVersion(GetDomRVersionCmd cmd);
+	Map<String, MockVMVO> getVms(String hostGuid);
+
+    CheckRouterAnswer checkRouter(CheckRouterCommand cmd);
+
+    Answer bumpPriority(BumpUpPriorityCommand cmd);
+}