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/12 03:10:11 UTC

[1/4] git commit: updated refs/heads/object_store to bb64672

Updated Branches:
  refs/heads/object_store cd2d066fd -> bb6467271


Fix ImageStoreDaoImpl to return only image stores, not image cache
stores.

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

Branch: refs/heads/object_store
Commit: 582a1f0539869290d65d4a05b7ccf2897205f859
Parents: cd2d066
Author: Min Chen <mi...@citrix.com>
Authored: Thu Apr 11 11:54:30 2013 -0700
Committer: Min Chen <mi...@citrix.com>
Committed: Thu Apr 11 11:54:30 2013 -0700

----------------------------------------------------------------------
 .../storage/image/db/ImageStoreDaoImpl.java        |   10 ++++++++--
 .../cloud/storage/download/DownloadListener.java   |   11 +++++++----
 2 files changed, 15 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/582a1f05/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java
index 5bcf2f3..ee07822 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java
@@ -24,6 +24,7 @@ import java.util.Map;
 import javax.naming.ConfigurationException;
 
 
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole;
 import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
 import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
 import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
@@ -50,10 +51,12 @@ public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implem
 
         nameSearch = createSearchBuilder();
         nameSearch.and("name", nameSearch.entity().getName(), SearchCriteria.Op.EQ);
+        nameSearch.and("role", nameSearch.entity().getRole(), SearchCriteria.Op.EQ);
         nameSearch.done();
 
         providerSearch = createSearchBuilder();
         providerSearch.and("providerName", providerSearch.entity().getProviderName(), SearchCriteria.Op.EQ);
+        providerSearch.and("role", providerSearch.entity().getProviderName(), SearchCriteria.Op.EQ);
         providerSearch.done();
 
         return true;
