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/06/07 03:01:47 UTC

[2/3] git commit: updated refs/heads/object_store to 03f4c60

Simplify various DeleteTemplateCommnad,  DeleteVolumeCommand and
DeleteSnapshotBackupCommand to use one DeleteCommand, also provide
BaseImageStoreDriverImpl class for plugin to inherit to avoid code
duplication.

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

Branch: refs/heads/object_store
Commit: 66e702222d2f0efab1db6ce0e895e5a21c3b7cd4
Parents: c78f398
Author: Min Chen <mi...@citrix.com>
Authored: Thu Jun 6 18:00:38 2013 -0700
Committer: Min Chen <mi...@citrix.com>
Committed: Thu Jun 6 18:00:38 2013 -0700

----------------------------------------------------------------------
 api/src/com/cloud/agent/api/to/DataTO.java         |    2 +
 .../agent/api/DeleteSnapshotBackupCommand2.java    |   56 ---
 .../cloudstack/storage/to/SnapshotObjectTO.java    |    3 +-
 .../cloudstack/storage/to/TemplateObjectTO.java    |    1 +
 .../cloudstack/storage/to/VolumeObjectTO.java      |    4 +
 .../storage/snapshot/SnapshotServiceImpl.java      |   36 --
 .../storage/volume/VolumeServiceImpl.java          |   13 +
 plugins/storage/image/default/pom.xml              |    5 +
 .../driver/CloudStackImageStoreDriverImpl.java     |  365 +--------------
 plugins/storage/image/s3/pom.xml                   |    5 +
 .../datastore/driver/S3ImageStoreDriverImpl.java   |  370 +--------------
 plugins/storage/image/sample/pom.xml               |    5 +
 .../driver/SampleImageStoreDriverImpl.java         |   94 +----
 plugins/storage/image/swift/pom.xml                |    5 +
 .../driver/SwiftImageStoreDriverImpl.java          |  382 +--------------
 .../src/com/cloud/storage/StorageManagerImpl.java  |    5 +-
 .../storage/snapshot/SnapshotManagerImpl.java      |   10 -
 .../cloud/template/HypervisorTemplateAdapter.java  |   32 +-
 .../resource/NfsSecondaryStorageResource.java      |   67 ++--
 19 files changed, 118 insertions(+), 1342 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66e70222/api/src/com/cloud/agent/api/to/DataTO.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/to/DataTO.java b/api/src/com/cloud/agent/api/to/DataTO.java
