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/04/23 01:16:56 UTC

[1/2] Rename SnapshotStrategy to SnapshotService to have consistent naming convention for Template, Snapshot, Volume. Also rename CopyCmd to CopyCommand to follow internal command naming convention.

Updated Branches:
  refs/heads/object_store 5f90aa971 -> 29687663e


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/29687663/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 3a453d5..88bcc6a 100755
--- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
+++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
@@ -34,7 +34,7 @@ import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotsCmd;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
@@ -126,8 +126,8 @@ import com.cloud.vm.dao.UserVmDao;
 import com.cloud.vm.snapshot.dao.VMSnapshotDao;
 
 @Component
-@Local(value = { SnapshotManager.class, SnapshotService.class })
-public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, SnapshotService {
+@Local(value = { SnapshotManager.class, SnapshotApiService.class })
+public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, SnapshotApiService {
     private static final Logger s_logger = Logger.getLogger(SnapshotManagerImpl.class);
     @Inject
     protected VMTemplateDao _templateDao;
@@ -171,9 +171,9 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
     private ResourceLimitService _resourceLimitMgr;
     @Inject
     private SwiftManager _swiftMgr;
-    @Inject 
+    @Inject
     private S3Manager _s3Mgr;
-    @Inject 
+    @Inject
     private SecondaryStorageVmManager _ssvmMgr;
     @Inject
     private DomainManager _domainMgr;
@@ -182,17 +182,17 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
     @Inject
     private ConfigurationDao _configDao;
 
-    @Inject 
+    @Inject
     private VMSnapshotDao _vmSnapshotDao;
     String _name;
 
     @Inject TemplateManager templateMgr;
     @Inject VolumeManager volumeMgr;
     @Inject DataStoreManager dataStoreMgr;
-    @Inject List<SnapshotStrategy> snapshotStrategies;
+    @Inject SnapshotService snapshotSrv;
     @Inject VolumeDataFactory volFactory;
     @Inject SnapshotDataFactory snapshotFactory;
-    
+
 
     private int _totalRetries;
     private int _pauseInterval;
@@ -201,14 +201,14 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
 
     protected SearchBuilder<SnapshotVO> PolicySnapshotSearch;
     protected SearchBuilder<SnapshotPolicyVO> PoliciesForSnapSearch;
-    
+
     @Override
     public Answer sendToPool(Volume vol, Command cmd) {
         StoragePool pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(vol.getPoolId());
         long[] hostIdsToTryFirst = null;
-        
+
         Long vmHostId = getHostIdForSnapshotOperation(vol);
-                
+
         if (vmHostId != null) {
             hostIdsToTryFirst = new long[] { vmHostId };
         }
@@ -263,29 +263,22 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
         if (volume == null) {
         	throw new InvalidParameterValueException("No such volume exist");
         }
-        
+
         if (volume.getState() != Volume.State.Ready) {
         	throw new InvalidParameterValueException("Volume is not in ready state");
         }
-        
+
         SnapshotInfo snapshot = null;
-     
+
         boolean backedUp = false;
         // does the caller have the authority to act on this volume
         _accountMgr.checkAccess(UserContext.current().getCaller(), null, true, volume);
-        
+
 
         SnapshotInfo snap = this.snapshotFactory.getSnapshot(snapshotId);
-        SnapshotStrategy strategy = null;
-        for (SnapshotStrategy st : snapshotStrategies) {
-        	if (st.canHandle(snap)) {
-        		strategy = st;
-        		break;
-        	}
-        }
 
         try {
-        	snapshot = strategy.takeSnapshot(volume, snapshotId);
+        	snapshot = this.snapshotSrv.takeSnapshot(volume, snapshotId);
         	if (snapshot != null) {
         		postCreateSnapshot(volumeId, snapshot.getId(), policyId);
         		//Check if the snapshot was removed while backingUp. If yes, do not log snapshot create usage event
@@ -344,20 +337,13 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
     	 if (snapshot == null) {
     		 throw new CloudRuntimeException("Can't find snapshot:" + snapshotId);
     	 }
-    	 
+
     	 if (snapshot.getState() == Snapshot.State.BackedUp) {
     	     return snapshot;
     	 }
-    	 
-    	 SnapshotStrategy strategy = null;
-         for (SnapshotStrategy st : snapshotStrategies) {
-         	if (st.canHandle(snapshot)) {
-         		strategy = st;
-         		break;
-         	}
-         }
-         
-         return strategy.backupSnapshot(snapshot);
+
+
+         return this.snapshotSrv.backupSnapshot(snapshot);
     }
 
     @Override
@@ -394,7 +380,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
         } catch (Exception e) {
             throw new CloudRuntimeException("downloadSnapshotsFromSwift failed due to " + e.toString());
         }
-        
+
     }
 
     private List<String> determineBackupUuids(final SnapshotVO snapshot) {
@@ -445,7 +431,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
         }
 
     }
-    
+
     @Override
     public SnapshotVO getParentSnapshot(VolumeInfo volume, Snapshot snapshot) {
     	 long preId = _snapshotDao.getLastSnapshot(volume.getId(), snapshot.getId());
@@ -454,7 +440,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
          if (preId != 0 && !(volume.getLastPoolId() != null && !volume.getLastPoolId().equals(volume.getPoolId()))) {
              preSnapshotVO = _snapshotDao.findByIdIncludingRemoved(preId);
          }
-         
+
          return preSnapshotVO;
     }
 
@@ -475,7 +461,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
             snapshotSchedule.setSnapshotId(snapshotId);
             _snapshotScheduleDao.update(snapshotSchedule.getId(), snapshotSchedule);
         }
-        
+
         if (snapshot != null && snapshot.isRecursive()) {
             postCreateRecurringSnapshotForPolicy(userId, volumeId, snapshotId, policyId);
         }
@@ -515,18 +501,11 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
         if (snapshotCheck == null) {
             throw new InvalidParameterValueException("unable to find a snapshot with id " + snapshotId);
         }
-        
+
         _accountMgr.checkAccess(caller, null, true, snapshotCheck);
