You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mc...@apache.org on 2013/10/29 04:52:59 UTC

[09/50] [abbrv] move a lot of code into vmsnapshot strategy

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/engine/storage/snapshot/test/src/VMSnapshotStrategyTest.java
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/test/src/VMSnapshotStrategyTest.java b/engine/storage/snapshot/test/src/VMSnapshotStrategyTest.java
new file mode 100644
index 0000000..8e36faf
--- /dev/null
+++ b/engine/storage/snapshot/test/src/VMSnapshotStrategyTest.java
@@ -0,0 +1,256 @@
+/*
+ * 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 src;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.VMSnapshotStrategy;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.cloudstack.storage.vmsnapshot.DefaultVMSnapshotStrategy;
+import org.apache.cloudstack.storage.vmsnapshot.VMSnapshotHelper;
+import org.apache.cloudstack.test.utils.SpringUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.FilterType;
+import org.springframework.core.type.classreading.MetadataReader;
+import org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.core.type.filter.TypeFilter;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.CreateVMSnapshotAnswer;
+import com.cloud.agent.api.DeleteVMSnapshotAnswer;
+import com.cloud.agent.api.RevertToVMSnapshotAnswer;
+import com.cloud.agent.api.VMSnapshotTO;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.storage.GuestOSVO;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.snapshot.VMSnapshot;
+import com.cloud.vm.snapshot.VMSnapshotVO;
+import com.cloud.vm.snapshot.dao.VMSnapshotDao;
+
+import junit.framework.TestCase;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
+public class VMSnapshotStrategyTest extends TestCase {
+    @Inject
+    VMSnapshotStrategy vmSnapshotStrategy;
+    @Inject
+    VMSnapshotHelper vmSnapshotHelper;
+    @Inject UserVmDao userVmDao;
+    @Inject
+    GuestOSDao guestOSDao;
+    @Inject
+    AgentManager agentMgr;
+    @Inject
+    VMSnapshotDao vmSnapshotDao;
+    @Override
+    @Before
+    public void setUp() {
+        ComponentContext.initComponentsLifeCycle();
+    }
+
+
+    @Test
+    public void testCreateVMSnapshot() throws AgentUnavailableException, OperationTimedoutException {
+        Long hostId = 1L;
+        Long vmId = 1L;
+        Long guestOsId = 1L;
+        List<VolumeObjectTO> volumeObjectTOs = new ArrayList<VolumeObjectTO>();
+        VMSnapshotVO vmSnapshot = Mockito.mock(VMSnapshotVO.class);
+        UserVmVO userVmVO = Mockito.mock(UserVmVO.class);
+        Mockito.when(userVmVO.getGuestOSId()).thenReturn(guestOsId);
+        Mockito.when(vmSnapshot.getVmId()).thenReturn(vmId);
+        Mockito.when(vmSnapshotHelper.pickRunningHost(Mockito.anyLong())).thenReturn(hostId);
+        Mockito.when(vmSnapshotHelper.getVolumeTOList(Mockito.anyLong())).thenReturn(volumeObjectTOs);
+        Mockito.when(userVmDao.findById(Mockito.anyLong())).thenReturn(userVmVO);
+        GuestOSVO guestOSVO = Mockito.mock(GuestOSVO.class);
+        Mockito.when(guestOSDao.findById(Mockito.anyLong())).thenReturn(guestOSVO);
+        Mockito.when(agentMgr.send(Mockito.anyLong(), Mockito.any(Command.class))).thenReturn(null);
+        Exception e = null;
+        try {
+            vmSnapshotStrategy.takeVMSnapshot(vmSnapshot);
+        } catch (CloudRuntimeException e1) {
+            e = e1;
+        }
+
+        assertNotNull(e);
+        CreateVMSnapshotAnswer answer = Mockito.mock(CreateVMSnapshotAnswer.class);
+        Mockito.when(answer.getResult()).thenReturn(true);
+        Mockito.when(agentMgr.send(Mockito.anyLong(), Mockito.any(Command.class))).thenReturn(answer);
+        Mockito.when(vmSnapshotDao.findById(Mockito.anyLong())).thenReturn(vmSnapshot);
+        VMSnapshot snapshot = null;
+        snapshot = vmSnapshotStrategy.takeVMSnapshot(vmSnapshot);
+        assertNotNull(snapshot);
+    }
+
+    @Test
+    public void testRevertSnapshot() throws AgentUnavailableException, OperationTimedoutException {
+        Long hostId = 1L;
+        Long vmId = 1L;
+        Long guestOsId = 1L;
+        List<VolumeObjectTO> volumeObjectTOs = new ArrayList<VolumeObjectTO>();
+        VMSnapshotVO vmSnapshot = Mockito.mock(VMSnapshotVO.class);
+        UserVmVO userVmVO = Mockito.mock(UserVmVO.class);
+        Mockito.when(userVmVO.getGuestOSId()).thenReturn(guestOsId);
+        Mockito.when(vmSnapshot.getVmId()).thenReturn(vmId);
+        Mockito.when(vmSnapshotHelper.pickRunningHost(Mockito.anyLong())).thenReturn(hostId);
+        Mockito.when(vmSnapshotHelper.getVolumeTOList(Mockito.anyLong())).thenReturn(volumeObjectTOs);
+        Mockito.when(userVmDao.findById(Mockito.anyLong())).thenReturn(userVmVO);
+        GuestOSVO guestOSVO = Mockito.mock(GuestOSVO.class);
+        Mockito.when(guestOSDao.findById(Mockito.anyLong())).thenReturn(guestOSVO);
+        VMSnapshotTO vmSnapshotTO = Mockito.mock(VMSnapshotTO.class);
+        Mockito.when(vmSnapshotHelper.getSnapshotWithParents(Mockito.any(VMSnapshotVO.class))).thenReturn(vmSnapshotTO);
+        Mockito.when(vmSnapshotDao.findById(Mockito.anyLong())).thenReturn(vmSnapshot);
+        Mockito.when(vmSnapshot.getId()).thenReturn(1L);
+        Mockito.when(vmSnapshot.getCreated()).thenReturn(new Date());
+        Mockito.when(agentMgr.send(Mockito.anyLong(), Mockito.any(Command.class))).thenReturn(null);
+        Exception e = null;
+        try {
+            vmSnapshotStrategy.revertVMSnapshot(vmSnapshot);
+        } catch (CloudRuntimeException e1) {
+            e = e1;
+        }
+
+        assertNotNull(e);
+
+        RevertToVMSnapshotAnswer answer = Mockito.mock(RevertToVMSnapshotAnswer.class);
+        Mockito.when(answer.getResult()).thenReturn(Boolean.TRUE);
+        Mockito.when(agentMgr.send(Mockito.anyLong(), Mockito.any(Command.class))).thenReturn(answer);
+        boolean result = vmSnapshotStrategy.revertVMSnapshot(vmSnapshot);
+        assertTrue(result);
+    }
+
+    @Test
+    public void testDeleteVMSnapshot() throws AgentUnavailableException, OperationTimedoutException {
+        Long hostId = 1L;
+        Long vmId = 1L;
+        Long guestOsId = 1L;
+        List<VolumeObjectTO> volumeObjectTOs = new ArrayList<VolumeObjectTO>();
+        VMSnapshotVO vmSnapshot = Mockito.mock(VMSnapshotVO.class);
+        UserVmVO userVmVO = Mockito.mock(UserVmVO.class);
+        Mockito.when(userVmVO.getGuestOSId()).thenReturn(guestOsId);
+        Mockito.when(vmSnapshot.getVmId()).thenReturn(vmId);
+        Mockito.when(vmSnapshotHelper.pickRunningHost(Mockito.anyLong())).thenReturn(hostId);
+        Mockito.when(vmSnapshotHelper.getVolumeTOList(Mockito.anyLong())).thenReturn(volumeObjectTOs);
+        Mockito.when(userVmDao.findById(Mockito.anyLong())).thenReturn(userVmVO);
+        GuestOSVO guestOSVO = Mockito.mock(GuestOSVO.class);
+        Mockito.when(guestOSDao.findById(Mockito.anyLong())).thenReturn(guestOSVO);
+        VMSnapshotTO vmSnapshotTO = Mockito.mock(VMSnapshotTO.class);
+        Mockito.when(vmSnapshotHelper.getSnapshotWithParents(Mockito.any(VMSnapshotVO.class))).thenReturn(vmSnapshotTO);
+        Mockito.when(vmSnapshotDao.findById(Mockito.anyLong())).thenReturn(vmSnapshot);
+        Mockito.when(vmSnapshot.getId()).thenReturn(1L);
+        Mockito.when(vmSnapshot.getCreated()).thenReturn(new Date());
+        Mockito.when(agentMgr.send(Mockito.anyLong(), Mockito.any(Command.class))).thenReturn(null);
+
+        Exception e = null;
+        try {
+            vmSnapshotStrategy.deleteVMSnapshot(vmSnapshot);
+        } catch (CloudRuntimeException e1) {
+            e = e1;
+        }
+
+        assertNotNull(e);
+
+        DeleteVMSnapshotAnswer answer = Mockito.mock(DeleteVMSnapshotAnswer.class);
+        Mockito.when(answer.getResult()).thenReturn(true);
+        Mockito.when(agentMgr.send(Mockito.anyLong(), Mockito.any(Command.class))).thenReturn(answer);
+
+        boolean result = vmSnapshotStrategy.deleteVMSnapshot(vmSnapshot);
+        assertTrue(result);
+    }
+
+
+    @Configuration
+    @ComponentScan(basePackageClasses = {NetUtils.class, DefaultVMSnapshotStrategy.class}, includeFilters = {@ComponentScan.Filter(value = TestConfiguration.Library.class, type = FilterType.CUSTOM)}, useDefaultFilters = false)
+    public static class TestConfiguration extends SpringUtils.CloudStackTestConfiguration {
+
+        public static class Library implements TypeFilter {
+            @Override
+            public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
+                mdr.getClassMetadata().getClassName();
+                ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class);
+                return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
+            }
+        }
+
+        @Bean
+        public VMSnapshotHelper vmSnapshotHelper() {
+            return Mockito.mock(VMSnapshotHelper.class);
+        }
+
+        @Bean
+        public GuestOSDao guestOSDao() {
+            return Mockito.mock(GuestOSDao.class);
+        }
+
+        @Bean
+        public UserVmDao userVmDao() {
+            return Mockito.mock(UserVmDao.class);
+        }
+
+        @Bean
+        public VMSnapshotDao vmSnapshotDao() {
+            return Mockito.mock(VMSnapshotDao.class);
+        }
+
+        @Bean
+        public ConfigurationDao configurationDao() {
+            return Mockito.mock(ConfigurationDao.class);
+        }
+
+        @Bean
+        public AgentManager agentManager() {
+            return Mockito.mock(AgentManager.class);
+        }
+
+        @Bean
+        public VolumeDao volumeDao() {
+            return Mockito.mock(VolumeDao.class);
+        }
+
+        @Bean
+        public DiskOfferingDao diskOfferingDao() {
+            return Mockito.mock(DiskOfferingDao.class);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
index c902aef..376baa5 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
@@ -18,16 +18,37 @@
  */
 package org.apache.cloudstack.storage.volume;
 
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.storage.ListVolumeAnswer;
+import com.cloud.agent.api.storage.ListVolumeCommand;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.alert.AlertManager;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.host.Host;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.VMTemplateStoragePoolVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.storage.Volume;
+import com.cloud.storage.Volume.State;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VMTemplatePoolDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.snapshot.SnapshotManager;
+import com.cloud.storage.template.TemplateProp;
+import com.cloud.user.AccountManager;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.exception.CloudRuntimeException;
 import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
 import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