index bd9a16b..21e802f 100644
--- a/api/src/com/cloud/agent/api/to/DataTO.java
+++ b/api/src/com/cloud/agent/api/to/DataTO.java
@@ -25,4 +25,6 @@ public interface DataTO {
      * @return
      */
     String getPath();
+
+    long getId();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66e70222/core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand2.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand2.java b/core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand2.java
deleted file mode 100644
index 2fcb62a..0000000
--- a/core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand2.java
+++ /dev/null
@@ -1,56 +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.agent.api;
-
-import com.cloud.agent.api.to.DataStoreTO;
-
-/**
- * This command encapsulates a primitive operation which enables coalescing the backed up VHD snapshots on the secondary server
- * This currently assumes that the secondary storage are mounted on the XenServer.
- */
-public class DeleteSnapshotBackupCommand2 extends Command {
-    private DataStoreTO store;
-    private String snapshotPath;
-
-
-    public DeleteSnapshotBackupCommand2() {
-    }
-
-
-    public DeleteSnapshotBackupCommand2(DataStoreTO store,
-                                       String snapshotPath)
-    {
-        this.store = store;
-        this.snapshotPath = snapshotPath;
-    }
-
-
-    public DataStoreTO getDataStore(){
-        return store;
-    }
-
-
-    public String getSnapshotPath() {
-        return snapshotPath;
-    }
-
-
-    @Override
-    public boolean executeInSequence() {
-        return true;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66e70222/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
index f8f622c..fcaa320 100644
--- a/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
@@ -11,7 +11,7 @@
 // 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 
+// KIND, either express or implied.  See the License for the
 // specific language governing permissions and limitations
 // under the License.
 package org.apache.cloudstack.storage.to;
@@ -93,6 +93,7 @@ public class SnapshotObjectTO implements DataTO {
         this.vmName = vmName;
     }
 
+    @Override
     public long getId() {
         return id;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66e70222/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java
index fefb0ad..0effd8d 100644
--- a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java
@@ -80,6 +80,7 @@ public class TemplateObjectTO implements DataTO {
         return this.uuid;
     }
 
+    @Override
     public long getId() {
         return id;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66e70222/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java
index be268ff..549481e 100644
--- a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java
@@ -65,6 +65,7 @@ public class VolumeObjectTO implements DataTO {
         return this.uuid;
     }
 
+    @Override
     public String getPath() {
         return this.path;
     }
@@ -73,6 +74,7 @@ public class VolumeObjectTO implements DataTO {
         return this.volumeType;
     }
 
+    @Override
     public DataStoreTO getDataStore() {
         return this.dataStore;
     }
@@ -89,6 +91,7 @@ public class VolumeObjectTO implements DataTO {
         return this.size;
     }
 
+    @Override
     public DataObjectType getObjectType() {
         return DataObjectType.VOLUME;
     }
@@ -141,6 +144,7 @@ public class VolumeObjectTO implements DataTO {
         this.chainInfo = chainInfo;
     }
 
+    @Override
     public long getId() {
         return id;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66e70222/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 545a6a0..ed53811 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
@@ -342,42 +342,6 @@ public class SnapshotServiceImpl implements SnapshotService {
         return null;
     }
 
-    @DB
-    protected boolean destroySnapshotBackUp(SnapshotVO snapshot) {
-        SnapshotDataStoreVO snapshotStore = this._snapshotStoreDao
-                .findBySnapshot(snapshot.getId(), DataStoreRole.Image);
-        if (snapshotStore == null) {
-            s_logger.debug("Can't find snapshot" + snapshot.getId() + " backed up into image store");
-            return false;
-        }
-        DataStore store = this.dataStoreMgr.getDataStore(snapshotStore.getDataStoreId(), DataStoreRole.Image);
-        if (store == null) {
-            s_logger.debug("Can't find mage store " + snapshotStore.getDataStoreId());
-            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) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66e70222/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
index 99aac17..04e97dd 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
@@ -55,6 +55,7 @@ import org.springframework.stereotype.Component;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.storage.DeleteVolumeCommand;
 import com.cloud.agent.api.storage.ListVolumeAnswer;
 import com.cloud.agent.api.storage.ListVolumeCommand;
 import com.cloud.agent.api.to.VirtualMachineTO;
@@ -67,6 +68,7 @@ import com.cloud.exception.ResourceAllocationException;
 import com.cloud.host.Host;
 import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.StoragePool;
+import com.cloud.storage.VMTemplateStorageResourceAssoc;
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 import com.cloud.storage.Volume;
 import com.cloud.storage.VolumeVO;
@@ -78,6 +80,7 @@ import com.cloud.user.AccountManager;
 import com.cloud.user.ResourceLimitService;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.db.DB;
+import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.vm.dao.VMInstanceDao;
 
 @Component
@@ -214,6 +217,16 @@ public class VolumeServiceImpl implements VolumeService {
             return future;
         }
 
+        // Find out if the volume is at state of download_in_progress on secondary storage
+        VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(volume.getId());
+        if (volumeStore != null) {
+            if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) {
+                s_logger.debug("Volume: " + volume.getName() + " is currently being uploaded; cant' delete it.");
+                future.complete(result);
+                return future;
+            }
+        }
+
         VolumeVO vol = volDao.findById(volume.getId());
 
         String volumePath = vol.getPath();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66e70222/plugins/storage/image/default/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/storage/image/default/pom.xml b/plugins/storage/image/default/pom.xml
index d1b079d..f51d8f5 100644
--- a/plugins/storage/image/default/pom.xml
+++ b/plugins/storage/image/default/pom.xml
@@ -22,6 +22,11 @@
   <dependencies>
     <dependency>
       <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-storage</artifactId>
+      <version>${project.version}</version>
+    </dependency>  
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
       <artifactId>cloud-engine-storage-image</artifactId>
       <version>${project.version}</version>
     </dependency>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66e70222/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java
----------------------------------------------------------------------
diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java
index 243017f..aa2d533 100644
--- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java
+++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java
@@ -18,116 +18,35 @@
  */
 package org.apache.cloudstack.storage.datastore.driver;
 
-import java.util.Date;
-import java.util.List;
-import java.util.Set;
 import java.util.UUID;
 
 import javax.inject.Inject;
 
-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.DataObject;
 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.EndPoint;
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
-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.command.CommandResult;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
-import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
-import org.apache.cloudstack.storage.image.ImageStoreDriver;
 import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
 import org.apache.cloudstack.storage.image.store.ImageStoreImpl;
-import org.apache.cloudstack.storage.image.store.TemplateObject;
-import org.apache.cloudstack.storage.snapshot.SnapshotObject;
 import org.apache.log4j.Logger;
+import org.apache.cloudstack.storage.image.BaseImageStoreDriverImpl;
 
-import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.DeleteSnapshotBackupCommand2;
 import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
-import com.cloud.agent.api.storage.DeleteTemplateCommand;
-import com.cloud.agent.api.storage.DeleteVolumeCommand;
-import com.cloud.agent.api.storage.DownloadAnswer;
-import com.cloud.agent.api.to.DataObjectType;
 import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
 import com.cloud.agent.api.to.NfsTO;
 import com.cloud.configuration.Config;
 import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.host.dao.HostDao;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.SnapshotVO;
 import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Upload.Mode;
-import com.cloud.storage.Upload.Status;
-import com.cloud.storage.Upload.Type;
-import com.cloud.storage.UploadVO;
-import com.cloud.storage.VMTemplateStorageResourceAssoc;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.VMTemplateZoneVO;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplateZoneDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.download.DownloadMonitor;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
-import com.cloud.storage.snapshot.SnapshotManager;
-import com.cloud.user.Account;
-import com.cloud.user.dao.AccountDao;
 import com.cloud.utils.exception.CloudRuntimeException;
 
-public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
+public class CloudStackImageStoreDriverImpl extends BaseImageStoreDriverImpl {
     private static final Logger s_logger = Logger.getLogger(CloudStackImageStoreDriverImpl.class);
-    @Inject
-    VMTemplateZoneDao templateZoneDao;
-    @Inject
-    VMTemplateDao templateDao;
-    @Inject
-    DownloadMonitor _downloadMonitor;
-    @Inject
-    VolumeDao volumeDao;
-    @Inject
-    VolumeDataStoreDao _volumeStoreDao;
-    @Inject
-    HostDao hostDao;
-    @Inject
-    SnapshotDao snapshotDao;
-    @Inject
-    AgentManager agentMgr;
-    @Inject
-    SnapshotManager snapshotMgr;
-    @Inject
-    AccountDao _accountDao;
+
     @Inject
     ConfigurationDao _configDao;
     @Inject
-    SecondaryStorageVmManager _ssvmMgr;
-    @Inject
-    TemplateDataStoreDao _templateStoreDao;
-    @Inject
     EndPointSelector _epSelector;
-    @Inject
-    DataStoreManager _dataStoreMgr;
 
-    @Override
-    public String grantAccess(DataObject data, EndPoint ep) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public DataTO getTO(DataObject data) {
-        return null;
-    }
 
     @Override
     public DataStoreTO getStoreTO(DataStore store) {
@@ -139,284 +58,6 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
     }
 
     @Override
-    public boolean revokeAccess(DataObject data, EndPoint ep) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public Set<DataObject> listObjects(DataStore store) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    class CreateContext<T> extends AsyncRpcConext<T> {
-        final DataObject data;
-
-        public CreateContext(AsyncCompletionCallback<T> callback, DataObject data) {
-            super(callback);
-            this.data = data;
-        }
-    }
-
-    @Override
-    public void createAsync(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
-        CreateContext<CreateCmdResult> context = new CreateContext<CreateCmdResult>(callback, data);
-        AsyncCallbackDispatcher<CloudStackImageStoreDriverImpl, DownloadAnswer> caller = AsyncCallbackDispatcher
-                .create(this);
-        caller.setContext(context);
-        if (data.getType() == DataObjectType.TEMPLATE) {
-            caller.setCallback(caller.getTarget().createTemplateAsyncCallback(null, null));
-            _downloadMonitor.downloadTemplateToStorage(data, caller);
-        } else if (data.getType() == DataObjectType.VOLUME) {
-            caller.setCallback(caller.getTarget().createVolumeAsyncCallback(null, null));
-            _downloadMonitor.downloadVolumeToStorage(data, caller);
-        }
-    }
-
-    protected Void createTemplateAsyncCallback(AsyncCallbackDispatcher<CloudStackImageStoreDriverImpl, DownloadAnswer> callback,
-            CreateContext<CreateCmdResult> context) {
-        DownloadAnswer answer = callback.getResult();
-        DataObject obj = context.data;
-        DataStore store = obj.getDataStore();
-
-        TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(), obj.getId());
-        if (tmpltStoreVO != null) {
-            TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate();
-            updateBuilder.setDownloadPercent(answer.getDownloadPct());
-            updateBuilder.setDownloadState(answer.getDownloadStatus());
-            updateBuilder.setLastUpdated(new Date());
-            updateBuilder.setErrorString(answer.getErrorString());
-            updateBuilder.setJobId(answer.getJobId());
-            updateBuilder.setLocalDownloadPath(answer.getDownloadPath());
-            updateBuilder.setInstallPath(answer.getInstallPath());
-            updateBuilder.setSize(answer.getTemplateSize());
-            updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize());
-            _templateStoreDao.update(tmpltStoreVO.getId(), updateBuilder);
-            // update size in vm_template table
-            VMTemplateVO tmlptUpdater = templateDao.createForUpdate();
-            tmlptUpdater.setSize(answer.getTemplateSize());
-            templateDao.update(obj.getId(), tmlptUpdater);
-        }
-
-        AsyncCompletionCallback<CreateCmdResult> caller = context.getParentCallback();
-
-        if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR
-                || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED
-                || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) {
-            CreateCmdResult result = new CreateCmdResult(null, null);
-            result.setSuccess(false);
-            result.setResult(answer.getErrorString());
-            caller.complete(result);
-        } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
-            if (answer.getCheckSum() != null) {
-                VMTemplateVO templateDaoBuilder = templateDao.createForUpdate();
-                templateDaoBuilder.setChecksum(answer.getCheckSum());
-                templateDao.update(obj.getId(), templateDaoBuilder);
-            }
-
-            CreateCmdResult result = new CreateCmdResult(null, null);
-            caller.complete(result);
-        }
-        return null;
-    }
-
-    protected Void createVolumeAsyncCallback(AsyncCallbackDispatcher<CloudStackImageStoreDriverImpl, DownloadAnswer> callback,
-            CreateContext<CreateCmdResult> context) {
-        DownloadAnswer answer = callback.getResult();
-        DataObject obj = context.data;
-        DataStore store = obj.getDataStore();
-
-        VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(store.getId(), obj.getId());
-        if (volStoreVO != null) {
-            VolumeDataStoreVO updateBuilder = _volumeStoreDao.createForUpdate();
-            updateBuilder.setDownloadPercent(answer.getDownloadPct());
-            updateBuilder.setDownloadState(answer.getDownloadStatus());
-            updateBuilder.setLastUpdated(new Date());
-            updateBuilder.setErrorString(answer.getErrorString());
-            updateBuilder.setJobId(answer.getJobId());
-            updateBuilder.setLocalDownloadPath(answer.getDownloadPath());
-            updateBuilder.setInstallPath(answer.getInstallPath());
-            updateBuilder.setSize(answer.getTemplateSize());
-            updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize());
-            _volumeStoreDao.update(volStoreVO.getId(), updateBuilder);
-            // update size in volume table
-            VolumeVO volUpdater = volumeDao.createForUpdate();
-            volUpdater.setSize(answer.getTemplateSize());
-            volumeDao.update(obj.getId(), volUpdater);
-        }
-
-        AsyncCompletionCallback<CreateCmdResult> caller = context.getParentCallback();
-
-        if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR
-                || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED
-                || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) {
-            CreateCmdResult result = new CreateCmdResult(null, null);
-            result.setSuccess(false);
-            result.setResult(answer.getErrorString());
-            caller.complete(result);
-        } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
-            CreateCmdResult result = new CreateCmdResult(null, null);
-            caller.complete(result);
-        }
-        return null;
-    }
-
-    private void deleteVolume(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
-        VolumeVO vol = volumeDao.findById(data.getId());
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Expunging " + vol);
-        }
-
-        // Find out if the volume is present on secondary storage
-        VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(vol.getId());
-        if (volumeStore != null) {
-            if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
-                DataStore store = _dataStoreMgr.getDataStore(volumeStore.getDataStoreId(), DataStoreRole.Image);
-                EndPoint ep = _epSelector.select(store);
-                DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(store.getTO(), volumeStore.getVolumeId(),
-                        volumeStore.getInstallPath());
-                Answer answer = ep.sendMessage(dtCommand);
-                if (answer == null || !answer.getResult()) {
-                    s_logger.debug("Failed to delete " + volumeStore + " due to "
-                            + ((answer == null) ? "answer is null" : answer.getDetails()));
-                    return;
-                }
-            } else if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) {
-                s_logger.debug("Volume: " + vol.getName() + " is currently being uploaded; cant' delete it.");
-                throw new CloudRuntimeException("Please specify a volume that is not currently being uploaded.");
-            }
-
-            CommandResult result = new CommandResult();
-            callback.complete(result);
-            return;
-        }
-    }
-
-    private void deleteTemplate(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
-
-        TemplateObject templateObj = (TemplateObject) data;
-        VMTemplateVO template = templateObj.getImage();
-        ImageStoreImpl store = (ImageStoreImpl) templateObj.getDataStore();
-        long storeId = store.getId();
-        Long sZoneId = store.getDataCenterId();
-        long templateId = template.getId();
-
-        Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId());
-        String eventType = "";
-
-        if (template.getFormat().equals(ImageFormat.ISO)) {
-            eventType = EventTypes.EVENT_ISO_DELETE;
-        } else {
-            eventType = EventTypes.EVENT_TEMPLATE_DELETE;
-        }
-
-        // TODO: need to understand why we need to mark destroyed in
-        // template_store_ref table here instead of in callback.
-        // Currently I did that in callback, so I removed previous code to mark
-        // template_host_ref
-        if (sZoneId != null) {
-            UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null);
-        }
-
-        // get installpath of this template on image store
-        TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId);
-        String installPath = tmplStore.getInstallPath();
-        if (installPath != null) {
-            DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(),
-                    template.getAccountId());
-            EndPoint ep = _epSelector.select(templateObj);
-            Answer answer = ep.sendMessage(cmd);
-
-            if (answer == null || !answer.getResult()) {
-                s_logger.debug("Failed to deleted template at store: " + store.getName());
-                CommandResult result = new CommandResult();
-                result.setSuccess(false);
-                result.setResult("Delete template failed");
-                callback.complete(result);
-
-            } else {
-                s_logger.debug("Deleted template at: " + installPath);
-                CommandResult result = new CommandResult();
-                result.setSuccess(true);
-                callback.complete(result);
-            }
-
-            List<VMTemplateZoneVO> templateZones = templateZoneDao.listByZoneTemplate(sZoneId, templateId);
-            if (templateZones != null) {
-                for (VMTemplateZoneVO templateZone : templateZones) {
-                    templateZoneDao.remove(templateZone.getId());
-                }
-            }
-        }
-
-    }
-
-    private void deleteSnapshot(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
-        SnapshotObject snapshotObj = (SnapshotObject) data;
-        DataStore secStore = snapshotObj.getDataStore();
-        CommandResult result = new CommandResult();
-        SnapshotVO snapshot = snapshotObj.getSnapshotVO();
-
-        if (snapshot == null) {
-            s_logger.debug("Destroying snapshot " + snapshotObj.getId()
-                    + " backup failed due to unable to find snapshot ");
-            result.setResult("Unable to find snapshot: " + snapshotObj.getId());
-            callback.complete(result);
-            return;
-        }
-
-        try {
-            String backupOfSnapshot = snapshotObj.getPath();
-            if (backupOfSnapshot == null) {
-                callback.complete(result);
-                return;
-            }
-
-            DeleteSnapshotBackupCommand2 cmd = new DeleteSnapshotBackupCommand2(secStore.getTO(), backupOfSnapshot);
-            EndPoint ep = _epSelector.select(secStore);
-            Answer answer = ep.sendMessage(cmd);
-
-            if (answer != null && !answer.getResult()) {
-                result.setResult(answer.getDetails());
-            }
-        } catch (Exception e) {
-            s_logger.debug("failed to delete snapshot: " + snapshotObj.getId() + ": " + e.toString());
-            result.setResult(e.toString());
-        }
-        callback.complete(result);
-    }
-
-    @Override
-    public void deleteAsync(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
-        if (data.getType() == DataObjectType.VOLUME) {
-            deleteVolume(data, callback);
-        } else if (data.getType() == DataObjectType.TEMPLATE) {
-            deleteTemplate(data, callback);
-        } else if (data.getType() == DataObjectType.SNAPSHOT) {
-            deleteSnapshot(data, callback);
-        }
-    }
-
-    @Override
-    public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean canCopy(DataObject srcData, DataObject destData) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void resize(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
     public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) {
         // find an endpoint to send command
         EndPoint ep = _epSelector.select(store);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66e70222/plugins/storage/image/s3/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/storage/image/s3/pom.xml b/plugins/storage/image/s3/pom.xml
index 7f5b9c4..ad42e6f 100644
--- a/plugins/storage/image/s3/pom.xml
+++ b/plugins/storage/image/s3/pom.xml
@@ -29,6 +29,11 @@
   <dependencies>
     <dependency>
       <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-storage</artifactId>
+      <version>${project.version}</version>
+    </dependency>  
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
       <artifactId>cloud-engine-storage-image</artifactId>
       <version>${project.version}</version>
     </dependency>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66e70222/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java
----------------------------------------------------------------------
diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java
index 8cf4835..49da980 100644
--- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java
+++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java
@@ -18,118 +18,29 @@
  */
 package org.apache.cloudstack.storage.datastore.driver;
 
-import java.util.Date;
-import java.util.List;
 import java.util.Map;
-import java.util.Set;
-
 import javax.inject.Inject;
 
 import org.apache.cloudstack.api.ApiConstants;
-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.DataObject;
 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.EndPoint;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
-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.command.CommandResult;
 import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
-import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
-import org.apache.cloudstack.storage.image.ImageStoreDriver;
+import org.apache.cloudstack.storage.image.BaseImageStoreDriverImpl;
 import org.apache.cloudstack.storage.image.store.ImageStoreImpl;
-import org.apache.cloudstack.storage.image.store.TemplateObject;
-import org.apache.cloudstack.storage.snapshot.SnapshotObject;
 import org.apache.log4j.Logger;
 
 import com.amazonaws.services.s3.model.CannedAccessControlList;
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.DeleteSnapshotBackupCommand2;
-import com.cloud.agent.api.storage.DeleteTemplateCommand;
-import com.cloud.agent.api.storage.DeleteVolumeCommand;
-import com.cloud.agent.api.storage.DownloadAnswer;
-import com.cloud.agent.api.to.DataObjectType;
 import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
 import com.cloud.agent.api.to.S3TO;
-import com.cloud.api.query.dao.UserVmJoinDao;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.host.dao.HostDao;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.SnapshotVO;
 import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.VMTemplateStorageResourceAssoc;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.VMTemplateZoneVO;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplateZoneDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.download.DownloadMonitor;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
-import com.cloud.storage.snapshot.SnapshotManager;
-import com.cloud.user.Account;
-import com.cloud.user.dao.AccountDao;
 import com.cloud.utils.S3Utils;
 import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.dao.UserVmDao;
 
-public class S3ImageStoreDriverImpl implements ImageStoreDriver {
+public class S3ImageStoreDriverImpl extends  BaseImageStoreDriverImpl {
     private static final Logger s_logger = Logger.getLogger(S3ImageStoreDriverImpl.class);
-    @Inject
-    VMTemplateZoneDao templateZoneDao;
-    @Inject
-    VMTemplateDao templateDao;
-    @Inject
-    DownloadMonitor _downloadMonitor;
+
     @Inject
     ImageStoreDetailsDao _imageStoreDetailsDao;
-    @Inject
-    VolumeDao volumeDao;
-    @Inject
-    VolumeDataStoreDao _volumeStoreDao;
-    @Inject
-    HostDao hostDao;
-    @Inject
-    SnapshotDao snapshotDao;
-    @Inject
-    AgentManager agentMgr;
-    @Inject
-    SnapshotManager snapshotMgr;
-    @Inject
-    AccountDao _accountDao;
-    @Inject
-    UserVmDao _userVmDao;
-    @Inject
-    UserVmJoinDao _userVmJoinDao;
-    @Inject
-    SecondaryStorageVmManager _ssvmMgr;
-    @Inject
-    TemplateDataStoreDao _templateStoreDao;
-    @Inject
-    EndPointSelector _epSelector;
-    @Inject
-    DataStoreManager _dataStoreMgr;
 
-    @Override
-    public String grantAccess(DataObject data, EndPoint ep) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public DataTO getTO(DataObject data) {
-        return null;
-    }
 
     @Override
     public DataStoreTO getStoreTO(DataStore store) {
@@ -148,281 +59,6 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver {
 
     }
 
-    @Override
-    public boolean revokeAccess(DataObject data, EndPoint ep) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public Set<DataObject> listObjects(DataStore store) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    class CreateContext<T> extends AsyncRpcConext<T> {
-        final DataObject data;
-
-        public CreateContext(AsyncCompletionCallback<T> callback, DataObject data) {
-            super(callback);
-            this.data = data;
-        }
-    }
-
-    @Override
-    public void createAsync(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
-
-        CreateContext<CreateCmdResult> context = new CreateContext<CreateCmdResult>(callback, data);
-        AsyncCallbackDispatcher<S3ImageStoreDriverImpl, DownloadAnswer> caller = AsyncCallbackDispatcher.create(this);
-        caller.setContext(context);
-        if (data.getType() == DataObjectType.TEMPLATE) {
-            caller.setCallback(caller.getTarget().createTemplateAsyncCallback(null, null));
-            _downloadMonitor.downloadTemplateToStorage(data, caller);
-        } else if (data.getType() == DataObjectType.VOLUME) {
-            caller.setCallback(caller.getTarget().createVolumeAsyncCallback(null, null));
-            _downloadMonitor.downloadVolumeToStorage(data, caller);
-        }
-    }
-
-    private void deleteVolume(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
-        VolumeVO vol = volumeDao.findById(data.getId());
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Expunging " + vol);
-        }
-
-        // Find out if the volume is present on secondary storage
-        VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(vol.getId());
-        if (volumeStore != null) {
-            if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
-                DataStore store = _dataStoreMgr.getDataStore(volumeStore.getDataStoreId(), DataStoreRole.Image);
-                EndPoint ep = _epSelector.select(store);
-                DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(store.getTO(), volumeStore.getVolumeId(),
-                        volumeStore.getInstallPath());
-                Answer answer = ep.sendMessage(dtCommand);
-                if (answer == null || !answer.getResult()) {
-                    s_logger.debug("Failed to delete " + volumeStore + " due to "
-                            + ((answer == null) ? "answer is null" : answer.getDetails()));
-                    return;
-                }
-            } else if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) {
-                s_logger.debug("Volume: " + vol.getName() + " is currently being uploaded; cant' delete it.");
-                throw new CloudRuntimeException("Please specify a volume that is not currently being uploaded.");
-            }
-            _volumeStoreDao.remove(volumeStore.getId());
-            volumeDao.remove(vol.getId());
-            CommandResult result = new CommandResult();
-            callback.complete(result);
-            return;
-        }
-    }
-
-    protected Void createTemplateAsyncCallback(AsyncCallbackDispatcher<S3ImageStoreDriverImpl, DownloadAnswer> callback,
-            CreateContext<CreateCmdResult> context) {
-        DownloadAnswer answer = callback.getResult();
-        DataObject obj = context.data;
-        DataStore store = obj.getDataStore();
-
-        TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(), obj.getId());
-        if (tmpltStoreVO != null) {
-            TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate();
-            updateBuilder.setDownloadPercent(answer.getDownloadPct());
-            updateBuilder.setDownloadState(answer.getDownloadStatus());
-            updateBuilder.setLastUpdated(new Date());
-            updateBuilder.setErrorString(answer.getErrorString());
-            updateBuilder.setJobId(answer.getJobId());
-            updateBuilder.setLocalDownloadPath(answer.getDownloadPath());
-            updateBuilder.setInstallPath(answer.getInstallPath());
-            updateBuilder.setSize(answer.getTemplateSize());
-            updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize());
-            _templateStoreDao.update(tmpltStoreVO.getId(), updateBuilder);
-            // update size in vm_template table
-            VMTemplateVO tmlptUpdater = templateDao.createForUpdate();
-            tmlptUpdater.setSize(answer.getTemplateSize());
-            templateDao.update(obj.getId(), tmlptUpdater);
-        }
-
-        AsyncCompletionCallback<CreateCmdResult> caller = context.getParentCallback();
-
-        if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR
-                || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED
-                || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) {
-            CreateCmdResult result = new CreateCmdResult(null, null);
-            result.setSuccess(false);
-            result.setResult(answer.getErrorString());
-            caller.complete(result);
-        } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
-            if (answer.getCheckSum() != null) {
-                VMTemplateVO templateDaoBuilder = templateDao.createForUpdate();
-                templateDaoBuilder.setChecksum(answer.getCheckSum());
-                templateDao.update(obj.getId(), templateDaoBuilder);
-            }
-
-            CreateCmdResult result = new CreateCmdResult(null, null);
-            caller.complete(result);
-        }
-        return null;
-    }
-
-    protected Void createVolumeAsyncCallback(AsyncCallbackDispatcher<S3ImageStoreDriverImpl, DownloadAnswer> callback,
-            CreateContext<CreateCmdResult> context) {
-        DownloadAnswer answer = callback.getResult();
-        DataObject obj = context.data;
-        DataStore store = obj.getDataStore();
-
-        VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(store.getId(), obj.getId());
-        if (volStoreVO != null) {
-            VolumeDataStoreVO updateBuilder = _volumeStoreDao.createForUpdate();
-            updateBuilder.setDownloadPercent(answer.getDownloadPct());
-            updateBuilder.setDownloadState(answer.getDownloadStatus());
-            updateBuilder.setLastUpdated(new Date());
-            updateBuilder.setErrorString(answer.getErrorString());
-            updateBuilder.setJobId(answer.getJobId());
-            updateBuilder.setLocalDownloadPath(answer.getDownloadPath());
-            updateBuilder.setInstallPath(answer.getInstallPath());
-            updateBuilder.setSize(answer.getTemplateSize());
-            updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize());
-            _volumeStoreDao.update(volStoreVO.getId(), updateBuilder);
-            // update size in volume table
-            VolumeVO volUpdater = volumeDao.createForUpdate();
-            volUpdater.setSize(answer.getTemplateSize());
-            volumeDao.update(obj.getId(), volUpdater);
-        }
-
-        AsyncCompletionCallback<CreateCmdResult> caller = context.getParentCallback();
-
-        if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR
-                || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED
-                || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) {
-            CreateCmdResult result = new CreateCmdResult(null, null);
-            result.setSuccess(false);
-            result.setResult(answer.getErrorString());
-            caller.complete(result);
-        } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
-            CreateCmdResult result = new CreateCmdResult(null, null);
-            caller.complete(result);
-        }
-        return null;
-    }
-
-    private void deleteTemplate(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
-        TemplateObject templateObj = (TemplateObject) data;
-        VMTemplateVO template = templateObj.getImage();
-        ImageStoreImpl store = (ImageStoreImpl) templateObj.getDataStore();
-        long storeId = store.getId();
-        Long sZoneId = store.getDataCenterId();
-        long templateId = template.getId();
-
-        Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId());
-        String eventType = "";
-
-        if (template.getFormat().equals(ImageFormat.ISO)) {
-            eventType = EventTypes.EVENT_ISO_DELETE;
-        } else {
-            eventType = EventTypes.EVENT_TEMPLATE_DELETE;
-        }
-
-        if (sZoneId != null) {
-            // TODO: how to handle region wide usage data where sZoneId == null
-            UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null);
-        }
-
-        // get installpath of this template on image store
-        TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId);
-        String installPath = tmplStore.getInstallPath();
-        if (installPath != null) {
-            DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(),
-                    template.getAccountId());
-            EndPoint ep = _epSelector.select(templateObj);
-            Answer answer = ep.sendMessage(cmd);
-
-            if (answer == null || !answer.getResult()) {
-                s_logger.debug("Failed to deleted template at store: " + store.getName());
-                CommandResult result = new CommandResult();
-                result.setSuccess(false);
-                result.setResult("Delete template failed");
-                callback.complete(result);
-
-            } else {
-                s_logger.debug("Deleted template at: " + installPath);
-                CommandResult result = new CommandResult();
-                result.setSuccess(true);
-                callback.complete(result);
-            }
-
-            // for S3, a template can be associated with multiple zones
-            List<VMTemplateZoneVO> templateZones = templateZoneDao.listByZoneTemplate(sZoneId, templateId);
-            if (templateZones != null) {
-                for (VMTemplateZoneVO templateZone : templateZones) {
-                    templateZoneDao.remove(templateZone.getId());
-                }
-            }
-        }
-    }
-
-    private void deleteSnapshot(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
-        SnapshotObject snapshotObj = (SnapshotObject) data;
-        DataStore secStore = snapshotObj.getDataStore();
-        CommandResult result = new CommandResult();
-        SnapshotVO snapshot = snapshotObj.getSnapshotVO();
-
-        if (snapshot == null) {
-            s_logger.debug("Destroying snapshot " + snapshotObj.getId()
-                    + " backup failed due to unable to find snapshot ");
-            result.setResult("Unable to find snapshot: " + snapshotObj.getId());
-            callback.complete(result);
-            return;
-        }
-
-        try {
-
-            String backupOfSnapshot = snapshotObj.getPath();
-            if (backupOfSnapshot == null) {
-                callback.complete(result);
-                return;
-            }
-
-            DeleteSnapshotBackupCommand2 cmd = new DeleteSnapshotBackupCommand2(secStore.getTO(), backupOfSnapshot);
-            EndPoint ep = _epSelector.select(secStore);
-            Answer answer = ep.sendMessage(cmd);
-
-            if (answer != null) {
-                result.setResult(answer.getDetails());
-            }
-        } catch (Exception e) {
-            s_logger.debug("failed to delete snapshot: " + snapshotObj.getId() + ": " + e.toString());
-            result.setResult(e.toString());
-        }
-        callback.complete(result);
-    }
-
-    @Override
-    public void deleteAsync(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
-        if (data.getType() == DataObjectType.VOLUME) {
-            deleteVolume(data, callback);
-        } else if (data.getType() == DataObjectType.TEMPLATE) {
-            deleteTemplate(data, callback);
-        } else if (data.getType() == DataObjectType.SNAPSHOT) {
-            deleteSnapshot(data, callback);
-        }
-    }
-
-    @Override
-    public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean canCopy(DataObject srcData, DataObject destData) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void resize(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
-        // TODO Auto-generated method stub
-
-    }
 
     @Override
     public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66e70222/plugins/storage/image/sample/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/storage/image/sample/pom.xml b/plugins/storage/image/sample/pom.xml