-        
-        SnapshotStrategy strategy = null;
-        for (SnapshotStrategy st : snapshotStrategies) {
-        	if (st.canHandle(snapshotCheck)) {
-        		strategy = st;
-        		break;
-        	}
-        }
+
         try {
-        	boolean result = strategy.deleteSnapshot(snapshotCheck);
+        	boolean result = this.snapshotSrv.deleteSnapshot(snapshotCheck);
         	if (result) {
         		if (snapshotCheck.getState() == Snapshot.State.BackedUp) {
         			UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_DELETE, snapshotCheck.getAccountId(),
@@ -573,7 +552,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
         String snapshotTypeStr = cmd.getSnapshotType();
         String intervalTypeStr = cmd.getIntervalType();
         Map<String, String> tags = cmd.getTags();
-        
+
         Account caller = UserContext.current().getCaller();
         List<Long> permittedAccounts = new ArrayList<Long>();
 
@@ -589,8 +568,8 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
        Long domainId = domainIdRecursiveListProject.first();
        Boolean isRecursive = domainIdRecursiveListProject.second();
-       ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();        
-        
+       ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+
         Filter searchFilter = new Filter(SnapshotVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
         SearchBuilder<SnapshotVO> sb = _snapshotDao.createSearchBuilder();
         _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
@@ -601,7 +580,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
         sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
         sb.and("snapshotTypeEQ", sb.entity().getsnapshotType(), SearchCriteria.Op.IN);
         sb.and("snapshotTypeNEQ", sb.entity().getsnapshotType(), SearchCriteria.Op.NEQ);
-        
+
         if (tags != null && !tags.isEmpty()) {
         SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
         for (int count=0; count < tags.size(); count++) {
@@ -620,7 +599,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
         if (volumeId != null) {
             sc.setParameters("volumeId", volumeId);
         }
-        
+
         if (tags != null && !tags.isEmpty()) {
             int count = 0;
             sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.Snapshot.toString());
@@ -765,9 +744,9 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
         if (volume == null) {
             throw new InvalidParameterValueException("Failed to create snapshot policy, unable to find a volume with id " + volumeId);
         }
-        
+
         _accountMgr.checkAccess(UserContext.current().getCaller(), null, true, volume);
-        
+
         if (volume.getState() != Volume.State.Ready) {
             throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot.");
         }
@@ -823,7 +802,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
         	if (owner.getType() == Account.ACCOUNT_TYPE_PROJECT) {
         		message = "domain/project";
         	}
-        	
+
             throw new InvalidParameterValueException("Max number of snapshots shouldn't exceed the " + message + " level snapshot limit");
         }
 
@@ -869,11 +848,11 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
         return new Pair<List<? extends SnapshotPolicy>, Integer>(result.first(), result.second());
     }
 
-    
+
     private List<SnapshotPolicyVO> listPoliciesforVolume(long volumeId) {
         return _snapshotPolicyDao.listByVolumeId(volumeId);
     }
-    
+
     private List<SnapshotVO> listSnapsforVolume(long volumeId) {
         return _snapshotDao.listByVolumeId(volumeId);
     }
@@ -961,7 +940,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
     @Override
     public SnapshotVO allocSnapshot(Long volumeId, Long policyId) throws ResourceAllocationException {
         Account caller = UserContext.current().getCaller();
-        
+
         VolumeVO volume = _volsDao.findById(volumeId);
         if (volume == null) {
             throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist");
@@ -970,11 +949,11 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
         if (zone == null) {
             throw new InvalidParameterValueException("Can't find zone by id " + volume.getDataCenterId());
         }
-        
+
         if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) {
             throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zone.getName());
         }
-        
+
         if (volume.getState() != Volume.State.Ready) {
             throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot.");
         }
@@ -985,7 +964,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
                 throw new InvalidParameterValueException("VolumeId: " + volumeId + " is for System VM , Creating snapshot against System VM volumes is not supported");
             }
         }
-        
+
         StoragePoolVO storagePoolVO = _storagePoolDao.findById(volume.getPoolId());
         if (storagePoolVO == null) {
             throw new InvalidParameterValueException("VolumeId: " + volumeId + " please attach this volume to a VM before create snapshot for it");
@@ -1030,7 +1009,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
         String snapshotName = vmDisplayName + "_" + volume.getName() + "_" + timeString;
 
         // Create the Snapshot object and save it so we can return it to the
-        // user        
+        // user
         HypervisorType hypervisorType = this._volsDao.getHypervisorType(volumeId);
         SnapshotVO snapshotVO = new SnapshotVO(volume.getDataCenterId(), volume.getAccountId(), volume.getDomainId(), volume.getId(), volume.getDiskOfferingId(), null, snapshotName,
                 (short) snapshotType.ordinal(), snapshotType.name(), volume.getSize(), hypervisorType);
@@ -1050,7 +1029,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
 
     @Override
     public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
- 
+
         String value = _configDao.getValue(Config.BackupSnapshotWait.toString());
         _backupsnapshotwait = NumbersUtil.parseInt(value, Integer.parseInt(Config.BackupSnapshotWait.getDefaultValue()));
         backup = Boolean.parseBoolean(this._configDao.getValue(Config.BackupSnapshotAferTakingSnapshot.toString()));
@@ -1124,7 +1103,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
 
         return success;
     }
-    
+
     @Override
     public boolean canOperateOnVolume(Volume volume) {
         List<SnapshotVO> snapshots = _snapshotDao.listByStatus(volume.getId(), Snapshot.State.Creating,


[2/2] git commit: updated refs/heads/object_store to 2968766

Posted by mc...@apache.org.
Rename SnapshotStrategy to SnapshotService to have consistent naming
convention for Template, Snapshot, Volume. Also rename CopyCmd to
CopyCommand to follow internal command naming convention.

Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/29687663
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/29687663
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/29687663

Branch: refs/heads/object_store
Commit: 29687663e84c06067e8433b4598629aaedebceb4
Parents: 5f90aa9
Author: Min Chen <mi...@citrix.com>
Authored: Mon Apr 22 16:15:57 2013 -0700
Committer: Min Chen <mi...@citrix.com>
Committed: Mon Apr 22 16:15:57 2013 -0700

----------------------------------------------------------------------
 .../cloud/storage/snapshot/SnapshotApiService.java |  109 +++
 .../cloud/storage/snapshot/SnapshotService.java    |  109 ---
 api/src/org/apache/cloudstack/api/BaseCmd.java     |    4 +-
 .../resource/NfsSecondaryStorageResource.java      |   12 +-
 .../subsystem/api/storage/SnapshotService.java     |   26 +
 .../subsystem/api/storage/SnapshotStrategy.java    |   27 -
 .../apache/cloudstack/storage/command/CopyCmd.java |   62 --
 .../cloudstack/storage/command/CopyCommand.java    |   62 ++
 .../storage/motion/AncientDataMotionStrategy.java  |    6 +-
 .../storage/test/DirectAgentManagerSimpleImpl.java |   13 -
 .../storage/snapshot/SnapshotServiceImpl.java      |  566 +++++++++++++-
 .../snapshot/strategy/AncientSnapshotStrategy.java |  597 ---------------
 .../cloudstack/storage/LocalHostEndpoint.java      |    4 +-
 .../xen/resource/XenServerStorageResource.java     |   10 +-
 .../storage/snapshot/SnapshotManagerImpl.java      |  109 ++--
 15 files changed, 809 insertions(+), 907 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/29687663/api/src/com/cloud/storage/snapshot/SnapshotApiService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/snapshot/SnapshotApiService.java b/api/src/com/cloud/storage/snapshot/SnapshotApiService.java
new file mode 100644
index 0000000..23e6522
--- /dev/null
+++ b/api/src/com/cloud/storage/snapshot/SnapshotApiService.java
@@ -0,0 +1,109 @@
+// 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.storage.snapshot;
+
+import java.util.List;
+
+import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotPolicyCmd;
+import org.apache.cloudstack.api.command.user.snapshot.DeleteSnapshotPoliciesCmd;
+import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotPoliciesCmd;
+import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotsCmd;
+
+import com.cloud.api.commands.ListRecurringSnapshotScheduleCmd;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.Volume;
+import com.cloud.user.Account;
+import com.cloud.utils.Pair;
+
+public interface SnapshotApiService {
+
+    /**
+     * List all snapshots of a disk volume. Optionally lists snapshots created by specified interval
+     *
+     * @param cmd
+     *            the command containing the search criteria (order by, limit, etc.)
+     * @return list of snapshots
+     * @throws PermissionDeniedException
+     */
+    Pair<List<? extends Snapshot>, Integer> listSnapshots(ListSnapshotsCmd cmd);
+
+    /**
+     * Delete specified snapshot from the specified. If no other policies are assigned it calls destroy snapshot. This
+     * will be
+     * used for manual snapshots too.
+     *
+     * @param snapshotId
+     *            TODO
+     */
+    boolean deleteSnapshot(long snapshotId);
+
+    /**
+     * Creates a policy with specified schedule. maxSnaps specifies the number of most recent snapshots that are to be
+     * retained.
+     * If the number of snapshots go beyond maxSnaps the oldest snapshot is deleted
+     *
+     * @param cmd
+     *            the command that
+     * @param policyOwner
+     *            TODO
+     * @return the newly created snapshot policy if success, null otherwise
+     */
+    SnapshotPolicy createPolicy(CreateSnapshotPolicyCmd cmd, Account policyOwner);
+
+    /**
+     * Get the recurring snapshots scheduled for this volume currently along with the time at which they are scheduled
+     *
+     * @param cmd
+     *            the command wrapping the volumeId (volume for which the snapshots are required) and policyId (to show
+     *            snapshots for only this policy).
+     * @return The list of snapshot schedules.
+     */
+    public List<? extends SnapshotSchedule> findRecurringSnapshotSchedule(ListRecurringSnapshotScheduleCmd cmd);
+
+    /**
+     * list all snapshot policies assigned to the specified volume
+     *
+     * @param cmd
+     *            the command that specifies the volume criteria
+     * @return list of snapshot policies
+     */
+    Pair<List<? extends SnapshotPolicy>, Integer> listPoliciesforVolume(ListSnapshotPoliciesCmd cmd);
+
+    boolean deleteSnapshotPolicies(DeleteSnapshotPoliciesCmd cmd);
+
+    Snapshot allocSnapshot(Long volumeId, Long policyId) throws ResourceAllocationException;
+
+    /**
+     * Create a snapshot of a volume
+     *
+     * @param snapshotOwner
+     *            TODO
+     * @param cmd
+     *            the API command wrapping the parameters for creating the snapshot (mainly volumeId)
+     *
+     * @return the Snapshot that was created
+     */
+    Snapshot createSnapshot(Long volumeId, Long policyId, Long snapshotId, Account snapshotOwner);
+
+    /**
+     * @param vol
+     * @return
+     */
+    Long getHostIdForSnapshotOperation(Volume vol);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/29687663/api/src/com/cloud/storage/snapshot/SnapshotService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/snapshot/SnapshotService.java b/api/src/com/cloud/storage/snapshot/SnapshotService.java
deleted file mode 100644
index b5325f5..0000000
--- a/api/src/com/cloud/storage/snapshot/SnapshotService.java
+++ /dev/null
@@ -1,109 +0,0 @@
-// 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.storage.snapshot;
-
-import java.util.List;
-
-import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotPolicyCmd;
-import org.apache.cloudstack.api.command.user.snapshot.DeleteSnapshotPoliciesCmd;
-import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotPoliciesCmd;
-import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotsCmd;
-
-import com.cloud.api.commands.ListRecurringSnapshotScheduleCmd;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.Volume;
-import com.cloud.user.Account;
-import com.cloud.utils.Pair;
-
-public interface SnapshotService {
-
-    /**
-     * List all snapshots of a disk volume. Optionally lists snapshots created by specified interval
-     *
-     * @param cmd
-     *            the command containing the search criteria (order by, limit, etc.)
-     * @return list of snapshots
-     * @throws PermissionDeniedException
-     */
-    Pair<List<? extends Snapshot>, Integer> listSnapshots(ListSnapshotsCmd cmd);
-
-    /**
-     * Delete specified snapshot from the specified. If no other policies are assigned it calls destroy snapshot. This
-     * will be
-     * used for manual snapshots too.
-     *
-     * @param snapshotId
-     *            TODO
-     */
-    boolean deleteSnapshot(long snapshotId);
-
-    /**
-     * Creates a policy with specified schedule. maxSnaps specifies the number of most recent snapshots that are to be
-     * retained.
-     * If the number of snapshots go beyond maxSnaps the oldest snapshot is deleted
-     *
-     * @param cmd
-     *            the command that
-     * @param policyOwner
-     *            TODO
-     * @return the newly created snapshot policy if success, null otherwise
-     */
-    SnapshotPolicy createPolicy(CreateSnapshotPolicyCmd cmd, Account policyOwner);
-
-    /**
-     * Get the recurring snapshots scheduled for this volume currently along with the time at which they are scheduled
-     *
-     * @param cmd
-     *            the command wrapping the volumeId (volume for which the snapshots are required) and policyId (to show
-     *            snapshots for only this policy).
-     * @return The list of snapshot schedules.
-     */
-    public List<? extends SnapshotSchedule> findRecurringSnapshotSchedule(ListRecurringSnapshotScheduleCmd cmd);
-
-    /**
-     * list all snapshot policies assigned to the specified volume
-     *
-     * @param cmd
-     *            the command that specifies the volume criteria
-     * @return list of snapshot policies
-     */
-    Pair<List<? extends SnapshotPolicy>, Integer> listPoliciesforVolume(ListSnapshotPoliciesCmd cmd);
-
-    boolean deleteSnapshotPolicies(DeleteSnapshotPoliciesCmd cmd);
-
-    Snapshot allocSnapshot(Long volumeId, Long policyId) throws ResourceAllocationException;
-
-    /**
-     * Create a snapshot of a volume
-     *
-     * @param snapshotOwner
-     *            TODO
-     * @param cmd
-     *            the API command wrapping the parameters for creating the snapshot (mainly volumeId)
-     *
-     * @return the Snapshot that was created
-     */
-    Snapshot createSnapshot(Long volumeId, Long policyId, Long snapshotId, Account snapshotOwner);
-
-    /**
-     * @param vol
-     * @return
-     */
-    Long getHostIdForSnapshotOperation(Volume vol);
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/29687663/api/src/org/apache/cloudstack/api/BaseCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/BaseCmd.java b/api/src/org/apache/cloudstack/api/BaseCmd.java
index b845053..46a9dfc 100644
--- a/api/src/org/apache/cloudstack/api/BaseCmd.java
+++ b/api/src/org/apache/cloudstack/api/BaseCmd.java
@@ -64,7 +64,7 @@ import com.cloud.server.TaggedResourceService;
 import com.cloud.storage.DataStoreProviderApiService;
 import com.cloud.storage.StorageService;
 import com.cloud.storage.VolumeApiService;
-import com.cloud.storage.snapshot.SnapshotService;
+import com.cloud.storage.snapshot.SnapshotApiService;
 import com.cloud.template.TemplateApiService;
 import com.cloud.user.Account;
 import com.cloud.user.AccountService;
@@ -108,7 +108,7 @@ public abstract class BaseCmd {
     @Inject public NetworkService _networkService;
     @Inject public TemplateApiService _templateService;
     @Inject public SecurityGroupService _securityGroupService;
-    @Inject public SnapshotService _snapshotService;
+    @Inject public SnapshotApiService _snapshotService;
     @Inject public ConsoleProxyService _consoleProxyService;
     @Inject public VpcVirtualNetworkApplianceService _routerService;
     @Inject public ResponseGenerator _responseGenerator;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/29687663/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java
index e8abcbf..3be9ced 100755
--- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java
+++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java
@@ -48,7 +48,7 @@ import java.util.concurrent.Callable;
 import javax.naming.ConfigurationException;
 
 import org.apache.cloudstack.engine.subsystem.api.storage.DataTO;
-import org.apache.cloudstack.storage.command.CopyCmd;
+import org.apache.cloudstack.storage.command.CopyCommand;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.api.Answer;
@@ -215,14 +215,14 @@ SecondaryStorageResource {
             return execute((DeleteTemplateFromS3Command) cmd);
         } else if (cmd instanceof CleanupSnapshotBackupCommand){
             return execute((CleanupSnapshotBackupCommand)cmd);
-        } else if (cmd instanceof CopyCmd) {
-        	return execute((CopyCmd)cmd);
+        } else if (cmd instanceof CopyCommand) {
+        	return execute((CopyCommand)cmd);
         } else {
             return Answer.createUnsupportedCommandAnswer(cmd);
         }
     }
 
-    protected Answer downloadFromS3ToNfs(CopyCmd cmd, DataTO srcData, S3TO s3,
+    protected Answer downloadFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3,
     		DataTO destData, NfsTO destImageStore) {
           final String storagePath = destImageStore.getUrl();
           final String destPath = destData.getPath();
@@ -265,12 +265,12 @@ SecondaryStorageResource {
           }
     }
 
-    protected Answer downloadFromSwiftToNfs(CopyCmd cmd, DataTO srcData, SwiftTO srcImageStore,
+    protected Answer downloadFromSwiftToNfs(CopyCommand cmd, DataTO srcData, SwiftTO srcImageStore,
     		DataTO destData, NfsTO destImageStore) {
     	return Answer.createUnsupportedCommandAnswer(cmd);
     }
 
-    protected Answer execute(CopyCmd cmd) {
+    protected Answer execute(CopyCommand cmd) {
     	DataTO srcData = cmd.getSrcTO();
     	DataTO destData = cmd.getDestTO();
     	DataStoreTO srcDataStore = srcData.getDataStore();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/29687663/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java
new file mode 100644
index 0000000..68dc55f
--- /dev/null
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java
@@ -0,0 +1,26 @@
+// 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 org.apache.cloudstack.engine.subsystem.api.storage;
+
+
+public interface SnapshotService {
+	public SnapshotInfo takeSnapshot(VolumeInfo volume, Long snapshotId);
+	public SnapshotInfo backupSnapshot(SnapshotInfo snapshot);
+	public boolean deleteSnapshot(SnapshotInfo snapshot);
+	public boolean revertSnapshot(SnapshotInfo snapshot);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/29687663/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java
deleted file mode 100644
index e9492c4..0000000
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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 org.apache.cloudstack.engine.subsystem.api.storage;
-
-
-public interface SnapshotStrategy {
-	public boolean canHandle(SnapshotInfo snapshot);
-	public SnapshotInfo takeSnapshot(VolumeInfo volume, Long snapshotId);
-	public SnapshotInfo backupSnapshot(SnapshotInfo snapshot);
-	public boolean deleteSnapshot(SnapshotInfo snapshot);
-	public boolean revertSnapshot(SnapshotInfo snapshot);
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/29687663/engine/api/src/org/apache/cloudstack/storage/command/CopyCmd.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CopyCmd.java b/engine/api/src/org/apache/cloudstack/storage/command/CopyCmd.java
deleted file mode 100644
index 9cb225b..0000000
--- a/engine/api/src/org/apache/cloudstack/storage/command/CopyCmd.java
+++ /dev/null
@@ -1,62 +0,0 @@
-// 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 org.apache.cloudstack.storage.command;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.DataTO;
-
-import com.cloud.agent.api.Command;
-
-public class CopyCmd extends Command implements StorageSubSystemCommand {
-    private DataTO srcTO;
-    private DataTO destTO;
-    private int timeout;
-
-    /**
-     * @return the timeout
-     */
-    public int getTimeout() {
-        return timeout;
-    }
-
-    /**
-     * @param timeout the timeout to set
-     */
-    public void setTimeout(int timeout) {
-        this.timeout = timeout;
-    }
-
-    public CopyCmd(DataTO srcUri, DataTO destUri, int timeout) {
-        super();
-        this.srcTO = srcUri;
-        this.destTO = destUri;
-        this.timeout = timeout;
-    }
-    
-    public DataTO getDestTO() {
-        return this.destTO;
-    }
-    
-    public DataTO getSrcTO() {
-        return this.srcTO;
-    }
-
-    @Override
-    public boolean executeInSequence() {
-        return true;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/29687663/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java
new file mode 100644
index 0000000..fb28034
--- /dev/null
+++ b/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java
@@ -0,0 +1,62 @@
+// 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 org.apache.cloudstack.storage.command;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataTO;
+
+import com.cloud.agent.api.Command;
+
+public class CopyCommand extends Command implements StorageSubSystemCommand {
+    private DataTO srcTO;
+    private DataTO destTO;
+    private int timeout;
+
+    /**
+     * @return the timeout
+     */
+    public int getTimeout() {
+        return timeout;
+    }
+
+    /**
+     * @param timeout the timeout to set
+     */
+    public void setTimeout(int timeout) {
+        this.timeout = timeout;
+    }
+
+    public CopyCommand(DataTO srcUri, DataTO destUri, int timeout) {
+        super();
+        this.srcTO = srcUri;
+        this.destTO = destUri;
+        this.timeout = timeout;
+    }
+    
+    public DataTO getDestTO() {
+        return this.destTO;
+    }
+    
+    public DataTO getSrcTO() {
+        return this.srcTO;
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/29687663/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
----------------------------------------------------------------------
diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
index e72bb54..8274fd7 100644
--- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
+++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
@@ -35,7 +35,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-import org.apache.cloudstack.storage.command.CopyCmd;
+import org.apache.cloudstack.storage.command.CopyCommand;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.log4j.Logger;
@@ -194,13 +194,13 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
         if (srcData.getDataStore().getRole() != DataStoreRole.ImageCache && destData.getDataStore().getRole() != DataStoreRole.ImageCache) {
             //need to copy it to image cache store
             DataObject cacheData = cacheMgr.createCacheObject(srcData, destData.getDataStore().getScope());
-            CopyCmd cmd = new CopyCmd(cacheData.getTO(), destData.getTO(), _primaryStorageDownloadWait);
+            CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _primaryStorageDownloadWait);
             EndPoint ep = selector.select(cacheData, destData);
             Answer answer = ep.sendMessage(cmd);
             return answer;
         } else {
             //handle copy it to cache store
-            CopyCmd cmd = new CopyCmd(srcData.getTO(), destData.getTO(), _primaryStorageDownloadWait);
+            CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _primaryStorageDownloadWait);
             EndPoint ep = selector.select(srcData, destData);
             Answer answer = ep.sendMessage(cmd);
             return answer;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/29687663/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java
index 0725971..c5b5883 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java
@@ -187,19 +187,6 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa
         return null;
     }
 
-
-    @Override
-    public void sendToSecStorage(DataStore ssStore, Command cmd, Listener listener) throws AgentUnavailableException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public Answer sendToSecStorage(DataStore ssStore, Command cmd) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
     @Override
     public boolean tapLoadingAgents(Long hostId, TapAgentsAction action) {
         // TODO Auto-generated method stub

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/29687663/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
index 1b64fd0..7eee772 100644
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
@@ -14,43 +14,577 @@
 // KIND, either express or implied.  See the License for the
 // specific language governing permissions and limitations
 // under the License.
+
 package org.apache.cloudstack.storage.snapshot;
 
-import org.apache.cloudstack.engine.cloud.entity.api.SnapshotEntity;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.framework.async.AsyncCallFuture;
+import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.framework.async.AsyncRpcConext;
+import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
+import com.cloud.agent.api.BackupSnapshotAnswer;
+import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.host.HostVO;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.resource.ResourceManager;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.VolumeManager;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.snapshot.SnapshotManager;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachine.State;
+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;
+
 @Component
 public class SnapshotServiceImpl implements SnapshotService {
-	
-	public SnapshotServiceImpl() {
-		
+	private static final Logger s_logger = Logger.getLogger(SnapshotServiceImpl.class);
+	@Inject
+	protected VolumeDao _volsDao;
+	@Inject
+	protected UserVmDao _vmDao;
+	@Inject
+	protected PrimaryDataStoreDao _storagePoolDao;
+	@Inject
+	protected ClusterDao _clusterDao;
+	@Inject
+	protected SnapshotDao _snapshotDao;
+	@Inject
+	private ResourceManager _resourceMgr;
+	@Inject
+	protected SnapshotManager snapshotMgr;
+	@Inject
+	protected VolumeManager volumeMgr;
+	@Inject
+	private ConfigurationDao _configDao;
+	@Inject
+	protected SnapshotStateMachineManager stateMachineManager;
+	@Inject
+	private VolumeDao volumeDao;
+	@Inject
+	SnapshotDataFactory snapshotfactory;
+	@Inject
+	DataStoreManager dataStoreMgr;
+	@Inject
+	DataMotionService motionSrv;
+	@Inject
+	ObjectInDataStoreManager objInStoreMgr;
+	@Inject
+	VMSnapshotDao _vmSnapshotDao;
+
+
+
+
+	static private class CreateSnapshotContext<T> extends AsyncRpcConext<T> {
+		final VolumeInfo volume;
+		final SnapshotInfo snapshot;
+		final AsyncCallFuture<SnapshotResult> future;
+		public CreateSnapshotContext(AsyncCompletionCallback<T> callback, VolumeInfo volume,
+				SnapshotInfo snapshot,
+				AsyncCallFuture<SnapshotResult> future) {
+			super(callback);
+			this.volume = volume;
+			this.snapshot = snapshot;
+			this.future = future;
+		}
 	}
 
-	@Override
-	public SnapshotEntity getSnapshotEntity(long snapshotId) {
-		// TODO Auto-generated method stub
+	static private class DeleteSnapshotContext<T> extends AsyncRpcConext<T> {
+		final SnapshotInfo snapshot;
+		final AsyncCallFuture<SnapshotResult> future;
+		public DeleteSnapshotContext(AsyncCompletionCallback<T> callback, SnapshotInfo snapshot,
+				AsyncCallFuture<SnapshotResult> future) {
+			super(callback);
+			this.snapshot = snapshot;
+			this.future = future;
+		}
+
+	}
+
+	static private class CopySnapshotContext<T> extends AsyncRpcConext<T> {
+		final SnapshotInfo srcSnapshot;
+		final SnapshotInfo destSnapshot;
+		final AsyncCallFuture<SnapshotResult> future;
+		public CopySnapshotContext(AsyncCompletionCallback<T> callback,
+				SnapshotInfo srcSnapshot,
+				SnapshotInfo destSnapshot,
+				AsyncCallFuture<SnapshotResult> future) {
+			super(callback);
+			this.srcSnapshot = srcSnapshot;
+			this.destSnapshot = destSnapshot;
+			this.future = future;
+		}
+
+	}
+
+	protected Void createSnapshotAsyncCallback(AsyncCallbackDispatcher<SnapshotServiceImpl, CreateCmdResult> callback,
+			CreateSnapshotContext<CreateCmdResult> context) {
+		CreateCmdResult result = callback.getResult();
+		SnapshotObject snapshot = (SnapshotObject)context.snapshot;
+		VolumeInfo volume = context.volume;
+		AsyncCallFuture<SnapshotResult> future = context.future;
+		SnapshotResult snapResult = new SnapshotResult(snapshot);
+		if (result.isFailed()) {
+			s_logger.debug("create snapshot " + context.snapshot.getName() + " failed: " + result.getResult());
+			try {
+				snapshot.processEvent(Snapshot.Event.OperationFailed);
+			} catch (NoTransitionException nte) {
+				s_logger.debug("Failed to update snapshot state due to " + nte.getMessage());
+			}
+
+
+			snapResult.setResult(result.getResult());
+			future.complete(snapResult);
+			return null;
+		}
+
+		try {
+			SnapshotVO preSnapshotVO = this.snapshotMgr.getParentSnapshot(volume, snapshot);
+			String preSnapshotPath = null;
+			if (preSnapshotVO != null) {
+			    preSnapshotPath = preSnapshotVO.getPath();
+			}
+			SnapshotVO snapshotVO = this._snapshotDao.findById(snapshot.getId());
+			// The snapshot was successfully created
+			if (preSnapshotPath != null && preSnapshotPath.equals(result.getPath())) {
+				// empty snapshot
+				s_logger.debug("CreateSnapshot: this is empty snapshot ");
+
+				snapshotVO.setPath(preSnapshotPath);
+				snapshotVO.setBackupSnapshotId(preSnapshotVO.getBackupSnapshotId());
+				snapshotVO.setSwiftId(preSnapshotVO.getSwiftId());
+				snapshotVO.setPrevSnapshotId(preSnapshotVO.getId());
+				snapshotVO.setSecHostId(preSnapshotVO.getSecHostId());
+				snapshot.processEvent(Snapshot.Event.OperationNotPerformed);
+			} else {
+				long preSnapshotId = 0;
+
+				if (preSnapshotVO != null && preSnapshotVO.getBackupSnapshotId() != null) {
+					preSnapshotId = preSnapshotVO.getId();
+					int _deltaSnapshotMax = NumbersUtil.parseInt(_configDao.getValue("snapshot.delta.max"), SnapshotManager.DELTAMAX);
+					int deltaSnap = _deltaSnapshotMax;
+
+					int i;
+					for (i = 1; i < deltaSnap; i++) {
+						String prevBackupUuid = preSnapshotVO.getBackupSnapshotId();
+						// previous snapshot doesn't have backup, create a full snapshot
+						if (prevBackupUuid == null) {
+							preSnapshotId = 0;
+							break;
+						}
+						long preSSId = preSnapshotVO.getPrevSnapshotId();
+						if (preSSId == 0) {
+							break;
+						}
+						preSnapshotVO = _snapshotDao.findByIdIncludingRemoved(preSSId);
+					}
+					if (i >= deltaSnap) {
+						preSnapshotId = 0;
+					}
+				}
+
+				//If the volume is moved around, backup a full snapshot to secondary storage
+				if (volume.getLastPoolId() != null && !volume.getLastPoolId().equals(volume.getPoolId())) {
+					preSnapshotId = 0;
+					//TODO: fix this hack
+					VolumeVO volumeVO = this.volumeDao.findById(volume.getId());
+					volumeVO.setLastPoolId(volume.getPoolId());
+					this.volumeDao.update(volume.getId(), volumeVO);
+				}
+
+				snapshot.setPath(result.getPath());
+				snapshot.setPrevSnapshotId(preSnapshotId);
+
+				snapshot.processEvent(Snapshot.Event.OperationSucceeded);
+				snapResult = new SnapshotResult(this.snapshotfactory.getSnapshot(snapshot.getId()));
+			}
+		} catch (Exception e) {
+			s_logger.debug("Failed to create snapshot: ", e);
+			snapResult.setResult(e.toString());
+			try {
+                snapshot.processEvent(Snapshot.Event.OperationFailed);
+            } catch (NoTransitionException e1) {
+                s_logger.debug("Failed to change snapshot state: " + e1.toString());
+            }
+		}
+
+		future.complete(snapResult);
 		return null;
 	}
 
-	@Override
-	public boolean takeSnapshot(SnapshotInfo snapshot) {
-		// TODO Auto-generated method stub
+	class SnapshotResult extends CommandResult {
+		SnapshotInfo snashot;
+		public SnapshotResult(SnapshotInfo snapshot) {
+			this.snashot = snapshot;
+		}
+	}
+
+	protected SnapshotInfo createSnapshotOnPrimary(VolumeInfo volume, Long snapshotId) {
+		SnapshotObject snapshot = (SnapshotObject)this.snapshotfactory.getSnapshot(snapshotId);
+		if (snapshot == null) {
+			throw new CloudRuntimeException("Can not find snapshot " + snapshotId);
+		}
+
+		try {
+			snapshot.processEvent(Snapshot.Event.CreateRequested);
+		} catch (NoTransitionException nte) {
+			s_logger.debug("Failed to update snapshot state due to " + nte.getMessage());
+			throw new CloudRuntimeException("Failed to update snapshot state due to " + nte.getMessage());
+		}
+
+		AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
+		try {
+		    CreateSnapshotContext<CommandResult> context = new CreateSnapshotContext<CommandResult>(
+		            null, volume, snapshot, future);
+		    AsyncCallbackDispatcher<SnapshotServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher
+		            .create(this);
+		    caller.setCallback(
+		            caller.getTarget().createSnapshotAsyncCallback(null, null))
+		            .setContext(context);
+		    PrimaryDataStoreDriver primaryStore = (PrimaryDataStoreDriver)volume.getDataStore().getDriver();
+		    primaryStore.takeSnapshot(snapshot, caller);
+		} catch (Exception e) {
+		    s_logger.debug("Failed to take snapshot: " + snapshot.getId(), e);
+		    try {
+                snapshot.processEvent(Snapshot.Event.OperationFailed);
+            } catch (NoTransitionException e1) {
+                s_logger.debug("Failed to change state for event: OperationFailed" , e);
+            }
+		    throw new CloudRuntimeException("Failed to take snapshot" + snapshot.getId());
+		}
+
+		SnapshotResult result;
+
+		try {
+			result = future.get();
+			if (result.isFailed()) {
+				s_logger.debug("Failed to create snapshot:" + result.getResult());
+				throw new CloudRuntimeException(result.getResult());
+			}
+			return result.snashot;
+		} catch (InterruptedException e) {
+			s_logger.debug("Failed to create snapshot", e);
+			throw new CloudRuntimeException("Failed to create snapshot", e);
+		} catch (ExecutionException e) {
+			s_logger.debug("Failed to create snapshot", e);
+			throw new CloudRuntimeException("Failed to create snapshot", e);
+		}
+
+	}
+
+	private boolean hostSupportSnapsthot(HostVO host) {
+		if (host.getHypervisorType() != HypervisorType.KVM) {
+			return true;
+		}
+		// Determine host capabilities
+		String caps = host.getCapabilities();
+
+		if (caps != null) {
+			String[] tokens = caps.split(",");
+			for (String token : tokens) {
+				if (token.contains("snapshot")) {
+					return true;
+				}
+			}
+		}
 		return false;
 	}
 
+	protected boolean supportedByHypervisor(VolumeInfo volume) {
+		if (volume.getHypervisorType().equals(HypervisorType.KVM)) {
+			StoragePool storagePool = (StoragePool)volume.getDataStore();
+			ClusterVO cluster = _clusterDao.findById(storagePool.getClusterId());
+			List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(cluster.getId());
+			if (hosts != null && !hosts.isEmpty()) {
+				HostVO host = hosts.get(0);
+				if (!hostSupportSnapsthot(host)) {
+					throw new CloudRuntimeException("KVM Snapshot is not supported on cluster: " + host.getId());
+				}
+			}
+		}
+
+		// if volume is attached to a vm in destroyed or expunging state; disallow
+		if (volume.getInstanceId() != null) {
+			UserVmVO userVm = _vmDao.findById(volume.getInstanceId());
+			if (userVm != null) {
+				if (userVm.getState().equals(State.Destroyed) || userVm.getState().equals(State.Expunging)) {
+					throw new CloudRuntimeException("Creating snapshot failed due to volume:" + volume.getId() + " is associated with vm:" + userVm.getInstanceName() + " is in "
+							+ userVm.getState().toString() + " state");
+				}
+
+				if(userVm.getHypervisorType() == HypervisorType.VMware || userVm.getHypervisorType() == HypervisorType.KVM) {
+					List<SnapshotVO> activeSnapshots = _snapshotDao.listByInstanceId(volume.getInstanceId(), Snapshot.State.Creating,  Snapshot.State.CreatedOnPrimary,  Snapshot.State.BackingUp);
+					if(activeSnapshots.size() > 1)
+						throw new CloudRuntimeException("There is other active snapshot tasks on the instance to which the volume is attached, please try again later");
+				}
+
+				List<VMSnapshotVO> activeVMSnapshots = _vmSnapshotDao.listByInstanceId(userVm.getId(),
+                        VMSnapshot.State.Creating, VMSnapshot.State.Reverting, VMSnapshot.State.Expunging);
+                if (activeVMSnapshots.size() > 0) {
+                    throw new CloudRuntimeException(
+                            "There is other active vm snapshot tasks on the instance to which the volume is attached, please try again later");
+                }
+			}
+		}
+
+		return true;
+	}
+
 	@Override
-	public boolean revertSnapshot(SnapshotInfo snapshot) {
-		// TODO Auto-generated method stub
-		return false;
+	public SnapshotInfo takeSnapshot(VolumeInfo volume, Long snapshotId) {
+
+		supportedByHypervisor(volume);
+
+		SnapshotInfo snapshot = createSnapshotOnPrimary(volume, snapshotId);
+		return snapshot;
 	}
 
 	@Override
-	public boolean deleteSnapshot(SnapshotInfo snapshot) {
+	public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) {
+		SnapshotObject snapObj = (SnapshotObject)snapshot;
+		AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
+		SnapshotResult result = new SnapshotResult(snapshot);
+		try {
+
+			snapObj.processEvent(Snapshot.Event.BackupToSecondary);
+
+			ZoneScope scope = new ZoneScope(snapshot.getDataCenterId());
+			List<DataStore> stores = this.dataStoreMgr.getImageStoresByScope(scope);
+			if (stores.size() != 1) {
+				throw new CloudRuntimeException("find out more than one image stores");
+			}
+
+			DataStore imageStore = stores.get(0);
+			SnapshotInfo snapshotOnImageStore = (SnapshotInfo)imageStore.create(snapshot);
+
+			snapshotOnImageStore.processEvent(Event.CreateOnlyRequested);
+			CopySnapshotContext<CommandResult> context = new CopySnapshotContext<CommandResult>(null, snapshot,
+					snapshotOnImageStore, future);
+			AsyncCallbackDispatcher<SnapshotServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher
+					.create(this);
+			caller.setCallback(
+					caller.getTarget().copySnapshotAsyncCallback(null, null))
+					.setContext(context);
+			this.motionSrv.copyAsync(snapshot, snapshotOnImageStore, caller);
+		} catch (Exception e) {
+			s_logger.debug("Failed to copy snapshot", e);
+			result.setResult("Failed to copy snapshot:" +e.toString());
+			try {
+                snapObj.processEvent(Snapshot.Event.OperationFailed);
+            } catch (NoTransitionException e1) {
+                s_logger.debug("Failed to change state: " + e1.toString());
+            }
+			future.complete(result);
+		}
+
+		try {
+			SnapshotResult res = future.get();
+			SnapshotInfo destSnapshot = res.snashot;
+			return destSnapshot;
+		} catch (InterruptedException e) {
+			s_logger.debug("failed copy snapshot", e);
+			throw new CloudRuntimeException("Failed to copy snapshot" , e);
+		} catch (ExecutionException e) {
+			s_logger.debug("Failed to copy snapshot", e);
+			throw new CloudRuntimeException("Failed to copy snapshot" , e);
+		}
+
+	}
+
+	protected Void copySnapshotAsyncCallback(AsyncCallbackDispatcher<SnapshotServiceImpl, CopyCommandResult> callback,
+			CopySnapshotContext<CommandResult> context) {
+		CopyCommandResult result = callback.getResult();
+		SnapshotInfo destSnapshot = context.destSnapshot;
+		SnapshotObject srcSnapshot = (SnapshotObject)context.srcSnapshot;
+		AsyncCallFuture<SnapshotResult> future = context.future;
+		SnapshotResult snapResult = new SnapshotResult(destSnapshot);
+		if (result.isFailed()) {
+			snapResult.setResult(result.getResult());
+			future.complete(snapResult);
+			return null;
+		}
+
+		try {
+			BackupSnapshotAnswer answer = (BackupSnapshotAnswer)result.getAnswer();
+
+			DataObjectInStore dataInStore =  objInStoreMgr.findObject(destSnapshot, destSnapshot.getDataStore());
+			dataInStore.setInstallPath(answer.getBackupSnapshotName());
+			objInStoreMgr.update(destSnapshot, Event.OperationSuccessed);
+
+			srcSnapshot.processEvent(Snapshot.Event.OperationSucceeded);
+			snapResult = new SnapshotResult(this.snapshotfactory.getSnapshot(destSnapshot.getId()));
+			future.complete(snapResult);
+		} catch (Exception e) {
+			s_logger.debug("Failed to update snapshot state", e);
+			snapResult.setResult(e.toString());
+			future.complete(snapResult);
+		}
+		return null;
+	}
+
+	@DB
+	protected boolean destroySnapshotBackUp(SnapshotVO snapshot) {
+		DataStore store = objInStoreMgr.findStore(snapshot.getId(), DataObjectType.SNAPSHOT, DataStoreRole.Image);
+		if (store == null) {
+			s_logger.debug("Can't find snapshot" + snapshot.getId() + " backed up into image store");
+			return false;
+		}
+
+		try {
+			SnapshotInfo snapshotInfo = this.snapshotfactory.getSnapshot(snapshot.getId(), store);
+			snapshotInfo.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested);
+
+			AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
+			DeleteSnapshotContext<CommandResult> context = new DeleteSnapshotContext<CommandResult>(null,
+					snapshotInfo, future);
+			AsyncCallbackDispatcher<SnapshotServiceImpl, CommandResult> caller = AsyncCallbackDispatcher
+					.create(this);
+			caller.setCallback(
+					caller.getTarget().deleteSnapshotCallback(null, null))
+					.setContext(context);
+
+			store.getDriver().deleteAsync(snapshotInfo, caller);
+
+			SnapshotResult result = future.get();
+			if (result.isFailed()) {
+				s_logger.debug("Failed to delete snapsoht: " + result.getResult());
+			}
+			return result.isSuccess();
+		} catch (Exception e) {
+			s_logger.debug("Failed to delete snapshot", e);
+			return false;
+		}
+	}
+
+	protected Void deleteSnapshotCallback(AsyncCallbackDispatcher<SnapshotServiceImpl, CommandResult> callback,
+			DeleteSnapshotContext<CommandResult> context) {
+		CommandResult result = callback.getResult();
+		AsyncCallFuture<SnapshotResult> future = context.future;
+		SnapshotInfo snapshot = context.snapshot;
+		if (result.isFailed()) {
+			s_logger.debug("delete snapshot failed" + result.getResult());
+			snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
+			SnapshotResult res = new SnapshotResult(context.snapshot);
+			future.complete(res);
+			return null;
+		}
+		snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed);
+		SnapshotResult res = new SnapshotResult(context.snapshot);
+		future.complete(res);
+		return null;
+	}
+
+	@Override
+	public boolean deleteSnapshot(SnapshotInfo snapInfo) {
+		Long snapshotId = snapInfo.getId();
+		SnapshotObject snapshot = (SnapshotObject)snapInfo;
+
+		if (!Snapshot.State.BackedUp.equals(snapshot.getState())) {
+			throw new InvalidParameterValueException("Can't delete snapshotshot " + snapshotId + " due to it is not in BackedUp Status");
+		}
+
+		if (s_logger.isDebugEnabled()) {
+			s_logger.debug("Calling deleteSnapshot for snapshotId: " + snapshotId);
+		}
+		SnapshotVO lastSnapshot = null;
+		if (snapshot.getBackupSnapshotId() != null) {
+			List<SnapshotVO> snaps = _snapshotDao.listByBackupUuid(snapshot.getVolumeId(), snapshot.getBackupSnapshotId());
+			if (snaps != null && snaps.size() > 1) {
+				snapshot.setBackupSnapshotId(null);
+				SnapshotVO snapshotVO = this._snapshotDao.findById(snapshotId);
+				_snapshotDao.update(snapshot.getId(), snapshotVO);
+			}
+		}
+
+		_snapshotDao.remove(snapshotId);
+
+		long lastId = snapshotId;
+		boolean destroy = false;
+		while (true) {
+			lastSnapshot = _snapshotDao.findNextSnapshot(lastId);
+			if (lastSnapshot == null) {
+				// if all snapshots after this snapshot in this chain are removed, remove those snapshots.
+				destroy = true;
+				break;
+			}
+			if (lastSnapshot.getRemoved() == null) {
+				// if there is one child not removed, then can not remove back up snapshot.
+				break;
+			}
+			lastId = lastSnapshot.getId();
+		}
+		if (destroy) {
+			lastSnapshot = _snapshotDao.findByIdIncludingRemoved(lastId);
+			while (lastSnapshot.getRemoved() != null) {
+				String BackupSnapshotId = lastSnapshot.getBackupSnapshotId();
+				if (BackupSnapshotId != null) {
+					List<SnapshotVO> snaps = _snapshotDao.listByBackupUuid(lastSnapshot.getVolumeId(), BackupSnapshotId);
+					if (snaps != null && snaps.size() > 1) {
+						lastSnapshot.setBackupSnapshotId(null);
+						_snapshotDao.update(lastSnapshot.getId(), lastSnapshot);
+					} else {
+						if (destroySnapshotBackUp(lastSnapshot)) {
+
+						} else {
+							s_logger.debug("Destroying snapshot backup failed " + lastSnapshot);
+							break;
+						}
+					}
+				}
+				lastId = lastSnapshot.getPrevSnapshotId();
+				if (lastId == 0) {
+					break;
+				}
+				lastSnapshot = _snapshotDao.findByIdIncludingRemoved(lastId);
+			}
+		}
+		return true;
+
+	}
+
+	@Override
+	public boolean revertSnapshot(SnapshotInfo snapshot) {
 		// TODO Auto-generated method stub
 		return false;
 	}
-	
-	
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/29687663/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java
deleted file mode 100644
index 944c477..0000000
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java
+++ /dev/null
@@ -1,597 +0,0 @@
-// 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 org.apache.cloudstack.storage.snapshot.strategy;
-
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
-import org.apache.cloudstack.framework.async.AsyncCallFuture;
-import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
-import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-import org.apache.cloudstack.framework.async.AsyncRpcConext;
-import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.snapshot.SnapshotObject;
-import org.apache.cloudstack.storage.snapshot.SnapshotStateMachineManager;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.agent.api.BackupSnapshotAnswer;
-import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.host.HostVO;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.resource.ResourceManager;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.VolumeManager;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.snapshot.SnapshotManager;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VirtualMachine.State;
-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;
-
-@Component
-public class AncientSnapshotStrategy implements SnapshotStrategy {
-	private static final Logger s_logger = Logger.getLogger(AncientSnapshotStrategy.class);
-	@Inject
-	protected VolumeDao _volsDao;
-	@Inject
-	protected UserVmDao _vmDao;
-	@Inject
-	protected PrimaryDataStoreDao _storagePoolDao;
-	@Inject
-	protected ClusterDao _clusterDao;
-	@Inject
-	protected SnapshotDao snapshotDao;
-	@Inject
-	private ResourceManager _resourceMgr;
-	@Inject
-	protected SnapshotDao _snapshotDao;
-	@Inject
-	protected SnapshotManager snapshotMgr;
-	@Inject
-	protected VolumeManager volumeMgr;
-	@Inject
-	private ConfigurationDao _configDao;
-	@Inject
-	protected SnapshotStateMachineManager stateMachineManager;
-	@Inject
-	private VolumeDao volumeDao;
-	@Inject
-	SnapshotDataFactory snapshotfactory;
-	@Inject
-	DataStoreManager dataStoreMgr;
-	@Inject
-	DataMotionService motionSrv;
-	@Inject
-	ObjectInDataStoreManager objInStoreMgr;
-	@Inject
-	VMSnapshotDao _vmSnapshotDao;
-
-
-	@Override
-	public boolean canHandle(SnapshotInfo snapshot) {
-		return true;
-	}
-
-	static private class CreateSnapshotContext<T> extends AsyncRpcConext<T> {
-		final VolumeInfo volume;
-		final SnapshotInfo snapshot;
-		final AsyncCallFuture<SnapshotResult> future;
-		public CreateSnapshotContext(AsyncCompletionCallback<T> callback, VolumeInfo volume,
-				SnapshotInfo snapshot,
-				AsyncCallFuture<SnapshotResult> future) {
-			super(callback);
-			this.volume = volume;
-			this.snapshot = snapshot;
-			this.future = future;
-		}
-	}
-	
-	static private class DeleteSnapshotContext<T> extends AsyncRpcConext<T> {
-		final SnapshotInfo snapshot;
-		final AsyncCallFuture<SnapshotResult> future;
-		public DeleteSnapshotContext(AsyncCompletionCallback<T> callback, SnapshotInfo snapshot,
-				AsyncCallFuture<SnapshotResult> future) {
-			super(callback);
-			this.snapshot = snapshot;
-			this.future = future;
-		}
-		
-	}
-
-	static private class CopySnapshotContext<T> extends AsyncRpcConext<T> {
-		final SnapshotInfo srcSnapshot;
-		final SnapshotInfo destSnapshot;
-		final AsyncCallFuture<SnapshotResult> future;
-		public CopySnapshotContext(AsyncCompletionCallback<T> callback,
-				SnapshotInfo srcSnapshot,
-				SnapshotInfo destSnapshot,
-				AsyncCallFuture<SnapshotResult> future) {
-			super(callback);
-			this.srcSnapshot = srcSnapshot;
-			this.destSnapshot = destSnapshot;
-			this.future = future;
-		}
-
-	}
-
-	protected Void createSnapshotAsyncCallback(AsyncCallbackDispatcher<AncientSnapshotStrategy, CreateCmdResult> callback, 
-			CreateSnapshotContext<CreateCmdResult> context) {
-		CreateCmdResult result = callback.getResult();
-		SnapshotObject snapshot = (SnapshotObject)context.snapshot;
-		VolumeInfo volume = context.volume;
-		AsyncCallFuture<SnapshotResult> future = context.future;
-		SnapshotResult snapResult = new SnapshotResult(snapshot);
-		if (result.isFailed()) {
-			s_logger.debug("create snapshot " + context.snapshot.getName() + " failed: " + result.getResult());
-			try {
-				snapshot.processEvent(Snapshot.Event.OperationFailed);
-			} catch (NoTransitionException nte) {
-				s_logger.debug("Failed to update snapshot state due to " + nte.getMessage());
-			}
-
-
-			snapResult.setResult(result.getResult());
-			future.complete(snapResult);
-			return null;
-		}
-
-		try {
-			SnapshotVO preSnapshotVO = this.snapshotMgr.getParentSnapshot(volume, snapshot);
-			String preSnapshotPath = null;
-			if (preSnapshotVO != null) {
-			    preSnapshotPath = preSnapshotVO.getPath();
-			}
-			SnapshotVO snapshotVO = this.snapshotDao.findById(snapshot.getId());
-			// The snapshot was successfully created
-			if (preSnapshotPath != null && preSnapshotPath.equals(result.getPath())) {
-				// empty snapshot
-				s_logger.debug("CreateSnapshot: this is empty snapshot ");
-
-				snapshotVO.setPath(preSnapshotPath);
-				snapshotVO.setBackupSnapshotId(preSnapshotVO.getBackupSnapshotId());
-				snapshotVO.setSwiftId(preSnapshotVO.getSwiftId());
-				snapshotVO.setPrevSnapshotId(preSnapshotVO.getId());
-				snapshotVO.setSecHostId(preSnapshotVO.getSecHostId());
-				snapshot.processEvent(Snapshot.Event.OperationNotPerformed);
-			} else {
-				long preSnapshotId = 0;
-
-				if (preSnapshotVO != null && preSnapshotVO.getBackupSnapshotId() != null) {
-					preSnapshotId = preSnapshotVO.getId();
-					int _deltaSnapshotMax = NumbersUtil.parseInt(_configDao.getValue("snapshot.delta.max"), SnapshotManager.DELTAMAX);
-					int deltaSnap = _deltaSnapshotMax;
-
-					int i;
-					for (i = 1; i < deltaSnap; i++) {
-						String prevBackupUuid = preSnapshotVO.getBackupSnapshotId();
-						// previous snapshot doesn't have backup, create a full snapshot
-						if (prevBackupUuid == null) {
-							preSnapshotId = 0;
-							break;
-						}
-						long preSSId = preSnapshotVO.getPrevSnapshotId();
-						if (preSSId == 0) {
-							break;
-						}
-						preSnapshotVO = _snapshotDao.findByIdIncludingRemoved(preSSId);
-					}
-					if (i >= deltaSnap) {
-						preSnapshotId = 0;
-					}
-				}
-
-				//If the volume is moved around, backup a full snapshot to secondary storage
-				if (volume.getLastPoolId() != null && !volume.getLastPoolId().equals(volume.getPoolId())) {
-					preSnapshotId = 0;
-					//TODO: fix this hack
-					VolumeVO volumeVO = this.volumeDao.findById(volume.getId());
-					volumeVO.setLastPoolId(volume.getPoolId());
-					this.volumeDao.update(volume.getId(), volumeVO);
-				}
-
-				snapshot.setPath(result.getPath());
-				snapshot.setPrevSnapshotId(preSnapshotId);
-
-				snapshot.processEvent(Snapshot.Event.OperationSucceeded);
-				snapResult = new SnapshotResult(this.snapshotfactory.getSnapshot(snapshot.getId()));
-			} 
-		} catch (Exception e) {
-			s_logger.debug("Failed to create snapshot: ", e);
-			snapResult.setResult(e.toString());
-			try {
-                snapshot.processEvent(Snapshot.Event.OperationFailed);
-            } catch (NoTransitionException e1) {
-                s_logger.debug("Failed to change snapshot state: " + e1.toString());
-            }
-		}
-
-		future.complete(snapResult);
-		return null;
-	} 
-
-	class SnapshotResult extends CommandResult {
-		SnapshotInfo snashot;
-		public SnapshotResult(SnapshotInfo snapshot) {
-			this.snashot = snapshot;
-		}
-	}
-
-	protected SnapshotInfo createSnapshotOnPrimary(VolumeInfo volume, Long snapshotId) {
-		SnapshotObject snapshot = (SnapshotObject)this.snapshotfactory.getSnapshot(snapshotId);
-		if (snapshot == null) {
-			throw new CloudRuntimeException("Can not find snapshot " + snapshotId);
-		}
-
-		try {
-			snapshot.processEvent(Snapshot.Event.CreateRequested);
-		} catch (NoTransitionException nte) {
-			s_logger.debug("Failed to update snapshot state due to " + nte.getMessage());
-			throw new CloudRuntimeException("Failed to update snapshot state due to " + nte.getMessage());
-		}
-
-		AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
-		try {
-		    CreateSnapshotContext<CommandResult> context = new CreateSnapshotContext<CommandResult>(
-		            null, volume, snapshot, future);
-		    AsyncCallbackDispatcher<AncientSnapshotStrategy, CreateCmdResult> caller = AsyncCallbackDispatcher
-		            .create(this);
-		    caller.setCallback(
-		            caller.getTarget().createSnapshotAsyncCallback(null, null))
-		            .setContext(context);
-		    PrimaryDataStoreDriver primaryStore = (PrimaryDataStoreDriver)volume.getDataStore().getDriver();
-		    primaryStore.takeSnapshot(snapshot, caller);
-		} catch (Exception e) {
-		    s_logger.debug("Failed to take snapshot: " + snapshot.getId(), e);
-		    try {
-                snapshot.processEvent(Snapshot.Event.OperationFailed);
-            } catch (NoTransitionException e1) {
-                s_logger.debug("Failed to change state for event: OperationFailed" , e);
-            }
-		    throw new CloudRuntimeException("Failed to take snapshot" + snapshot.getId());
-		}
-		
-		SnapshotResult result;
-		
-		try {
-			result = future.get();
-			if (result.isFailed()) {
-				s_logger.debug("Failed to create snapshot:" + result.getResult());
-				throw new CloudRuntimeException(result.getResult());
-			}
-			return result.snashot;
-		} catch (InterruptedException e) {
-			s_logger.debug("Failed to create snapshot", e);
-			throw new CloudRuntimeException("Failed to create snapshot", e);
-		} catch (ExecutionException e) {
-			s_logger.debug("Failed to create snapshot", e);
-			throw new CloudRuntimeException("Failed to create snapshot", e);
-		}
-
-	}
-
-	private boolean hostSupportSnapsthot(HostVO host) {
-		if (host.getHypervisorType() != HypervisorType.KVM) {
-			return true;
-		}
-		// Determine host capabilities
-		String caps = host.getCapabilities();
-
-		if (caps != null) {
-			String[] tokens = caps.split(",");
-			for (String token : tokens) {
-				if (token.contains("snapshot")) {
-					return true;
-				}
-			}
-		}
-		return false;
-	}
-
-	protected boolean supportedByHypervisor(VolumeInfo volume) {
-		if (volume.getHypervisorType().equals(HypervisorType.KVM)) {
-			StoragePool storagePool = (StoragePool)volume.getDataStore();
-			ClusterVO cluster = _clusterDao.findById(storagePool.getClusterId());
-			List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(cluster.getId());
-			if (hosts != null && !hosts.isEmpty()) {
-				HostVO host = hosts.get(0);
-				if (!hostSupportSnapsthot(host)) {
-					throw new CloudRuntimeException("KVM Snapshot is not supported on cluster: " + host.getId());
-				}
-			}
-		}
-
-		// if volume is attached to a vm in destroyed or expunging state; disallow
-		if (volume.getInstanceId() != null) {
-			UserVmVO userVm = _vmDao.findById(volume.getInstanceId());
-			if (userVm != null) {
-				if (userVm.getState().equals(State.Destroyed) || userVm.getState().equals(State.Expunging)) {
-					throw new CloudRuntimeException("Creating snapshot failed due to volume:" + volume.getId() + " is associated with vm:" + userVm.getInstanceName() + " is in "
-							+ userVm.getState().toString() + " state");
-				}
-
-				if(userVm.getHypervisorType() == HypervisorType.VMware || userVm.getHypervisorType() == HypervisorType.KVM) {
-					List<SnapshotVO> activeSnapshots = _snapshotDao.listByInstanceId(volume.getInstanceId(), Snapshot.State.Creating,  Snapshot.State.CreatedOnPrimary,  Snapshot.State.BackingUp);
-					if(activeSnapshots.size() > 1)
-						throw new CloudRuntimeException("There is other active snapshot tasks on the instance to which the volume is attached, please try again later");
-				}
-				
-				List<VMSnapshotVO> activeVMSnapshots = _vmSnapshotDao.listByInstanceId(userVm.getId(),
-                        VMSnapshot.State.Creating, VMSnapshot.State.Reverting, VMSnapshot.State.Expunging);
-                if (activeVMSnapshots.size() > 0) {
-                    throw new CloudRuntimeException(
-                            "There is other active vm snapshot tasks on the instance to which the volume is attached, please try again later");
-                }           
-			}
-		}
-
-		return true;
-	}
-
-	@Override
-	public SnapshotInfo takeSnapshot(VolumeInfo volume, Long snapshotId) {
-
-		supportedByHypervisor(volume);
-
-		SnapshotInfo snapshot = createSnapshotOnPrimary(volume, snapshotId);
-		return snapshot;
-	}
-
-	@Override
-	public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) {
-		SnapshotObject snapObj = (SnapshotObject)snapshot;
-		AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
-		SnapshotResult result = new SnapshotResult(snapshot);
-		try {
-
-			snapObj.processEvent(Snapshot.Event.BackupToSecondary);
-
-			ZoneScope scope = new ZoneScope(snapshot.getDataCenterId());
-			List<DataStore> stores = this.dataStoreMgr.getImageStoresByScope(scope);
-			if (stores.size() != 1) {
-				throw new CloudRuntimeException("find out more than one image stores");
-			}
-
-			DataStore imageStore = stores.get(0);
-			SnapshotInfo snapshotOnImageStore = (SnapshotInfo)imageStore.create(snapshot);
-
-			snapshotOnImageStore.processEvent(Event.CreateOnlyRequested);
-			CopySnapshotContext<CommandResult> context = new CopySnapshotContext<CommandResult>(null, snapshot,
-					snapshotOnImageStore, future);
-			AsyncCallbackDispatcher<AncientSnapshotStrategy, CopyCommandResult> caller = AsyncCallbackDispatcher
-					.create(this);
-			caller.setCallback(
-					caller.getTarget().copySnapshotAsyncCallback(null, null))
-					.setContext(context);
-			this.motionSrv.copyAsync(snapshot, snapshotOnImageStore, caller);
-		} catch (Exception e) {
-			s_logger.debug("Failed to copy snapshot", e);
-			result.setResult("Failed to copy snapshot:" +e.toString());
-			try {
-                snapObj.processEvent(Snapshot.Event.OperationFailed);
-            } catch (NoTransitionException e1) {
-                s_logger.debug("Failed to change state: " + e1.toString());
-            }
-			future.complete(result);
-		}
-
-		try {
-			SnapshotResult res = future.get();
-			SnapshotInfo destSnapshot = res.snashot;
-			return destSnapshot;
-		} catch (InterruptedException e) {
-			s_logger.debug("failed copy snapshot", e);
-			throw new CloudRuntimeException("Failed to copy snapshot" , e);
-		} catch (ExecutionException e) {
-			s_logger.debug("Failed to copy snapshot", e);
-			throw new CloudRuntimeException("Failed to copy snapshot" , e);
-		}
-
-	}
-
-	protected Void copySnapshotAsyncCallback(AsyncCallbackDispatcher<AncientSnapshotStrategy, CopyCommandResult> callback, 
-			CopySnapshotContext<CommandResult> context) {
-		CopyCommandResult result = callback.getResult();
-		SnapshotInfo destSnapshot = context.destSnapshot;
-		SnapshotObject srcSnapshot = (SnapshotObject)context.srcSnapshot;
-		AsyncCallFuture<SnapshotResult> future = context.future;
-		SnapshotResult snapResult = new SnapshotResult(destSnapshot);
-		if (result.isFailed()) {
-			snapResult.setResult(result.getResult());
-			future.complete(snapResult);
-			return null;
-		}
-
-		try {
-			BackupSnapshotAnswer answer = (BackupSnapshotAnswer)result.getAnswer();
-			
-			DataObjectInStore dataInStore =  objInStoreMgr.findObject(destSnapshot, destSnapshot.getDataStore());
-			dataInStore.setInstallPath(answer.getBackupSnapshotName());
-			objInStoreMgr.update(destSnapshot, Event.OperationSuccessed);
-			
-			srcSnapshot.processEvent(Snapshot.Event.OperationSucceeded);
-			snapResult = new SnapshotResult(this.snapshotfactory.getSnapshot(destSnapshot.getId()));
-			future.complete(snapResult);
-		} catch (Exception e) {
-			s_logger.debug("Failed to update snapshot state", e);
-			snapResult.setResult(e.toString());
-			future.complete(snapResult);
-		}
-		return null;
-	}
-
-	@DB
-	protected boolean destroySnapshotBackUp(SnapshotVO snapshot) {
-		DataStore store = objInStoreMgr.findStore(snapshot.getId(), DataObjectType.SNAPSHOT, DataStoreRole.Image);
-		if (store == null) {
-			s_logger.debug("Can't find snapshot" + snapshot.getId() + " backed up into image store");
-			return false;
-		}
-
-		try {
-			SnapshotInfo snapshotInfo = this.snapshotfactory.getSnapshot(snapshot.getId(), store);
-			snapshotInfo.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested);
-			
-			AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
-			DeleteSnapshotContext<CommandResult> context = new DeleteSnapshotContext<CommandResult>(null,
-					snapshotInfo, future);
-			AsyncCallbackDispatcher<AncientSnapshotStrategy, CommandResult> caller = AsyncCallbackDispatcher
-					.create(this);
-			caller.setCallback(
-					caller.getTarget().deleteSnapshotCallback(null, null))
-					.setContext(context);
-			
-			store.getDriver().deleteAsync(snapshotInfo, caller);
-			
-			SnapshotResult result = future.get();
-			if (result.isFailed()) {
-				s_logger.debug("Failed to delete snapsoht: " + result.getResult());
-			}
-			return result.isSuccess();
-		} catch (Exception e) {
-			s_logger.debug("Failed to delete snapshot", e);
-			return false;
-		}
-	}
-	
-	protected Void deleteSnapshotCallback(AsyncCallbackDispatcher<AncientSnapshotStrategy, CommandResult> callback, 
-			DeleteSnapshotContext<CommandResult> context) {
-		CommandResult result = callback.getResult();
-		AsyncCallFuture<SnapshotResult> future = context.future;
-		SnapshotInfo snapshot = context.snapshot;
-		if (result.isFailed()) {
-			s_logger.debug("delete snapshot failed" + result.getResult());
-			snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
-			SnapshotResult res = new SnapshotResult(context.snapshot);
-			future.complete(res);
-			return null;
-		}
-		snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed);
-		SnapshotResult res = new SnapshotResult(context.snapshot);
-		future.complete(res);
-		return null;
-	}
-
-	@Override
-	public boolean deleteSnapshot(SnapshotInfo snapInfo) {
-		Long snapshotId = snapInfo.getId();
-		SnapshotObject snapshot = (SnapshotObject)snapInfo;
-
-		if (!Snapshot.State.BackedUp.equals(snapshot.getState())) {
-			throw new InvalidParameterValueException("Can't delete snapshotshot " + snapshotId + " due to it is not in BackedUp Status");
-		}
-		
-		if (s_logger.isDebugEnabled()) {
-			s_logger.debug("Calling deleteSnapshot for snapshotId: " + snapshotId);
-		}
-		SnapshotVO lastSnapshot = null;
-		if (snapshot.getBackupSnapshotId() != null) {
-			List<SnapshotVO> snaps = _snapshotDao.listByBackupUuid(snapshot.getVolumeId(), snapshot.getBackupSnapshotId());
-			if (snaps != null && snaps.size() > 1) {
-				snapshot.setBackupSnapshotId(null);
-				SnapshotVO snapshotVO = this._snapshotDao.findById(snapshotId);
-				_snapshotDao.update(snapshot.getId(), snapshotVO);
-			}
-		}
-		
-		_snapshotDao.remove(snapshotId);
-
-		long lastId = snapshotId;
-		boolean destroy = false;
-		while (true) {
-			lastSnapshot = _snapshotDao.findNextSnapshot(lastId);
-			if (lastSnapshot == null) {
-				// if all snapshots after this snapshot in this chain are removed, remove those snapshots.
-				destroy = true;
-				break;
-			}
-			if (lastSnapshot.getRemoved() == null) {
-				// if there is one child not removed, then can not remove back up snapshot.
-				break;
-			}
-			lastId = lastSnapshot.getId();
-		}
-		if (destroy) {
-			lastSnapshot = _snapshotDao.findByIdIncludingRemoved(lastId);
-			while (lastSnapshot.getRemoved() != null) {
-				String BackupSnapshotId = lastSnapshot.getBackupSnapshotId();
-				if (BackupSnapshotId != null) {
-					List<SnapshotVO> snaps = _snapshotDao.listByBackupUuid(lastSnapshot.getVolumeId(), BackupSnapshotId);
-					if (snaps != null && snaps.size() > 1) {
-						lastSnapshot.setBackupSnapshotId(null);
-						_snapshotDao.update(lastSnapshot.getId(), lastSnapshot);
-					} else {
-						if (destroySnapshotBackUp(lastSnapshot)) {
-
-						} else {
-							s_logger.debug("Destroying snapshot backup failed " + lastSnapshot);
-							break;
-						}
-					}
-				}
-				lastId = lastSnapshot.getPrevSnapshotId();
-				if (lastId == 0) {
-					break;
-				}
-				lastSnapshot = _snapshotDao.findByIdIncludingRemoved(lastId);
-			}
-		}
-		return true;
-
-	}
-
-	@Override
-	public boolean revertSnapshot(SnapshotInfo snapshot) {
-		// TODO Auto-generated method stub
-		return false;
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/29687663/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java
index f08a597..9fe0c55 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java
@@ -6,7 +6,7 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-import org.apache.cloudstack.storage.command.CopyCmd;
+import org.apache.cloudstack.storage.command.CopyCommand;
 
 import com.cloud.agent.Listener;
 import com.cloud.agent.api.Answer;
@@ -32,7 +32,7 @@ public class LocalHostEndpoint implements EndPoint {
 
 	@Override
 	public Answer sendMessage(Command cmd) {
-		if (cmd instanceof CopyCmd) {
+		if (cmd instanceof CopyCommand) {
 			return resource.executeRequest(cmd);
 		}
 		// TODO Auto-generated method stub

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/29687663/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java
index e7c009b..300daa5 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java
@@ -34,7 +34,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataTO;
 import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreAnswer;
 import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreCmd;
-import org.apache.cloudstack.storage.command.CopyCmd;
+import org.apache.cloudstack.storage.command.CopyCommand;
 import org.apache.cloudstack.storage.command.CopyCmdAnswer;
 import org.apache.cloudstack.storage.command.CreateObjectAnswer;
 import org.apache.cloudstack.storage.command.CreateObjectCommand;
@@ -84,8 +84,8 @@ public class XenServerStorageResource {
     }
     
     public Answer handleStorageCommands(StorageSubSystemCommand command) {
-        if (command instanceof CopyCmd) {
-            return this.execute((CopyCmd)command);
+        if (command instanceof CopyCommand) {
+            return this.execute((CopyCommand)command);
         } else if (command instanceof AttachPrimaryDataStoreCmd) {
             return this.execute((AttachPrimaryDataStoreCmd)command);
         } else if (command instanceof CreatePrimaryDataStoreCmd) {
@@ -505,7 +505,7 @@ public class XenServerStorageResource {
        
     }
     
-    protected Answer directDownloadHttpTemplate(CopyCmd cmd, DecodedDataObject srcObj, DecodedDataObject destObj) {
+    protected Answer directDownloadHttpTemplate(CopyCommand cmd, DecodedDataObject srcObj, DecodedDataObject destObj) {
         Connection conn = hypervisorResource.getConnection();
         SR poolsr = null;
         VDI vdi = null;
@@ -724,7 +724,7 @@ public class XenServerStorageResource {
     }
  
     
-    protected Answer execute(CopyCmd cmd) {
+    protected Answer execute(CopyCommand cmd) {
         DataTO srcData = cmd.getSrcTO();
         DataTO destData = cmd.getDestTO();