@@ -55,45 +76,19 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 import org.apache.cloudstack.storage.command.CommandResult;
 import org.apache.cloudstack.storage.command.CopyCmdAnswer;
 import org.apache.cloudstack.storage.command.DeleteCommand;
-import org.apache.cloudstack.storage.datastore.DataObjectManager;
-import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
 import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
 import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager;
 import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
 import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
 
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.storage.ListVolumeAnswer;
-import com.cloud.agent.api.storage.ListVolumeCommand;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.alert.AlertManager;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.host.Host;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.VMTemplateStoragePoolVO;
-import com.cloud.storage.VMTemplateStorageResourceAssoc;
-import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
-import com.cloud.storage.Volume;
-import com.cloud.storage.Volume.State;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.VMTemplatePoolDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.snapshot.SnapshotManager;
-import com.cloud.storage.template.TemplateProp;
-import com.cloud.user.AccountManager;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.exception.CloudRuntimeException;
+import javax.inject.Inject;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
 
 @Component
 public class VolumeServiceImpl implements VolumeService {
@@ -103,10 +98,6 @@ public class VolumeServiceImpl implements VolumeService {
     @Inject
     PrimaryDataStoreProviderManager dataStoreMgr;
     @Inject
-    ObjectInDataStoreManager objectInDataStoreMgr;
-    @Inject
-    DataObjectManager dataObjectMgr;
-    @Inject
     DataMotionService motionSrv;
     @Inject
     VolumeDataFactory volFactory;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
index e11e766..0e2423e 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
@@ -16,39 +16,6 @@
 // under the License.
 package com.cloud.hypervisor.vmware.manager;
 
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.OutputStreamWriter;
-import java.rmi.RemoteException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.UUID;
-
-import org.apache.log4j.Logger;
-
-import com.vmware.vim25.FileInfo;
-import com.vmware.vim25.FileQueryFlags;
-import com.vmware.vim25.HostDatastoreBrowserSearchResults;
-import com.vmware.vim25.HostDatastoreBrowserSearchSpec;
-import com.vmware.vim25.ManagedObjectReference;
-import com.vmware.vim25.TaskInfo;
-import com.vmware.vim25.VirtualDeviceConfigSpec;
-import com.vmware.vim25.VirtualDeviceConfigSpecOperation;
-import com.vmware.vim25.VirtualDisk;
-import com.vmware.vim25.VirtualLsiLogicController;
-import com.vmware.vim25.VirtualMachineConfigSpec;
-import com.vmware.vim25.VirtualMachineFileInfo;
-import com.vmware.vim25.VirtualMachineGuestOsIdentifier;
-import com.vmware.vim25.VirtualSCSISharing;
-
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.BackupSnapshotAnswer;
 import com.cloud.agent.api.BackupSnapshotCommand;
@@ -73,7 +40,6 @@ import com.cloud.agent.api.to.DataStoreTO;
 import com.cloud.agent.api.to.DataTO;
 import com.cloud.agent.api.to.NfsTO;
 import com.cloud.agent.api.to.StorageFilerTO;
-import com.cloud.agent.api.to.VolumeTO;
 import com.cloud.hypervisor.vmware.mo.CustomFieldConstants;
 import com.cloud.hypervisor.vmware.mo.DatacenterMO;
 import com.cloud.hypervisor.vmware.mo.DatastoreMO;
@@ -97,6 +63,29 @@ import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.script.Script;
 import com.cloud.vm.VirtualMachine;
 import com.cloud.vm.snapshot.VMSnapshot;
+import com.vmware.vim25.FileInfo;
+import com.vmware.vim25.FileQueryFlags;
+import com.vmware.vim25.HostDatastoreBrowserSearchResults;
+import com.vmware.vim25.HostDatastoreBrowserSearchSpec;
+import com.vmware.vim25.ManagedObjectReference;
+import com.vmware.vim25.TaskInfo;
+import com.vmware.vim25.VirtualDisk;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.log4j.Logger;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.rmi.RemoteException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.UUID;
 
 public class VmwareStorageManagerImpl implements VmwareStorageManager {
     @Override
@@ -1280,7 +1269,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
 
     @Override
     public CreateVMSnapshotAnswer execute(VmwareHostService hostService, CreateVMSnapshotCommand cmd) {
-        List<VolumeTO> volumeTOs = cmd.getVolumeTOs();
+        List<VolumeObjectTO> volumeTOs = cmd.getVolumeTOs();
         String vmName = cmd.getVmName();
         String vmSnapshotName = cmd.getTarget().getSnapshotName();
         String vmSnapshotDesc = cmd.getTarget().getDescription();
@@ -1330,19 +1319,20 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
                         mapNewDisk.put(baseName, vmdkName);
                     }
                 }
-                for (VolumeTO volumeTO : volumeTOs) {
+                for (VolumeObjectTO volumeTO : volumeTOs) {
                     String baseName = extractSnapshotBaseFileName(volumeTO.getPath());
                     String newPath = mapNewDisk.get(baseName);
                     // get volume's chain size for this VM snapshot, exclude current volume vdisk
+                    DataStoreTO store = volumeTO.getDataStore();
                     long size = getVMSnapshotChainSize(context,hyperHost,baseName + "*.vmdk",
-                            volumeTO.getPoolUuid(), newPath);
+                            store.getUuid(), newPath);
 
-                    if(volumeTO.getType()== Volume.Type.ROOT){
+                    if(volumeTO.getVolumeType()== Volume.Type.ROOT){
                         // add memory snapshot size
-                        size = size + getVMSnapshotChainSize(context,hyperHost,cmd.getVmName()+"*.vmsn",volumeTO.getPoolUuid(),null);
+                        size = size + getVMSnapshotChainSize(context,hyperHost,cmd.getVmName()+"*.vmsn",store.getUuid(),null);
                     }
 
-                    volumeTO.setChainSize(size);
+                    volumeTO.setSize(size);
                     volumeTO.setPath(newPath);
                 }
                 return new CreateVMSnapshotAnswer(cmd, cmd.getTarget(), volumeTOs);
@@ -1362,7 +1352,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
 
     @Override
     public DeleteVMSnapshotAnswer execute(VmwareHostService hostService, DeleteVMSnapshotCommand cmd) {
-        List<VolumeTO> listVolumeTo = cmd.getVolumeTOs();
+        List<VolumeObjectTO> listVolumeTo = cmd.getVolumeTOs();
         VirtualMachineMO vmMo = null;
         VmwareContext context = hostService.getServiceContext(cmd);
         Map<String, String> mapNewDisk = new HashMap<String, String>();
@@ -1403,16 +1393,17 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
                         mapNewDisk.put(baseName, vmdkName);
                     }
                 }
-                for (VolumeTO volumeTo : listVolumeTo) {
+                for (VolumeObjectTO volumeTo : listVolumeTo) {
                     String baseName = extractSnapshotBaseFileName(volumeTo.getPath());
                     String newPath = mapNewDisk.get(baseName);
+                    DataStoreTO store = volumeTo.getDataStore();
                     long size = getVMSnapshotChainSize(context,hyperHost,
-                            baseName + "*.vmdk", volumeTo.getPoolUuid(), newPath);
-                    if(volumeTo.getType()== Volume.Type.ROOT){
+                            baseName + "*.vmdk", store.getUuid(), newPath);
+                    if(volumeTo.getVolumeType()== Volume.Type.ROOT){
                         // add memory snapshot size
-                        size = size + getVMSnapshotChainSize(context,hyperHost,cmd.getVmName()+"*.vmsn",volumeTo.getPoolUuid(),null);
+                        size = size + getVMSnapshotChainSize(context,hyperHost,cmd.getVmName()+"*.vmsn",volumeTo.getUuid(),null);
                     }
-                    volumeTo.setChainSize(size);
+                    volumeTo.setSize(size);
                     volumeTo.setPath(newPath);
                 }
                 return new DeleteVMSnapshotAnswer(cmd, listVolumeTo);
@@ -1429,7 +1420,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
         String snapshotName = cmd.getTarget().getSnapshotName();
         String vmName = cmd.getVmName();
         Boolean snapshotMemory = cmd.getTarget().getType() == VMSnapshot.Type.DiskAndMemory;
-        List<VolumeTO> listVolumeTo = cmd.getVolumeTOs();
+        List<VolumeObjectTO> listVolumeTo = cmd.getVolumeTOs();
         VirtualMachine.State vmState = VirtualMachine.State.Running;
         VirtualMachineMO vmMo = null;
         VmwareContext context = hostService.getServiceContext(cmd);
@@ -1483,7 +1474,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
                         }
                     }
                     String key = null;
-                    for (VolumeTO volumeTo : listVolumeTo) {
+                    for (VolumeObjectTO volumeTo : listVolumeTo) {
                         String parentUUID = volumeTo.getPath();
                         String[] s = parentUUID.split("-");
                         key = s[0];

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
index 0ac8b1c..c6a35cc 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
@@ -734,7 +734,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
 
     private Answer execute(RevertToVMSnapshotCommand cmd) {
         String vmName = cmd.getVmName();
-        List<VolumeTO> listVolumeTo = cmd.getVolumeTOs();
+        List<VolumeObjectTO> listVolumeTo = cmd.getVolumeTOs();
         VMSnapshot.Type vmSnapshotType = cmd.getTarget().getType();
         Boolean snapshotMemory = vmSnapshotType == VMSnapshot.Type.DiskAndMemory;
         Connection conn = getConnection();
@@ -786,7 +786,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             }
 
             // after revert, VM's volumes path have been changed, need to report to manager
-            for (VolumeTO volumeTo : listVolumeTo) {
+            for (VolumeObjectTO volumeTo : listVolumeTo) {
                 Long deviceId = volumeTo.getDeviceId();
                 VDI vdi = vdiMap.get(deviceId.toString());
                 volumeTo.setPath(vdi.getUuid(conn));
@@ -6633,7 +6633,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
 
     }
 
-    private long getVMSnapshotChainSize(Connection conn, VolumeTO volumeTo, String vmName) 
+    private long getVMSnapshotChainSize(Connection conn, VolumeObjectTO volumeTo, String vmName)
             throws BadServerResponse, XenAPIException, XmlRpcException {
         Set<VDI> allvolumeVDIs = VDI.getByNameLabel(conn, volumeTo.getName());
         long size = 0;
@@ -6657,7 +6657,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
                 continue;
             }
         }
-        if (volumeTo.getType() == Volume.Type.ROOT) {
+        if (volumeTo.getVolumeType() == Volume.Type.ROOT) {
             Map<VM, VM.Record> allVMs = VM.getAllRecords(conn);
             // add size of memory snapshot vdi
             if (allVMs.size() > 0) {
@@ -6690,7 +6690,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
     protected Answer execute(final CreateVMSnapshotCommand cmd) {
         String vmName = cmd.getVmName();
         String vmSnapshotName = cmd.getTarget().getSnapshotName();
-        List<VolumeTO> listVolumeTo = cmd.getVolumeTOs();
+        List<VolumeObjectTO> listVolumeTo = cmd.getVolumeTOs();
         VirtualMachine.State vmState = cmd.getVmState();
         String guestOSType = cmd.getGuestOSType();
 
@@ -6770,9 +6770,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
 
             }
             // calculate used capacity for this VM snapshot
-            for (VolumeTO volumeTo : cmd.getVolumeTOs()){
+            for (VolumeObjectTO volumeTo : cmd.getVolumeTOs()){
                 long size = getVMSnapshotChainSize(conn,volumeTo,cmd.getVmName());
-                volumeTo.setChainSize(size);
+                volumeTo.setSize(size);
             }
             
             success = true;
@@ -6821,7 +6821,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
     }
 
     private VM createWorkingVM(Connection conn, String vmName,
-            String guestOSType, List<VolumeTO> listVolumeTo)
+            String guestOSType, List<VolumeObjectTO> listVolumeTo)
                     throws BadServerResponse, VmBadPowerState, SrFull,
                     OperationNotAllowed, XenAPIException, XmlRpcException {
         String guestOsTypeName = getGuestOsType(guestOSType, false);
@@ -6835,8 +6835,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         VM template = getVM(conn, guestOsTypeName);
         VM vm = template.createClone(conn, vmName);
         vm.setIsATemplate(conn, false);
-        Map<VDI, VolumeTO> vdiMap = new HashMap<VDI, VolumeTO>();
-        for (VolumeTO volume : listVolumeTo) {
+        Map<VDI, VolumeObjectTO> vdiMap = new HashMap<VDI, VolumeObjectTO>();
+        for (VolumeObjectTO volume : listVolumeTo) {
             String vdiUuid = volume.getPath();
             try {
                 VDI vdi = VDI.getByUuid(conn, vdiUuid);
@@ -6847,11 +6847,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             }
         }
         for (VDI vdi : vdiMap.keySet()) {
-            VolumeTO volumeTO = vdiMap.get(vdi);
+            VolumeObjectTO volumeTO = vdiMap.get(vdi);
             VBD.Record vbdr = new VBD.Record();
             vbdr.VM = vm;
             vbdr.VDI = vdi;
-            if (volumeTO.getType() == Volume.Type.ROOT) {
+            if (volumeTO.getVolumeType() == Volume.Type.ROOT) {
                 vbdr.bootable = true;
                 vbdr.unpluggable = false;
             } else {
@@ -6898,9 +6898,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
 
             }
             // re-calculate used capacify for this VM snapshot
-            for (VolumeTO volumeTo : cmd.getVolumeTOs()){
+            for (VolumeObjectTO volumeTo : cmd.getVolumeTOs()){
                 long size = getVMSnapshotChainSize(conn,volumeTo,cmd.getVmName());
-                volumeTo.setChainSize(size);
+                volumeTo.setSize(size);
             }
             
             return new DeleteVMSnapshotAnswer(cmd, cmd.getVolumeTOs());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
index dade983..9de0031 100755
--- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
+++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
@@ -342,8 +342,6 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
         return snapshot;
     }
 
-
-
     @Override
     public Snapshot backupSnapshot(Long snapshotId) {
         SnapshotInfo snapshot = snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Image);
@@ -354,97 +352,6 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
         return snapshotSrv.backupSnapshot(snapshot);
     }
 
-    /*
-    @Override
-    public void downloadSnapshotsFromSwift(SnapshotVO ss) {
-
-        long volumeId = ss.getVolumeId();
-        VolumeVO volume = _volsDao.findById(volumeId);
-        Long dcId = volume.getDataCenterId();
-        Long accountId = volume.getAccountId();
-        DataStore secStore = this.dataStoreMgr.getImageStore(dcId);
-
-        Long swiftId = ss.getSwiftId();
-        SwiftTO swift = _swiftMgr.getSwiftTO(swiftId);
-        SnapshotVO tss = ss;
-        List<String> BackupUuids = new ArrayList<String>(30);
-        while (true) {
-            BackupUuids.add(0, tss.getBackupSnapshotId());
-            if (tss.getPrevSnapshotId() == 0)
-                break;
-            Long id = tss.getPrevSnapshotId();
-            tss = _snapshotDao.findById(id);
-            assert tss != null : " can not find snapshot " + id;
-        }
-        String parent = null;
-        try {
-            for (String backupUuid : BackupUuids) {
-<<<<<<< HEAD
-                downloadSnapshotFromSwiftCommand cmd = new downloadSnapshotFromSwiftCommand(swift, secStore.getUri(), dcId, accountId, volumeId, parent, backupUuid, _backupsnapshotwait);
-=======
-                 DownloadSnapshotFromSwiftCommand cmd = new DownloadSnapshotFromSwiftCommand(swift, secondaryStoragePoolUrl, dcId, accountId, volumeId, parent, backupUuid, _backupsnapshotwait);
->>>>>>> master
-                Answer answer = _agentMgr.sendToSSVM(dcId, cmd);
-                if ((answer == null) || !answer.getResult()) {
-                    throw new CloudRuntimeException("downloadSnapshotsFromSwift failed ");
-                }
-                parent = backupUuid;
-            }
-        } catch (Exception e) {
-            throw new CloudRuntimeException("downloadSnapshotsFromSwift failed due to " + e.toString());
-        }
-
-    }
-
-    private List<String> determineBackupUuids(final SnapshotVO snapshot) {
-
-        final List<String> backupUuids = new ArrayList<String>();
-        backupUuids.add(0, snapshot.getBackupSnapshotId());
-
-        SnapshotVO tempSnapshot = snapshot;
-        while (tempSnapshot.getPrevSnapshotId() != 0) {
-            tempSnapshot = _snapshotDao.findById(tempSnapshot
-                    .getPrevSnapshotId());
-            backupUuids.add(0, tempSnapshot.getBackupSnapshotId());
-        }
-
-        return Collections.unmodifiableList(backupUuids);
-    }
-
-    @Override
-    public void downloadSnapshotsFromS3(final SnapshotVO snapshot) {
-
-        final VolumeVO volume = _volsDao.findById(snapshot.getVolumeId());
-        final Long zoneId = volume.getDataCenterId();
-        final DataStore secStore = this.dataStoreMgr.getImageStore(zoneId);
-
-        final S3TO s3 = _s3Mgr.getS3TO(snapshot.getS3Id());
-        final List<String> backupUuids = determineBackupUuids(snapshot);
-
-        try {
-            String parent = null;
-            for (final String backupUuid : backupUuids) {
-                final DownloadSnapshotFromS3Command cmd = new DownloadSnapshotFromS3Command(
-                        s3, parent, secStore.getUri(), zoneId,
-                        volume.getAccountId(), volume.getId(), backupUuid,
-                        _backupsnapshotwait);
-                final Answer answer = _agentMgr.sendToSSVM(zoneId, cmd);
-                if ((answer == null) || !answer.getResult()) {
-                    throw new CloudRuntimeException(String.format(
-                            "S3 snapshot download failed due to %1$s.",
-                            answer != null ? answer.getDetails()
-                                    : "unspecified error"));
-                }
-                parent = backupUuid;
-            }
-        } catch (Exception e) {
-            throw new CloudRuntimeException(
-                    "Snapshot download from S3 failed due to " + e.toString(),
-                    e);
-        }
-
-    }*/
-
     @Override
     public SnapshotVO getParentSnapshot(VolumeInfo volume) {
         long preId = _snapshotDao.getLastSnapshot(volume.getId(), DataStoreRole.Primary);
@@ -546,7 +453,6 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
         }
     }
 
-
     @Override
     public String getSecondaryStorageURL(SnapshotVO snapshot) {
         SnapshotDataStoreVO snapshotStore = _snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Image);
@@ -672,7 +578,6 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
         return new Pair<List<? extends Snapshot>, Integer>(result.first(), result.second());
     }
 
-
     @Override
     public boolean deleteSnapshotDirsForAccount(long accountId) {
 
@@ -942,8 +847,6 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
         return null;
     }
 
-
-
     private boolean hostSupportSnapsthotForVolume(HostVO host, VolumeInfo volume) {
         if (host.getHypervisorType() != HypervisorType.KVM) {
             return true;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
index aa772fe..7a200ff 100644
--- a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
+++ b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
@@ -17,82 +17,34 @@
 
 package com.cloud.vm.snapshot;
 
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.ejb.Local;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.CreateVMSnapshotAnswer;
-import com.cloud.agent.api.CreateVMSnapshotCommand;
-import com.cloud.agent.api.DeleteVMSnapshotAnswer;
-import com.cloud.agent.api.DeleteVMSnapshotCommand;
-import com.cloud.agent.api.RevertToVMSnapshotAnswer;
-import com.cloud.agent.api.RevertToVMSnapshotCommand;
-import com.cloud.agent.api.VMSnapshotTO;
-import com.cloud.agent.api.to.VolumeTO;
 import com.cloud.event.ActionEvent;
 import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.exception.AgentUnavailableException;
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InsufficientCapacityException;
 import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.OperationTimedoutException;
 import com.cloud.exception.ResourceAllocationException;
 import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.HypervisorGuruManager;
 import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
 import com.cloud.projects.Project.ListProjectResourcesCriteria;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.DiskOfferingVO;
-import com.cloud.storage.GuestOSVO;
 import com.cloud.storage.Snapshot;
 import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.StoragePool;
 import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.DiskOfferingDao;
 import com.cloud.storage.dao.GuestOSDao;
 import com.cloud.storage.dao.SnapshotDao;
 import com.cloud.storage.dao.VolumeDao;
 import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
 import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.UserDao;
 import com.cloud.uservm.UserVm;
 import com.cloud.utils.DateUtil;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Ternary;
 import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
 import com.cloud.utils.db.Filter;
 import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
 import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.utils.fsm.StateMachine2;
 import com.cloud.vm.UserVmVO;
 import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.VirtualMachine;
@@ -100,8 +52,22 @@ import com.cloud.vm.VirtualMachine.State;
 import com.cloud.vm.VirtualMachineManager;
 import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.VMInstanceDao;
 import com.cloud.vm.snapshot.dao.VMSnapshotDao;
+import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.subsystem.api.storage.VMSnapshotStrategy;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 @Component
 @Local(value = { VMSnapshotManager.class, VMSnapshotService.class })
@@ -111,25 +77,27 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
     @Inject VMSnapshotDao _vmSnapshotDao;
     @Inject VolumeDao _volumeDao;
     @Inject AccountDao _accountDao;
-    @Inject VMInstanceDao _vmInstanceDao;
     @Inject UserVmDao _userVMDao;
-    @Inject HostDao _hostDao;
-    @Inject UserDao _userDao;
-    @Inject AgentManager _agentMgr;
-    @Inject HypervisorGuruManager _hvGuruMgr;
     @Inject AccountManager _accountMgr;
     @Inject GuestOSDao _guestOSDao;
-    @Inject PrimaryDataStoreDao _storagePoolDao;
     @Inject SnapshotDao _snapshotDao;
     @Inject VirtualMachineManager _itMgr;
-    @Inject DataStoreManager dataStoreMgr;
     @Inject ConfigurationDao _configDao;
     @Inject HypervisorCapabilitiesDao _hypervisorCapabilitiesDao;
-    @Inject DiskOfferingDao _diskOfferingDao;
-    @Inject ServiceOfferingDao _serviceOfferingDao;
+    @Inject List<VMSnapshotStrategy> vmSnapshotStrategies;
+
+    public List<VMSnapshotStrategy> getVmSnapshotStrategies() {
+        return vmSnapshotStrategies;
+    }
+
+    @Inject
+    public void setVmSnapshotStrategies(List<VMSnapshotStrategy> vmSnapshotStrategies) {
+        this.vmSnapshotStrategies = vmSnapshotStrategies;
+    }
+
     int _vmSnapshotMax;
     int _wait;
-    StateMachine2<VMSnapshot.State, VMSnapshot.Event, VMSnapshot> _vmSnapshottateMachine ;
+
 
     @Override
     public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
@@ -144,7 +112,6 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
         String value = _configDao.getValue("vmsnapshot.create.wait");
         _wait = NumbersUtil.parseInt(value, 1800);
 
-        _vmSnapshottateMachine   = VMSnapshot.State.getStateMachine();
         return true;
     }
 
@@ -336,6 +303,22 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
         return _name;
     }
 
+    private VMSnapshotStrategy findVMSnapshotStrategy(VMSnapshot vmSnapshot) {
+        VMSnapshotStrategy snapshotStrategy = null;
+        for(VMSnapshotStrategy strategy : vmSnapshotStrategies) {
+            if (strategy.canHandle(vmSnapshot)) {
+                snapshotStrategy = strategy;
+                break;
+            }
+        }
+
+        if (snapshotStrategy == null) {
+            throw new CloudRuntimeException("can't find vm snapshot strategy for vmsnapshot: " + vmSnapshot.getId());
+        }
+
+        return snapshotStrategy;
+    }
+
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_VM_SNAPSHOT_CREATE, eventDescription = "creating VM snapshot", async = true)
     public VMSnapshot creatVMSnapshot(Long vmId, Long vmSnapshotId) {
@@ -347,241 +330,21 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
         if(vmSnapshot == null){
             throw new CloudRuntimeException("VM snapshot id: " + vmSnapshotId + " can not be found");
         }
-        Long hostId = pickRunningHost(vmId);
-        try {
-            vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.CreateRequested);
-        } catch (NoTransitionException e) {
-            throw new CloudRuntimeException(e.getMessage());
-        }
-        return createVmSnapshotInternal(userVm, vmSnapshot, hostId);
-    }
-
-    protected VMSnapshot createVmSnapshotInternal(UserVmVO userVm, VMSnapshotVO vmSnapshot, Long hostId) {
-        CreateVMSnapshotAnswer answer = null;
-        try {
-            GuestOSVO guestOS = _guestOSDao.findById(userVm.getGuestOSId());
-            
-            // prepare snapshotVolumeTos
-            List<VolumeTO> volumeTOs = getVolumeTOList(userVm.getId());
-            
-            // prepare target snapshotTO and its parent snapshot (current snapshot)
-            VMSnapshotTO current = null;
-            VMSnapshotVO currentSnapshot = _vmSnapshotDao.findCurrentSnapshotByVmId(userVm.getId());
-            if (currentSnapshot != null)
-                current = getSnapshotWithParents(currentSnapshot);
-            VMSnapshotTO target = new VMSnapshotTO(vmSnapshot.getId(),  vmSnapshot.getName(), vmSnapshot.getType(), null, vmSnapshot.getDescription(), false,
-                    current);
-            if (current == null)
-                vmSnapshot.setParent(null);
-            else
-                vmSnapshot.setParent(current.getId());
-
-            CreateVMSnapshotCommand ccmd = new CreateVMSnapshotCommand(userVm.getInstanceName(),target ,volumeTOs, guestOS.getDisplayName(),userVm.getState());
-            ccmd.setWait(_wait);
-            
-            answer = (CreateVMSnapshotAnswer) sendToPool(hostId, ccmd);
-            if (answer != null && answer.getResult()) {
-                processAnswer(vmSnapshot, userVm, answer, hostId);
-                s_logger.debug("Create vm snapshot " + vmSnapshot.getName() + " succeeded for vm: " + userVm.getInstanceName());
-            }else{
-                
-                String errMsg = "Creating VM snapshot: " + vmSnapshot.getName() + " failed";
-                if(answer != null && answer.getDetails() != null)
-                    errMsg = errMsg + " due to " + answer.getDetails();
-                s_logger.error(errMsg);
-                vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationFailed);
-                throw new CloudRuntimeException(errMsg);
-            }
-            return vmSnapshot;
-        } catch (Exception e) {
-            if(e instanceof AgentUnavailableException){
-                try {
-                    vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationFailed);
-                } catch (NoTransitionException e1) {
-                    s_logger.error("Cannot set vm snapshot state due to: " + e1.getMessage());
-                }
-            }
-            String msg = e.getMessage();
-            s_logger.error("Create vm snapshot " + vmSnapshot.getName() + " failed for vm: " + userVm.getInstanceName() + " due to " + msg);
-            throw new CloudRuntimeException(msg);
-        } finally{
-            if(vmSnapshot.getState() == VMSnapshot.State.Allocated){
-                s_logger.warn("Create vm snapshot " + vmSnapshot.getName() + " failed for vm: " + userVm.getInstanceName());
-                _vmSnapshotDao.remove(vmSnapshot.getId());
-            }
-            if(vmSnapshot.getState() == VMSnapshot.State.Ready && answer != null){
-                for (VolumeTO volumeTo : answer.getVolumeTOs()){
-                    publishUsageEvent(EventTypes.EVENT_VM_SNAPSHOT_CREATE,vmSnapshot,userVm,volumeTo);
-                }
-            }
-        }
-    }
-
-    private void publishUsageEvent(String type, VMSnapshot vmSnapshot, UserVm userVm, VolumeTO volumeTo){
-        VolumeVO volume = _volumeDao.findById(volumeTo.getId());
-        Long diskOfferingId = volume.getDiskOfferingId();
-        Long offeringId = null;
-        if (diskOfferingId != null) {
-            DiskOfferingVO offering = _diskOfferingDao.findById(diskOfferingId);
-            if (offering != null
-                    && (offering.getType() == DiskOfferingVO.Type.Disk)) {
-                offeringId = offering.getId();
-            }
-        }
-        UsageEventUtils.publishUsageEvent(
-                type,
-                vmSnapshot.getAccountId(),
-                userVm.getDataCenterId(),
-                userVm.getId(),
-                vmSnapshot.getName(),
-                offeringId,     
-                volume.getId(), // save volume's id into templateId field
-                volumeTo.getChainSize(),
-                VMSnapshot.class.getName(), vmSnapshot.getUuid());       
-    }
-    
-    protected List<VolumeTO> getVolumeTOList(Long vmId) {
-        List<VolumeTO> volumeTOs = new ArrayList<VolumeTO>();
-        List<VolumeVO> volumeVos = _volumeDao.findByInstance(vmId);
-        
-        for (VolumeVO volume : volumeVos) {
-            StoragePool pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(volume.getPoolId());
-            VolumeTO volumeTO = new VolumeTO(volume, pool);
-            volumeTOs.add(volumeTO);
-        }
-        return volumeTOs;
-    }
-
-    // get snapshot and its parents recursively
-    private VMSnapshotTO getSnapshotWithParents(VMSnapshotVO snapshot) {
-        Map<Long, VMSnapshotVO> snapshotMap = new HashMap<Long, VMSnapshotVO>();
-        List<VMSnapshotVO> allSnapshots = _vmSnapshotDao.findByVm(snapshot.getVmId());
-        for (VMSnapshotVO vmSnapshotVO : allSnapshots) {
-            snapshotMap.put(vmSnapshotVO.getId(), vmSnapshotVO);
-        }
-
-        VMSnapshotTO currentTO = convert2VMSnapshotTO(snapshot);
-        VMSnapshotTO result = currentTO;
-        VMSnapshotVO current = snapshot;
-        while (current.getParent() != null) {
-            VMSnapshotVO parent = snapshotMap.get(current.getParent());
-            currentTO.setParent(convert2VMSnapshotTO(parent));
-            current = snapshotMap.get(current.getParent());
-            currentTO = currentTO.getParent();
-        }
-        return result;
-    }
 
-    private VMSnapshotTO convert2VMSnapshotTO(VMSnapshotVO vo) {
-        return new VMSnapshotTO(vo.getId(), vo.getName(),  vo.getType(), vo.getCreated().getTime(), vo.getDescription(),
-                vo.getCurrent(), null);
-    }
-
-    protected boolean vmSnapshotStateTransitTo(VMSnapshotVO vsnp, VMSnapshot.Event event) throws NoTransitionException {
-        return _vmSnapshottateMachine.transitTo(vsnp, event, null, _vmSnapshotDao);
-    }
-    
-    @DB
-    protected void processAnswer(VMSnapshotVO vmSnapshot, UserVmVO  userVm, Answer as, Long hostId) {
-        final Transaction txn = Transaction.currentTxn();
         try {
-            txn.start();
-            if (as instanceof CreateVMSnapshotAnswer) {
-                CreateVMSnapshotAnswer answer = (CreateVMSnapshotAnswer) as;
-                finalizeCreate(vmSnapshot, answer.getVolumeTOs());
-                vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded);
-            } else if (as instanceof RevertToVMSnapshotAnswer) {
-                RevertToVMSnapshotAnswer answer = (RevertToVMSnapshotAnswer) as;
-                finalizeRevert(vmSnapshot, answer.getVolumeTOs());
-                vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded);
-            } else if (as instanceof DeleteVMSnapshotAnswer) {
-                DeleteVMSnapshotAnswer answer = (DeleteVMSnapshotAnswer) as;
-                finalizeDelete(vmSnapshot, answer.getVolumeTOs());
-                _vmSnapshotDao.remove(vmSnapshot.getId());
-            }
-            txn.commit();
+            VMSnapshotStrategy strategy = findVMSnapshotStrategy(vmSnapshot);
+            VMSnapshot snapshot = strategy.takeVMSnapshot(vmSnapshot);
+            return snapshot;
         } catch (Exception e) {
-            String errMsg = "Error while process answer: " + as.getClass() + " due to " + e.getMessage();
-            s_logger.error(errMsg, e);
-            txn.rollback();
-            throw new CloudRuntimeException(errMsg);
-        } finally {
-            txn.close();
-        }
-    }
-
-    protected void finalizeDelete(VMSnapshotVO vmSnapshot, List<VolumeTO> VolumeTOs) {
-        // update volumes path
-        updateVolumePath(VolumeTOs);
-        
-        // update children's parent snapshots
-        List<VMSnapshotVO> children= _vmSnapshotDao.listByParent(vmSnapshot.getId());
-        for (VMSnapshotVO child : children) {
-            child.setParent(vmSnapshot.getParent());
-            _vmSnapshotDao.persist(child);
+            s_logger.debug("Failed to create vm snapshot: " + vmSnapshotId ,e);
+            return null;
         }
-        
-        // update current snapshot
-        VMSnapshotVO current = _vmSnapshotDao.findCurrentSnapshotByVmId(vmSnapshot.getVmId());
-        if(current != null && current.getId() == vmSnapshot.getId() && vmSnapshot.getParent() != null){
-            VMSnapshotVO parent = _vmSnapshotDao.findById(vmSnapshot.getParent());
-            parent.setCurrent(true);
-            _vmSnapshotDao.persist(parent);
-        }
-        vmSnapshot.setCurrent(false);
-        _vmSnapshotDao.persist(vmSnapshot);
-    }
-
-    protected void finalizeCreate(VMSnapshotVO vmSnapshot, List<VolumeTO> VolumeTOs) {
-        // update volumes path
-        updateVolumePath(VolumeTOs);
-        
-        vmSnapshot.setCurrent(true);
-        
-        // change current snapshot
-        if (vmSnapshot.getParent() != null) {
-            VMSnapshotVO previousCurrent = _vmSnapshotDao.findById(vmSnapshot.getParent());
-            previousCurrent.setCurrent(false);
-            _vmSnapshotDao.persist(previousCurrent);
-        }
-        _vmSnapshotDao.persist(vmSnapshot);
-    }
-
-    protected void finalizeRevert(VMSnapshotVO vmSnapshot, List<VolumeTO> volumeToList) {
-        // update volumes path
-        updateVolumePath(volumeToList);
-
-        // update current snapshot, current snapshot is the one reverted to
-        VMSnapshotVO previousCurrent = _vmSnapshotDao.findCurrentSnapshotByVmId(vmSnapshot.getVmId());
-        if(previousCurrent != null){
-            previousCurrent.setCurrent(false);
-            _vmSnapshotDao.persist(previousCurrent);
-        }
-        vmSnapshot.setCurrent(true);
-        _vmSnapshotDao.persist(vmSnapshot);
     }
 