index d9eab9b..44b50b0 100644
--- a/plugins/storage/image/sample/pom.xml
+++ b/plugins/storage/image/sample/pom.xml
@@ -22,6 +22,11 @@
   <dependencies>
     <dependency>
       <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-storage</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
       <artifactId>cloud-engine-storage-image</artifactId>
       <version>${project.version}</version>
     </dependency>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66e70222/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java
----------------------------------------------------------------------
diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java
index abc8741..2dae3c8 100644
--- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java
+++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java
@@ -18,30 +18,17 @@
  */
 package org.apache.cloudstack.storage.datastore.driver;
 
-import java.util.Set;
-
 import javax.inject.Inject;
 
-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.DataObject;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
-import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-import org.apache.cloudstack.storage.command.CommandResult;
-import org.apache.cloudstack.storage.command.CreateObjectAnswer;
-import org.apache.cloudstack.storage.command.CreateObjectCommand;
-import org.apache.cloudstack.storage.image.ImageStoreDriver;
-
-import com.cloud.agent.api.to.DataObjectType;
+import org.apache.cloudstack.storage.image.BaseImageStoreDriverImpl;
 import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
 import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.dao.VMTemplateDao;
 
 //http-read-only based image store
-public class SampleImageStoreDriverImpl implements ImageStoreDriver {
+public class SampleImageStoreDriverImpl extends BaseImageStoreDriverImpl {
     @Inject
     EndPointSelector selector;
     @Inject
@@ -50,10 +37,6 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver {
     public SampleImageStoreDriverImpl() {
     }
 
-    @Override
-    public DataTO getTO(DataObject data) {
-        return null;
-    }
 
     @Override
     public DataStoreTO getStoreTO(DataStore store) {
@@ -61,80 +44,7 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver {
         return null;
     }
 
-    @Override
-    public String grantAccess(DataObject data, EndPoint ep) {
-        return data.getUri();
-    }
-
-    @Override
-    public boolean revokeAccess(DataObject data, EndPoint ep) {
-        // TODO Auto-generated method stub
-        return true;
-    }
-
-    @Override
-    public Set<DataObject> listObjects(DataStore store) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void createAsync(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
-        // for default http data store, can create http based template/iso
-        CreateCmdResult result = new CreateCmdResult("", null);
-        if (!data.getUri().startsWith("http")) {
-            result.setResult("can't register an image which is not a http link");
-            callback.complete(result);
-            return;
-        }
-
-        if (data.getSize() == null && data.getType() == DataObjectType.TEMPLATE) {
-            // the template size is unknown during registration, need to find
-            // out the size of template
-            EndPoint ep = selector.select(data);
-            if (ep == null) {
-                result.setResult("can't find storage client for:" + data.getId() + "," + data.getType());
-                callback.complete(result);
-                return;
-            }
-            CreateObjectCommand createCmd = new CreateObjectCommand(data.getTO());
-            CreateObjectAnswer answer = (CreateObjectAnswer) ep.sendMessage(createCmd);
-            if (answer.getResult()) {
-                // update imagestorevo
-
-                result = new CreateCmdResult(null, null);
-            } else {
-                result.setResult(answer.getDetails());
-            }
 
-        }
-
-        callback.complete(result);
-    }
-
-    @Override
-    public void deleteAsync(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
-        CommandResult result = new CommandResult();
-        callback.complete(result);
-    }
-
-    @Override
-    public boolean canCopy(DataObject srcData, DataObject destData) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void resize(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
-        // TODO Auto-generated method stub
-
-    }
 
     @Override
     public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66e70222/plugins/storage/image/swift/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/storage/image/swift/pom.xml b/plugins/storage/image/swift/pom.xml
index 6254cce..4e3907f 100644
--- a/plugins/storage/image/swift/pom.xml
+++ b/plugins/storage/image/swift/pom.xml
@@ -22,6 +22,11 @@
   <dependencies>
     <dependency>
       <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-storage</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
       <artifactId>cloud-engine-storage-image</artifactId>
       <version>${project.version}</version>
     </dependency>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66e70222/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java
----------------------------------------------------------------------
diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java
index bd48c44..bd5a14a 100644
--- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java
+++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java
@@ -18,125 +18,27 @@
  */
 package org.apache.cloudstack.storage.datastore.driver;
 
-import java.util.Date;
-import java.util.List;
 import java.util.Map;
-import java.util.Set;
-
 import javax.inject.Inject;
 
 import org.apache.cloudstack.api.ApiConstants;
-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.DataObject;
 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.EndPoint;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
-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.command.CommandResult;
 import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
-import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
-import org.apache.cloudstack.storage.image.ImageStoreDriver;
+import org.apache.cloudstack.storage.image.BaseImageStoreDriverImpl;
 import org.apache.cloudstack.storage.image.store.ImageStoreImpl;
-import org.apache.cloudstack.storage.image.store.TemplateObject;
-import org.apache.cloudstack.storage.snapshot.SnapshotObject;
 import org.apache.log4j.Logger;
 
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.DeleteSnapshotBackupCommand2;
-import com.cloud.agent.api.storage.DeleteTemplateCommand;
-import com.cloud.agent.api.storage.DeleteVolumeCommand;
-import com.cloud.agent.api.storage.DownloadAnswer;
-import com.cloud.agent.api.to.DataObjectType;
 import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
 import com.cloud.agent.api.to.SwiftTO;
-import com.cloud.api.query.dao.UserVmJoinDao;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
 import com.cloud.exception.UnsupportedServiceException;
-import com.cloud.host.dao.HostDao;
 import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.VMTemplateStorageResourceAssoc;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.VMTemplateZoneVO;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplateZoneDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.download.DownloadMonitor;
-import com.cloud.storage.s3.S3Manager;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
-import com.cloud.storage.snapshot.SnapshotManager;
-import com.cloud.storage.swift.SwiftManager;
-import com.cloud.user.Account;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.dao.UserVmDao;
 
-public class SwiftImageStoreDriverImpl implements ImageStoreDriver {
+public class SwiftImageStoreDriverImpl extends BaseImageStoreDriverImpl {
     private static final Logger s_logger = Logger.getLogger(SwiftImageStoreDriverImpl.class);
-    @Inject
-    VMTemplateZoneDao templateZoneDao;
-    @Inject
-    VMTemplateDao templateDao;
-    @Inject
-    DownloadMonitor _downloadMonitor;
+
     @Inject
     ImageStoreDetailsDao _imageStoreDetailsDao;
-    @Inject
-    VolumeDao volumeDao;
-    @Inject
-    VolumeDataStoreDao _volumeStoreDao;
-    @Inject
-    HostDao hostDao;
-    @Inject
-    SnapshotDao snapshotDao;
-    @Inject
-    AgentManager agentMgr;
-    @Inject
-    SnapshotManager snapshotMgr;
-    @Inject
-    private SwiftManager _swiftMgr;
-    @Inject
-    private S3Manager _s3Mgr;
-    @Inject
-    AccountDao _accountDao;
-    @Inject
-    UserVmDao _userVmDao;
-    @Inject
-    UserVmJoinDao _userVmJoinDao;
-    @Inject
-    SecondaryStorageVmManager _ssvmMgr;
-    @Inject
-    private AgentManager _agentMgr;
-    @Inject
-    TemplateDataStoreDao _templateStoreDao;
-    @Inject
-    EndPointSelector _epSelector;
-    @Inject
-    DataStoreManager _dataStoreMgr;
 
-    @Override
-    public String grantAccess(DataObject data, EndPoint ep) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public DataTO getTO(DataObject data) {
-        return null;
-    }
 
     @Override
     public DataStoreTO getStoreTO(DataStore store) {
@@ -146,284 +48,6 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver {
                 details.get(ApiConstants.USERNAME), details.get(ApiConstants.KEY));
     }
 
-    @Override
-    public boolean revokeAccess(DataObject data, EndPoint ep) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public Set<DataObject> listObjects(DataStore store) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    class CreateContext<T> extends AsyncRpcConext<T> {
-        final DataObject data;
-
-        public CreateContext(AsyncCompletionCallback<T> callback, DataObject data) {
-            super(callback);
-            this.data = data;
-        }
-    }
-
-    @Override
-    public void createAsync(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
-        CreateContext<CreateCmdResult> context = new CreateContext<CreateCmdResult>(callback, data);
-        AsyncCallbackDispatcher<SwiftImageStoreDriverImpl, DownloadAnswer> caller = AsyncCallbackDispatcher
-                .create(this);
-        caller.setContext(context);
-        if (data.getType() == DataObjectType.TEMPLATE) {
-            caller.setCallback(caller.getTarget().createTemplateAsyncCallback(null, null));
-            _downloadMonitor.downloadTemplateToStorage(data, caller);
-        } else if (data.getType() == DataObjectType.VOLUME) {
-            caller.setCallback(caller.getTarget().createVolumeAsyncCallback(null, null));
-            _downloadMonitor.downloadVolumeToStorage(data, caller);
-        }
-    }
-
-    protected Void createTemplateAsyncCallback(AsyncCallbackDispatcher<SwiftImageStoreDriverImpl, DownloadAnswer> callback,
-            CreateContext<CreateCmdResult> context) {
-        DownloadAnswer answer = callback.getResult();
-        DataObject obj = context.data;
-        DataStore store = obj.getDataStore();
-
-        TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(), obj.getId());
-        if (tmpltStoreVO != null) {
-            TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate();
-            updateBuilder.setDownloadPercent(answer.getDownloadPct());
-            updateBuilder.setDownloadState(answer.getDownloadStatus());
-            updateBuilder.setLastUpdated(new Date());
-            updateBuilder.setErrorString(answer.getErrorString());
-            updateBuilder.setJobId(answer.getJobId());
-            updateBuilder.setLocalDownloadPath(answer.getDownloadPath());
-            updateBuilder.setInstallPath(answer.getInstallPath());
-            updateBuilder.setSize(answer.getTemplateSize());
-            updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize());
-            _templateStoreDao.update(tmpltStoreVO.getId(), updateBuilder);
-            // update size in vm_template table
-            VMTemplateVO tmlptUpdater = templateDao.createForUpdate();
-            tmlptUpdater.setSize(answer.getTemplateSize());
-            templateDao.update(obj.getId(), tmlptUpdater);
-        }
-
-        AsyncCompletionCallback<CreateCmdResult> caller = context.getParentCallback();
-
-        if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR
-                || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED
-                || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) {
-            CreateCmdResult result = new CreateCmdResult(null, null);
-            result.setSuccess(false);
-            result.setResult(answer.getErrorString());
-            caller.complete(result);
-        } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
-            if (answer.getCheckSum() != null) {
-                VMTemplateVO templateDaoBuilder = templateDao.createForUpdate();
-                templateDaoBuilder.setChecksum(answer.getCheckSum());
-                templateDao.update(obj.getId(), templateDaoBuilder);
-            }
-
-            CreateCmdResult result = new CreateCmdResult(null, null);
-            caller.complete(result);
-        }
-        return null;
-    }
-
-    protected Void createVolumeAsyncCallback(AsyncCallbackDispatcher<SwiftImageStoreDriverImpl, DownloadAnswer> callback,
-            CreateContext<CreateCmdResult> context) {
-        DownloadAnswer answer = callback.getResult();
-        DataObject obj = context.data;
-        DataStore store = obj.getDataStore();
-
-        VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(store.getId(), obj.getId());
-        if (volStoreVO != null) {
-            VolumeDataStoreVO updateBuilder = _volumeStoreDao.createForUpdate();
-            updateBuilder.setDownloadPercent(answer.getDownloadPct());
-            updateBuilder.setDownloadState(answer.getDownloadStatus());
-            updateBuilder.setLastUpdated(new Date());
-            updateBuilder.setErrorString(answer.getErrorString());
-            updateBuilder.setJobId(answer.getJobId());
-            updateBuilder.setLocalDownloadPath(answer.getDownloadPath());
-            updateBuilder.setInstallPath(answer.getInstallPath());
-            updateBuilder.setSize(answer.getTemplateSize());
-            updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize());
-            _volumeStoreDao.update(volStoreVO.getId(), updateBuilder);
-            // update size in volume table
-            VolumeVO volUpdater = volumeDao.createForUpdate();
-            volUpdater.setSize(answer.getTemplateSize());
-            volumeDao.update(obj.getId(), volUpdater);
-        }
-
-        AsyncCompletionCallback<CreateCmdResult> caller = context.getParentCallback();
-
-        if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR
-                || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED
-                || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) {
-            CreateCmdResult result = new CreateCmdResult(null, null);
-            result.setSuccess(false);
-            result.setResult(answer.getErrorString());
-            caller.complete(result);
-        } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
-            CreateCmdResult result = new CreateCmdResult(null, null);
-            caller.complete(result);
-        }
-        return null;
-    }
-
-    private void deleteVolume(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
-        // TODO Auto-generated method stub
-        VolumeVO vol = volumeDao.findById(data.getId());
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Expunging " + vol);
-        }
-
-        // Find out if the volume is present on secondary storage
-        VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(vol.getId());
-        if (volumeStore != null) {
-            if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
-                DataStore store = this._dataStoreMgr.getDataStore(volumeStore.getDataStoreId(), DataStoreRole.Image);
-                EndPoint ep = _epSelector.select(store);
-                DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(store.getTO(), volumeStore.getVolumeId(),
-                        volumeStore.getInstallPath());
-                Answer answer = ep.sendMessage(dtCommand);
-                if (answer == null || !answer.getResult()) {
-                    s_logger.debug("Failed to delete " + volumeStore + " due to "
-                            + ((answer == null) ? "answer is null" : answer.getDetails()));
-                    return;
-                }
-            } else if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) {
-                s_logger.debug("Volume: " + vol.getName() + " is currently being uploaded; cant' delete it.");
-                throw new CloudRuntimeException("Please specify a volume that is not currently being uploaded.");
-            }
-            _volumeStoreDao.remove(volumeStore.getId());
-            volumeDao.remove(vol.getId());
-            CommandResult result = new CommandResult();
-            callback.complete(result);
-            return;
-        }
-    }
-
-    private void deleteTemplate(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
-        TemplateObject templateObj = (TemplateObject) data;
-        VMTemplateVO template = templateObj.getImage();
-        ImageStoreImpl store = (ImageStoreImpl) templateObj.getDataStore();
-        long storeId = store.getId();
-        Long sZoneId = store.getDataCenterId();
-        long templateId = template.getId();
-
-        Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId());
-        String eventType = "";
-
-        if (template.getFormat().equals(ImageFormat.ISO)) {
-            eventType = EventTypes.EVENT_ISO_DELETE;
-        } else {
-            eventType = EventTypes.EVENT_TEMPLATE_DELETE;
-        }
-
-        // TODO: need to understand why we need to mark destroyed in
-        // template_store_ref table here instead of in callback.
-        // Currently I did that in callback, so I removed previous code to mark
-        // template_host_ref
-        if (sZoneId != null) {
-            UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null);
-        }
-
-        // get installpath of this template on image store
-        TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId);
-        String installPath = tmplStore.getInstallPath();
-        if (installPath != null) {
-            DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(),
-                    template.getAccountId());
-            EndPoint ep = _epSelector.select(templateObj);
-            Answer answer = ep.sendMessage(cmd);
-
-            if (answer == null || !answer.getResult()) {
-                s_logger.debug("Failed to deleted template at store: " + store.getName());
-                CommandResult result = new CommandResult();
-                // result.setSucess(false);
-                result.setResult("Delete template failed");
-                callback.complete(result);
-
-            } else {
-                s_logger.debug("Deleted template at: " + installPath);
-                CommandResult result = new CommandResult();
-                // result.setSucess(true);
-                callback.complete(result);
-            }
-
-            // for Swift, a template can be associated with multiple zones
-            List<VMTemplateZoneVO> templateZones = templateZoneDao.listByZoneTemplate(sZoneId, templateId);
-            if (templateZones != null) {
-                for (VMTemplateZoneVO templateZone : templateZones) {
-                    templateZoneDao.remove(templateZone.getId());
-                }
-            }
-        }
-    }
-
-    private void deleteSnapshot(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
-        SnapshotObject snapshotObj = (SnapshotObject) data;
-        DataStore secStore = snapshotObj.getDataStore();
-        CommandResult result = new CommandResult();
-        SnapshotVO snapshot = snapshotObj.getSnapshotVO();
-
-        if (snapshot == null) {
-            s_logger.debug("Destroying snapshot " + snapshotObj.getId()
-                    + " backup failed due to unable to find snapshot ");
-            result.setResult("Unable to find snapshot: " + snapshotObj.getId());
-            callback.complete(result);
-            return;
-        }
-
-        try {
-            String backupOfSnapshot = snapshotObj.getPath();
-            if (backupOfSnapshot == null) {
-                callback.complete(result);
-                return;
-            }
-
-            DeleteSnapshotBackupCommand2 cmd = new DeleteSnapshotBackupCommand2(secStore.getTO(), backupOfSnapshot);
-            EndPoint ep = _epSelector.select(secStore);
-            Answer answer = ep.sendMessage(cmd);
-
-            if (answer != null) {
-                result.setResult(answer.getDetails());
-            }
-        } catch (Exception e) {
-            s_logger.debug("failed to delete snapshot: " + snapshotObj.getId() + ": " + e.toString());
-            result.setResult(e.toString());
-        }
-        callback.complete(result);
-    }
-
-    @Override
-    public void deleteAsync(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
-        if (data.getType() == DataObjectType.VOLUME) {
-            deleteVolume(data, callback);
-        } else if (data.getType() == DataObjectType.TEMPLATE) {
-            deleteTemplate(data, callback);
-        } else if (data.getType() == DataObjectType.SNAPSHOT) {
-            deleteSnapshot(data, callback);
-        }
-    }
-
-    @Override
-    public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean canCopy(DataObject srcData, DataObject destData) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void resize(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
-        // TODO Auto-generated method stub
-
-    }
 
     @Override
     public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66e70222/server/src/com/cloud/storage/StorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java