@@ -76,8 +79,11 @@ public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implem
     @Override
     public List<ImageStoreVO> findByScope(ZoneScope scope) {
         SearchCriteria<ImageStoreVO> sc = createSearchCriteria();
-        sc.addOr("scope", SearchCriteria.Op.EQ, ScopeType.REGION);
-        sc.addOr("dcId", SearchCriteria.Op.EQ, scope.getScopeId());
+        sc.addAnd("role", SearchCriteria.Op.EQ, DataStoreRole.Image);
+        SearchCriteria<ImageStoreVO> scc = createSearchCriteria();
+        scc.addOr("scope", SearchCriteria.Op.EQ, ScopeType.REGION);
+        scc.addOr("dcId", SearchCriteria.Op.EQ, scope.getScopeId());
+        sc.addAnd("scope", SearchCriteria.Op.SC, scc);
         return listBy(sc);
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/582a1f05/server/src/com/cloud/storage/download/DownloadListener.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/download/DownloadListener.java b/server/src/com/cloud/storage/download/DownloadListener.java
index 2741af1..8e979ab 100755
--- a/server/src/com/cloud/storage/download/DownloadListener.java
+++ b/server/src/com/cloud/storage/download/DownloadListener.java
@@ -474,17 +474,20 @@ public class DownloadListener implements Listener {
 	@Override
 	public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
 	    if (cmd instanceof StartupRoutingCommand) {
+
 	        downloadMonitor.handleSysTemplateDownload(agent);
-	    } else if ( cmd instanceof StartupStorageCommand) {
+	    }
+	    /* This can be removed since
+	    else if ( cmd instanceof StartupStorageCommand) {
 	        StartupStorageCommand storage = (StartupStorageCommand)cmd;
             if( storage.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE ||
                     storage.getResourceType() == Storage.StorageResourceType.LOCAL_SECONDARY_STORAGE  ) {
                 downloadMonitor.addSystemVMTemplatesToHost(agent, storage.getTemplateInfo());
-                // DO we need to do sync here since we have been doing sync in StartupSecondaryStorageCommand?
-               // downloadMonitor.handleTemplateSync(agent);
+                downloadMonitor.handleTemplateSync(agent);
                 downloadMonitor.handleVolumeSync(agent);
             }
-	    } else if ( cmd instanceof StartupSecondaryStorageCommand ) {
+	    }*/
+	    else if ( cmd instanceof StartupSecondaryStorageCommand ) {
 	        downloadMonitor.handleSync(agent.getDataCenterId());
 	    }
 	}


[3/4] Refactor DownloadMonitorImpl code, move some functionalities to TemplateServiceImpl and VolumeServiceImpl.

Posted by mc...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java
index a429dc9..e34a1ab 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java
@@ -30,6 +30,7 @@ import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
 import com.cloud.storage.VMTemplateHostVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 import com.cloud.utils.db.GenericDaoBase;
 import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria;
@@ -42,23 +43,20 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
     private static final Logger s_logger = Logger.getLogger(TemplateDataStoreDaoImpl.class);
     private SearchBuilder<TemplateDataStoreVO> updateStateSearch;
     private SearchBuilder<TemplateDataStoreVO> storeSearch;
-    private SearchBuilder<TemplateDataStoreVO> liveStoreSearch;
     private SearchBuilder<TemplateDataStoreVO> storeTemplateStateSearch;
+    private SearchBuilder<TemplateDataStoreVO> storeTemplateDownloadStatusSearch;
     private SearchBuilder<TemplateDataStoreVO> storeTemplateSearch;
 
     @Override
     public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
     	super.configure(name, params);
 
+
         storeSearch = createSearchBuilder();
         storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
+        storeSearch.and("destroyed", storeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
         storeSearch.done();
 
-        liveStoreSearch = createSearchBuilder();
-        liveStoreSearch.and("store_id", liveStoreSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
-        liveStoreSearch.and("destroyed", liveStoreSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
-        liveStoreSearch.done();
-
     	updateStateSearch = this.createSearchBuilder();
         updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ);
         updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ);
@@ -72,6 +70,14 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
         storeTemplateStateSearch.and("destroyed", storeTemplateStateSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
         storeTemplateStateSearch.done();
 
+        storeTemplateDownloadStatusSearch = createSearchBuilder();
+        storeTemplateDownloadStatusSearch.and("template_id", storeTemplateDownloadStatusSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
+        storeTemplateDownloadStatusSearch.and("store_id", storeTemplateDownloadStatusSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
+        storeTemplateDownloadStatusSearch.and("downloadState", storeTemplateDownloadStatusSearch.entity().getDownloadState(), SearchCriteria.Op.IN);
+        storeTemplateDownloadStatusSearch.and("destroyed", storeTemplateDownloadStatusSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
+        storeTemplateDownloadStatusSearch.done();
+
+
         storeTemplateSearch = createSearchBuilder();
         storeTemplateSearch.and("store_id", storeTemplateSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
         storeTemplateSearch.and("template_id", storeTemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
@@ -118,16 +124,11 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
         return rows > 0;
     }
 
+
     @Override
     public List<TemplateDataStoreVO> listByStoreId(long id) {
         SearchCriteria<TemplateDataStoreVO> sc = storeSearch.create();
         sc.setParameters("store_id", id);
-        return listIncludingRemovedBy(sc);
-    }
-    @Override
-    public List<TemplateDataStoreVO> listLiveByStoreId(long id) {
-        SearchCriteria<TemplateDataStoreVO> sc = liveStoreSearch.create();
-        sc.setParameters("store_id", id);
         sc.setParameters("destroyed", false);
         return listIncludingRemovedBy(sc);
     }
@@ -152,6 +153,17 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
         return search(sc, null);
     }
 
+
+
+    @Override
+    public List<TemplateDataStoreVO> listByTemplateStoreDownloadStatus(long templateId, long storeId, Status... status) {
+        SearchCriteria<TemplateDataStoreVO> sc = storeTemplateStateSearch.create();
+        sc.setParameters("template_id", templateId);
+        sc.setParameters("store_id", storeId);
+        sc.setParameters("downloadState", (Object[])status);
+        return search(sc, null);
+    }
+
     @Override
     public TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId) {
         SearchCriteria<TemplateDataStoreVO> sc = storeTemplateSearch.create();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java
index 9a93f98..dc6c235 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java
@@ -31,6 +31,7 @@ import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
+import com.cloud.storage.VolumeHostVO;
 import com.cloud.utils.db.GenericDaoBase;
 import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria;
@@ -42,21 +43,30 @@ import com.cloud.utils.db.UpdateBuilder;
 public class VolumeDataStoreDaoImpl extends GenericDaoBase<VolumeDataStoreVO, Long> implements VolumeDataStoreDao {
     private static final Logger s_logger = Logger.getLogger(VolumeDataStoreDaoImpl.class);
     private SearchBuilder<VolumeDataStoreVO> updateStateSearch;
+    private SearchBuilder<VolumeDataStoreVO> volumeSearch;
     private SearchBuilder<VolumeDataStoreVO> storeSearch;
-    private SearchBuilder<VolumeDataStoreVO> liveStoreSearch;
+    private SearchBuilder<VolumeDataStoreVO> storeVolumeSearch;
 
     @Override
     public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
     	super.configure(name, params);
 
+
         storeSearch = createSearchBuilder();
         storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
+        storeSearch.and("destroyed", storeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
         storeSearch.done();
 
-        liveStoreSearch = createSearchBuilder();
-        liveStoreSearch.and("store_id", liveStoreSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
-        liveStoreSearch.and("destroyed", liveStoreSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
-        liveStoreSearch.done();
+        volumeSearch = createSearchBuilder();
+        volumeSearch.and("volume_id", volumeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
+        volumeSearch.and("destroyed", volumeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
+        volumeSearch.done();
+
+        storeVolumeSearch = createSearchBuilder();
+        storeVolumeSearch.and("store_id", storeVolumeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
+        storeVolumeSearch.and("volume_id", storeVolumeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
+        storeVolumeSearch.and("destroyed", storeVolumeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
+        storeVolumeSearch.done();
 
         updateStateSearch = this.createSearchBuilder();
         updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ);
@@ -102,16 +112,11 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase<VolumeDataStoreVO, Lo
         return rows > 0;
     }
 
+
     @Override
     public List<VolumeDataStoreVO> listByStoreId(long id) {
         SearchCriteria<VolumeDataStoreVO> sc = storeSearch.create();
         sc.setParameters("store_id", id);
-        return listIncludingRemovedBy(sc);
-    }
-    @Override
-    public List<VolumeDataStoreVO> listLiveByStoreId(long id) {
-        SearchCriteria<VolumeDataStoreVO> sc = liveStoreSearch.create();
-        sc.setParameters("store_id", id);
         sc.setParameters("destroyed", false);
         return listIncludingRemovedBy(sc);
     }
@@ -125,4 +130,23 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase<VolumeDataStoreVO, Lo
         remove(sc);
         txn.commit();
     }
+
+
+    @Override
+    public VolumeDataStoreVO findByVolumeId(long volumeId) {
+        SearchCriteria<VolumeDataStoreVO> sc = volumeSearch.create();
+        sc.setParameters("volume_id", volumeId);
+        sc.setParameters("destroyed", false);
+        return findOneBy(sc);
+    }
+    @Override
+    public VolumeDataStoreVO findByStoreVolume(long storeId, long volumeId) {
+        SearchCriteria<VolumeDataStoreVO> sc = storeVolumeSearch.create();
+        sc.setParameters("store_id", storeId);
+        sc.setParameters("volume_id", volumeId);
+        sc.setParameters("destroyed", false);
+        return findOneBy(sc);
+    }
+
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
index cde576b..766d219 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
@@ -318,6 +318,10 @@ public class VolumeObject implements VolumeInfo {
        return this.payload;
     }
 
+    public VolumeVO getVolume(){
+        return this.volumeVO;
+    }
+
 	@Override
 	public HypervisorType getHypervisorType() {
 		return this.volumeDao.getHypervisorType(this.volumeVO.getId());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/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 2b43ade..2da16c1 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
@@ -18,6 +18,11 @@
  */
 package org.apache.cloudstack.storage.volume;
 
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
 import javax.inject.Inject;
 
 import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
@@ -41,19 +46,37 @@ import org.apache.cloudstack.storage.datastore.DataObjectManager;
 import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
 import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
 import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager;
+import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
 import org.apache.log4j.Logger;
 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.alert.AlertManager;
 import com.cloud.configuration.Config;
 import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.exception.AgentUnavailableException;
 import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.host.HostVO;
 import com.cloud.storage.StoragePool;
 import com.cloud.storage.Volume;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 import com.cloud.storage.Volume.Type;
 import com.cloud.storage.VolumeVO;
 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.storage.template.TemplateProp;
+import com.cloud.user.AccountManager;
+import com.cloud.user.ResourceLimitService;
 import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.UriUtils;
 import com.cloud.utils.db.DB;
 import com.cloud.vm.VirtualMachine;
 import com.cloud.vm.dao.VMInstanceDao;
@@ -77,13 +100,29 @@ public class VolumeServiceImpl implements VolumeService {
     @Inject
     VolumeDataFactory volFactory;
     @Inject SnapshotManager snapshotMgr;
+    @Inject
+    ResourceLimitService _resourceLimitMgr;
+    @Inject
+    DownloadMonitor _dlMonitor;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    AlertManager _alertMgr;
     @Inject VMInstanceDao vmDao;
     @Inject
     ConfigurationDao configDao;
+    @Inject
+    SecondaryStorageVmManager _ssvmMgr;
+    @Inject
+    AgentManager _agentMgr;
+    @Inject
+    VolumeDataStoreDao _volumeStoreDao;
+    @Inject
+    VolumeDao _volumeDao;
 
     public VolumeServiceImpl() {
     }
-    
+
     private class CreateVolumeContext<T> extends AsyncRpcConext<T> {
 
         private DataObject volume;
@@ -96,17 +135,17 @@ public class VolumeServiceImpl implements VolumeService {
             this.volume = volume;
             this.future = future;
         }
-        
+
         public DataObject getVolume() {
             return this.volume;
         }
-        
+
         public AsyncCallFuture<VolumeApiResult> getFuture() {
             return this.future;
         }
-        
+
     }
-    
+
     @Override
     public AsyncCallFuture<VolumeApiResult> createVolumeAsync(VolumeInfo volume, DataStore dataStore) {
         AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
@@ -117,11 +156,11 @@ public class VolumeServiceImpl implements VolumeService {
         AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
         caller.setCallback(caller.getTarget().createVolumeCallback(null, null))
         .setContext(context);
-        
+
         dataStore.getDriver().createAsync(volumeOnStore, caller);
         return future;
     }
-    
+
     protected Void createVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeContext<VolumeApiResult> context) {
         CreateCmdResult result = callback.getResult();
         DataObject vo = context.getVolume();
@@ -139,7 +178,7 @@ public class VolumeServiceImpl implements VolumeService {
         context.getFuture().complete(volResult);
         return null;
     }
-    
+
     private class DeleteVolumeContext<T> extends AsyncRpcConext<T> {
         private final VolumeObject volume;
         private AsyncCallFuture<VolumeApiResult> future;
@@ -151,11 +190,11 @@ public class VolumeServiceImpl implements VolumeService {
             this.volume = volume;
             this.future = future;
         }
-        
+
         public VolumeObject getVolume() {
             return this.volume;
         }
-        
+
         public AsyncCallFuture<VolumeApiResult> getFuture() {
             return this.future;
         }
@@ -171,7 +210,7 @@ public class VolumeServiceImpl implements VolumeService {
             future.complete(result);
             return future;
         }
-        
+
         String vmName = null;
         VolumeVO vol = this.volDao.findById(volume.getId());
         if (vol.getVolumeType() == Type.ROOT && vol.getInstanceId() != null) {
@@ -194,19 +233,19 @@ public class VolumeServiceImpl implements VolumeService {
             return future;
         }
         VolumeObject vo = (VolumeObject)volume;
-      
+
         volume.processEvent(Event.ExpungeRequested);
-      
-        
+
+
         DeleteVolumeContext<VolumeApiResult> context = new DeleteVolumeContext<VolumeApiResult>(null, vo, future);
         AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> caller = AsyncCallbackDispatcher.create(this);
         caller.setCallback(caller.getTarget().deleteVolumeCallback(null, null))
             .setContext(context);
-        
+
         volume.getDataStore().getDriver().deleteAsync(volume, caller);
         return future;
     }
-    
+
     public Void deleteVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> callback, DeleteVolumeContext<VolumeApiResult> context) {
         CommandResult result = callback.getResult();
         VolumeObject vo = context.getVolume();
@@ -249,7 +288,7 @@ public class VolumeServiceImpl implements VolumeService {
         private final TemplateInfo srcTemplate;
         private final AsyncCallFuture<VolumeApiResult> future;
         final DataObject destObj;
-        public CreateBaseImageContext(AsyncCompletionCallback<T> callback, VolumeInfo volume, PrimaryDataStore datastore, 
+        public CreateBaseImageContext(AsyncCompletionCallback<T> callback, VolumeInfo volume, PrimaryDataStore datastore,
                 TemplateInfo srcTemplate,
                 AsyncCallFuture<VolumeApiResult> future, DataObject destObj) {
             super(callback);
@@ -259,11 +298,11 @@ public class VolumeServiceImpl implements VolumeService {
             this.srcTemplate = srcTemplate;
             this.destObj = destObj;
         }
-        
+
         public VolumeInfo getVolume() {
             return this.volume;
         }
-        
+
         public PrimaryDataStore getDataStore() {
             return this.dataStore;
         }
@@ -271,13 +310,13 @@ public class VolumeServiceImpl implements VolumeService {
         public TemplateInfo getSrcTemplate() {
             return this.srcTemplate;
         }
-        
+
         public AsyncCallFuture<VolumeApiResult> getFuture() {
             return this.future;
         }
-        
+
     }
-    
+
     static class CreateBaseImageResult extends CommandResult {
         final TemplateInfo template;
         public CreateBaseImageResult(TemplateInfo template) {
@@ -285,7 +324,7 @@ public class VolumeServiceImpl implements VolumeService {
             this.template = template;
         }
     }
-    
+
     private TemplateInfo waitForTemplateDownloaded(PrimaryDataStore store, TemplateInfo template) {
     	int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
     	int sleepTime = 120;
@@ -306,16 +345,16 @@ public class VolumeServiceImpl implements VolumeService {
     }
     @DB
     protected void createBaseImageAsync(VolumeInfo volume, PrimaryDataStore dataStore, TemplateInfo template, AsyncCallFuture<VolumeApiResult> future) {
-       
+
         DataObject templateOnPrimaryStoreObj = dataStore.create(template);
-        CreateBaseImageContext<CreateCmdResult> context = new CreateBaseImageContext<CreateCmdResult>(null, volume, 
+        CreateBaseImageContext<CreateCmdResult> context = new CreateBaseImageContext<CreateCmdResult>(null, volume,
                 dataStore,
                 template,
                 future, templateOnPrimaryStoreObj);
         AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
         caller.setCallback(caller.getTarget().copyBaseImageCallback(null, null))
         .setContext(context);
-        
+
         try {
          	templateOnPrimaryStoreObj.processEvent(Event.CreateOnlyRequested);
         } catch (Exception e) {
@@ -330,7 +369,7 @@ public class VolumeServiceImpl implements VolumeService {
         		}
         	}
         }
-        
+
         try {
             motionSrv.copyAsync(template, templateOnPrimaryStoreObj, caller);
         } catch (Exception e) {
@@ -342,12 +381,12 @@ public class VolumeServiceImpl implements VolumeService {
         }
         return;
     }
-    
+
     @DB
     protected Void copyBaseImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CreateBaseImageContext<VolumeApiResult> context) {
         CopyCommandResult result = callback.getResult();
         VolumeApiResult res = new VolumeApiResult(context.getVolume());
-        
+
         AsyncCallFuture<VolumeApiResult> future = context.getFuture();
         DataObject templateOnPrimaryStoreObj = context.destObj;
         if (!result.isSuccess()) {
@@ -356,18 +395,18 @@ public class VolumeServiceImpl implements VolumeService {
             future.complete(res);
             return null;
         }
-        
+
         templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed);
         createVolumeFromBaseImageAsync(context.volume, templateOnPrimaryStoreObj, context.dataStore, future);
         return null;
     }
-    
+
     private class CreateVolumeFromBaseImageContext<T> extends AsyncRpcConext<T> {
         private final VolumeObject vo;
         private final AsyncCallFuture<VolumeApiResult> future;
         private final DataStore primaryStore;
         private final DataObject templateOnStore;
-        public CreateVolumeFromBaseImageContext(AsyncCompletionCallback<T> callback, VolumeObject vo, 
+        public CreateVolumeFromBaseImageContext(AsyncCompletionCallback<T> callback, VolumeObject vo,
                 DataStore primaryStore,
                 DataObject templateOnStore,
                 AsyncCallFuture<VolumeApiResult> future) {
@@ -377,13 +416,13 @@ public class VolumeServiceImpl implements VolumeService {
             this.primaryStore = primaryStore;
             this.templateOnStore = templateOnStore;
         }
-        
+
 
         public AsyncCallFuture<VolumeApiResult> getFuture() {
             return this.future;
         }
     }
-    
+
     @DB
     protected void createVolumeFromBaseImageAsync(VolumeInfo volume, DataObject templateOnPrimaryStore, PrimaryDataStore pd, AsyncCallFuture<VolumeApiResult> future) {
         VolumeObject vo = (VolumeObject)volume;
@@ -398,23 +437,23 @@ public class VolumeServiceImpl implements VolumeService {
         motionSrv.copyAsync(context.templateOnStore, volumeOnPrimaryStorage, caller);
         return;
     }
-    
+
     @DB
     public Void copyBaseImageCallBack(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CreateVolumeFromBaseImageContext<VolumeApiResult> context) {
         VolumeObject vo = context.vo;
         CopyCommandResult result = callback.getResult();
         VolumeApiResult volResult = new VolumeApiResult(vo);
-       
+
         if (result.isSuccess()) {
             if (result.getPath() != null) {
                 vo.setPath(result.getPath());
             }
-            vo.processEvent(Event.OperationSuccessed); 
+            vo.processEvent(Event.OperationSuccessed);
         } else {
             vo.processEvent(Event.OperationFailed);
             volResult.setResult(result.getResult());
         }
-        
+
         AsyncCallFuture<VolumeApiResult> future = context.getFuture();
         future.complete(volResult);
         return null;
@@ -427,12 +466,12 @@ public class VolumeServiceImpl implements VolumeService {
         TemplateInfo templateOnPrimaryStore = pd.getTemplate(template.getId());
         AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
         VolumeApiResult result = new VolumeApiResult(volume);
-        
+
         if (templateOnPrimaryStore == null) {
             createBaseImageAsync(volume, pd, template, future);
             return future;
         }
-            
+
         createVolumeFromBaseImageAsync(volume, templateOnPrimaryStore, pd, future);
         return future;
     }
@@ -441,13 +480,13 @@ public class VolumeServiceImpl implements VolumeService {
     @DB
     public boolean destroyVolume(long volumeId)
             throws ConcurrentOperationException {
-        
+
         VolumeInfo vol = this.volFactory.getVolume(volumeId);
         vol.processEvent(Event.DestroyRequested);
         this.snapshotMgr.deletePoliciesForVolume(volumeId);
 
         vol.processEvent(Event.OperationSuccessed);
-             
+
         return true;
     }
 
@@ -455,11 +494,11 @@ public class VolumeServiceImpl implements VolumeService {
     public AsyncCallFuture<VolumeApiResult> createVolumeFromSnapshot(
             VolumeInfo volume, DataStore store, SnapshotInfo snapshot) {
         AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
-        
+
         try {
         	DataObject volumeOnStore = store.create(volume);
         	volume.processEvent(Event.CreateOnlyRequested);
-        	 CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<VolumeApiResult>(null, 
+        	 CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<VolumeApiResult>(null,
         			 (VolumeObject)volume, store, volumeOnStore, future);
              AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller =  AsyncCallbackDispatcher.create(this);
              caller.setCallback(caller.getTarget().createVolumeFromSnapshotCallback(null, null))
@@ -471,11 +510,11 @@ public class VolumeServiceImpl implements VolumeService {
         	result.setResult(e.toString());
         	future.complete(result);
         }
-        
+
         return future;
     }
-    
-    protected Void createVolumeFromSnapshotCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, 
+
+    protected Void createVolumeFromSnapshotCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback,
     		CreateVolumeFromBaseImageContext<VolumeApiResult> context) {
     	CopyCommandResult result = callback.getResult();
     	VolumeInfo volume = context.vo;
@@ -487,19 +526,19 @@ public class VolumeServiceImpl implements VolumeService {
     	} else {
     		event = Event.OperationSuccessed;
     	}
-    	
+
     	try {
     		volume.processEvent(event);
     	} catch (Exception e) {
     		s_logger.debug("create volume from snapshot failed", e);
     		apiResult.setResult(e.toString());
     	}
-    	
+
     	AsyncCallFuture<VolumeApiResult> future = context.future;
     	future.complete(apiResult);
     	return null;
     }
-    
+
     protected VolumeVO duplicateVolumeOnAnotherStorage(Volume volume, StoragePool pool) {
         Long lastPoolId = volume.getPoolId();
         VolumeVO newVol = new VolumeVO(volume);
@@ -511,7 +550,7 @@ public class VolumeServiceImpl implements VolumeService {
         newVol.setPodId(pool.getPodId());
         return this.volDao.persist(newVol);
     }
-    
+
 
     private class CopyVolumeContext<T> extends AsyncRpcConext<T> {
         final VolumeInfo srcVolume;
@@ -529,7 +568,7 @@ public class VolumeServiceImpl implements VolumeService {
             this.destStore = destStore;
             this.future = future;
         }
-        
+
     }
     @Override
     public AsyncCallFuture<VolumeApiResult> copyVolume(VolumeInfo srcVolume,
@@ -540,7 +579,7 @@ public class VolumeServiceImpl implements VolumeService {
             if (!this.snapshotMgr.canOperateOnVolume(srcVolume)) {
                 s_logger.debug(
                         "There are snapshots creating on this volume, can not move this volume");
-                
+
                 res.setResult("There are snapshots creating on this volume, can not move this volume");
                 future.complete(res);
                 return future;
@@ -551,7 +590,7 @@ public class VolumeServiceImpl implements VolumeService {
             destVolume.processEvent(Event.CreateOnlyRequested);
             srcVolume.processEvent(Event.CopyingRequested);
 
-            CopyVolumeContext<VolumeApiResult> context = new CopyVolumeContext<VolumeApiResult>(null, future, srcVolume, 
+            CopyVolumeContext<VolumeApiResult> context = new CopyVolumeContext<VolumeApiResult>(null, future, srcVolume,
                     destVolume,
                     destStore);
             AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
@@ -565,7 +604,7 @@ public class VolumeServiceImpl implements VolumeService {
         }
         return future;
     }
-    
+
     protected Void copyVolumeCallBack(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CopyVolumeContext<VolumeApiResult> context) {
         VolumeInfo srcVolume = context.srcVolume;
         VolumeInfo destVolume = context.destVolume;
@@ -593,13 +632,13 @@ public class VolumeServiceImpl implements VolumeService {
             res.setResult(e.toString());
             future.complete(res);
         }
-        
+
         return null;
     }
-    
+
     @Override
     public AsyncCallFuture<VolumeApiResult> registerVolume(VolumeInfo volume, DataStore store) {
-        
+
         AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
         VolumeObject vo = (VolumeObject) volume;
 
@@ -607,11 +646,11 @@ public class VolumeServiceImpl implements VolumeService {
         AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
         caller.setCallback(caller.getTarget().registerVolumeCallback(null, null))
         .setContext(context);
-        
+
         dataObjectMgr.createAsync(volume, store, caller, true);
         return future;
     }
-    
+
     protected Void registerVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeContext<VolumeApiResult> context) {
         CreateCmdResult result = callback.getResult();
         VolumeObject vo = (VolumeObject)context.volume;
@@ -624,7 +663,7 @@ public class VolumeServiceImpl implements VolumeService {
         context.future.complete(res);
         return null;
     }
-    
+
 
 	@Override
 	public AsyncCallFuture<VolumeApiResult> resize(VolumeInfo volume) {
@@ -645,12 +684,12 @@ public class VolumeServiceImpl implements VolumeService {
 		volume.getDataStore().getDriver().resize(volume, caller);
 		return future;
 	}
-	
+
 	protected Void resizeVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeContext<VolumeApiResult> context) {
 		CreateCmdResult result = callback.getResult();
 		AsyncCallFuture<VolumeApiResult> future  = context.future;
 		VolumeInfo volume = (VolumeInfo)context.volume;
-		
+
 		if (result.isFailed()) {
 			try {
 				volume.processEvent(Event.OperationFailed);
@@ -662,7 +701,7 @@ public class VolumeServiceImpl implements VolumeService {
 			future.complete(res);
 			return null;
 		}
-		
+
 		try {
 			volume.processEvent(Event.OperationSuccessed);
 		} catch(Exception e) {
@@ -672,13 +711,137 @@ public class VolumeServiceImpl implements VolumeService {
 			future.complete(res);
 			return null;
 		}
-		
+
 		VolumeApiResult res = new VolumeApiResult(volume);
 		future.complete(res);
-		
+
 		return null;
 	}
-	
-	
+
+    @Override
+    public void handleVolumeSync(DataStore store) {
+        if (store == null) {
+            s_logger.warn("Huh? ssHost is null");
+            return;
+        }
+        long storeId = store.getId();
+        Long zoneId = store.getScope().getScopeId();
+
+
+        Map<Long, TemplateProp> volumeInfos = listVolume(store);
+        if (volumeInfos == null) {
+            return;
+        }
+
+        List<VolumeDataStoreVO> dbVolumes = _volumeStoreDao.listByStoreId(storeId);
+        List<VolumeDataStoreVO> toBeDownloaded = new ArrayList<VolumeDataStoreVO>(dbVolumes);
+        for (VolumeDataStoreVO volumeStore : dbVolumes){
+            VolumeVO volume = _volumeDao.findById(volumeStore.getVolumeId());
+            //Exists then don't download
+            if (volumeInfos.containsKey(volume.getId())){
+                TemplateProp volInfo = volumeInfos.remove(volume.getId());
+                toBeDownloaded.remove(volumeStore);
+                s_logger.info("Volume Sync found " + volume.getUuid() + " already in the volume image store table");
+                if (volumeStore.getDownloadState() != Status.DOWNLOADED) {
+                    volumeStore.setErrorString("");
+                }
+                if (volInfo.isCorrupted()) {
+                    volumeStore.setDownloadState(Status.DOWNLOAD_ERROR);
+                    String msg = "Volume " + volume.getUuid() + " is corrupted on image store ";
+                    volumeStore.setErrorString(msg);
+                    s_logger.info("msg");
+                    if (volumeStore.getDownloadUrl() == null) {
+                        msg = "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() + "is corrupted, please check in image store: " + volumeStore.getDataStoreId();
+                        s_logger.warn(msg);
+                    } else {
+                        toBeDownloaded.add(volumeStore);
+                    }
+
+                } else { // Put them in right status
+                    volumeStore.setDownloadPercent(100);
+                    volumeStore.setDownloadState(Status.DOWNLOADED);
+                    volumeStore.setInstallPath(volInfo.getInstallPath());
+                    volumeStore.setSize(volInfo.getSize());
+                    volumeStore.setPhysicalSize(volInfo.getPhysicalSize());
+                    volumeStore.setLastUpdated(new Date());
+                    _volumeStoreDao.update(volumeStore.getId(), volumeStore);
+
+                    if (volume.getSize() == 0) {
+                        // Set volume size in volumes table
+                        volume.setSize(volInfo.getSize());
+                        _volumeDao.update(volumeStore.getVolumeId(), volume);
+                    }
+
+                    if (volInfo.getSize() > 0) {
+                        try {
+                            String url = _volumeStoreDao.findByVolumeId(volume.getId()).getDownloadUrl();
+                            _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()),
+                                    com.cloud.configuration.Resource.ResourceType.secondary_storage,
+                                    volInfo.getSize() - UriUtils.getRemoteSize(url));
+                        } catch (ResourceAllocationException e) {
+                            s_logger.warn(e.getMessage());
+                            _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(),
+                                    volume.getPodId(), e.getMessage(), e.getMessage());
+                        } finally {
+                            _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(),
+                                    com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
+                        }
+                    }
+                }
+                continue;
+            }
+            // Volume is not on secondary but we should download.
+            if (volumeStore.getDownloadState() != Status.DOWNLOADED) {
+                s_logger.info("Volume Sync did not find " + volume.getName() + " ready on image store " + storeId + ", will request download to start/resume shortly");
+                toBeDownloaded.add(volumeStore);
+            }
+        }
+
+        //Download volumes which haven't been downloaded yet.
+        if (toBeDownloaded.size() > 0) {
+            for (VolumeDataStoreVO volumeHost : toBeDownloaded) {
+                if (volumeHost.getDownloadUrl() == null) { // If url is null we can't initiate the download
+                    continue;
+                }
+                s_logger.debug("Volume " + volumeHost.getVolumeId() + " needs to be downloaded to " + store.getName());
+                //TODO: pass a callback later
+                _dlMonitor.downloadVolumeToStorage(_volumeDao.findById(volumeHost.getVolumeId()), store,  volumeHost.getDownloadUrl(), volumeHost.getChecksum(), volumeHost.getFormat(), null);
+            }
+        }
+
+        //Delete volumes which are not present on DB.
+        for (Long uniqueName : volumeInfos.keySet()) {
+            TemplateProp vInfo = volumeInfos.get(uniqueName);
+            DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(store.getUri(), vInfo.getInstallPath());
+            try {
+                HostVO ssAhost = _ssvmMgr.pickSsvmHost(store);
+                _agentMgr.sendToSecStorage(ssAhost, dtCommand, null);
+            } catch (AgentUnavailableException e) {
+                String err = "Failed to delete " + vInfo.getTemplateName() + " on image store " + storeId + " which isn't in the database";
+                s_logger.error(err);
+                return;
+            }
+
+            String description = "Deleted volume " + vInfo.getTemplateName() + " on image store " + storeId + " since it isn't in the database";
+            s_logger.info(description);
+        }
+
+    }
+
+    private Map<Long, TemplateProp> listVolume(DataStore store) {
+        ListVolumeCommand cmd = new ListVolumeCommand(store.getUri());
+        HostVO ssAhost = _ssvmMgr.pickSsvmHost(store);
+        Answer answer = _agentMgr.sendToSecStorage(ssAhost, cmd);
+        if (answer != null && answer.getResult()) {
+            ListVolumeAnswer tanswer = (ListVolumeAnswer)answer;
+            return tanswer.getTemplateInfo();
+        } else {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Can not list volumes for image store " + store.getId());
+            }
+        }
+
+        return null;
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index 362e0a5..706c9ef 100755
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -215,7 +215,7 @@ import com.cloud.storage.Volume;
 import com.cloud.storage.template.Processor;
 import com.cloud.storage.template.Processor.FormatInfo;
 import com.cloud.storage.template.QCOW2Processor;
-import com.cloud.storage.template.TemplateInfo;
+import com.cloud.storage.template.TemplateProp;
 import com.cloud.storage.template.TemplateLocation;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
@@ -2381,7 +2381,7 @@ ServerResource {
             return new Answer(cmd, false, " Failed to create storage pool");
         }
 
-        Map<String, TemplateInfo> tInfo = new HashMap<String, TemplateInfo>();
+        Map<String, TemplateProp> tInfo = new HashMap<String, TemplateProp>();
         ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd,
                 storagepool.getCapacity(), storagepool.getUsed(), tInfo);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java b/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java
index a626e31..7d8d90c 100755
--- a/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java
+++ b/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java
@@ -114,7 +114,7 @@ import com.cloud.resource.hypervisor.HypervisorResource;
 import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.Storage.StoragePoolType;
 import com.cloud.storage.Volume;
-import com.cloud.storage.template.TemplateInfo;
+import com.cloud.storage.template.TemplateProp;
 import com.cloud.template.VirtualMachineTemplate.BootloaderType;
 import com.cloud.utils.Pair;
 import com.cloud.utils.Ternary;
@@ -458,7 +458,7 @@ public class OvmResourceBase implements ServerResource, HypervisorResource {
 			
 			setupHeartBeat(pool.getUuid());
 			OvmStoragePool.Details d = OvmStoragePool.getDetailsByUuid(_conn, pool.getUuid());
-			Map<String, TemplateInfo> tInfo = new HashMap<String, TemplateInfo>();
+			Map<String, TemplateProp> tInfo = new HashMap<String, TemplateProp>();
 			ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, d.totalSpace, d.freeSpace, tInfo);
 			return answer;
 		} catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java
index a50dff6..ae7cf29 100644
--- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java
+++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java
@@ -74,7 +74,7 @@ import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.Storage.StoragePoolType;
 import com.cloud.storage.VMTemplateStorageResourceAssoc;
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
-import com.cloud.storage.template.TemplateInfo;
+import com.cloud.storage.template.TemplateProp;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.db.Transaction;
 import com.cloud.utils.exception.CloudRuntimeException;
@@ -357,7 +357,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa
             txn = Transaction.open(Transaction.CLOUD_DB);
             txn.close();
         }
-        return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap<String, TemplateInfo>());
+        return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap<String, TemplateProp>());
     }
 
     @Override
@@ -398,7 +398,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa
             txn = Transaction.open(Transaction.CLOUD_DB);
             txn.close();
         }
-        return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap<String, TemplateInfo>());
+        return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap<String, TemplateProp>());
     }
 
     @Override
@@ -449,9 +449,9 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa
             List<MockVolumeVO> volumes = _mockVolumeDao.findByStorageIdAndType(storage.getId(),
                     MockVolumeType.VOLUME);
 
-            Map<Long, TemplateInfo> templateInfos = new HashMap<Long, TemplateInfo>();
+            Map<Long, TemplateProp> templateInfos = new HashMap<Long, TemplateProp>();
             for (MockVolumeVO volume : volumes) {
-                templateInfos.put(volume.getId(), new TemplateInfo(volume.getName(), volume.getPath()
+                templateInfos.put(volume.getId(), new TemplateProp(volume.getName(), volume.getPath()
                         .replaceAll(storage.getMountPoint(), ""), volume.getSize(), volume.getSize(), true, false));
             }
             txn.commit();
@@ -492,9 +492,9 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa
             List<MockVolumeVO> templates = _mockVolumeDao.findByStorageIdAndType(storage.getId(),
                     MockVolumeType.TEMPLATE);
 
-            Map<String, TemplateInfo> templateInfos = new HashMap<String, TemplateInfo>();
+            Map<String, TemplateProp> templateInfos = new HashMap<String, TemplateProp>();
             for (MockVolumeVO template : templates) {
-                templateInfos.put(template.getName(), new TemplateInfo(template.getName(), template.getPath()
+                templateInfos.put(template.getName(), new TemplateProp(template.getName(), template.getPath()
                         .replaceAll(storage.getMountPoint(), ""), template.getSize(), template.getSize(), true, false));
             }
             txn.commit();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java
index 46df50c..8a03c4b 100644
--- a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java
+++ b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java
@@ -51,7 +51,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.network.Networks.RouterPrivateIpStrategy;
 import com.cloud.simulator.MockVMVO;
 import com.cloud.storage.Storage.StorageResourceType;
-import com.cloud.storage.template.TemplateInfo;
+import com.cloud.storage.template.TemplateProp;
 import com.cloud.utils.Pair;
 import com.cloud.vm.VirtualMachine.State;
 
@@ -168,7 +168,7 @@ public class AgentRoutingResource extends AgentStorageResource {
     }
 
     private StartupStorageCommand initializeLocalSR() {
-        Map<String, TemplateInfo> tInfo = new HashMap<String, TemplateInfo>();
+        Map<String, TemplateProp> tInfo = new HashMap<String, TemplateProp>();
 
         StoragePoolInfo poolInfo = _simMgr.getLocalStorage(hostGuid);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
index 634827b..4079d0d 100755
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -210,7 +210,7 @@ import com.cloud.storage.Storage;
 import com.cloud.storage.Storage.StoragePoolType;
 import com.cloud.storage.Volume;
 import com.cloud.storage.resource.StoragePoolResource;
-import com.cloud.storage.template.TemplateInfo;
+import com.cloud.storage.template.TemplateProp;
 import com.cloud.utils.DateUtil;
 import com.cloud.utils.Pair;
 import com.cloud.utils.StringUtils;
@@ -3137,7 +3137,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
             DatastoreSummary summary = new DatastoreMO(getServiceContext(), morDatastore).getSummary();
             long capacity = summary.getCapacity();
             long available = summary.getFreeSpace();
-            Map<String, TemplateInfo> tInfo = new HashMap<String, TemplateInfo>();
+            Map<String, TemplateProp> tInfo = new HashMap<String, TemplateProp>();
             ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, capacity, available, tInfo);
             return answer;
         } catch (Throwable e) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
index c50f13c..046827d 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
@@ -233,7 +233,7 @@ import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.Storage.StoragePoolType;
 import com.cloud.storage.Volume;
 import com.cloud.storage.VolumeVO;
-import com.cloud.storage.template.TemplateInfo;
+import com.cloud.storage.template.TemplateProp;
 import com.cloud.template.VirtualMachineTemplate.BootloaderType;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
@@ -5287,7 +5287,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
                     s_logger.warn(msg);
                     return new Answer(cmd, false, msg);
                 }
-                Map<String, TemplateInfo> tInfo = new HashMap<String, TemplateInfo>();
+                Map<String, TemplateProp> tInfo = new HashMap<String, TemplateProp>();
                 ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, capacity, available, tInfo);
                 return answer;
             } catch (XenAPIException e) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/plugins/storage/image/default/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/storage/image/default/pom.xml b/plugins/storage/image/default/pom.xml
index e84eab4..d1b079d 100644
--- a/plugins/storage/image/default/pom.xml
+++ b/plugins/storage/image/default/pom.xml
@@ -26,6 +26,16 @@
       <version>${project.version}</version>
     </dependency>
     <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-storage-volume</artifactId>
+      <version>${project.version}</version>
+    </dependency>    
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-storage-snapshot</artifactId>
+      <version>${project.version}</version>
+    </dependency>        
+    <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
       <version>${cs.mysql.version}</version>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/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 d52af65..46c87b7 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
@@ -35,6 +35,7 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 import org.apache.cloudstack.framework.async.AsyncRpcConext;
 import org.apache.cloudstack.storage.image.ImageStoreDriver;
 import org.apache.cloudstack.storage.image.store.TemplateObject;
+import org.apache.cloudstack.storage.volume.VolumeObject;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
@@ -118,11 +119,10 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
             TemplateObject tData = (TemplateObject)data;
             _downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback);
         } else if (data.getType() == DataObjectType.VOLUME) {
-            VolumeVO vol = this.volumeDao.findById(data.getId());
-            VolumeInfo volInfo = (VolumeInfo)data;
+            VolumeObject volInfo = (VolumeObject)data;
             RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload();
-            _downloadMonitor.downloadVolumeToStorage(vol, vol.getDataCenterId(), payload.getUrl(),
-                    payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()));
+            _downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(),
+                    payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback);
         }
 
         CreateCmdResult result = new CreateCmdResult(null, null);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/plugins/storage/image/s3/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/storage/image/s3/pom.xml b/plugins/storage/image/s3/pom.xml
index 7ab0d3e..7f5b9c4 100644
--- a/plugins/storage/image/s3/pom.xml
+++ b/plugins/storage/image/s3/pom.xml
@@ -32,6 +32,16 @@
       <artifactId>cloud-engine-storage-image</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-storage-volume</artifactId>
+      <version>${project.version}</version>
+    </dependency>    
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-storage-snapshot</artifactId>
+      <version>${project.version}</version>
+    </dependency>            
   </dependencies>
   <build>
       <defaultGoal>install</defaultGoal>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/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 0d84f58..50a82cc 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
@@ -35,6 +35,7 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 import org.apache.cloudstack.framework.async.AsyncRpcConext;
 import org.apache.cloudstack.storage.image.ImageStoreDriver;
 import org.apache.cloudstack.storage.image.store.TemplateObject;
+import org.apache.cloudstack.storage.volume.VolumeObject;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
@@ -118,11 +119,10 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver {
             TemplateObject tData = (TemplateObject)data;
             _downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback);
         } else if (data.getType() == DataObjectType.VOLUME) {
-            VolumeVO vol = this.volumeDao.findById(data.getId());
-            VolumeInfo volInfo = (VolumeInfo)data;
+            VolumeObject volInfo = (VolumeObject)data;
             RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload();
-            _downloadMonitor.downloadVolumeToStorage(vol, vol.getDataCenterId(), payload.getUrl(),
-                    payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()));
+            _downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(),
+                    payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback);
         }
 
         CreateCmdResult result = new CreateCmdResult(null, null);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/plugins/storage/image/sample/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/storage/image/sample/pom.xml b/plugins/storage/image/sample/pom.xml
index e4d5ac2..d9eab9b 100644
--- a/plugins/storage/image/sample/pom.xml
+++ b/plugins/storage/image/sample/pom.xml
@@ -26,6 +26,16 @@
       <version>${project.version}</version>
     </dependency>
     <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-storage-volume</artifactId>
+      <version>${project.version}</version>
+    </dependency>    
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-storage-snapshot</artifactId>
+      <version>${project.version}</version>
+    </dependency>            
+    <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
       <version>${cs.mysql.version}</version>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/plugins/storage/image/swift/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/storage/image/swift/pom.xml b/plugins/storage/image/swift/pom.xml
index 27ebbe5..6254cce 100644
--- a/plugins/storage/image/swift/pom.xml
+++ b/plugins/storage/image/swift/pom.xml
@@ -26,6 +26,16 @@
       <version>${project.version}</version>
     </dependency>
     <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-storage-volume</artifactId>
+      <version>${project.version}</version>
+    </dependency>    
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-storage-snapshot</artifactId>
+      <version>${project.version}</version>
+    </dependency>            
+    <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
       <version>${cs.mysql.version}</version>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/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 36fd5fb..e539e5c 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
@@ -35,6 +35,7 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 import org.apache.cloudstack.framework.async.AsyncRpcConext;
 import org.apache.cloudstack.storage.image.ImageStoreDriver;
 import org.apache.cloudstack.storage.image.store.TemplateObject;
+import org.apache.cloudstack.storage.volume.VolumeObject;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
@@ -118,11 +119,10 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver {
             TemplateObject tData = (TemplateObject)data;
             _downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback);
         } else if (data.getType() == DataObjectType.VOLUME) {
-            VolumeVO vol = this.volumeDao.findById(data.getId());
-            VolumeInfo volInfo = (VolumeInfo)data;
+            VolumeObject volInfo = (VolumeObject)data;
             RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload();
-            _downloadMonitor.downloadVolumeToStorage(vol, vol.getDataCenterId(), payload.getUrl(),
-                    payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()));
+            _downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(),
+                    payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback);
         }
 
         CreateCmdResult result = new CreateCmdResult(null, null);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/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 78b26bb..3b1a768 100755
--- a/server/src/com/cloud/storage/StorageManagerImpl.java
+++ b/server/src/com/cloud/storage/StorageManagerImpl.java
@@ -1993,15 +1993,15 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
         _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), store.getDataCenterId());
 
         // Verify that there are no live snapshot, template, volume on the image store to be deleted
-        List<SnapshotDataStoreVO> snapshots = _snapshotStoreDao.listLiveByStoreId(storeId);
+        List<SnapshotDataStoreVO> snapshots = _snapshotStoreDao.listByStoreId(storeId);
         if ( snapshots != null && snapshots.size() > 0 ){
             throw new CloudRuntimeException("Cannot delete image store with active snapshots backup!");
         }
-        List<VolumeDataStoreVO> volumes = _volumeStoreDao.listLiveByStoreId(storeId);
+        List<VolumeDataStoreVO> volumes = _volumeStoreDao.listByStoreId(storeId);
         if ( volumes != null && volumes.size() > 0 ){
             throw new CloudRuntimeException("Cannot delete image store with active volumes backup!");
         }
-        List<TemplateDataStoreVO> templates = _templateStoreDao.listLiveByStoreId(storeId);
+        List<TemplateDataStoreVO> templates = _templateStoreDao.listByStoreId(storeId);
         if ( templates != null && templates.size() > 0 ){
             throw new CloudRuntimeException("Cannot delete image store with active templates backup!");
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/server/src/com/cloud/storage/download/DownloadListener.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/download/DownloadListener.java b/server/src/com/cloud/storage/download/DownloadListener.java
index 8e979ab..3eb2233 100755
--- a/server/src/com/cloud/storage/download/DownloadListener.java
+++ b/server/src/com/cloud/storage/download/DownloadListener.java
@@ -18,6 +18,7 @@ package com.cloud.storage.download;
 
 import java.util.Date;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Timer;
 import java.util.TimerTask;
@@ -26,9 +27,15 @@ import javax.inject.Inject;
 
 import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
 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.TemplateService;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
 import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 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.log4j.Level;
 import org.apache.log4j.Logger;
 
@@ -52,6 +59,8 @@ import com.cloud.exception.ConnectionException;
 import com.cloud.exception.ResourceAllocationException;
 import com.cloud.host.HostVO;
 import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.resource.ResourceManager;
 import com.cloud.storage.Storage;
 import com.cloud.storage.StorageManager;
 import com.cloud.storage.VMTemplateHostVO;
@@ -117,57 +126,68 @@ public class DownloadListener implements Listener {
 	public static final String DOWNLOAD_ABANDONED=Status.ABANDONED.toString();
 
 
-	private HostVO sserver;
-	private HostVO ssAgent;
+	private HostVO _sserver;
+	private HostVO _ssAgent;
 
-	private VMTemplateVO template;
-	private VolumeVO volume;
-	private boolean downloadActive = true;
+	private VMTemplateVO _template;
+	private VolumeVO _volume;
+	private boolean _downloadActive = true;
 
-	private VolumeHostDao volumeHostDao;
+	private VolumeHostDao _volumeHostDao;
+	private VolumeDataStoreDao _volumeStoreDao;
 	private VolumeDao _volumeDao;
 	private StorageManager _storageMgr;
-	private VMTemplateHostDao vmTemplateHostDao;
+	private VMTemplateHostDao _vmTemplateHostDao;
 	private TemplateDataStoreDao _vmTemplateStoreDao;
 	private VMTemplateDao _vmTemplateDao;
 	private ResourceLimitService _resourceLimitMgr;
 	private AccountManager _accountMgr;
 	private AlertManager _alertMgr;
 
-	private final DownloadMonitorImpl downloadMonitor;
+	private final DownloadMonitorImpl _downloadMonitor;
 
-	private DownloadState currState;
+	private DownloadState _currState;
 
-	private DownloadCommand cmd;
+	private DownloadCommand _cmd;
 
-	private Timer timer;
+	private Timer _timer;
 
-	private StatusTask statusTask;
-	private TimeoutTask timeoutTask;
-	private Date lastUpdated = new Date();
-	private String jobId;
+	private StatusTask _statusTask;
+	private TimeoutTask _timeoutTask;
+	private Date _lastUpdated = new Date();
+	private String _jobId;
 
-	private final Map<String,  DownloadState> stateMap = new HashMap<String, DownloadState>();
-	private Long templateHostId;
-	private Long volumeHostId;
+	private final Map<String,  DownloadState> _stateMap = new HashMap<String, DownloadState>();
+	private Long _templateHostId;
+	private Long _volumeHostId;
 
-    private DataStore sstore;
-    private Long templateStoreId;
-	private AsyncCompletionCallback<CreateCmdResult> callback;
+    private DataStore _sstore;
+    private Long _templateStoreId;
+    private Long _volumeStoreId;
+	private AsyncCompletionCallback<CreateCmdResult> _callback;
+
+    @Inject
+    private ResourceManager _resourceMgr;
+    @Inject
+    private TemplateService _imageSrv;
+    @Inject
+    private DataStoreManager _storeMgr;
+    @Inject
+    private VolumeService _volumeSrv;
 
 	public DownloadListener(HostVO ssAgent, HostVO host, VMTemplateVO template, Timer _timer, VMTemplateHostDao dao, Long templHostId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VMTemplateDao templateDao, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr) {
-	    this.ssAgent = ssAgent;
-        this.sserver = host;
-		this.template = template;
-		this.vmTemplateHostDao = dao;
-		this.downloadMonitor = downloadMonitor;
-		this.cmd = cmd;
-		this.templateHostId = templHostId;
+	    this._ssAgent = ssAgent;
+        this._sserver = host;
+		this._template = template;
+		this._vmTemplateHostDao = dao;
+		this._downloadMonitor = downloadMonitor;
+		this._cmd = cmd;
+		this._templateHostId = templHostId;
 		initStateMachine();
-		this.currState=getState(Status.NOT_DOWNLOADED.toString());
-		this.timer = _timer;
-		this.timeoutTask = new TimeoutTask(this);
-		this.timer.schedule(timeoutTask, 3*STATUS_POLL_INTERVAL);
+		this._currState=getState(Status.NOT_DOWNLOADED.toString());
+		this._timer = _timer;
+		this._timeoutTask = new TimeoutTask(this);
+		this._timer.schedule(_timeoutTask, 3*STATUS_POLL_INTERVAL);
 		this._vmTemplateDao = templateDao;
 		this._resourceLimitMgr = _resourceLimitMgr;
 		this._accountMgr = _accountMgr;
@@ -177,63 +197,64 @@ public class DownloadListener implements Listener {
 
 	// TODO: this constructor should be the one used for template only, remove other template constructor later
     public DownloadListener(HostVO ssAgent, DataStore store, VMTemplateVO template, Timer _timer, TemplateDataStoreDao dao, Long templStoreId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VMTemplateDao templateDao, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr, AsyncCompletionCallback<CreateCmdResult> callback) {
-        this.ssAgent = ssAgent;
-        this.sstore = store;
-        this.template = template;
+        this._ssAgent = ssAgent;
+        this._sstore = store;
+        this._template = template;
         this._vmTemplateStoreDao = dao;
-        this.downloadMonitor = downloadMonitor;
-        this.cmd = cmd;
-        this.templateStoreId = templStoreId;
+        this._downloadMonitor = downloadMonitor;
+        this._cmd = cmd;
+        this._templateStoreId = templStoreId;
         initStateMachine();
-        this.currState=getState(Status.NOT_DOWNLOADED.toString());
-        this.timer = _timer;
-        this.timeoutTask = new TimeoutTask(this);
-        this.timer.schedule(timeoutTask, 3*STATUS_POLL_INTERVAL);
+        this._currState=getState(Status.NOT_DOWNLOADED.toString());
+        this._timer = _timer;
+        this._timeoutTask = new TimeoutTask(this);
+        this._timer.schedule(_timeoutTask, 3*STATUS_POLL_INTERVAL);
         this._vmTemplateDao = templateDao;
         this._resourceLimitMgr = _resourceLimitMgr;
         this._accountMgr = _accountMgr;
         this._alertMgr = _alertMgr;
-        this.callback = callback;
+        this._callback = callback;
         updateDatabase(Status.NOT_DOWNLOADED, "");
     }
 
 
-	public DownloadListener(HostVO ssAgent, HostVO host, VolumeVO volume, Timer _timer, VolumeHostDao dao, Long volHostId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VolumeDao volumeDao, StorageManager storageMgr, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr) {
-	    this.ssAgent = ssAgent;
-        this.sserver = host;
-		this.volume = volume;
-		this.volumeHostDao = dao;
-		this.downloadMonitor = downloadMonitor;
-		this.cmd = cmd;
-		this.volumeHostId = volHostId;
+	public DownloadListener(HostVO ssAgent, DataStore store, VolumeVO volume, Timer _timer, VolumeDataStoreDao dao, Long volStoreId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VolumeDao volumeDao, StorageManager storageMgr, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr, AsyncCompletionCallback<CreateCmdResult> callback) {
+	    this._ssAgent = ssAgent;
+        this._sstore = store;
+		this._volume = volume;
+		this._volumeStoreDao = dao;
+		this._downloadMonitor = downloadMonitor;
+		this._cmd = cmd;
+		this._volumeStoreId = volStoreId;
 		initStateMachine();
-		this.currState=getState(Status.NOT_DOWNLOADED.toString());
-		this.timer = _timer;
-		this.timeoutTask = new TimeoutTask(this);
-		this.timer.schedule(timeoutTask, 3*STATUS_POLL_INTERVAL);
+		this._currState=getState(Status.NOT_DOWNLOADED.toString());
+		this._timer = _timer;
+		this._timeoutTask = new TimeoutTask(this);
+		this._timer.schedule(_timeoutTask, 3*STATUS_POLL_INTERVAL);
 		this._volumeDao = volumeDao;
 		this._storageMgr = storageMgr;
 		this._resourceLimitMgr = _resourceLimitMgr;
 		this._accountMgr = _accountMgr;
 		this._alertMgr = _alertMgr;
+		this._callback = callback;
 		updateDatabase(Status.NOT_DOWNLOADED, "");
 	}
 
 
 	public void setCurrState(VMTemplateHostVO.Status currState) {
-		this.currState = getState(currState.toString());
+		this._currState = getState(currState.toString());
 	}
 
 	private void initStateMachine() {
-		stateMap.put(Status.NOT_DOWNLOADED.toString(), new NotDownloadedState(this));
-		stateMap.put(Status.DOWNLOADED.toString(), new DownloadCompleteState(this));
-		stateMap.put(Status.DOWNLOAD_ERROR.toString(), new DownloadErrorState(this));
-		stateMap.put(Status.DOWNLOAD_IN_PROGRESS.toString(), new DownloadInProgressState(this));
-		stateMap.put(Status.ABANDONED.toString(), new DownloadAbandonedState(this));
+		_stateMap.put(Status.NOT_DOWNLOADED.toString(), new NotDownloadedState(this));
+		_stateMap.put(Status.DOWNLOADED.toString(), new DownloadCompleteState(this));
+		_stateMap.put(Status.DOWNLOAD_ERROR.toString(), new DownloadErrorState(this));
+		_stateMap.put(Status.DOWNLOAD_IN_PROGRESS.toString(), new DownloadInProgressState(this));
+		_stateMap.put(Status.ABANDONED.toString(), new DownloadAbandonedState(this));
 	}
 
 	private DownloadState getState(String stateName) {
-		return stateMap.get(stateName);
+		return _stateMap.get(stateName);
 	}
 
 	public void sendCommand(RequestType reqType) {
@@ -243,10 +264,10 @@ public class DownloadListener implements Listener {
 			}
 			try {
 				DownloadProgressCommand dcmd = new DownloadProgressCommand(getCommand(), getJobId(), reqType);
-				if (template == null){
+				if (_template == null){
 					dcmd.setResourceType(ResourceType.VOLUME);
 				}
-	            downloadMonitor.send(ssAgent.getId(), dcmd, this);
+	            _downloadMonitor.send(_ssAgent.getId(), dcmd, this);
             } catch (AgentUnavailableException e) {
             	s_logger.debug("Send command failed", e);
 				setDisconnected();
@@ -264,63 +285,63 @@ public class DownloadListener implements Listener {
 	}
 
 	public void logDisconnect() {
-		if (template != null){
-			s_logger.warn("Unable to monitor download progress of " + template.getName() + " at host " + sserver.getName());
+		if (_template != null){
+			s_logger.warn("Unable to monitor download progress of " + _template.getName() + " at host " + _sserver.getName());
 		}else {
-			s_logger.warn("Unable to monitor download progress of " + volume.getName() + " at host " + sserver.getName());
+			s_logger.warn("Unable to monitor download progress of " + _volume.getName() + " at host " + _sserver.getName());
 		}
 	}
 
 	public synchronized void updateDatabase(Status state, String errorString) {
-		if (template != null){
-		    VMTemplateHostVO vo = vmTemplateHostDao.createForUpdate();
+		if (_template != null){
+		    VMTemplateHostVO vo = _vmTemplateHostDao.createForUpdate();
 			vo.setDownloadState(state);
 			vo.setLastUpdated(new Date());
 			vo.setErrorString(errorString);
-			vmTemplateHostDao.update(getTemplateHostId(), vo);
+			_vmTemplateHostDao.update(getTemplateHostId(), vo);
 		}else {
-		    VolumeHostVO vo = volumeHostDao.createForUpdate();
+		    VolumeHostVO vo = _volumeHostDao.createForUpdate();
 			vo.setDownloadState(state);
 			vo.setLastUpdated(new Date());
 			vo.setErrorString(errorString);
-			volumeHostDao.update(getVolumeHostId(), vo);
+			_volumeHostDao.update(getVolumeHostId(), vo);
 		}
 	}
 
 	public void log(String message, Level level) {
-		if (template != null){
-			s_logger.log(level, message + ", template=" + template.getName() + " at host " + sserver.getName());
+		if (_template != null){
+			s_logger.log(level, message + ", template=" + _template.getName() + " at host " + _sserver.getName());
 		}else {
-			s_logger.log(level, message + ", volume=" + volume.getName() + " at host " + sserver.getName());
+			s_logger.log(level, message + ", volume=" + _volume.getName() + " at host " + _sserver.getName());
 		}
 	}
 
 	private Long getTemplateHostId() {
-		if (templateHostId == null){
-			VMTemplateHostVO templHost = vmTemplateHostDao.findByHostTemplate(sserver.getId(), template.getId());
-			templateHostId = templHost.getId();
+		if (_templateHostId == null){
+			VMTemplateHostVO templHost = _vmTemplateHostDao.findByHostTemplate(_sserver.getId(), _template.getId());
+			_templateHostId = templHost.getId();
 		}
-		return templateHostId;
+		return _templateHostId;
 	}
 
     private Long getTemplateStoreId() {
-        if (templateStoreId == null){
-            TemplateDataStoreVO templStore = _vmTemplateStoreDao.findByStoreTemplate(sstore.getId(), template.getId());
-            templateStoreId = templStore.getId();
+        if (_templateStoreId == null){
+            TemplateDataStoreVO templStore = _vmTemplateStoreDao.findByStoreTemplate(_sstore.getId(), _template.getId());
+            _templateStoreId = templStore.getId();
         }
-        return templateStoreId;
+        return _templateStoreId;
     }
 
 	private Long getVolumeHostId() {
-		if (volumeHostId == null){
-			VolumeHostVO volHost = volumeHostDao.findByHostVolume(sserver.getId(), volume.getId());
-			volumeHostId = volHost.getId();
+		if (_volumeHostId == null){
+			VolumeHostVO volHost = _volumeHostDao.findByHostVolume(_sserver.getId(), _volume.getId());
+			_volumeHostId = volHost.getId();
 		}
-		return volumeHostId;
+		return _volumeHostId;
 	}
 
 	public DownloadListener(DownloadMonitorImpl monitor) {
-	    downloadMonitor = monitor;
+	    _downloadMonitor = monitor;
 	}
 
 
@@ -350,15 +371,15 @@ public class DownloadListener implements Listener {
 	}
 
 	private synchronized void transition(DownloadEvent event, Object evtObj) {
-	    if (currState == null) {
+	    if (_currState == null) {
 	        return;
 	    }
-		String prevName = currState.getName();
-		String nextState = currState.handleEvent(event, evtObj);
+		String prevName = _currState.getName();
+		String nextState = _currState.handleEvent(event, evtObj);
 		if (nextState != null) {
-			currState = getState(nextState);
-			if (currState != null) {
-				currState.onEntry(prevName, event, evtObj);
+			_currState = getState(nextState);
+			if (_currState != null) {
+				_currState.onEntry(prevName, event, evtObj);
 			} else {
 				throw new CloudRuntimeException("Invalid next state: currState="+prevName+", evt="+event + ", next=" + nextState);
 			}
@@ -368,7 +389,7 @@ public class DownloadListener implements Listener {
 	}
 
 	public synchronized void updateDatabase(DownloadAnswer answer) {
-		if (template != null){
+		if (_template != null){
 	        TemplateDataStoreVO updateBuilder = _vmTemplateStoreDao.createForUpdate();
 			updateBuilder.setDownloadPercent(answer.getDownloadPct());
 			updateBuilder.setDownloadState(answer.getDownloadStatus());
@@ -380,40 +401,58 @@ public class DownloadListener implements Listener {
 			updateBuilder.setSize(answer.getTemplateSize());
 			updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize());
 
+            // only invoke callback when Download is completed or errored so that callback will update template_store_ref state column
+            Status dndStatus = answer.getDownloadStatus();
+           // if (dndStatus == Status.DOWNLOAD_ERROR || dndStatus == Status.DOWNLOADED ){
+                if ( _callback != null ){
+                    if (dndStatus == Status.DOWNLOAD_ERROR){
+                        CreateCmdResult result = new CreateCmdResult(null, null);
+                        result.setSucess(false);
+                        result.setResult("Download template failed");
+                        _callback.complete(result);
+                    } else if (dndStatus == Status.DOWNLOADED){
+                        CreateCmdResult result = new CreateCmdResult(null, null);
+                        _callback.complete(result);
+                    }
+                }
+                else{
+                    // no callback specified, just update state here
+                    if (dndStatus == Status.DOWNLOAD_ERROR){
+                        updateBuilder.setState(ObjectInDataStoreStateMachine.State.Failed);
+                    } else if (dndStatus == Status.DOWNLOAD_IN_PROGRESS){
+                        updateBuilder.setState(ObjectInDataStoreStateMachine.State.Creating2);
+                    } else if (dndStatus == Status.DOWNLOADED){
+                        updateBuilder.setState(ObjectInDataStoreStateMachine.State.Ready);
+                    }
+                }
+           // }
 			_vmTemplateStoreDao.update(getTemplateStoreId(), updateBuilder);
 
 			if (answer.getCheckSum() != null) {
 				VMTemplateVO templateDaoBuilder = _vmTemplateDao.createForUpdate();
 				templateDaoBuilder.setChecksum(answer.getCheckSum());
-				_vmTemplateDao.update(template.getId(), templateDaoBuilder);
+				_vmTemplateDao.update(_template.getId(), templateDaoBuilder);
 			}
 
             if (answer.getTemplateSize() > 0) {
                 //long hostId = vmTemplateHostDao.findByTemplateId(template.getId()).getHostId();
-                long accountId = template.getAccountId();
+                long accountId = _template.getAccountId();
                 try {
                     _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(accountId),
                             com.cloud.configuration.Resource.ResourceType.secondary_storage,
-                            answer.getTemplateSize() - UriUtils.getRemoteSize(template.getUrl()));
+                            answer.getTemplateSize() - UriUtils.getRemoteSize(_template.getUrl()));
                 } catch (ResourceAllocationException e) {
                     s_logger.warn(e.getMessage());
-                    _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, sserver.getDataCenterId(),
+                    _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, _sserver.getDataCenterId(),
                             null, e.getMessage(), e.getMessage());
                 } finally {
                     _resourceLimitMgr.recalculateResourceCount(accountId, _accountMgr.getAccount(accountId).getDomainId(),
                             com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
                 }
             }
-            // only invoke callback when Download is completed or errored so that callback will update template_store_ref state column
-            Status dndStatus = answer.getDownloadStatus();
-            if (dndStatus == Status.DOWNLOAD_ERROR || dndStatus == Status.DOWNLOADED ){
-                if ( callback != null ){
-                    CreateCmdResult result = new CreateCmdResult(null, null);
-                    callback.complete(result);
-                }
-            }
+
 		} else {
-	        VolumeHostVO updateBuilder = volumeHostDao.createForUpdate();
+	        VolumeHostVO updateBuilder = _volumeHostDao.createForUpdate();
 			updateBuilder.setDownloadPercent(answer.getDownloadPct());
 			updateBuilder.setDownloadState(answer.getDownloadStatus());
 			updateBuilder.setLastUpdated(new Date());
@@ -424,25 +463,25 @@ public class DownloadListener implements Listener {
 			updateBuilder.setSize(answer.getTemplateSize());
 			updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize());
 
-			volumeHostDao.update(getVolumeHostId(), updateBuilder);
+			_volumeHostDao.update(getVolumeHostId(), updateBuilder);
 
 			// Update volume size in Volume table.
 			VolumeVO updateVolume = _volumeDao.createForUpdate();
 			updateVolume.setSize(answer.getTemplateSize());
-			_volumeDao.update(volume.getId(), updateVolume);
+			_volumeDao.update(_volume.getId(), updateVolume);
 
             if (answer.getTemplateSize() > 0) {
                 try {
-                    String url = volumeHostDao.findByVolumeId(volume.getId()).getDownloadUrl();
-                    _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()),
+                    String url = _volumeHostDao.findByVolumeId(_volume.getId()).getDownloadUrl();
+                    _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(_volume.getAccountId()),
                             com.cloud.configuration.Resource.ResourceType.secondary_storage,
                             answer.getTemplateSize() - UriUtils.getRemoteSize(url));
                 } catch (ResourceAllocationException e) {
                     s_logger.warn(e.getMessage());
-                    _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(),
-                            volume.getPodId(), e.getMessage(), e.getMessage());
+                    _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, _volume.getDataCenterId(),
+                            _volume.getPodId(), e.getMessage(), e.getMessage());
                 } finally {
-                    _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(),
+                    _resourceLimitMgr.recalculateResourceCount(_volume.getAccountId(), _volume.getDomainId(),
                             com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
                 }
             }
@@ -474,8 +513,12 @@ public class DownloadListener implements Listener {
 	@Override
 	public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
 	    if (cmd instanceof StartupRoutingCommand) {
-
-	        downloadMonitor.handleSysTemplateDownload(agent);
+	        List<HypervisorType> hypers = _resourceMgr.listAvailHypervisorInZone(agent.getId(), agent.getDataCenterId());
+	        HypervisorType hostHyper = agent.getHypervisorType();
+	        if (hypers.contains(hostHyper)) {
+	            return;
+	        }
+	        _imageSrv.handleSysTemplateDownload(hostHyper, agent.getDataCenterId());
 	    }
 	    /* This can be removed since
 	    else if ( cmd instanceof StartupStorageCommand) {
@@ -488,16 +531,20 @@ public class DownloadListener implements Listener {
             }
 	    }*/
 	    else if ( cmd instanceof StartupSecondaryStorageCommand ) {
-	        downloadMonitor.handleSync(agent.getDataCenterId());
+	        List<DataStore> imageStores = this._storeMgr.getImageStoresByScope(new ZoneScope(agent.getDataCenterId()));
+	        for (DataStore store : imageStores){
+	            _volumeSrv.handleVolumeSync(store);
+	            _imageSrv.handleTemplateSync(store);
+	        }
 	    }
 	}
 
 	public void setCommand(DownloadCommand _cmd) {
-		this.cmd = _cmd;
+		this._cmd = _cmd;
 	}
 
 	public DownloadCommand getCommand() {
-		return cmd;
+		return _cmd;
 	}
 
 
@@ -506,63 +553,63 @@ public class DownloadListener implements Listener {
 	}
 
 	public void setJobId(String _jobId) {
-		this.jobId = _jobId;
+		this._jobId = _jobId;
 	}
 
 	public String getJobId() {
-		return jobId;
+		return _jobId;
 	}
 
 	public void scheduleStatusCheck(RequestType request) {
-		if (statusTask != null) statusTask.cancel();
+		if (_statusTask != null) _statusTask.cancel();
 
-		statusTask = new StatusTask(this, request);
-		timer.schedule(statusTask, STATUS_POLL_INTERVAL);
+		_statusTask = new StatusTask(this, request);
+		_timer.schedule(_statusTask, STATUS_POLL_INTERVAL);
 	}
 
 	public void scheduleTimeoutTask(long delay) {
-		if (timeoutTask != null) timeoutTask.cancel();
+		if (_timeoutTask != null) _timeoutTask.cancel();
 
-		timeoutTask = new TimeoutTask(this);
-		timer.schedule(timeoutTask, delay);
+		_timeoutTask = new TimeoutTask(this);
+		_timer.schedule(_timeoutTask, delay);
 		if (s_logger.isDebugEnabled()) {
 			log("Scheduling timeout at " + delay + " ms", Level.DEBUG);
 		}
 	}
 
 	public void scheduleImmediateStatusCheck(RequestType request) {
-		if (statusTask != null) statusTask.cancel();
-		statusTask = new StatusTask(this, request);
-		timer.schedule(statusTask, SMALL_DELAY);
+		if (_statusTask != null) _statusTask.cancel();
+		_statusTask = new StatusTask(this, request);
+		_timer.schedule(_statusTask, SMALL_DELAY);
 	}
 
 	public boolean isDownloadActive() {
-		return downloadActive;
+		return _downloadActive;
 	}
 
 	public void cancelStatusTask() {
-		if (statusTask != null) statusTask.cancel();
+		if (_statusTask != null) _statusTask.cancel();
 	}
 
 	public Date getLastUpdated() {
-		return lastUpdated;
+		return _lastUpdated;
 	}
 
 	public void setLastUpdated() {
-		lastUpdated  = new Date();
+		_lastUpdated  = new Date();
 	}
 
 	public void setDownloadInactive(Status reason) {
-		downloadActive=false;
-		if (template != null){
-			downloadMonitor.handleDownloadEvent(sserver, template, reason);
+		_downloadActive=false;
+		if (_template != null){
+			_downloadMonitor.handleDownloadEvent(_sserver, _template, reason);
 		}else {
-			downloadMonitor.handleDownloadEvent(sserver, volume, reason);
+			_downloadMonitor.handleDownloadEvent(_sserver, _volume, reason);
 		}
 	}
 
 	public void cancelTimeoutTask() {
-		if (timeoutTask != null) timeoutTask.cancel();
+		if (_timeoutTask != null) _timeoutTask.cancel();
 	}
 
 	public void logDownloadStart() {


[2/4] Refactor DownloadMonitorImpl code, move some functionalities to TemplateServiceImpl and VolumeServiceImpl.

Posted by mc...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/server/src/com/cloud/storage/download/DownloadMonitor.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/download/DownloadMonitor.java b/server/src/com/cloud/storage/download/DownloadMonitor.java
index b209733..b5a3f85 100644
--- a/server/src/com/cloud/storage/download/DownloadMonitor.java
+++ b/server/src/com/cloud/storage/download/DownloadMonitor.java
@@ -16,8 +16,6 @@
 // under the License.
 package com.cloud.storage.download;
 
-import java.util.Map;
-
 import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
@@ -28,7 +26,6 @@ import com.cloud.host.HostVO;
 import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.VolumeVO;
 import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.template.TemplateInfo;
 import com.cloud.utils.component.Manager;
 
 /**
@@ -37,23 +34,17 @@ import com.cloud.utils.component.Manager;
  */
 public interface DownloadMonitor extends Manager{
 
-	public boolean downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback<CreateCmdResult> callback);
+	public void downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback<CreateCmdResult> callback);
 
 	public void cancelAllDownloads(Long templateId);
 
-	public void handleTemplateSync(DataStore store);
-
 	public boolean copyTemplate(VMTemplateVO template, HostVO sourceServer, HostVO destServer)
 			throws StorageUnavailableException;
 
-    void handleSysTemplateDownload(HostVO hostId);
-
-    void handleSync(Long dcId);
-
-    void addSystemVMTemplatesToHost(HostVO host, Map<String, TemplateInfo> templateInfos);
+    //void addSystemVMTemplatesToHost(HostVO host, Map<String, TemplateProp> templateInfos);
 
-	boolean downloadVolumeToStorage(VolumeVO volume, Long zoneId, String url, String checkSum, ImageFormat format);
+	//public boolean downloadVolumeToStorage(VolumeVO volume, Long zoneId, String url, String checkSum, ImageFormat format);
 
-	void handleVolumeSync(HostVO ssHost);
+	public void downloadVolumeToStorage(VolumeVO volume, DataStore store, String url, String checkSum, ImageFormat format, AsyncCompletionCallback<CreateCmdResult> callback);
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
index 82665e3..507d575 100755
--- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
+++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
@@ -18,12 +18,9 @@ package com.cloud.storage.download;
 
 import java.net.URI;
 import java.net.URISyntaxException;
-import java.util.ArrayList;
 import java.util.Date;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.Timer;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -33,19 +30,17 @@ import javax.inject.Inject;
 import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
 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.ZoneScope;
 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.log4j.Logger;
 import org.springframework.stereotype.Component;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.Listener;
-import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.Command;
 
-import com.cloud.agent.api.storage.DeleteTemplateCommand;
-import com.cloud.agent.api.storage.DeleteVolumeCommand;
 import com.cloud.agent.api.storage.DownloadCommand;
 
 import com.cloud.agent.api.storage.DownloadCommand.Proxy;
@@ -53,16 +48,10 @@ import com.cloud.agent.api.storage.DownloadCommand.ResourceType;
 import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType;
 
 import com.cloud.agent.api.storage.DownloadProgressCommand;
-import com.cloud.agent.api.storage.ListTemplateAnswer;
-import com.cloud.agent.api.storage.ListTemplateCommand;
-import com.cloud.agent.api.storage.ListVolumeAnswer;
-import com.cloud.agent.api.storage.ListVolumeCommand;
-
 import com.cloud.agent.manager.Commands;
 import com.cloud.alert.AlertManager;
 import com.cloud.configuration.Config;
 import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.dc.DataCenterVO;
 import com.cloud.dc.dao.ClusterDao;
 import com.cloud.dc.dao.DataCenterDao;
 import com.cloud.event.EventTypes;
@@ -70,9 +59,7 @@ import com.cloud.event.UsageEventUtils;
 import com.cloud.event.dao.UsageEventDao;
 import com.cloud.exception.AgentUnavailableException;
 import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
 import com.cloud.exception.StorageUnavailableException;
-import com.cloud.host.Host;
 import com.cloud.host.HostVO;
 import com.cloud.host.dao.HostDao;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
@@ -80,12 +67,10 @@ import com.cloud.resource.ResourceManager;
 import com.cloud.storage.Storage.ImageFormat;
 
 import com.cloud.storage.StorageManager;
-import com.cloud.storage.SwiftVO;
 import com.cloud.storage.VMTemplateHostVO;
 import com.cloud.storage.VMTemplateStorageResourceAssoc;
 import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
-import com.cloud.storage.VMTemplateZoneVO;
 import com.cloud.storage.VolumeHostVO;
 import com.cloud.storage.VolumeVO;
 import com.cloud.storage.dao.StoragePoolHostDao;
@@ -101,12 +86,10 @@ import com.cloud.storage.dao.VolumeHostDao;
 import com.cloud.storage.secondary.SecondaryStorageVmManager;
 import com.cloud.storage.swift.SwiftManager;
 import com.cloud.storage.template.TemplateConstants;
-import com.cloud.storage.template.TemplateInfo;
 import com.cloud.template.TemplateManager;
 import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
 import com.cloud.user.ResourceLimitService;
-import com.cloud.utils.UriUtils;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.db.DB;
 import com.cloud.utils.db.JoinBuilder;
@@ -117,14 +100,10 @@ import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.vm.SecondaryStorageVm;
 import com.cloud.vm.SecondaryStorageVmVO;
 import com.cloud.vm.UserVmManager;
-import com.cloud.vm.UserVmVO;
 import com.cloud.vm.VirtualMachine.State;
 import com.cloud.vm.dao.SecondaryStorageVmDao;
 import com.cloud.vm.dao.UserVmDao;
 
-import edu.emory.mathcs.backport.java.util.Collections;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
 import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 
 
@@ -152,6 +131,8 @@ public class DownloadMonitorImpl extends ManagerBase implements  DownloadMonitor
     @Inject
     VolumeHostDao _volumeHostDao;
     @Inject
+    VolumeDataStoreDao _volumeStoreDao;
+    @Inject
     AlertManager _alertMgr;
     @Inject
     protected SwiftManager _swiftMgr;
@@ -206,6 +187,7 @@ public class DownloadMonitorImpl extends ManagerBase implements  DownloadMonitor
     final Map<TemplateDataStoreVO, DownloadListener> _listenerTemplateMap = new ConcurrentHashMap<TemplateDataStoreVO, DownloadListener>();
 	final Map<VMTemplateHostVO, DownloadListener> _listenerMap = new ConcurrentHashMap<VMTemplateHostVO, DownloadListener>();
 	final Map<VolumeHostVO, DownloadListener> _listenerVolumeMap = new ConcurrentHashMap<VolumeHostVO, DownloadListener>();
+	final Map<VolumeDataStoreVO, DownloadListener> _listenerVolMap = new ConcurrentHashMap<VolumeDataStoreVO, DownloadListener>();
 
 
 	public void send(Long hostId, Command cmd, Listener listener) throws AgentUnavailableException {
@@ -256,7 +238,7 @@ public class DownloadMonitorImpl extends ManagerBase implements  DownloadMonitor
 
 	public boolean isTemplateUpdateable(Long templateId, Long storeId) {
 		List<TemplateDataStoreVO> downloadsInProgress =
-			_vmTemplateStoreDao.listByTemplateStoreStatus(templateId, storeId, ObjectInDataStoreStateMachine.State.Creating, ObjectInDataStoreStateMachine.State.Creating2, ObjectInDataStoreStateMachine.State.Ready);
+			_vmTemplateStoreDao.listByTemplateStoreDownloadStatus(templateId, storeId, Status.DOWNLOAD_IN_PROGRESS, Status.DOWNLOADED );
 		return (downloadsInProgress.size() == 0);
 	}
 
@@ -370,7 +352,11 @@ public class DownloadMonitorImpl extends ManagerBase implements  DownloadMonitor
         TemplateDataStoreVO vmTemplateStore = null;
 
         vmTemplateStore = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId());
-        // we should already persist one entry in template_store_ref table, so vmTemplateStore should not be null
+        if (vmTemplateStore == null) {
+            // This method can be invoked other places, for example, handleTemplateSync, in that case, vmTemplateStore may be null
+            vmTemplateStore = new TemplateDataStoreVO(store.getId(), template.getId(), new Date(), 0, VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, template.getUrl());
+            _vmTemplateStoreDao.persist(vmTemplateStore);
+        } else
         if ((vmTemplateStore.getJobId() != null) && (vmTemplateStore.getJobId().length() > 2)) {
             downloadJobExists = true;
         }
@@ -420,42 +406,33 @@ public class DownloadMonitorImpl extends ManagerBase implements  DownloadMonitor
 
 
 	@Override
-	public boolean downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback<CreateCmdResult> callback) {
+	public void downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback<CreateCmdResult> callback) {
         long templateId = template.getId();
         if (isTemplateUpdateable(templateId, store.getId())) {
             if ( template != null && template.getUrl() != null ){
                 initiateTemplateDownload(template, store, callback);
             }
         }
-	    return true;
 	}
 
-	@Override
-	public boolean downloadVolumeToStorage(VolumeVO volume, Long zoneId, String url, String checkSum, ImageFormat format) {
-
-	    List<HostVO> ssHosts = _ssvmMgr.listAllTypesSecondaryStorageHostsInOneZone(zoneId);
-	    Collections.shuffle(ssHosts);
-	    HostVO ssHost = ssHosts.get(0);
-	    downloadVolumeToStorage(volume, ssHost, url, checkSum, format);
-	    return true;
-	}
 
-	private void downloadVolumeToStorage(VolumeVO volume, HostVO sserver, String url, String checkSum, ImageFormat format) {
+	@Override
+	public void downloadVolumeToStorage(VolumeVO volume, DataStore store, String url, String checkSum, ImageFormat format, AsyncCompletionCallback<CreateCmdResult> callback) {
 		boolean downloadJobExists = false;
-        VolumeHostVO volumeHost = null;
+        VolumeDataStoreVO volumeHost = null;
 
-        volumeHost = _volumeHostDao.findByHostVolume(sserver.getId(), volume.getId());
+        volumeHost = _volumeStoreDao.findByStoreVolume(store.getId(), volume.getId());
         if (volumeHost == null) {
-            volumeHost = new VolumeHostVO(sserver.getId(), volume.getId(), sserver.getDataCenterId(), new Date(), 0, VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null,
+            volumeHost = new VolumeDataStoreVO(store.getId(), volume.getId(), new Date(), 0, VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null,
             		"jobid0000", null, url, checkSum, format);
-            _volumeHostDao.persist(volumeHost);
+            _volumeStoreDao.persist(volumeHost);
         } else if ((volumeHost.getJobId() != null) && (volumeHost.getJobId().length() > 2)) {
             downloadJobExists = true;
         }
 
 
         Long maxVolumeSizeInBytes = getMaxVolumeSizeInBytes();
-        String secUrl = sserver.getStorageUrl();
+        String secUrl = store.getUri();
 		if(volumeHost != null) {
 		    start();
 			DownloadCommand dcmd = new DownloadCommand(secUrl, volume, maxVolumeSizeInBytes, checkSum, url, format);
@@ -465,45 +442,35 @@ public class DownloadMonitorImpl extends ManagerBase implements  DownloadMonitor
 	            dcmd.setResourceType(ResourceType.VOLUME);
 	        }
 
-			HostVO ssvm = _ssvmMgr.pickSsvmHost(sserver);
-			if( ssvm == null ) {
-	             s_logger.warn("There is no secondary storage VM for secondary storage host " + sserver.getName());
+			HostVO ssAhost = _ssvmMgr.pickSsvmHost(store);
+			if( ssAhost == null ) {
+	             s_logger.warn("There is no secondary storage VM for image store " + store.getName());
 	             return;
 			}
-			DownloadListener dl = new DownloadListener(ssvm, sserver, volume, _timer, _volumeHostDao, volumeHost.getId(),
-					this, dcmd, _volumeDao, _storageMgr, _resourceLimitMgr, _alertMgr, _accountMgr);
+			DownloadListener dl = new DownloadListener(ssAhost, store, volume, _timer, _volumeStoreDao, volumeHost.getId(),
+					this, dcmd, _volumeDao, _storageMgr, _resourceLimitMgr, _alertMgr, _accountMgr, callback);
 
 			if (downloadJobExists) {
 				dl.setCurrState(volumeHost.getDownloadState());
 	 		}
             DownloadListener old = null;
-            synchronized (_listenerVolumeMap) {
-                old = _listenerVolumeMap.put(volumeHost, dl);
+            synchronized (_listenerVolMap) {
+                old = _listenerVolMap.put(volumeHost, dl);
             }
             if( old != null ) {
                 old.abandon();
             }
 
 			try {
-	            send(ssvm.getId(), dcmd, dl);
+	            send(ssAhost.getId(), dcmd, dl);
             } catch (AgentUnavailableException e) {
-				s_logger.warn("Unable to start /resume download of volume " + volume.getName() + " to " + sserver.getName(), e);
+				s_logger.warn("Unable to start /resume download of volume " + volume.getName() + " to " + store.getName(), e);
 				dl.setDisconnected();
 				dl.scheduleStatusCheck(RequestType.GET_OR_RESTART);
             }
 		}
 	}
 
-/*
-	private void initiateTemplateDownload(Long templateId, DataStore store) {
-		VMTemplateVO template = _templateDao.findById(templateId);
-		if (template != null && (template.getUrl() != null)) {
-			//find all storage hosts and tell them to initiate download
-    		downloadTemplateToStorage(template, store);
-		}
-
-	}
-	*/
 
 	@DB
 	public void handleDownloadEvent(HostVO host, VMTemplateVO template, Status dnldStatus) {
@@ -583,62 +550,18 @@ public class DownloadMonitorImpl extends ManagerBase implements  DownloadMonitor
         txn.commit();
 	}
 
-	@Override
-    public void handleSysTemplateDownload(HostVO host) {
-	    List<HypervisorType> hypers = _resourceMgr.listAvailHypervisorInZone(host.getId(), host.getDataCenterId());
-	    HypervisorType hostHyper = host.getHypervisorType();
-	    if (hypers.contains(hostHyper)) {
-	        return;
-	    }
 
-	    Set<VMTemplateVO> toBeDownloaded = new HashSet<VMTemplateVO>();
-	    List<DataStore> ssHosts = this.storeMgr.getImageStoresByScope(new ZoneScope(host.getDataCenterId()));
-	    if (ssHosts == null || ssHosts.isEmpty()){
-	        return;
-	    }
-	       /*
-	    List<HostVO> ssHosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByType(Host.Type.SecondaryStorage, host.getDataCenterId());
-	    if (ssHosts == null || ssHosts.isEmpty()) {
-	        return;
-	    }
-	    */
-	    /*Download all the templates in zone with the same hypervisortype*/
-        for ( DataStore ssHost : ssHosts) {
-    	    List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
-    	    List<VMTemplateVO> defaultBuiltin = _templateDao.listDefaultBuiltinTemplates();
-
-
-    	    for (VMTemplateVO rtngTmplt : rtngTmplts) {
-    	        if (rtngTmplt.getHypervisorType() == hostHyper) {
-    	            toBeDownloaded.add(rtngTmplt);
-    	        }
-    	    }
-
-    	    for (VMTemplateVO builtinTmplt : defaultBuiltin) {
-    	        if (builtinTmplt.getHypervisorType() == hostHyper) {
-    	            toBeDownloaded.add(builtinTmplt);
-    	        }
-    	    }
-
-    	    for (VMTemplateVO template: toBeDownloaded) {
-    	        VMTemplateHostVO tmpltHost = _vmTemplateHostDao.findByHostTemplate(ssHost.getId(), template.getId());
-    	        if (tmpltHost == null || tmpltHost.getDownloadState() != Status.DOWNLOADED) {
-    	            //TODO: pass callback here
-    	            initiateTemplateDownload(template, ssHost, null);
-    	        }
-    	    }
-        }
-	}
 
+	/*
     @Override
-	public void addSystemVMTemplatesToHost(HostVO host, Map<String, TemplateInfo> templateInfos){
+	public void addSystemVMTemplatesToHost(HostVO host, Map<String, TemplateProp> templateInfos){
 	    if ( templateInfos == null ) {
 	        return;
 	    }
 	    Long hostId = host.getId();
 	    List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
 	    for ( VMTemplateVO tmplt : rtngTmplts ) {
-	        TemplateInfo tmpltInfo = templateInfos.get(tmplt.getUniqueName());
+	        TemplateProp tmpltInfo = templateInfos.get(tmplt.getUniqueName());
 	        if ( tmpltInfo == null ) {
 	            continue;
 	        }
@@ -651,354 +574,9 @@ public class DownloadMonitorImpl extends ManagerBase implements  DownloadMonitor
 	        }
 	    }
 	}
+    */
 
-    @Override
-    public void handleSync(Long dcId) {
-        if (dcId != null) {
-            List<HostVO> ssHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(dcId);
-            for (HostVO ssHost : ssHosts) {
-                //handleTemplateSync(ssHost);
-                handleVolumeSync(ssHost);
-            }
-        }
-        List<DataStore> imageStores = this.storeMgr.getImageStoresByScope(new ZoneScope(dcId));
-        for (DataStore store : imageStores){
-            handleTemplateSync(store);
-        }
-    }
-
-    private Map<String, TemplateInfo> listTemplate(DataStore ssHost) {
-        ListTemplateCommand cmd = new ListTemplateCommand(ssHost.getUri());
-        HostVO ssAhost = _ssvmMgr.pickSsvmHost(ssHost);
-        Answer answer = _agentMgr.sendToSecStorage(ssAhost, cmd);
-        if (answer != null && answer.getResult()) {
-            ListTemplateAnswer tanswer = (ListTemplateAnswer)answer;
-            return tanswer.getTemplateInfo();
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("can not list template for secondary storage host " + ssHost.getId());
-            }
-        }
-
-        return null;
-    }
-
-    private Map<Long, TemplateInfo> listVolume(HostVO ssHost) {
-    	ListVolumeCommand cmd = new ListVolumeCommand(ssHost.getStorageUrl());
-        Answer answer = _agentMgr.sendToSecStorage(ssHost, cmd);
-        if (answer != null && answer.getResult()) {
-        	ListVolumeAnswer tanswer = (ListVolumeAnswer)answer;
-            return tanswer.getTemplateInfo();
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Can not list volumes for secondary storage host " + ssHost.getId());
-            }
-        }
-
-        return null;
-    }
-
-    private Map<String, TemplateInfo> listTemplate(SwiftVO swift) {
-        if (swift == null) {
-            return null;
-        }
-        ListTemplateCommand cmd = new ListTemplateCommand(swift.toSwiftTO());
-        Answer answer = _agentMgr.sendToSSVM(null, cmd);
-        if (answer != null && answer.getResult()) {
-            ListTemplateAnswer tanswer = (ListTemplateAnswer) answer;
-            return tanswer.getTemplateInfo();
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("can not list template for swift " + swift);
-            }
-        }
-        return null;
-    }
 
-    @Override
-    public void handleVolumeSync(HostVO ssHost) {
-        if (ssHost == null) {
-            s_logger.warn("Huh? ssHost is null");
-            return;
-        }
-        long sserverId = ssHost.getId();
-        if (!(ssHost.getType() == Host.Type.SecondaryStorage || ssHost.getType() == Host.Type.LocalSecondaryStorage)) {
-            s_logger.warn("Huh? Agent id " + sserverId + " is not secondary storage host");
-            return;
-        }
-
-        Map<Long, TemplateInfo> volumeInfos = listVolume(ssHost);
-        if (volumeInfos == null) {
-            return;
-        }
-
-        List<VolumeHostVO> dbVolumes = _volumeHostDao.listBySecStorage(sserverId);
-        List<VolumeHostVO> toBeDownloaded = new ArrayList<VolumeHostVO>(dbVolumes);
-        for (VolumeHostVO volumeHost : dbVolumes){
-        	VolumeVO volume = _volumeDao.findById(volumeHost.getVolumeId());
-        	//Exists then don't download
-        	if (volumeInfos.containsKey(volume.getId())){
-                TemplateInfo volInfo = volumeInfos.remove(volume.getId());
-                toBeDownloaded.remove(volumeHost);
-                s_logger.info("Volume Sync found " + volume.getUuid() + " already in the volume host table");
-                if (volumeHost.getDownloadState() != Status.DOWNLOADED) {
-                	volumeHost.setErrorString("");
-                }
-                if (volInfo.isCorrupted()) {
-                	volumeHost.setDownloadState(Status.DOWNLOAD_ERROR);
-                    String msg = "Volume " + volume.getUuid() + " is corrupted on secondary storage ";
-                    volumeHost.setErrorString(msg);
-                    s_logger.info("msg");
-                    if (volumeHost.getDownloadUrl() == null) {
-                        msg = "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() + "is corrupted, please check in secondary storage: " + volumeHost.getHostId();
-                        s_logger.warn(msg);
-                    } else {
-                        toBeDownloaded.add(volumeHost);
-                    }
-
-                } else { // Put them in right status
-                    volumeHost.setDownloadPercent(100);
-                    volumeHost.setDownloadState(Status.DOWNLOADED);
-                    volumeHost.setInstallPath(volInfo.getInstallPath());
-                    volumeHost.setSize(volInfo.getSize());
-                    volumeHost.setPhysicalSize(volInfo.getPhysicalSize());
-                    volumeHost.setLastUpdated(new Date());
-                    _volumeHostDao.update(volumeHost.getId(), volumeHost);
-
-                    if (volume.getSize() == 0) {
-                        // Set volume size in volumes table
-                        volume.setSize(volInfo.getSize());
-                        _volumeDao.update(volumeHost.getVolumeId(), volume);
-                    }
-
-                    if (volInfo.getSize() > 0) {
-                        try {
-                            String url = _volumeHostDao.findByVolumeId(volume.getId()).getDownloadUrl();
-                            _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()),
-                                    com.cloud.configuration.Resource.ResourceType.secondary_storage,
-                                    volInfo.getSize() - UriUtils.getRemoteSize(url));
-                        } catch (ResourceAllocationException e) {
-                            s_logger.warn(e.getMessage());
-                            _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(),
-                                    volume.getPodId(), e.getMessage(), e.getMessage());
-                        } finally {
-                            _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(),
-                                    com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
-                        }
-                    }
-                }
-                continue;
-        	}
-        	// Volume is not on secondary but we should download.
-        	if (volumeHost.getDownloadState() != Status.DOWNLOADED) {
-                s_logger.info("Volume Sync did not find " + volume.getName() + " ready on server " + sserverId + ", will request download to start/resume shortly");
-                toBeDownloaded.add(volumeHost);
-            }
-        }
-
-        //Download volumes which haven't been downloaded yet.
-        if (toBeDownloaded.size() > 0) {
-            for (VolumeHostVO volumeHost : toBeDownloaded) {
-                if (volumeHost.getDownloadUrl() == null) { // If url is null we can't initiate the download
-                    continue;
-                }
-                s_logger.debug("Volume " + volumeHost.getVolumeId() + " needs to be downloaded to " + ssHost.getName());
-                downloadVolumeToStorage(_volumeDao.findById(volumeHost.getVolumeId()), ssHost,  volumeHost.getDownloadUrl(), volumeHost.getChecksum(), volumeHost.getFormat());
-            }
-        }
-
-        //Delete volumes which are not present on DB.
-        for (Long uniqueName : volumeInfos.keySet()) {
-            TemplateInfo vInfo = volumeInfos.get(uniqueName);
-            DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(ssHost.getStorageUrl(), vInfo.getInstallPath());
-            try {
-	            _agentMgr.sendToSecStorage(ssHost, dtCommand, null);
-            } catch (AgentUnavailableException e) {
-                String err = "Failed to delete " + vInfo.getTemplateName() + " on secondary storage " + sserverId + " which isn't in the database";
-                s_logger.error(err);
-                return;
-            }
-
-            String description = "Deleted volume " + vInfo.getTemplateName() + " on secondary storage " + sserverId + " since it isn't in the database";
-            s_logger.info(description);
-        }
-    }
-
-	@Override
-    public void handleTemplateSync(DataStore ssStore) {
-        if (ssStore == null) {
-            s_logger.warn("Huh? image store is null");
-            return;
-        }
-        long storeId = ssStore.getId();
-        Long zoneId = ssStore.getScope().getScopeId();
-
-        Map<String, TemplateInfo> templateInfos = listTemplate(ssStore);
-        if (templateInfos == null) {
-            return;
-        }
-
-        Set<VMTemplateVO> toBeDownloaded = new HashSet<VMTemplateVO>();
-        List<VMTemplateVO> allTemplates = null;
-        if (zoneId == null){
-            // region wide store
-            allTemplates = _templateDao.listAll();
-        }
-        else{
-            // zone wide store
-            allTemplates = _templateDao.listAllInZone(zoneId);
-        }
-        List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
-        List<VMTemplateVO> defaultBuiltin = _templateDao.listDefaultBuiltinTemplates();
-
-        if (rtngTmplts != null) {
-            for (VMTemplateVO rtngTmplt : rtngTmplts) {
-                if (!allTemplates.contains(rtngTmplt)) {
-                    allTemplates.add(rtngTmplt);
-                }
-            }
-        }
-
-        if (defaultBuiltin != null) {
-            for (VMTemplateVO builtinTmplt : defaultBuiltin) {
-                if (!allTemplates.contains(builtinTmplt)) {
-                    allTemplates.add(builtinTmplt);
-                }
-            }
-        }
-
-        toBeDownloaded.addAll(allTemplates);
-
-        for (VMTemplateVO tmplt : allTemplates) {
-            String uniqueName = tmplt.getUniqueName();
-            TemplateDataStoreVO tmpltStore = _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId());
-            if (templateInfos.containsKey(uniqueName)) {
-                TemplateInfo tmpltInfo = templateInfos.remove(uniqueName);
-                toBeDownloaded.remove(tmplt);
-                if (tmpltStore != null) {
-                    s_logger.info("Template Sync found " + uniqueName + " already in the template host table");
-                    if (tmpltStore.getDownloadState() != Status.DOWNLOADED) {
-                        tmpltStore.setErrorString("");
-                    }
-                    if (tmpltInfo.isCorrupted()) {
-                        tmpltStore.setDownloadState(Status.DOWNLOAD_ERROR);
-                        String msg = "Template " + tmplt.getName() + ":" + tmplt.getId() + " is corrupted on secondary storage " + tmpltStore.getId();
-                        tmpltStore.setErrorString(msg);
-                        s_logger.info("msg");
-                        if (tmplt.getUrl() == null) {
-                            msg = "Private Template (" + tmplt + ") with install path " + tmpltInfo.getInstallPath() + "is corrupted, please check in image store: " + tmpltStore.getDataStoreId();
-                            s_logger.warn(msg);
-                        } else {
-                            toBeDownloaded.add(tmplt);
-                        }
-
-                    } else {
-                        tmpltStore.setDownloadPercent(100);
-                        tmpltStore.setDownloadState(Status.DOWNLOADED);
-                        tmpltStore.setInstallPath(tmpltInfo.getInstallPath());
-                        tmpltStore.setSize(tmpltInfo.getSize());
-                        tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize());
-                        tmpltStore.setLastUpdated(new Date());
-
-                        if (tmpltInfo.getSize() > 0) {
-                            long accountId = tmplt.getAccountId();
-                            try {
-                                _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(accountId),
-                                        com.cloud.configuration.Resource.ResourceType.secondary_storage,
-                                        tmpltInfo.getSize() - UriUtils.getRemoteSize(tmplt.getUrl()));
-                            } catch (ResourceAllocationException e) {
-                                s_logger.warn(e.getMessage());
-                                _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, zoneId,
-                                        null, e.getMessage(), e.getMessage());
-                            } finally {
-                                _resourceLimitMgr.recalculateResourceCount(accountId, _accountMgr.getAccount(accountId).getDomainId(),
-                                        com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
-                            }
-                        }
-                    }
-                    _vmTemplateStoreDao.update(tmpltStore.getId(), tmpltStore);
-                } else {
-                    tmpltStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, tmpltInfo.getInstallPath(), tmplt.getUrl());
-                    tmpltStore.setSize(tmpltInfo.getSize());
-                    tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize());
-                    _vmTemplateStoreDao.persist(tmpltStore);
-                    this.associateTemplateToZone(tmplt.getId(), zoneId);
-                }
-
-                continue;
-            }
-            if (tmpltStore != null && tmpltStore.getDownloadState() != Status.DOWNLOADED) {
-                s_logger.info("Template Sync did not find " + uniqueName + " ready on server " + storeId + ", will request download to start/resume shortly");
-
-            } else if (tmpltStore == null) {
-                s_logger.info("Template Sync did not find " + uniqueName + " on the server " + storeId + ", will request download shortly");
-                TemplateDataStoreVO templtStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 0, Status.NOT_DOWNLOADED, null, null, null, null, tmplt.getUrl());
-                _vmTemplateStoreDao.persist(templtStore);
-                this.associateTemplateToZone(tmplt.getId(), zoneId);
-            }
-
-        }
-
-        if (toBeDownloaded.size() > 0) {
-            /* Only download templates whose hypervirsor type is in the zone */
-            List<HypervisorType> availHypers = _clusterDao.getAvailableHypervisorInZone(zoneId);
-            if (availHypers.isEmpty()) {
-                /*
-                 * This is for cloudzone, local secondary storage resource
-                 * started before cluster created
-                 */
-                availHypers.add(HypervisorType.KVM);
-            }
-            /* Baremetal need not to download any template */
-            availHypers.remove(HypervisorType.BareMetal);
-            availHypers.add(HypervisorType.None); // bug 9809: resume ISO
-                                                  // download.
-            for (VMTemplateVO tmplt : toBeDownloaded) {
-                if (tmplt.getUrl() == null) { // If url is null we can't
-                                              // initiate the download
-                    continue;
-                }
-                // if this is private template, and there is no record for this
-                // template in this sHost, skip
-                if (!tmplt.isPublicTemplate() && !tmplt.isFeatured()) {
-                    VMTemplateHostVO tmpltHost = _vmTemplateHostDao.findByHostTemplate(storeId, tmplt.getId());
-                    if (tmpltHost == null) {
-                        continue;
-                    }
-                }
-                if (availHypers.contains(tmplt.getHypervisorType())) {
-                    if (_swiftMgr.isSwiftEnabled()) {
-                        if (_swiftMgr.isTemplateInstalled(tmplt.getId())) {
-                            continue;
-                        }
-                    }
-                    s_logger.debug("Template " + tmplt.getName() + " needs to be downloaded to " + ssStore.getName());
-                    //TODO: we should pass a callback here
-                    initiateTemplateDownload(tmplt, ssStore, null);
-                }
-            }
-        }
-
-        for (String uniqueName : templateInfos.keySet()) {
-            TemplateInfo tInfo = templateInfos.get(uniqueName);
-            List<UserVmVO> userVmUsingIso = _userVmDao.listByIsoId(tInfo.getId());
-            //check if there is any Vm using this ISO.
-            if (userVmUsingIso == null || userVmUsingIso.isEmpty()) {
-                DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(ssStore.getUri(), tInfo.getInstallPath());
-                try {
-                    HostVO ssAhost = _ssvmMgr.pickSsvmHost(ssStore);
-                    _agentMgr.sendToSecStorage(ssAhost, dtCommand, null);
-                } catch (AgentUnavailableException e) {
-                    String err = "Failed to delete " + tInfo.getTemplateName() + " on secondary storage " + storeId + " which isn't in the database";
-                    s_logger.error(err);
-                    return;
-                }
-
-                String description = "Deleted template " + tInfo.getTemplateName() + " on secondary storage " + storeId + " since it isn't in the database";
-                s_logger.info(description);
-            }
-        }
-    }
 
 	@Override
 	public void cancelAllDownloads(Long templateId) {
@@ -1067,30 +645,6 @@ public class DownloadMonitorImpl extends ManagerBase implements  DownloadMonitor
 		}
 	}
 
-	// persist entry in template_zone_ref table. zoneId can be empty for region-wide image store, in that case,
-	// we will associate the template to all the zones.
-	private void associateTemplateToZone(long templateId, Long zoneId){
-        List<Long> dcs = new ArrayList<Long>();
-        if (zoneId != null ){
-            dcs.add(zoneId);
-        }
-        else{
-            List<DataCenterVO> zones = _dcDao.listAll();
-            for (DataCenterVO zone : zones){
-                dcs.add(zone.getId());
-            }
-        }
-        for (Long id : dcs) {
-            VMTemplateZoneVO tmpltZoneVO = _vmTemplateZoneDao.findByZoneTemplate(id, templateId);
-            if (tmpltZoneVO == null) {
-                tmpltZoneVO = new VMTemplateZoneVO(id, templateId, new Date());
-                _vmTemplateZoneDao.persist(tmpltZoneVO);
-            } else {
-                tmpltZoneVO.setLastUpdated(new Date());
-                _vmTemplateZoneDao.update(tmpltZoneVO.getId(), tmpltZoneVO);
-            }
-        }
-	}
 
 }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/server/src/com/cloud/storage/resource/DummySecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/resource/DummySecondaryStorageResource.java b/server/src/com/cloud/storage/resource/DummySecondaryStorageResource.java
index 8f25514..02463d2 100644
--- a/server/src/com/cloud/storage/resource/DummySecondaryStorageResource.java
+++ b/server/src/com/cloud/storage/resource/DummySecondaryStorageResource.java
@@ -50,7 +50,7 @@ import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.Storage.StoragePoolType;
 import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.storage.template.TemplateConstants;
-import com.cloud.storage.template.TemplateInfo;
+import com.cloud.storage.template.TemplateProp;
 
 
 public class DummySecondaryStorageResource extends ServerResourceBase implements ServerResource {
@@ -113,7 +113,7 @@ public class DummySecondaryStorageResource extends ServerResourceBase implements
     public StartupCommand[] initialize() {
         final StartupStorageCommand cmd = new StartupStorageCommand("dummy",
                 StoragePoolType.NetworkFilesystem, 1024*1024*1024*100L,
-                new HashMap<String, TemplateInfo>());
+                new HashMap<String, TemplateProp>());
 
         cmd.setResourceType(Storage.StorageResourceType.SECONDARY_STORAGE);
         cmd.setIqn(null);
@@ -173,12 +173,12 @@ public class DummySecondaryStorageResource extends ServerResourceBase implements
         return _useServiceVm;
     }
 
-    public Map<String, TemplateInfo> getDefaultSystemVmTemplateInfo() {	        
+    public Map<String, TemplateProp> getDefaultSystemVmTemplateInfo() {	        
         List<VMTemplateVO> tmplts = _tmpltDao.listAllSystemVMTemplates();
-        Map<String, TemplateInfo> tmpltInfo = new HashMap<String, TemplateInfo>();
+        Map<String, TemplateProp> tmpltInfo = new HashMap<String, TemplateProp>();
         if (tmplts != null) {
             for (VMTemplateVO tmplt : tmplts) {
-                TemplateInfo routingInfo = new TemplateInfo(tmplt.getUniqueName(), TemplateConstants.DEFAULT_SYSTEM_VM_TEMPLATE_PATH + tmplt.getId() + File.separator, false, false);
+                TemplateProp routingInfo = new TemplateProp(tmplt.getUniqueName(), TemplateConstants.DEFAULT_SYSTEM_VM_TEMPLATE_PATH + tmplt.getId() + File.separator, false, false);
                 tmpltInfo.put(tmplt.getUniqueName(), routingInfo);
             }
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/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 709288e..06cf6ac 100755
--- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java
+++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java
@@ -36,7 +36,7 @@ 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.DataStoreRole;
 import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.ImageService;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
 import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
 import org.apache.cloudstack.framework.async.AsyncCallFuture;
 import org.apache.log4j.Logger;
@@ -75,7 +75,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te
 	@Inject AgentManager _agentMgr;
 
     @Inject DataStoreManager storeMgr;
-    @Inject ImageService imageService;
+    @Inject TemplateService imageService;
     @Inject ImageDataFactory imageFactory;
     @Inject TemplateManager templateMgr;
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/server/src/com/cloud/template/TemplateManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/template/TemplateManager.java b/server/src/com/cloud/template/TemplateManager.java
index 19ba3b5..af54880 100755
--- a/server/src/com/cloud/template/TemplateManager.java
+++ b/server/src/com/cloud/template/TemplateManager.java
@@ -35,7 +35,7 @@ import com.cloud.utils.Pair;
 /**
  * TemplateManager manages the templates stored on secondary storage. It is responsible for creating private/public templates.
  */
-public interface TemplateManager extends TemplateService{
+public interface TemplateManager extends TemplateApiService{
 
     /**
      * Prepares a template for vm creation for a certain storage pool.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/server/src/com/cloud/template/TemplateManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java
index f4ad36e..77c6860 100755
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/com/cloud/template/TemplateManagerImpl.java
@@ -58,7 +58,7 @@ 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.DataStoreRole;
 import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.ImageService;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
 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.TemplateInfo;
@@ -187,8 +187,8 @@ import com.cloud.vm.dao.UserVmDao;
 import com.cloud.vm.dao.VMInstanceDao;
 
 @Component
-@Local(value={TemplateManager.class, TemplateService.class})
-public class TemplateManagerImpl extends ManagerBase implements TemplateManager, TemplateService {
+@Local(value={TemplateManager.class, TemplateApiService.class})
+public class TemplateManagerImpl extends ManagerBase implements TemplateManager, TemplateApiService {
     private final static Logger s_logger = Logger.getLogger(TemplateManagerImpl.class);
     @Inject VMTemplateDao _tmpltDao;
     @Inject VMTemplateHostDao _tmpltHostDao;
@@ -246,7 +246,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
     @Inject
     SnapshotDataFactory snapshotFactory;
     @Inject
-    ImageService imageSvr;
+    TemplateService imageSvr;
     @Inject
     DataStoreManager dataStoreMgr;
     @Inject


[4/4] git commit: updated refs/heads/object_store to bb64672

Posted by mc...@apache.org.
Refactor DownloadMonitorImpl code, move some functionalities to
TemplateServiceImpl and VolumeServiceImpl.

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

Branch: refs/heads/object_store
Commit: bb64672715e50f232373f24b2562c434a6e2ab64
Parents: 582a1f0
Author: Min Chen <mi...@citrix.com>
Authored: Thu Apr 11 18:09:42 2013 -0700
Committer: Min Chen <mi...@citrix.com>
Committed: Thu Apr 11 18:09:42 2013 -0700

----------------------------------------------------------------------
 .../cloud/agent/api/ModifyStoragePoolAnswer.java   |   10 +-
 .../com/cloud/agent/api/StartupStorageCommand.java |   12 +-
 .../agent/api/storage/ListTemplateAnswer.java      |   10 +-
 .../cloud/agent/api/storage/ListVolumeAnswer.java  |   10 +-
 .../com/cloud/storage/template/TemplateInfo.java   |   81 ---
 .../com/cloud/storage/template/TemplateProp.java   |   81 +++
 api/src/com/cloud/template/TemplateApiService.java |  100 +++
 api/src/com/cloud/template/TemplateService.java    |  100 ---
 api/src/org/apache/cloudstack/api/BaseCmd.java     |    4 +-
 client/tomcatconf/applicationContext.xml.in        |    2 +-
 .../hypervisor/hyperv/resource/HypervResource.java |    4 +-
 .../resource/CifsSecondaryStorageResource.java     |    4 +-
 .../resource/LocalSecondaryStorageResource.java    |    4 +-
 .../resource/NfsSecondaryStorageResource.java      |   14 +-
 .../cloud/storage/template/DownloadManager.java    |    4 +-
 .../storage/template/DownloadManagerImpl.java      |   12 +-
 .../cloud/storage/template/TemplateLocation.java   |    4 +-
 .../engine/subsystem/api/storage/ImageService.java |   29 -
 .../subsystem/api/storage/TemplateService.java     |   35 +
 .../subsystem/api/storage/VolumeService.java       |   18 +-
 .../storage/datastore/db/SnapshotDataStoreDao.java |    2 -
 .../storage/datastore/db/TemplateDataStoreDao.java |    6 +-
 .../storage/datastore/db/TemplateDataStoreVO.java  |    6 +
 .../storage/datastore/db/VolumeDataStoreDao.java   |    7 +-
 .../storage/datastore/db/VolumeDataStoreVO.java    |    4 +-
 .../cloudstack/storage/image/ImageServiceImpl.java |  147 -----
 .../storage/image/TemplateServiceImpl.java         |  481 ++++++++++++++
 .../cloudstack/storage/test/volumeServiceTest.java |    4 +-
 .../storage/image/db/SnapshotDataStoreDaoImpl.java |   17 +-
 .../storage/image/db/TemplateDataStoreDaoImpl.java |   36 +-
 .../storage/image/db/VolumeDataStoreDaoImpl.java   |   46 +-
 .../cloudstack/storage/volume/VolumeObject.java    |    4 +
 .../storage/volume/VolumeServiceImpl.java          |  299 +++++++--
 .../kvm/resource/LibvirtComputingResource.java     |    4 +-
 .../com/cloud/ovm/hypervisor/OvmResourceBase.java  |    4 +-
 .../agent/manager/MockStorageManagerImpl.java      |   14 +-
 .../com/cloud/resource/AgentRoutingResource.java   |    4 +-
 .../hypervisor/vmware/resource/VmwareResource.java |    4 +-
 .../xen/resource/CitrixResourceBase.java           |    4 +-
 plugins/storage/image/default/pom.xml              |   10 +
 .../driver/CloudStackImageStoreDriverImpl.java     |    8 +-
 plugins/storage/image/s3/pom.xml                   |   10 +
 .../datastore/driver/S3ImageStoreDriverImpl.java   |    8 +-
 plugins/storage/image/sample/pom.xml               |   10 +
 plugins/storage/image/swift/pom.xml                |   10 +
 .../driver/SwiftImageStoreDriverImpl.java          |    8 +-
 .../src/com/cloud/storage/StorageManagerImpl.java  |    6 +-
 .../cloud/storage/download/DownloadListener.java   |  327 ++++++----
 .../cloud/storage/download/DownloadMonitor.java    |   17 +-
 .../storage/download/DownloadMonitorImpl.java      |  510 +--------------
 .../resource/DummySecondaryStorageResource.java    |   10 +-
 .../cloud/template/HypervisorTemplateAdapter.java  |    4 +-
 server/src/com/cloud/template/TemplateManager.java |    2 +-
 .../com/cloud/template/TemplateManagerImpl.java    |    8 +-
 54 files changed, 1377 insertions(+), 1202 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/api/src/com/cloud/agent/api/ModifyStoragePoolAnswer.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/ModifyStoragePoolAnswer.java b/api/src/com/cloud/agent/api/ModifyStoragePoolAnswer.java
index df77985..ed7043a 100644
--- a/api/src/com/cloud/agent/api/ModifyStoragePoolAnswer.java
+++ b/api/src/com/cloud/agent/api/ModifyStoragePoolAnswer.java
@@ -18,16 +18,16 @@ package com.cloud.agent.api;
 
 import java.util.Map;
 
-import com.cloud.storage.template.TemplateInfo;
+import com.cloud.storage.template.TemplateProp;
 
 public class ModifyStoragePoolAnswer extends Answer {
     StoragePoolInfo poolInfo;
-    Map<String, TemplateInfo> templateInfo;
+    Map<String, TemplateProp> templateInfo;
 
     protected ModifyStoragePoolAnswer() {
     }
 
-    public ModifyStoragePoolAnswer(ModifyStoragePoolCommand cmd, long capacityBytes, long availableBytes, Map<String, TemplateInfo> tInfo) {
+    public ModifyStoragePoolAnswer(ModifyStoragePoolCommand cmd, long capacityBytes, long availableBytes, Map<String, TemplateProp> tInfo) {
         super(cmd);
         this.result = true;
         this.poolInfo = new StoragePoolInfo(null,
@@ -46,11 +46,11 @@ public class ModifyStoragePoolAnswer extends Answer {
     }
 
 
-    public Map<String, TemplateInfo> getTemplateInfo() {
+    public Map<String, TemplateProp> getTemplateInfo() {
         return templateInfo;
     }
 
-    public void setTemplateInfo(Map<String, TemplateInfo> templateInfo) {
+    public void setTemplateInfo(Map<String, TemplateProp> templateInfo) {
         this.templateInfo = templateInfo;
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/api/src/com/cloud/agent/api/StartupStorageCommand.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/StartupStorageCommand.java b/api/src/com/cloud/agent/api/StartupStorageCommand.java
index 3c3b058..52ed3ff 100755
--- a/api/src/com/cloud/agent/api/StartupStorageCommand.java
+++ b/api/src/com/cloud/agent/api/StartupStorageCommand.java
@@ -22,13 +22,13 @@ import java.util.Map;
 import com.cloud.host.Host;
 import com.cloud.storage.Storage;
 import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.template.TemplateInfo;
+import com.cloud.storage.template.TemplateProp;
 
 
 public class StartupStorageCommand extends StartupCommand {
 
 	String parent;
-    Map<String, TemplateInfo> templateInfo;
+    Map<String, TemplateProp> templateInfo;
     long totalSize;
     StoragePoolInfo poolInfo;
     Storage.StorageResourceType resourceType;
@@ -40,7 +40,7 @@ public class StartupStorageCommand extends StartupCommand {
         super(Host.Type.Storage);
     }
 
-    public StartupStorageCommand(String parent, StoragePoolType fsType, long totalSize, Map<String, TemplateInfo> info) {
+    public StartupStorageCommand(String parent, StoragePoolType fsType, long totalSize, Map<String, TemplateProp> info) {
         super(Host.Type.Storage);
         this.parent = parent;
         this.totalSize = totalSize;
@@ -50,7 +50,7 @@ public class StartupStorageCommand extends StartupCommand {
     }
 
 
-    public StartupStorageCommand(String parent, StoragePoolType fsType, Map<String, TemplateInfo> templateInfo, StoragePoolInfo poolInfo) {
+    public StartupStorageCommand(String parent, StoragePoolType fsType, Map<String, TemplateProp> templateInfo, StoragePoolInfo poolInfo) {
 		super(Host.Type.Storage);
 		this.parent = parent;
 		this.templateInfo = templateInfo;
@@ -79,11 +79,11 @@ public class StartupStorageCommand extends StartupCommand {
         return totalSize;
     }
 
-	public Map<String, TemplateInfo> getTemplateInfo() {
+	public Map<String, TemplateProp> getTemplateInfo() {
 		return templateInfo;
 	}
 
-	public void setTemplateInfo(Map<String, TemplateInfo> templateInfo) {
+	public void setTemplateInfo(Map<String, TemplateProp> templateInfo) {
 		this.templateInfo = templateInfo;
 	}
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/api/src/com/cloud/agent/api/storage/ListTemplateAnswer.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/storage/ListTemplateAnswer.java b/api/src/com/cloud/agent/api/storage/ListTemplateAnswer.java
index a4e2e25..4155a63 100644
--- a/api/src/com/cloud/agent/api/storage/ListTemplateAnswer.java
+++ b/api/src/com/cloud/agent/api/storage/ListTemplateAnswer.java
@@ -19,27 +19,27 @@ package com.cloud.agent.api.storage;
 import java.util.Map;
 
 import com.cloud.agent.api.Answer;
-import com.cloud.storage.template.TemplateInfo;
+import com.cloud.storage.template.TemplateProp;
 
 public class ListTemplateAnswer extends Answer  {
     private String secUrl;
-    private Map<String, TemplateInfo> templateInfos;
+    private Map<String, TemplateProp> templateInfos;
 
 	public ListTemplateAnswer() {
 
 	}
 
-	public ListTemplateAnswer(String secUrl, Map<String, TemplateInfo> templateInfos) {
+	public ListTemplateAnswer(String secUrl, Map<String, TemplateProp> templateInfos) {
 	    super(null, true, "success");
 	    this.setSecUrl(secUrl);
 	    this.templateInfos = templateInfos;
 	}
 
-	public Map<String, TemplateInfo> getTemplateInfo() {
+	public Map<String, TemplateProp> getTemplateInfo() {
 	    return templateInfos;
 	}
 
-	public void setTemplateInfo(Map<String, TemplateInfo> templateInfos) {
+	public void setTemplateInfo(Map<String, TemplateProp> templateInfos) {
 	    this.templateInfos = templateInfos;
 	}
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/api/src/com/cloud/agent/api/storage/ListVolumeAnswer.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/storage/ListVolumeAnswer.java b/api/src/com/cloud/agent/api/storage/ListVolumeAnswer.java
index 6bbb2e8..31ea09b 100755
--- a/api/src/com/cloud/agent/api/storage/ListVolumeAnswer.java
+++ b/api/src/com/cloud/agent/api/storage/ListVolumeAnswer.java
@@ -19,27 +19,27 @@ package com.cloud.agent.api.storage;
 import java.util.Map;
 
 import com.cloud.agent.api.Answer;
-import com.cloud.storage.template.TemplateInfo;
+import com.cloud.storage.template.TemplateProp;
 
 public class ListVolumeAnswer extends Answer {
 	private String secUrl;
-    private Map<Long, TemplateInfo> templateInfos;
+    private Map<Long, TemplateProp> templateInfos;
 
 	public ListVolumeAnswer() {
 
 	}
 
-	public ListVolumeAnswer(String secUrl, Map<Long, TemplateInfo> templateInfos) {
+	public ListVolumeAnswer(String secUrl, Map<Long, TemplateProp> templateInfos) {
 	    super(null, true, "success");
 	    this.setSecUrl(secUrl);
 	    this.templateInfos = templateInfos;
 	}
 
-	public Map<Long, TemplateInfo> getTemplateInfo() {
+	public Map<Long, TemplateProp> getTemplateInfo() {
 	    return templateInfos;
 	}
 
-	public void setTemplateInfo(Map<Long, TemplateInfo> templateInfos) {
+	public void setTemplateInfo(Map<Long, TemplateProp> templateInfos) {
 	    this.templateInfos = templateInfos;
 	}
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/api/src/com/cloud/storage/template/TemplateInfo.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/template/TemplateInfo.java b/api/src/com/cloud/storage/template/TemplateInfo.java
deleted file mode 100644
index 6559d73..0000000
--- a/api/src/com/cloud/storage/template/TemplateInfo.java
+++ /dev/null
@@ -1,81 +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.template;
-
-public class TemplateInfo {
-    String templateName;
-    String installPath;
-    long size;
-    long physicalSize;
-    long id;
-    boolean isPublic;
-    boolean isCorrupted;
-
-    protected TemplateInfo() {
-
-    }
-
-    public TemplateInfo(String templateName, String installPath, long size, long physicalSize, boolean isPublic, boolean isCorrupted) {
-        this.templateName = templateName;
-        this.installPath = installPath;
-        this.size = size;
-        this.physicalSize = physicalSize;
-        this.isPublic = isPublic;
-        this.isCorrupted = isCorrupted;
-    }
-
-    public TemplateInfo(String templateName, String installPath, boolean isPublic, boolean isCorrupted) {
-        this(templateName, installPath, 0, 0, isPublic, isCorrupted);
-    }
-
-    public long getId() {
-        return id;
-    }
-
-    public String getTemplateName() {
-        return templateName;
-    }
-
-    public String getInstallPath() {
-        return installPath;
-    }
-
-    public boolean isPublic() {
-        return isPublic;
-    }
-
-    public boolean isCorrupted() {
-        return isCorrupted;
-    }
-
-    public void setInstallPath(String installPath) {
-        this.installPath = installPath;
-    }
-
-    public long getSize() {
-        return size;
-    }
-
-    public long getPhysicalSize() {
-        return physicalSize;
-    }
-
-    public void setSize(long size) {
-        this.size = size;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/api/src/com/cloud/storage/template/TemplateProp.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/template/TemplateProp.java b/api/src/com/cloud/storage/template/TemplateProp.java
new file mode 100644
index 0000000..0a2efc1
--- /dev/null
+++ b/api/src/com/cloud/storage/template/TemplateProp.java
@@ -0,0 +1,81 @@
+// 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.template;
+
+public class TemplateProp {
+    String templateName;
+    String installPath;
+    long size;
+    long physicalSize;
+    long id;
+    boolean isPublic;
+    boolean isCorrupted;
+
+    protected TemplateProp() {
+
+    }
+
+    public TemplateProp(String templateName, String installPath, long size, long physicalSize, boolean isPublic, boolean isCorrupted) {
+        this.templateName = templateName;
+        this.installPath = installPath;
+        this.size = size;
+        this.physicalSize = physicalSize;
+        this.isPublic = isPublic;
+        this.isCorrupted = isCorrupted;
+    }
+
+    public TemplateProp(String templateName, String installPath, boolean isPublic, boolean isCorrupted) {
+        this(templateName, installPath, 0, 0, isPublic, isCorrupted);
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public String getTemplateName() {
+        return templateName;
+    }
+
+    public String getInstallPath() {
+        return installPath;
+    }
+
+    public boolean isPublic() {
+        return isPublic;
+    }
+
+    public boolean isCorrupted() {
+        return isCorrupted;
+    }
+
+    public void setInstallPath(String installPath) {
+        this.installPath = installPath;
+    }
+
+    public long getSize() {
+        return size;
+    }
+
+    public long getPhysicalSize() {
+        return physicalSize;
+    }
+
+    public void setSize(long size) {
+        this.size = size;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/api/src/com/cloud/template/TemplateApiService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/template/TemplateApiService.java b/api/src/com/cloud/template/TemplateApiService.java
new file mode 100755
index 0000000..50373fe
--- /dev/null
+++ b/api/src/com/cloud/template/TemplateApiService.java
@@ -0,0 +1,100 @@
+// 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.template;
+
+import java.net.URISyntaxException;
+import java.util.List;
+
+import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd;
+import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoPermissionsCmd;
+import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
+import org.apache.cloudstack.api.command.user.iso.ExtractIsoCmd;
+import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
+import org.apache.cloudstack.api.command.user.template.CopyTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.CreateTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
+
+import com.cloud.exception.InternalErrorException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.user.Account;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public interface TemplateApiService {
+
+    VirtualMachineTemplate registerTemplate(RegisterTemplateCmd cmd) throws URISyntaxException, ResourceAllocationException;
+
+    VirtualMachineTemplate registerIso(RegisterIsoCmd cmd) throws IllegalArgumentException, ResourceAllocationException;
+
+    VirtualMachineTemplate copyTemplate(CopyTemplateCmd cmd) throws StorageUnavailableException, ResourceAllocationException;
+
+    VirtualMachineTemplate prepareTemplate(long templateId, long zoneId);
+
+    boolean detachIso(long vmId);
+
+    boolean attachIso(long isoId, long vmId);
+
+    /**
+     * Deletes a template
+     *
+     * @param cmd
+     *            - the command specifying templateId
+     */
+    boolean deleteTemplate(DeleteTemplateCmd cmd);
+
+    /**
+     * Deletes a template
+     *
+     * @param cmd
+     *            - the command specifying isoId
+     * @return true if deletion is successful, false otherwise
+     */
+    boolean deleteIso(DeleteIsoCmd cmd);
+
+    /**
+     * Extracts an ISO
+     *
+     * @param cmd
+     *            - the command specifying the mode and id of the ISO
+     * @return extractId.
+     */
+    Long extract(ExtractIsoCmd cmd) throws InternalErrorException;
+
+    /**
+     * Extracts a Template
+     *
+     * @param cmd
+     *            - the command specifying the mode and id of the template
+     * @return extractId
+     */
+    Long extract(ExtractTemplateCmd cmd) throws InternalErrorException;
+
+    VirtualMachineTemplate getTemplate(long templateId);
+
+    List<String> listTemplatePermissions(BaseListTemplateOrIsoPermissionsCmd cmd);
+
+    boolean updateTemplateOrIsoPermissions(BaseUpdateTemplateOrIsoPermissionsCmd cmd);
+    
+    VirtualMachineTemplate createPrivateTemplateRecord(CreateTemplateCmd cmd,
+            Account templateOwner) throws ResourceAllocationException;
+
+    VirtualMachineTemplate createPrivateTemplate(CreateTemplateCmd command)
+            throws CloudRuntimeException;
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/api/src/com/cloud/template/TemplateService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/template/TemplateService.java b/api/src/com/cloud/template/TemplateService.java
deleted file mode 100755
index 7e831fb..0000000
--- a/api/src/com/cloud/template/TemplateService.java
+++ /dev/null
@@ -1,100 +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.template;
-
-import java.net.URISyntaxException;
-import java.util.List;
-
-import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd;
-import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoPermissionsCmd;
-import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
-import org.apache.cloudstack.api.command.user.iso.ExtractIsoCmd;
-import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
-import org.apache.cloudstack.api.command.user.template.CopyTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.CreateTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
-
-import com.cloud.exception.InternalErrorException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.user.Account;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-public interface TemplateService {
-
-    VirtualMachineTemplate registerTemplate(RegisterTemplateCmd cmd) throws URISyntaxException, ResourceAllocationException;
-
-    VirtualMachineTemplate registerIso(RegisterIsoCmd cmd) throws IllegalArgumentException, ResourceAllocationException;
-
-    VirtualMachineTemplate copyTemplate(CopyTemplateCmd cmd) throws StorageUnavailableException, ResourceAllocationException;
-
-    VirtualMachineTemplate prepareTemplate(long templateId, long zoneId);
-
-    boolean detachIso(long vmId);
-
-    boolean attachIso(long isoId, long vmId);
-
-    /**
-     * Deletes a template
-     *
-     * @param cmd
-     *            - the command specifying templateId
-     */
-    boolean deleteTemplate(DeleteTemplateCmd cmd);
-
-    /**
-     * Deletes a template
-     *
-     * @param cmd
-     *            - the command specifying isoId
-     * @return true if deletion is successful, false otherwise
-     */
-    boolean deleteIso(DeleteIsoCmd cmd);
-
-    /**
-     * Extracts an ISO
-     *
-     * @param cmd
-     *            - the command specifying the mode and id of the ISO
-     * @return extractId.
-     */
-    Long extract(ExtractIsoCmd cmd) throws InternalErrorException;
-
-    /**
-     * Extracts a Template
-     *
-     * @param cmd
-     *            - the command specifying the mode and id of the template
-     * @return extractId
-     */
-    Long extract(ExtractTemplateCmd cmd) throws InternalErrorException;
-
-    VirtualMachineTemplate getTemplate(long templateId);
-
-    List<String> listTemplatePermissions(BaseListTemplateOrIsoPermissionsCmd cmd);
-
-    boolean updateTemplateOrIsoPermissions(BaseUpdateTemplateOrIsoPermissionsCmd cmd);
-    
-    VirtualMachineTemplate createPrivateTemplateRecord(CreateTemplateCmd cmd,
-            Account templateOwner) throws ResourceAllocationException;
-
-    VirtualMachineTemplate createPrivateTemplate(CreateTemplateCmd command)
-            throws CloudRuntimeException;
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/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 78a2af3..b845053 100644
--- a/api/src/org/apache/cloudstack/api/BaseCmd.java
+++ b/api/src/org/apache/cloudstack/api/BaseCmd.java
@@ -65,7 +65,7 @@ import com.cloud.storage.DataStoreProviderApiService;
 import com.cloud.storage.StorageService;
 import com.cloud.storage.VolumeApiService;
 import com.cloud.storage.snapshot.SnapshotService;
-import com.cloud.template.TemplateService;
+import com.cloud.template.TemplateApiService;
 import com.cloud.user.Account;
 import com.cloud.user.AccountService;
 import com.cloud.user.DomainService;
@@ -106,7 +106,7 @@ public abstract class BaseCmd {
     @Inject public VolumeApiService _volumeService;
     @Inject public ResourceService _resourceService;
     @Inject public NetworkService _networkService;
-    @Inject public TemplateService _templateService;
+    @Inject public TemplateApiService _templateService;
     @Inject public SecurityGroupService _securityGroupService;
     @Inject public SnapshotService _snapshotService;
     @Inject public ConsoleProxyService _consoleProxyService;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/client/tomcatconf/applicationContext.xml.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in
index 206afd3..7ad3bb5 100644
--- a/client/tomcatconf/applicationContext.xml.in
+++ b/client/tomcatconf/applicationContext.xml.in
@@ -744,7 +744,7 @@
   <bean id="imageDataManagerImpl" class="org.apache.cloudstack.storage.image.manager.ImageDataManagerImpl" />
   <bean id="imageStoreHelper" class="org.apache.cloudstack.storage.image.datastore.ImageStoreHelper" />
   <bean id="imageFormatHelper" class="org.apache.cloudstack.storage.image.format.ImageFormatHelper" />
-  <bean id="imageServiceImpl" class="org.apache.cloudstack.storage.image.ImageServiceImpl" />
+  <bean id="templateServiceImpl" class="org.apache.cloudstack.storage.image.TemplateServiceImpl" />
   <bean id="iso" class="org.apache.cloudstack.engine.subsystem.api.storage.type.Iso" />
   <bean id="networkFileSystem" class="org.apache.cloudstack.storage.datastore.type.NetworkFileSystem" />
   <bean id="networkRestService" class="org.apache.cloudstack.engine.rest.service.api.NetworkRestService" />

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/core/src/com/cloud/hypervisor/hyperv/resource/HypervResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/hypervisor/hyperv/resource/HypervResource.java b/core/src/com/cloud/hypervisor/hyperv/resource/HypervResource.java
index 0f9b3dd..725f0cc 100755
--- a/core/src/com/cloud/hypervisor/hyperv/resource/HypervResource.java
+++ b/core/src/com/cloud/hypervisor/hyperv/resource/HypervResource.java
@@ -105,7 +105,7 @@ import com.cloud.resource.ServerResource;
 import com.cloud.resource.ServerResourceBase;
 import com.cloud.serializer.GsonHelper;
 import com.cloud.storage.Volume;
-import com.cloud.storage.template.TemplateInfo;
+import com.cloud.storage.template.TemplateProp;
 import com.cloud.utils.Pair;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.vm.DiskProfile;
@@ -765,7 +765,7 @@ public class HypervResource extends ServerResourceBase implements ServerResource
         try {
             StorageFilerTO pool = cmd.getPool();
             s_logger.info("Primary storage pool  details: " + pool.getHost() + " " + pool.getPath());
-            Map<String, TemplateInfo> tInfo = new HashMap<String, TemplateInfo>();
+            Map<String, TemplateProp> tInfo = new HashMap<String, TemplateProp>();
             // FIXME: get the actual storage capacity and storage stats of CSV volume
             // by running powershell cmdlet. This hardcoding just for prototype.
             ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd,

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java
index 285005a..435e0f7 100755
--- a/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java
+++ b/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java
@@ -60,7 +60,7 @@ import com.cloud.storage.Storage.StoragePoolType;
 import com.cloud.storage.StorageLayer;
 import com.cloud.storage.template.DownloadManager;
 import com.cloud.storage.template.DownloadManagerImpl;
-import com.cloud.storage.template.TemplateInfo;
+import com.cloud.storage.template.TemplateProp;
 import com.cloud.storage.template.UploadManager;
 import com.cloud.storage.template.UploadManagerImpl;
 import com.cloud.utils.NumbersUtil;
@@ -650,7 +650,7 @@ public class CifsSecondaryStorageResource extends ServerResourceBase implements
             return null;
         }*/
 
-        final StartupStorageCommand cmd = new StartupStorageCommand(_parent, StoragePoolType.NetworkFilesystem, getTotalSize(), new HashMap<String, TemplateInfo>());
+        final StartupStorageCommand cmd = new StartupStorageCommand(_parent, StoragePoolType.NetworkFilesystem, getTotalSize(), new HashMap<String, TemplateProp>());
 
         cmd.setResourceType(Storage.StorageResourceType.SECONDARY_STORAGE);
         cmd.setIqn(null);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java
index c638c5d..89d0fe1 100644
--- a/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java
+++ b/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java
@@ -48,7 +48,7 @@ import com.cloud.storage.Storage.StoragePoolType;
 import com.cloud.storage.StorageLayer;
 import com.cloud.storage.template.DownloadManager;
 import com.cloud.storage.template.DownloadManagerImpl;
-import com.cloud.storage.template.TemplateInfo;
+import com.cloud.storage.template.TemplateProp;
 import com.cloud.utils.component.ComponentContext;
 
 public class LocalSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
@@ -109,7 +109,7 @@ public class LocalSecondaryStorageResource extends ServerResourceBase implements
 
     private Answer execute(ListTemplateCommand cmd) {
         String root = getRootDir();
-        Map<String, TemplateInfo> templateInfos = _dlMgr.gatherTemplateInfo(root);
+        Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
         return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos);
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/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 e65cbe1..a8788c6 100755
--- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java
+++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java
@@ -100,7 +100,7 @@ import com.cloud.storage.StorageLayer;
 import com.cloud.storage.template.DownloadManager;
 import com.cloud.storage.template.DownloadManagerImpl;
 import com.cloud.storage.template.DownloadManagerImpl.ZfsPathParser;
-import com.cloud.storage.template.TemplateInfo;
+import com.cloud.storage.template.TemplateProp;
 import com.cloud.storage.template.TemplateLocation;
 import com.cloud.storage.template.UploadManager;
 import com.cloud.storage.template.UploadManagerImpl;
@@ -1073,12 +1073,12 @@ SecondaryStorageResource {
         }
     }
 
-    Map<String, TemplateInfo> swiftListTemplate(SwiftTO swift) {
+    Map<String, TemplateProp> swiftListTemplate(SwiftTO swift) {
         String[] containers = swiftList(swift, "", "");
         if (containers == null) {
             return null;
         }
-        Map<String, TemplateInfo> tmpltInfos = new HashMap<String, TemplateInfo>();
+        Map<String, TemplateProp> tmpltInfos = new HashMap<String, TemplateProp>();
         for( String container : containers) {
             if ( container.startsWith("T-")) {
                 String ldir = _tmpltDir + "/" + UUID.randomUUID().toString();
@@ -1095,7 +1095,7 @@ SecondaryStorageResource {
                     s_logger.warn("Unable to load template location " + ldir + " due to " + e.toString(), e);
                     continue;
                 }
-                TemplateInfo tInfo = loc.getTemplateInfo();
+                TemplateProp tInfo = loc.getTemplateInfo();
                 tInfo.setInstallPath(container);
                 tmpltInfos.put(tInfo.getTemplateName(), tInfo);
                 loc.purge();
@@ -1111,11 +1111,11 @@ SecondaryStorageResource {
             return new Answer(cmd, true, null);
         }
         if (cmd.getSwift() != null) {
-            Map<String, TemplateInfo> templateInfos = swiftListTemplate(cmd.getSwift());
+            Map<String, TemplateProp> templateInfos = swiftListTemplate(cmd.getSwift());
             return new ListTemplateAnswer(cmd.getSwift().toString(), templateInfos);
         } else {
             String root = getRootDir(cmd.getSecUrl());
-            Map<String, TemplateInfo> templateInfos = _dlMgr.gatherTemplateInfo(root);
+            Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
             return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos);
         }
     }
@@ -1126,7 +1126,7 @@ SecondaryStorageResource {
         }
 
         String root = getRootDir(cmd.getSecUrl());
-        Map<Long, TemplateInfo> templateInfos = _dlMgr.gatherVolumeInfo(root);
+        Map<Long, TemplateProp> templateInfos = _dlMgr.gatherVolumeInfo(root);
         return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos);
 
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/core/src/com/cloud/storage/template/DownloadManager.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/template/DownloadManager.java b/core/src/com/cloud/storage/template/DownloadManager.java
index f4f8a0f..82f4153 100644
--- a/core/src/com/cloud/storage/template/DownloadManager.java
+++ b/core/src/com/cloud/storage/template/DownloadManager.java
@@ -91,13 +91,13 @@ public interface DownloadManager extends Manager {
 	/**
 	 * @return list of template info for installed templates
 	 */
-	public Map<String, TemplateInfo> gatherTemplateInfo(String templateDir);
+	public Map<String, TemplateProp> gatherTemplateInfo(String templateDir);
 	
 	/**
 	/**
 	 * @return list of volume info for installed volumes
 	 */
-	public Map<Long, TemplateInfo> gatherVolumeInfo(String volumeDir);
+	public Map<Long, TemplateProp> gatherVolumeInfo(String volumeDir);
 
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/core/src/com/cloud/storage/template/DownloadManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/template/DownloadManagerImpl.java b/core/src/com/cloud/storage/template/DownloadManagerImpl.java
index 22e78a0..db264c1 100755
--- a/core/src/com/cloud/storage/template/DownloadManagerImpl.java
+++ b/core/src/com/cloud/storage/template/DownloadManagerImpl.java
@@ -717,8 +717,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
     }
 
     @Override
-    public Map<String, TemplateInfo> gatherTemplateInfo(String rootDir) {
-        Map<String, TemplateInfo> result = new HashMap<String, TemplateInfo>();
+    public Map<String, TemplateProp> gatherTemplateInfo(String rootDir) {
+        Map<String, TemplateProp> result = new HashMap<String, TemplateProp>();
         String templateDir = rootDir + File.separator + _templateDir;
 
         if (! _storage.exists(templateDir)) {
@@ -741,7 +741,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
                 continue;
             }
 
-            TemplateInfo tInfo = loc.getTemplateInfo();
+            TemplateProp tInfo = loc.getTemplateInfo();
 
             if ((tInfo.size == tInfo.physicalSize) && (tInfo.installPath.endsWith(ImageFormat.OVA.getFileExtension()))) {
                 try {
@@ -774,8 +774,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
     }
 
     @Override
-    public Map<Long, TemplateInfo> gatherVolumeInfo(String rootDir) {	
-        Map<Long, TemplateInfo> result = new HashMap<Long, TemplateInfo>();
+    public Map<Long, TemplateProp> gatherVolumeInfo(String rootDir) {	
+        Map<Long, TemplateProp> result = new HashMap<Long, TemplateProp>();
         String volumeDir = rootDir + File.separator + _volumeDir;
 
         if (! _storage.exists(volumeDir)) {
@@ -798,7 +798,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
                 continue;
             }
 
-            TemplateInfo vInfo = loc.getTemplateInfo();
+            TemplateProp vInfo = loc.getTemplateInfo();
 
             if ((vInfo.size == vInfo.physicalSize) && (vInfo.installPath.endsWith(ImageFormat.OVA.getFileExtension()))) {
                 try {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/core/src/com/cloud/storage/template/TemplateLocation.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/template/TemplateLocation.java b/core/src/com/cloud/storage/template/TemplateLocation.java
index 58d023a..515b1f2 100644
--- a/core/src/com/cloud/storage/template/TemplateLocation.java
+++ b/core/src/com/cloud/storage/template/TemplateLocation.java
@@ -156,8 +156,8 @@ public class TemplateLocation {
         return true;
     }
     
-    public TemplateInfo getTemplateInfo() {
-        TemplateInfo tmplInfo = new TemplateInfo();       
+    public TemplateProp getTemplateInfo() {
+        TemplateProp tmplInfo = new TemplateProp();       
         tmplInfo.id = Long.parseLong(_props.getProperty("id"));
         tmplInfo.installPath = _templatePath + File.separator + _props.getProperty("filename");
         if (_resourceType == ResourceType.VOLUME){

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageService.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageService.java
deleted file mode 100644
index 119f3b1..0000000
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageService.java
+++ /dev/null
@@ -1,29 +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;
-
-import org.apache.cloudstack.framework.async.AsyncCallFuture;
-
-public interface ImageService {
-    AsyncCallFuture<CommandResult> createTemplateAsync(TemplateInfo template, DataStore store);
-    AsyncCallFuture<CommandResult> createTemplateFromSnapshotAsync(SnapshotInfo snapshot, TemplateInfo template, DataStore store);
-    AsyncCallFuture<CommandResult> createTemplateFromVolumeAsync(VolumeInfo volume, TemplateInfo template, DataStore store);
-    AsyncCallFuture<CommandResult> deleteTemplateAsync(TemplateInfo template);
-    
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java
new file mode 100644
index 0000000..6bb58e0
--- /dev/null
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java
@@ -0,0 +1,35 @@
+/*
+ * 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;
+
+import org.apache.cloudstack.framework.async.AsyncCallFuture;
+
+
+
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+
+public interface TemplateService {
+    AsyncCallFuture<CommandResult> createTemplateAsync(TemplateInfo template, DataStore store);
+    AsyncCallFuture<CommandResult> createTemplateFromSnapshotAsync(SnapshotInfo snapshot, TemplateInfo template, DataStore store);
+    AsyncCallFuture<CommandResult> createTemplateFromVolumeAsync(VolumeInfo volume, TemplateInfo template, DataStore store);
+    AsyncCallFuture<CommandResult> deleteTemplateAsync(TemplateInfo template);
+
+    void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId);
+    void handleTemplateSync(DataStore store);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java
index 102c471..7175524 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java
@@ -25,13 +25,13 @@ import com.cloud.exception.ConcurrentOperationException;
 
 
 public interface VolumeService {
-    
+
     public class VolumeApiResult extends CommandResult {
         private final VolumeInfo volume;
         public VolumeApiResult(VolumeInfo volume) {
             this.volume = volume;
         }
-        
+
         public VolumeInfo getVolume() {
             return this.volume;
         }
@@ -39,16 +39,16 @@ public interface VolumeService {
 
     /**
      * Creates the volume based on the given criteria
-     * 
+     *
      * @param cmd
-     * 
+     *
      * @return the volume object
      */
     AsyncCallFuture<VolumeApiResult> createVolumeAsync(VolumeInfo volume, DataStore store);
 
     /**
      * Delete volume
-     * 
+     *
      * @param volumeId
      * @return
      * @throws ConcurrentOperationException
@@ -56,12 +56,12 @@ public interface VolumeService {
     AsyncCallFuture<VolumeApiResult> expungeVolumeAsync(VolumeInfo volume);
 
     /**
-     * 
+     *
      */
     boolean cloneVolume(long volumeId, long baseVolId);
 
     /**
-     * 
+     *
      */
     AsyncCallFuture<VolumeApiResult> createVolumeFromSnapshot(VolumeInfo volume, DataStore store,  SnapshotInfo snapshot);
 
@@ -74,7 +74,9 @@ public interface VolumeService {
     boolean destroyVolume(long volumeId) throws ConcurrentOperationException;
 
     AsyncCallFuture<VolumeApiResult> registerVolume(VolumeInfo volume, DataStore store);
-    
+
     AsyncCallFuture<VolumeApiResult> resize(VolumeInfo volume);
 
+    void handleVolumeSync(DataStore store);
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
index 91ffdaa..271ff41 100644
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
@@ -30,7 +30,5 @@ public interface SnapshotDataStoreDao extends GenericDao<SnapshotDataStoreVO, Lo
 
     public List<SnapshotDataStoreVO> listByStoreId(long id);
 
-    public List<SnapshotDataStoreVO> listLiveByStoreId(long id);
-
     public void deletePrimaryRecordsForStore(long id);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java
index 29c7859..f1fcdcc 100644
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java
@@ -23,18 +23,20 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
 
 
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 import com.cloud.utils.db.GenericDao;
 import com.cloud.utils.fsm.StateDao;
 
 public interface TemplateDataStoreDao extends GenericDao<TemplateDataStoreVO, Long>, StateDao<ObjectInDataStoreStateMachine.State, ObjectInDataStoreStateMachine.Event, DataObjectInStore>  {
 
-    public List<TemplateDataStoreVO> listByStoreId(long id);
 
-    public List<TemplateDataStoreVO> listLiveByStoreId(long id);
+    public List<TemplateDataStoreVO> listByStoreId(long id);
 
     public void deletePrimaryRecordsForStore(long id);
 
     List<TemplateDataStoreVO> listByTemplateStoreStatus(long templateId, long storeId, State... states);
 
+    List<TemplateDataStoreVO> listByTemplateStoreDownloadStatus(long templateId, long storeId, Status... status);
+
     TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
index 312fd11..d7c8443 100755
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
@@ -291,6 +291,12 @@ public class TemplateDataStoreVO implements StateObject<ObjectInDataStoreStateMa
         return this.state;
     }
 
+
+    public void setState(ObjectInDataStoreStateMachine.State state) {
+        this.state = state;
+    }
+
+
     public long getUpdatedCount() {
         return this.updatedCount;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreDao.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreDao.java
index 58ffde1..fb5bcc5 100644
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreDao.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreDao.java
@@ -22,6 +22,7 @@ import java.util.List;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
 
+
 import com.cloud.utils.db.GenericDao;
 import com.cloud.utils.fsm.StateDao;
 
@@ -29,7 +30,9 @@ public interface VolumeDataStoreDao extends GenericDao<VolumeDataStoreVO, Long>,
 
     public List<VolumeDataStoreVO> listByStoreId(long id);
 
-    public List<VolumeDataStoreVO> listLiveByStoreId(long id);
-
     public void deletePrimaryRecordsForStore(long id);
+
+    public VolumeDataStoreVO findByVolumeId(long volumeId);
+
+    public VolumeDataStoreVO findByStoreVolume(long storeId, long volumeId);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java
index 185b12b..a7134ea 100755
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java
@@ -203,14 +203,14 @@ public class VolumeDataStoreVO implements StateObject<ObjectInDataStoreStateMach
 		this.state = ObjectInDataStoreStateMachine.State.Allocated;
 	}
 
-	public VolumeDataStoreVO(long hostId, long volumeId, long zoneId, Date lastUpdated,
+	public VolumeDataStoreVO(long hostId, long volumeId, Date lastUpdated,
 			int downloadPercent, Status downloadState,
 			String localDownloadPath, String errorString, String jobId,
 			String installPath, String downloadUrl, String checksum, ImageFormat format) {
 		//super();
 		this.dataStoreId = hostId;
 		this.volumeId = volumeId;
-		this.zoneId = zoneId;
+		//this.zoneId = zoneId;
 		this.lastUpdated = lastUpdated;
 		this.downloadPercent = downloadPercent;
 		this.downloadState = downloadState;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageServiceImpl.java
deleted file mode 100644
index f393fc4..0000000
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageServiceImpl.java
+++ /dev/null
@@ -1,147 +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.image;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult;
-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.ImageService;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-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.DataObjectManager;
-import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
-import org.apache.cloudstack.storage.image.store.TemplateObject;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.utils.fsm.NoTransitionException;
-
-@Component
-public class ImageServiceImpl implements ImageService {
-    private static final Logger s_logger = Logger.getLogger(ImageServiceImpl.class);
-    @Inject
-    ObjectInDataStoreManager objectInDataStoreMgr;
-    @Inject
-    DataObjectManager dataObjectMgr;
-
-    class CreateTemplateContext<T> extends AsyncRpcConext<T> {
-        final TemplateInfo srcTemplate;
-        final DataStore store;
-        final AsyncCallFuture<CommandResult> future;
-        final DataObject templateOnStore;
-
-        public CreateTemplateContext(AsyncCompletionCallback<T> callback, TemplateInfo srcTemplate,
-                AsyncCallFuture<CommandResult> future,
-                DataStore store,
-                DataObject templateOnStore
-             ) {
-            super(callback);
-            this.srcTemplate = srcTemplate;
-            this.future = future;
-            this.store = store;
-            this.templateOnStore = templateOnStore;
-        }
-    }
-
-    @Override
-    public AsyncCallFuture<CommandResult> createTemplateAsync(
-            TemplateInfo template, DataStore store) {
-        TemplateObject to = (TemplateObject) template;
-        AsyncCallFuture<CommandResult> future = new AsyncCallFuture<CommandResult>();
-        // persist template_store_ref entry
-        DataObject templateOnStore = store.create(template);
-        // update template_store_ref state
-        templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested);
-
-        CreateTemplateContext<CommandResult> context = new CreateTemplateContext<CommandResult>(null,
-                template,
-                future,
-                store,
-                templateOnStore
-               );
-        AsyncCallbackDispatcher<ImageServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
-        caller.setCallback(caller.getTarget().createTemplateCallback(null, null)).setContext(context);
-        store.getDriver().createAsync(templateOnStore, caller);
-        return future;
-    }
-
-    protected Void createTemplateCallback(AsyncCallbackDispatcher<ImageServiceImpl, CreateCmdResult> callback,
-            CreateTemplateContext<CreateCmdResult> context) {
-        TemplateObject template = (TemplateObject)context.srcTemplate;
-        AsyncCallFuture<CommandResult> future = context.future;
-        CommandResult result = new CommandResult();
-        DataObject templateOnStore = context.templateOnStore;
-        CreateCmdResult callbackResult = callback.getResult();
-        if (callbackResult.isFailed()) {
-            try {
-                templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
-                template.stateTransit(TemplateEvent.OperationFailed);
-            } catch (NoTransitionException e) {
-               s_logger.debug("Failed to update template state", e);
-            }
-            result.setResult(callbackResult.getResult());
-            future.complete(result);
-            return null;
-        }
-
-        try {
-            templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed);
-            template.stateTransit(TemplateEvent.OperationSucceeded);
-        } catch (NoTransitionException e) {
-            s_logger.debug("Failed to transit state", e);
-            result.setResult(e.toString());
-            future.complete(result);
-            return null;
-        }
-
-        future.complete(result);
-        return null;
-    }
-
-    @Override
-    public AsyncCallFuture<CommandResult> deleteTemplateAsync(
-            TemplateInfo template) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public AsyncCallFuture<CommandResult> createTemplateFromSnapshotAsync(
-            SnapshotInfo snapshot, TemplateInfo template, DataStore store) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public AsyncCallFuture<CommandResult> createTemplateFromVolumeAsync(
-            VolumeInfo volume, TemplateInfo template, DataStore store) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
new file mode 100644
index 0000000..3dcb86b
--- /dev/null
+++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
@@ -0,0 +1,481 @@
+/*
+ * 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.image;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult;
+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.TemplateService;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
+import com.cloud.storage.template.TemplateProp;
+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.DataObjectManager;
+import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
+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.image.store.TemplateObject;
+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.storage.DeleteTemplateCommand;
+import com.cloud.agent.api.storage.ListTemplateAnswer;
+import com.cloud.agent.api.storage.ListTemplateCommand;
+import com.cloud.alert.AlertManager;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.host.HostVO;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.VMTemplateZoneVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+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.user.AccountManager;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.utils.UriUtils;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.dao.UserVmDao;
+
+@Component
+public class TemplateServiceImpl implements TemplateService {
+    private static final Logger s_logger = Logger.getLogger(TemplateServiceImpl.class);
+    @Inject
+    ObjectInDataStoreManager _objectInDataStoreMgr;
+    @Inject
+    DataObjectManager _dataObjectMgr;
+    @Inject
+    DataStoreManager _storeMgr;
+    @Inject
+    ResourceLimitService _resourceLimitMgr;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    AlertManager _alertMgr;
+    @Inject
+    VMTemplateDao _templateDao;
+    @Inject
+    TemplateDataStoreDao _vmTemplateStoreDao;
+    @Inject
+    VolumeDataStoreDao _volumeStoreDao;
+    @Inject
+    DownloadMonitor _dlMonitor;
+    @Inject
+    AgentManager _agentMgr;
+    @Inject
+    SecondaryStorageVmManager _ssvmMgr;
+    @Inject
+    DataCenterDao _dcDao = null;
+    @Inject
+    VMTemplateZoneDao _vmTemplateZoneDao;
+    @Inject
+    ClusterDao _clusterDao;
+    @Inject
+    UserVmDao _userVmDao;
+    @Inject
+    VolumeDao _volumeDao;
+
+
+    class CreateTemplateContext<T> extends AsyncRpcConext<T> {
+        final TemplateInfo srcTemplate;
+        final DataStore store;
+        final AsyncCallFuture<CommandResult> future;
+        final DataObject templateOnStore;
+
+        public CreateTemplateContext(AsyncCompletionCallback<T> callback, TemplateInfo srcTemplate,
+                AsyncCallFuture<CommandResult> future,
+                DataStore store,
+                DataObject templateOnStore
+             ) {
+            super(callback);
+            this.srcTemplate = srcTemplate;
+            this.future = future;
+            this.store = store;
+            this.templateOnStore = templateOnStore;
+        }
+    }
+
+    @Override
+    public AsyncCallFuture<CommandResult> createTemplateAsync(
+            TemplateInfo template, DataStore store) {
+        TemplateObject to = (TemplateObject) template;
+        AsyncCallFuture<CommandResult> future = new AsyncCallFuture<CommandResult>();
+        // persist template_store_ref entry
+        DataObject templateOnStore = store.create(template);
+        // update template_store_ref state
+        templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested);
+
+        CreateTemplateContext<CommandResult> context = new CreateTemplateContext<CommandResult>(null,
+                template,
+                future,
+                store,
+                templateOnStore
+               );
+        AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
+        caller.setCallback(caller.getTarget().createTemplateCallback(null, null)).setContext(context);
+        store.getDriver().createAsync(templateOnStore, caller);
+        return future;
+    }
+
+
+    @Override
+    public void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId) {
+        Set<VMTemplateVO> toBeDownloaded = new HashSet<VMTemplateVO>();
+        List<DataStore> ssHosts = this._storeMgr.getImageStoresByScope(new ZoneScope(dcId));
+        if (ssHosts == null || ssHosts.isEmpty()){
+            return;
+        }
+
+        /*Download all the templates in zone with the same hypervisortype*/
+        for ( DataStore ssHost : ssHosts) {
+            List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
+            List<VMTemplateVO> defaultBuiltin = _templateDao.listDefaultBuiltinTemplates();
+
+
+            for (VMTemplateVO rtngTmplt : rtngTmplts) {
+                if (rtngTmplt.getHypervisorType() == hostHyper) {
+                    toBeDownloaded.add(rtngTmplt);
+                }
+            }
+
+            for (VMTemplateVO builtinTmplt : defaultBuiltin) {
+                if (builtinTmplt.getHypervisorType() == hostHyper) {
+                    toBeDownloaded.add(builtinTmplt);
+                }
+            }
+
+            for (VMTemplateVO template: toBeDownloaded) {
+                TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(ssHost.getId(), template.getId());
+                if (tmpltHost == null || tmpltHost.getState() != ObjectInDataStoreStateMachine.State.Ready) {
+                    _dlMonitor.downloadTemplateToStorage(template, ssHost, null);
+                }
+            }
+        }
+    }
+
+
+
+
+
+    @Override
+    public void handleTemplateSync(DataStore store) {
+        if (store == null) {
+            s_logger.warn("Huh? image store is null");
+            return;
+        }
+        long storeId = store.getId();
+        Long zoneId = store.getScope().getScopeId();
+
+        Map<String, TemplateProp> templateInfos = listTemplate(store);
+        if (templateInfos == null) {
+            return;
+        }
+
+        Set<VMTemplateVO> toBeDownloaded = new HashSet<VMTemplateVO>();
+        List<VMTemplateVO> allTemplates = null;
+        if (zoneId == null){
+            // region wide store
+            allTemplates = _templateDao.listAll();
+        }
+        else{
+            // zone wide store
+            allTemplates = _templateDao.listAllInZone(zoneId);
+        }
+        List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
+        List<VMTemplateVO> defaultBuiltin = _templateDao.listDefaultBuiltinTemplates();
+
+        if (rtngTmplts != null) {
+            for (VMTemplateVO rtngTmplt : rtngTmplts) {
+                if (!allTemplates.contains(rtngTmplt)) {
+                    allTemplates.add(rtngTmplt);
+                }
+            }
+        }
+
+        if (defaultBuiltin != null) {
+            for (VMTemplateVO builtinTmplt : defaultBuiltin) {
+                if (!allTemplates.contains(builtinTmplt)) {
+                    allTemplates.add(builtinTmplt);
+                }
+            }
+        }
+
+        toBeDownloaded.addAll(allTemplates);
+
+        for (VMTemplateVO tmplt : allTemplates) {
+            String uniqueName = tmplt.getUniqueName();
+            TemplateDataStoreVO tmpltStore = _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId());
+            if (templateInfos.containsKey(uniqueName)) {
+                TemplateProp tmpltInfo = templateInfos.remove(uniqueName);
+                toBeDownloaded.remove(tmplt);
+                if (tmpltStore != null) {
+                    s_logger.info("Template Sync found " + uniqueName + " already in the template host table");
+                    if (tmpltStore.getDownloadState() != Status.DOWNLOADED) {
+                        tmpltStore.setErrorString("");
+                    }
+                    if (tmpltInfo.isCorrupted()) {
+                        tmpltStore.setDownloadState(Status.DOWNLOAD_ERROR);
+                        String msg = "Template " + tmplt.getName() + ":" + tmplt.getId() + " is corrupted on secondary storage " + tmpltStore.getId();
+                        tmpltStore.setErrorString(msg);
+                        s_logger.info("msg");
+                        if (tmplt.getUrl() == null) {
+                            msg = "Private Template (" + tmplt + ") with install path " + tmpltInfo.getInstallPath() + "is corrupted, please check in image store: " + tmpltStore.getDataStoreId();
+                            s_logger.warn(msg);
+                        } else {
+                            toBeDownloaded.add(tmplt);
+                        }
+
+                    } else {
+                        tmpltStore.setDownloadPercent(100);
+                        tmpltStore.setDownloadState(Status.DOWNLOADED);
+                        tmpltStore.setInstallPath(tmpltInfo.getInstallPath());
+                        tmpltStore.setSize(tmpltInfo.getSize());
+                        tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize());
+                        tmpltStore.setLastUpdated(new Date());
+
+                        if (tmpltInfo.getSize() > 0) {
+                            long accountId = tmplt.getAccountId();
+                            try {
+                                _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(accountId),
+                                        com.cloud.configuration.Resource.ResourceType.secondary_storage,
+                                        tmpltInfo.getSize() - UriUtils.getRemoteSize(tmplt.getUrl()));
+                            } catch (ResourceAllocationException e) {
+                                s_logger.warn(e.getMessage());
+                                _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, zoneId,
+                                        null, e.getMessage(), e.getMessage());
+                            } finally {
+                                _resourceLimitMgr.recalculateResourceCount(accountId, _accountMgr.getAccount(accountId).getDomainId(),
+                                        com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
+                            }
+                        }
+                    }
+                    _vmTemplateStoreDao.update(tmpltStore.getId(), tmpltStore);
+                } else {
+                    tmpltStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, tmpltInfo.getInstallPath(), tmplt.getUrl());
+                    tmpltStore.setSize(tmpltInfo.getSize());
+                    tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize());
+                    _vmTemplateStoreDao.persist(tmpltStore);
+                    this.associateTemplateToZone(tmplt.getId(), zoneId);
+                }
+
+                continue;
+            }
+            if (tmpltStore != null && tmpltStore.getDownloadState() != Status.DOWNLOADED) {
+                s_logger.info("Template Sync did not find " + uniqueName + " ready on server " + storeId + ", will request download to start/resume shortly");
+
+            } else if (tmpltStore == null) {
+                s_logger.info("Template Sync did not find " + uniqueName + " on the server " + storeId + ", will request download shortly");
+                TemplateDataStoreVO templtStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 0, Status.NOT_DOWNLOADED, null, null, null, null, tmplt.getUrl());
+                _vmTemplateStoreDao.persist(templtStore);
+                this.associateTemplateToZone(tmplt.getId(), zoneId);
+            }
+
+        }
+
+        if (toBeDownloaded.size() > 0) {
+            /* Only download templates whose hypervirsor type is in the zone */
+            List<HypervisorType> availHypers = _clusterDao.getAvailableHypervisorInZone(zoneId);
+            if (availHypers.isEmpty()) {
+                /*
+                 * This is for cloudzone, local secondary storage resource
+                 * started before cluster created
+                 */
+                availHypers.add(HypervisorType.KVM);
+            }
+            /* Baremetal need not to download any template */
+            availHypers.remove(HypervisorType.BareMetal);
+            availHypers.add(HypervisorType.None); // bug 9809: resume ISO
+                                                  // download.
+            for (VMTemplateVO tmplt : toBeDownloaded) {
+                if (tmplt.getUrl() == null) { // If url is null we can't
+                                              // initiate the download
+                    continue;
+                }
+                // check if there is a record for this template in this store
+                TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId());
+
+                // if this is private template, and there is no record for this
+                // template in this store, skip
+                if (!tmplt.isPublicTemplate() && !tmplt.isFeatured()) {
+                    if (tmpltHost == null) {
+                        continue;
+                    }
+                }
+                if (availHypers.contains(tmplt.getHypervisorType())) {
+                     if (tmpltHost != null ) {
+                        continue;
+                    }
+                    s_logger.debug("Template " + tmplt.getName() + " needs to be downloaded to " + store.getName());
+                    //TODO: we should pass a callback here
+                    _dlMonitor.downloadTemplateToStorage(tmplt, store, null);
+                }
+            }
+        }
+
+        for (String uniqueName : templateInfos.keySet()) {
+            TemplateProp tInfo = templateInfos.get(uniqueName);
+            List<UserVmVO> userVmUsingIso = _userVmDao.listByIsoId(tInfo.getId());
+            //check if there is any Vm using this ISO.
+            if (userVmUsingIso == null || userVmUsingIso.isEmpty()) {
+                DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(store.getUri(), tInfo.getInstallPath());
+                try {
+                    HostVO ssAhost = _ssvmMgr.pickSsvmHost(store);
+                    _agentMgr.sendToSecStorage(ssAhost, dtCommand, null);
+                } catch (AgentUnavailableException e) {
+                    String err = "Failed to delete " + tInfo.getTemplateName() + " on secondary storage " + storeId + " which isn't in the database";
+                    s_logger.error(err);
+                    return;
+                }
+
+                String description = "Deleted template " + tInfo.getTemplateName() + " on secondary storage " + storeId + " since it isn't in the database";
+                s_logger.info(description);
+            }
+        }
+
+    }
+
+
+    // persist entry in template_zone_ref table. zoneId can be empty for region-wide image store, in that case,
+    // we will associate the template to all the zones.
+    private void associateTemplateToZone(long templateId, Long zoneId){
+        List<Long> dcs = new ArrayList<Long>();
+        if (zoneId != null ){
+            dcs.add(zoneId);
+        }
+        else{
+            List<DataCenterVO> zones = _dcDao.listAll();
+            for (DataCenterVO zone : zones){
+                dcs.add(zone.getId());
+            }
+        }
+        for (Long id : dcs) {
+            VMTemplateZoneVO tmpltZoneVO = _vmTemplateZoneDao.findByZoneTemplate(id, templateId);
+            if (tmpltZoneVO == null) {
+                tmpltZoneVO = new VMTemplateZoneVO(id, templateId, new Date());
+                _vmTemplateZoneDao.persist(tmpltZoneVO);
+            } else {
+                tmpltZoneVO.setLastUpdated(new Date());
+                _vmTemplateZoneDao.update(tmpltZoneVO.getId(), tmpltZoneVO);
+            }
+        }
+    }
+
+
+    private Map<String, TemplateProp> listTemplate(DataStore ssHost) {
+        ListTemplateCommand cmd = new ListTemplateCommand(ssHost.getUri());
+        HostVO ssAhost = _ssvmMgr.pickSsvmHost(ssHost);
+        Answer answer = _agentMgr.sendToSecStorage(ssAhost, cmd);
+        if (answer != null && answer.getResult()) {
+            ListTemplateAnswer tanswer = (ListTemplateAnswer)answer;
+            return tanswer.getTemplateInfo();
+        } else {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("can not list template for secondary storage host " + ssHost.getId());
+            }
+        }
+
+        return null;
+    }
+
+
+    protected Void createTemplateCallback(AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> callback,
+            CreateTemplateContext<CreateCmdResult> context) {
+        TemplateObject template = (TemplateObject)context.srcTemplate;
+        AsyncCallFuture<CommandResult> future = context.future;
+        CommandResult result = new CommandResult();
+        DataObject templateOnStore = context.templateOnStore;
+        CreateCmdResult callbackResult = callback.getResult();
+        if (callbackResult.isFailed()) {
+            try {
+                templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
+                template.stateTransit(TemplateEvent.OperationFailed);
+            } catch (NoTransitionException e) {
+               s_logger.debug("Failed to update template state", e);
+            }
+            result.setResult(callbackResult.getResult());
+            future.complete(result);
+            return null;
+        }
+
+        try {
+            templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed);
+            template.stateTransit(TemplateEvent.OperationSucceeded);
+        } catch (NoTransitionException e) {
+            s_logger.debug("Failed to transit state", e);
+            result.setResult(e.toString());
+            future.complete(result);
+            return null;
+        }
+
+        future.complete(result);
+        return null;
+    }
+
+    @Override
+    public AsyncCallFuture<CommandResult> deleteTemplateAsync(
+            TemplateInfo template) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public AsyncCallFuture<CommandResult> createTemplateFromSnapshotAsync(
+            SnapshotInfo snapshot, TemplateInfo template, DataStore store) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public AsyncCallFuture<CommandResult> createTemplateFromVolumeAsync(
+            VolumeInfo volume, TemplateInfo template, DataStore store) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java
index 293d7fb..fcb8962 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java
@@ -39,7 +39,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManag
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole;
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.ImageService;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
 import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
@@ -86,7 +86,7 @@ public class volumeServiceTest extends CloudStackTestNGBase {
 	//@Inject
 	//ImageDataStoreProviderManager imageProviderMgr;
 	@Inject
-	ImageService imageService;
+	TemplateService imageService;
 	@Inject
 	VolumeService volumeService;
 	@Inject

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb646727/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java
index 6a6e04a..c9ade1a 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java
@@ -42,21 +42,16 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
     private static final Logger s_logger = Logger.getLogger(SnapshotDataStoreDaoImpl.class);
     private SearchBuilder<SnapshotDataStoreVO> updateStateSearch;
     private SearchBuilder<SnapshotDataStoreVO> storeSearch;
-    private SearchBuilder<SnapshotDataStoreVO> liveStoreSearch;
 
     @Override
     public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
     	super.configure(name, params);
 
-    	storeSearch = createSearchBuilder();
+        storeSearch = createSearchBuilder();
         storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
+        storeSearch.and("destroyed", storeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
         storeSearch.done();
 
-        liveStoreSearch = createSearchBuilder();
-        liveStoreSearch.and("store_id", liveStoreSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
-        liveStoreSearch.and("destroyed", liveStoreSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
-        liveStoreSearch.done();
-
         updateStateSearch = this.createSearchBuilder();
         updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ);
         updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ);
@@ -102,17 +97,11 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
         return rows > 0;
     }
 
+
     @Override
     public List<SnapshotDataStoreVO> listByStoreId(long id) {
         SearchCriteria<SnapshotDataStoreVO> sc = storeSearch.create();
         sc.setParameters("store_id", id);
-        return listIncludingRemovedBy(sc);
-    }
-
-    @Override
-    public List<SnapshotDataStoreVO> listLiveByStoreId(long id) {
-        SearchCriteria<SnapshotDataStoreVO> sc = liveStoreSearch.create();
-        sc.setParameters("store_id", id);
         sc.setParameters("destroyed", false);
         return listIncludingRemovedBy(sc);
     }