-    private void updateVolumePath(List<VolumeTO> volumeTOs) {
-        for (VolumeTO volume : volumeTOs) {
-            if (volume.getPath() != null) {
-                VolumeVO volumeVO = _volumeDao.findById(volume.getId());
-                volumeVO.setPath(volume.getPath());
-                volumeVO.setVmSnapshotChainSize(volume.getChainSize());
-                _volumeDao.persist(volumeVO);
-            }
-        }
-    }
-    
     public VMSnapshotManagerImpl() {
         
     }
-    
-    protected Answer sendToPool(Long hostId, Command cmd) throws AgentUnavailableException, OperationTimedoutException {
-        long targetHostId = _hvGuruMgr.getGuruProcessedCommandTargetHost(hostId, cmd);
-        Answer answer = _agentMgr.send(targetHostId, cmd);
-        return answer;
-    }
-    
+
     @Override
     public boolean hasActiveVMSnapshotTasks(Long vmId){
         List<VMSnapshotVO> activeVMSnapshots = _vmSnapshotDao.listByInstanceId(vmId,
@@ -617,50 +380,14 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
 
         if(vmSnapshot.getState() == VMSnapshot.State.Allocated){
             return _vmSnapshotDao.remove(vmSnapshot.getId());
-        }else{
-            return deleteSnapshotInternal(vmSnapshot);
-        }
-    }
-
-    @DB
-    protected boolean deleteSnapshotInternal(VMSnapshotVO vmSnapshot) {
-        UserVmVO userVm = _userVMDao.findById(vmSnapshot.getVmId());
-        DeleteVMSnapshotAnswer answer = null;
-        try {
-            vmSnapshotStateTransitTo(vmSnapshot,VMSnapshot.Event.ExpungeRequested);
-            Long hostId = pickRunningHost(vmSnapshot.getVmId());
-
-            // prepare snapshotVolumeTos
-            List<VolumeTO> volumeTOs = getVolumeTOList(vmSnapshot.getVmId());
-            
-            // prepare DeleteVMSnapshotCommand
-            String vmInstanceName = userVm.getInstanceName();
-            VMSnapshotTO parent = getSnapshotWithParents(vmSnapshot).getParent();
-            VMSnapshotTO vmSnapshotTO = new VMSnapshotTO(vmSnapshot.getId(), vmSnapshot.getName(), vmSnapshot.getType(),
-                    vmSnapshot.getCreated().getTime(), vmSnapshot.getDescription(), vmSnapshot.getCurrent(), parent);
-            GuestOSVO guestOS = _guestOSDao.findById(userVm.getGuestOSId());
-            DeleteVMSnapshotCommand deleteSnapshotCommand = new DeleteVMSnapshotCommand(vmInstanceName, vmSnapshotTO, volumeTOs,guestOS.getDisplayName());
-            
-            answer = (DeleteVMSnapshotAnswer) sendToPool(hostId, deleteSnapshotCommand);
-           
-            if (answer != null && answer.getResult()) {
-                processAnswer(vmSnapshot, userVm, answer, hostId);
-                s_logger.debug("Delete VM snapshot " + vmSnapshot.getName() + " succeeded for vm: " + userVm.getInstanceName());
-                return true;
-            } else {
-                s_logger.error("Delete vm snapshot " + vmSnapshot.getName() + " of vm " + userVm.getInstanceName() + " failed due to " + answer.getDetails());
+        } else{
+            try {
+                VMSnapshotStrategy strategy = findVMSnapshotStrategy(vmSnapshot);
+                return strategy.deleteVMSnapshot(vmSnapshot);
+            } catch (Exception e) {
+                s_logger.debug("Failed to delete vm snapshot: " + vmSnapshotId, e);
                 return false;
             }
-        } catch (Exception e) {
-            String msg = "Delete vm snapshot " + vmSnapshot.getName() + " of vm " + userVm.getInstanceName() + " failed due to " + e.getMessage();
-            s_logger.error(msg , e);
-            throw new CloudRuntimeException(e.getMessage());
-        } finally{
-            if(answer != null && answer.getResult()){
-                for (VolumeTO volumeTo : answer.getVolumeTOs()){
-                    publishUsageEvent(EventTypes.EVENT_VM_SNAPSHOT_DELETE,vmSnapshot,userVm,volumeTo);
-                }
-            }
         }
     }
 
@@ -726,108 +453,29 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
                     throw new CloudRuntimeException(e.getMessage());
                 }
             }