index 35fa323..d5b3f23 100755
--- a/server/src/com/cloud/storage/StorageManagerImpl.java
+++ b/server/src/com/cloud/storage/StorageManagerImpl.java
@@ -71,6 +71,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
 import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
 import org.apache.cloudstack.framework.async.AsyncCallFuture;
+import org.apache.cloudstack.storage.command.DeleteCommand;
 import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
 import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
 import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
@@ -88,8 +89,6 @@ import org.springframework.stereotype.Component;
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.Command;
-import com.cloud.agent.api.DeleteSnapshotBackupCommand;
-import com.cloud.agent.api.DeleteSnapshotBackupCommand2;
 import com.cloud.agent.api.StoragePoolInfo;
 import com.cloud.agent.api.storage.DeleteTemplateCommand;
 import com.cloud.agent.api.storage.DeleteVolumeCommand;
@@ -1198,7 +1197,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
 
                         if (installPath != null) {
                             EndPoint ep = _epSelector.select(store);
-                            DeleteSnapshotBackupCommand2 cmd = new DeleteSnapshotBackupCommand2(store.getTO(), destroyedSnapshotStoreVO.getInstallPath());
+                            DeleteCommand cmd = new DeleteCommand(snap.getTO());
                             Answer answer = ep.sendMessage(cmd);
                             if (answer == null || !answer.getResult()) {
                                 s_logger.debug("Failed to delete " + destroyedSnapshotStoreVO + " due to "

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66e70222/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 a87f542..a7e6137 100755
--- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
+++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
@@ -17,7 +17,6 @@
 package com.cloud.storage.snapshot;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -45,27 +44,19 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.Command;
-import com.cloud.agent.api.DeleteSnapshotBackupCommand;
-import com.cloud.agent.api.DeleteSnapshotBackupCommand2;
 import com.cloud.agent.api.DeleteSnapshotsDirCommand;
-import com.cloud.agent.api.DownloadSnapshotFromS3Command;
-import com.cloud.agent.api.DownloadSnapshotFromSwiftCommand;
-import com.cloud.agent.api.to.S3TO;
-import com.cloud.agent.api.to.SwiftTO;
 import com.cloud.alert.AlertManager;
 import com.cloud.api.commands.ListRecurringSnapshotScheduleCmd;
 import com.cloud.configuration.Config;
 import com.cloud.configuration.Resource.ResourceType;
 import com.cloud.configuration.dao.ConfigurationDao;
 import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenter;
 import com.cloud.dc.DataCenterVO;
 import com.cloud.dc.dao.ClusterDao;
 import com.cloud.dc.dao.DataCenterDao;
@@ -83,7 +74,6 @@ import com.cloud.exception.StorageUnavailableException;
 import com.cloud.host.HostVO;
 import com.cloud.host.dao.HostDao;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.org.Grouping;
 import com.cloud.projects.Project.ListProjectResourcesCriteria;
 import com.cloud.resource.ResourceManager;
 import com.cloud.server.ResourceTag.TaggedResourceType;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66e70222/server/src/com/cloud/template/HypervisorTemplateAdapter.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java
index e1d535b..92148c3 100755
--- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java
+++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java
@@ -16,11 +16,6 @@
 // under the License.
 package com.cloud.template;
 
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.UnknownHostException;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 
@@ -47,6 +42,7 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 import org.apache.cloudstack.framework.async.AsyncRpcConext;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
 import org.apache.log4j.Logger;
+import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
@@ -54,14 +50,19 @@ import com.cloud.agent.api.storage.PrepareOVAPackingCommand;
 import com.cloud.alert.AlertManager;
 import com.cloud.configuration.Resource.ResourceType;
 import com.cloud.dc.DataCenterVO;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.ResourceAllocationException;
 import com.cloud.host.HostVO;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.Storage.TemplateType;
 import com.cloud.storage.TemplateProfile;
+import com.cloud.storage.VMTemplateZoneVO;
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.dao.VMTemplateZoneDao;
 import com.cloud.storage.download.DownloadMonitor;
 import com.cloud.user.Account;
 import com.cloud.utils.UriUtils;
@@ -79,6 +80,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
     @Inject TemplateDataFactory imageFactory;
     @Inject TemplateManager templateMgr;
     @Inject AlertManager alertMgr;
+    @Inject VMTemplateZoneDao templateZoneDao;
     @Inject
     EndPointSelector _epSelector;
 
@@ -219,8 +221,20 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
             }
         }
 
+        String eventType = "";
+        if (template.getFormat().equals(ImageFormat.ISO)) {
+            eventType = EventTypes.EVENT_ISO_DELETE;
+        } else {
+            eventType = EventTypes.EVENT_TEMPLATE_DELETE;
+        }
 
         for (DataStore imageStore : imageStores) {
+            // publish zone-wide usage event
+            Long sZoneId = ((ImageStoreEntity)imageStore).getDataCenterId();
+            if (sZoneId != null) {
+                UsageEventUtils.publishUsageEvent(eventType, template.getAccountId(), sZoneId, template.getId(), null, null, null);
+            }
+
             s_logger.info("Delete template from image store: " + imageStore.getName());
             AsyncCallFuture<TemplateApiResult> future = this.imageService
                     .deleteTemplateAsync(this.imageFactory.getTemplate(template.getId(), imageStore));
@@ -229,6 +243,14 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
                 success = result.isSuccess();
                 if ( !success )
                     break;
+
+                // remove from template_zone_ref
+                List<VMTemplateZoneVO> templateZones = templateZoneDao.listByZoneTemplate(sZoneId, template.getId());
+                if (templateZones != null) {
+                    for (VMTemplateZoneVO templateZone : templateZones) {
+                        templateZoneDao.remove(templateZone.getId());
+                    }
+                }
             } catch (InterruptedException e) {
                 s_logger.debug("delete template Failed", e);
                 throw new CloudRuntimeException("delete template Failed", e);