-            hostId = pickRunningHost(userVm.getId());
         }
-        
-        if(hostId == null)
-            throw new CloudRuntimeException("Can not find any host to revert snapshot " + vmSnapshotVo.getName());
-        
+
         // check if there are other active VM snapshot tasks
         if (hasActiveVMSnapshotTasks(userVm.getId())) {
             throw new InvalidParameterValueException("There is other active vm snapshot tasks on the instance, please try again later");
         }
-        
-        userVm = _userVMDao.findById(userVm.getId());
-        try {
-            vmSnapshotStateTransitTo(vmSnapshotVo, VMSnapshot.Event.RevertRequested);
-        } catch (NoTransitionException e) {
-            throw new CloudRuntimeException(e.getMessage());
-        }
-        return revertInternal(userVm, vmSnapshotVo, hostId);
-    }
 
-    private UserVm revertInternal(UserVmVO userVm, VMSnapshotVO vmSnapshotVo, Long hostId) {
         try {
-            VMSnapshotVO snapshot = _vmSnapshotDao.findById(vmSnapshotVo.getId());
-            // prepare RevertToSnapshotCommand
-            List<VolumeTO> volumeTOs = getVolumeTOList(userVm.getId());
-            String vmInstanceName = userVm.getInstanceName();
-            VMSnapshotTO parent = getSnapshotWithParents(snapshot).getParent();
-            VMSnapshotTO vmSnapshotTO = new VMSnapshotTO(snapshot.getId(), snapshot.getName(), snapshot.getType(), 
-                    snapshot.getCreated().getTime(), snapshot.getDescription(), snapshot.getCurrent(), parent);
-            
-            GuestOSVO guestOS = _guestOSDao.findById(userVm.getGuestOSId());
-            RevertToVMSnapshotCommand revertToSnapshotCommand = new RevertToVMSnapshotCommand(vmInstanceName, vmSnapshotTO, volumeTOs, guestOS.getDisplayName());
-           
-            RevertToVMSnapshotAnswer answer = (RevertToVMSnapshotAnswer) sendToPool(hostId, revertToSnapshotCommand);
-            if (answer != null && answer.getResult()) {
-                processAnswer(vmSnapshotVo, userVm, answer, hostId);
-                s_logger.debug("RevertTo " + vmSnapshotVo.getName() + " succeeded for vm: " + userVm.getInstanceName());
-            } else {
-                String errMsg = "Revert VM: " + userVm.getInstanceName() + " to snapshot: "+ vmSnapshotVo.getName() + " failed";
-                if(answer != null && answer.getDetails() != null)
-                    errMsg = errMsg + " due to " + answer.getDetails();
-                s_logger.error(errMsg);
-                // agent report revert operation fails
-                vmSnapshotStateTransitTo(vmSnapshotVo, VMSnapshot.Event.OperationFailed);
-                throw new CloudRuntimeException(errMsg);
-            }
+            VMSnapshotStrategy strategy = findVMSnapshotStrategy(vmSnapshotVo);
+            strategy.revertVMSnapshot(vmSnapshotVo);
+            return userVm;
         } catch (Exception e) {
-            if(e instanceof AgentUnavailableException){
-                try {
-                    vmSnapshotStateTransitTo(vmSnapshotVo, VMSnapshot.Event.OperationFailed);
-                } catch (NoTransitionException e1) {
-                    s_logger.error("Cannot set vm snapshot state due to: " + e1.getMessage());
-                }
-            }
-            // for other exceptions, do not change VM snapshot state, leave it for snapshotSync
-            String errMsg = "revert vm: " + userVm.getInstanceName() + " to snapshot " + vmSnapshotVo.getName() + " failed due to " + e.getMessage();
-            s_logger.error(errMsg);
-            throw new CloudRuntimeException(e.getMessage());
+            s_logger.debug("Failed to revert vmsnapshot: " + vmSnapshotId, e);
+            return null;
         }
-        return userVm;
     }
 
-
     @Override
     public VMSnapshot getVMSnapshotById(Long id) {
         VMSnapshotVO vmSnapshot = _vmSnapshotDao.findById(id);
         return vmSnapshot;
     }
 
-    protected Long pickRunningHost(Long vmId) {
-        UserVmVO vm = _userVMDao.findById(vmId);
-        // use VM's host if VM is running
-        if(vm.getState() == State.Running)
-            return vm.getHostId();
-        
-        // check if lastHostId is available
-        if(vm.getLastHostId() != null){
-           HostVO lastHost =  _hostDao.findById(vm.getLastHostId());
-           if(lastHost.getStatus() == com.cloud.host.Status.Up && !lastHost.isInMaintenanceStates())
-               return lastHost.getId();
-        }
-        
-        List<VolumeVO> listVolumes = _volumeDao.findByInstance(vmId);
-        if (listVolumes == null || listVolumes.size() == 0) {
-            throw new InvalidParameterValueException("vmInstance has no volumes");
-        }
-        VolumeVO volume = listVolumes.get(0);
-        Long poolId = volume.getPoolId();
-        if (poolId == null) {
-            throw new InvalidParameterValueException("pool id is not found");
-        }
-        StoragePoolVO storagePool = _storagePoolDao.findById(poolId);
-        if (storagePool == null) {
-            throw new InvalidParameterValueException("storage pool is not found");
-        }
-        List<HostVO> listHost = _hostDao.listAllUpAndEnabledNonHAHosts(Host.Type.Routing, storagePool.getClusterId(), storagePool.getPodId(),
-                storagePool.getDataCenterId(), null);
-        if (listHost == null || listHost.size() == 0) {
-            throw new InvalidParameterValueException("no host in up state is found");
-        }
-        return listHost.get(0).getId();
-    }
 
     @Override
     public VirtualMachine getVMBySnapshotId(Long id) {
@@ -851,7 +499,8 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
             VMSnapshotVO target = _vmSnapshotDao.findById(snapshot.getId());
             if(type != null && target.getType() != type)
                 continue;
-            if (!deleteSnapshotInternal(target)) {
+            VMSnapshotStrategy strategy = findVMSnapshotStrategy(target);
+            if (!strategy.deleteVMSnapshot(target)) {
                 result = false;
                 break;
             }
@@ -869,12 +518,13 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
             
             List<VMSnapshotVO> vmSnapshotsInExpungingStates = _vmSnapshotDao.listByInstanceId(vm.getId(), VMSnapshot.State.Expunging, VMSnapshot.State.Reverting, VMSnapshot.State.Creating);
             for (VMSnapshotVO vmSnapshotVO : vmSnapshotsInExpungingStates) {
+                VMSnapshotStrategy strategy = findVMSnapshotStrategy(vmSnapshotVO);
                 if(vmSnapshotVO.getState() == VMSnapshot.State.Expunging){
-                    return deleteSnapshotInternal(vmSnapshotVO);
+                    return strategy.deleteVMSnapshot(vmSnapshotVO);
                 }else if(vmSnapshotVO.getState() == VMSnapshot.State.Creating){
-                    return createVmSnapshotInternal(userVm, vmSnapshotVO, hostId) != null;
+                    return strategy.takeVMSnapshot(vmSnapshotVO) != null;
                 }else if(vmSnapshotVO.getState() == VMSnapshot.State.Reverting){
-                    return revertInternal(userVm, vmSnapshotVO, hostId) != null;
+                    return strategy.revertVMSnapshot(vmSnapshotVO);
                 }
             }
         }catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/server/test/com/cloud/vm/snapshot/VMSnapshotManagerTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vm/snapshot/VMSnapshotManagerTest.java b/server/test/com/cloud/vm/snapshot/VMSnapshotManagerTest.java
index 055b2b0..da6e7af 100644
--- a/server/test/com/cloud/vm/snapshot/VMSnapshotManagerTest.java
+++ b/server/test/com/cloud/vm/snapshot/VMSnapshotManagerTest.java
@@ -192,13 +192,6 @@ public class VMSnapshotManagerTest {
         when(vmMock.getState()).thenReturn(State.Running);
         _vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID,"","",true);
 
-        when(_vmSnapshotDao.findCurrentSnapshotByVmId(anyLong())).thenReturn(null);
-        doReturn(new ArrayList<VolumeTO>()).when(_vmSnapshotMgr).getVolumeTOList(anyLong());
-        doReturn(new CreateVMSnapshotAnswer(null,true,"")).when(_vmSnapshotMgr).sendToPool(anyLong(), any(CreateVMSnapshotCommand.class));
-        doNothing().when(_vmSnapshotMgr).processAnswer(any(VMSnapshotVO.class),
-                any(UserVmVO.class), any(Answer.class), anyLong());
-        doReturn(true).when(_vmSnapshotMgr).vmSnapshotStateTransitTo(any(VMSnapshotVO.class),any(VMSnapshot.Event.class));
-        _vmSnapshotMgr.createVmSnapshotInternal(vmMock, mock(VMSnapshotVO.class), 5L);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/setup/db/db/schema-421to430.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-421to430.sql b/setup/db/db/schema-421to430.sql
index 8e4aa93..d355104 100644
--- a/setup/db/db/schema-421to430.sql
+++ b/setup/db/db/schema-421to430.sql
@@ -39,6 +39,15 @@ ALTER TABLE `cloud`.`vm_instance` ADD COLUMN `power_state_update_count` INT DEFA
 ALTER TABLE `cloud`.`vm_instance` ADD COLUMN `power_host` bigint unsigned;
 ALTER TABLE `cloud`.`vm_instance` ADD CONSTRAINT `fk_vm_instance__power_host` FOREIGN KEY (`power_host`) REFERENCES `cloud`.`host`(`id`);
 
+DROP TABLE IF EXISTS `cloud`.`vm_snapshot_details`;
+CREATE TABLE `cloud`.`vm_snapshot_details` (
+  `id` bigint unsigned UNIQUE NOT NULL,
+  `vm_snapshot_id` bigint unsigned NOT NULL,
+  `name` varchar(255) NOT NULL,
+  `value` varchar(255) NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
 CREATE TABLE `cloud`.`vm_work_job` (
   `id` bigint unsigned UNIQUE NOT NULL,
   `step` char(32) NOT NULL COMMENT 'state',