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

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

First draft of register template using image store.

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

Branch: refs/heads/object_store
Commit: 02686583cfada2c5705ac6f37c2ddf4c474df7e5
Parents: 3897590
Author: Min Chen <mi...@citrix.com>
Authored: Wed Apr 10 18:02:53 2013 -0700
Committer: Min Chen <mi...@citrix.com>
Committed: Wed Apr 10 18:02:53 2013 -0700

----------------------------------------------------------------------
 .../command/user/template/RegisterTemplateCmd.java |   11 +-
 .../engine/subsystem/api/storage/DataStore.java    |    1 +
 .../subsystem/api/storage/DataStoreManager.java    |    2 +-
 .../storage/datastore/db/ImageStoreDao.java        |    6 +-
 .../storage/datastore/db/SnapshotDataStoreDao.java |    3 +-
 .../storage/datastore/db/SnapshotDataStoreVO.java  |    6 +-
 .../storage/datastore/db/TemplateDataStoreDao.java |    9 +-
 .../storage/datastore/db/TemplateDataStoreVO.java  |    8 +-
 .../storage/datastore/db/VolumeDataStoreDao.java   |    3 +-
 .../storage/datastore/db/VolumeDataStoreVO.java    |    6 +-
 .../storage/image/ImageDataFactoryImpl.java        |    8 +-
 .../cloudstack/storage/image/ImageServiceImpl.java |   33 +-
 .../manager/ImageStoreProviderManagerImpl.java     |    5 +-
 .../storage/image/store/ImageStoreImpl.java        |    2 +-
 .../storage/snapshot/SnapshotDataFactoryImpl.java  |    4 +-
 .../storage/datastore/DataStoreManagerImpl.java    |    5 +-
 .../datastore/ObjectInDataStoreManager.java        |    4 +-
 .../datastore/ObjectInDataStoreManagerImpl.java    |  137 +++--
 .../image/datastore/ImageStoreProviderManager.java |    3 +-
 .../storage/image/db/ImageStoreDaoImpl.java        |   14 +-
 .../storage/image/db/SnapshotDataStoreDaoImpl.java |    4 +-
 .../storage/image/db/TemplateDataStoreDaoImpl.java |   43 ++-
 .../storage/image/db/VolumeDataStoreDaoImpl.java   |    3 +-
 .../cloudstack/storage/volume/VolumeObject.java    |   16 +-
 .../driver/CloudStackImageStoreDriverImpl.java     |   28 +-
 .../datastore/driver/S3ImageStoreDriverImpl.java   |   28 +-
 .../driver/SwiftImageStoreDriverImpl.java          |   28 +-
 server/src/com/cloud/storage/TemplateProfile.java  |   75 ++--
 .../cloud/storage/download/DownloadListener.java   |  117 +++--
 .../cloud/storage/download/DownloadMonitor.java    |   14 +-
 .../storage/download/DownloadMonitorImpl.java      |  409 ++++++++-------
 .../secondary/SecondaryStorageManagerImpl.java     |  109 +++--
 .../secondary/SecondaryStorageVmManager.java       |   11 +-
 .../cloud/template/HypervisorTemplateAdapter.java  |   33 +-
 server/src/com/cloud/template/TemplateAdapter.java |   14 +-
 .../com/cloud/template/TemplateAdapterBase.java    |   91 ++--
 36 files changed, 735 insertions(+), 558 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
index c9da0c2..f93c9f4 100644
--- a/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
@@ -110,11 +110,7 @@ public class RegisterTemplateCmd extends BaseCmd {
     @Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.UUID, entityType = ProjectResponse.class,
             description="Register template for the project")
     private Long projectId;
-    
-    @Parameter(name=ApiConstants.IMAGE_STORE_UUID, type=CommandType.STRING,
-            description="Image store uuid")
-    private String imageStoreUuid;
-    
+
     @Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, description="Template details in key/value pairs.")
     protected Map details;
 
@@ -193,10 +189,7 @@ public class RegisterTemplateCmd extends BaseCmd {
     public String getTemplateTag() {
         return templateTag;
     }
-    
-    public String getImageStoreUuid() {
-        return this.imageStoreUuid;
-    }
+
 
     public Map getDetails() {
         if (details == null || details.isEmpty()) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java
index f101f24..10f869c 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java
@@ -23,6 +23,7 @@ public interface DataStore {
     String getUuid();
     String getUri();
     Scope getScope();
+    String getName();
     DataObject create(DataObject obj);
     boolean delete(DataObject obj);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java
index f940e8e..def3b96 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java
@@ -26,7 +26,7 @@ public interface DataStoreManager {
     public DataStore getDataStore(long storeId, DataStoreRole role);
     public DataStore getPrimaryDataStore(long storeId);
     public DataStore getDataStore(String uuid, DataStoreRole role);
-    public List<DataStore> getImageStoresByScope(Scope scope);
+    public List<DataStore> getImageStoresByScope(ZoneScope scope);
     public List<DataStore> getImageStoresByProvider(String provider);
     public DataStore registerDataStore(Map<String, String> params, String providerUuid);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java
index fbd0988..8d6acbd 100644
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java
@@ -21,12 +21,14 @@ package org.apache.cloudstack.storage.datastore.db;
 import java.util.List;
 
 
-import com.cloud.storage.ScopeType;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+
+
 import com.cloud.utils.db.GenericDao;
 
 public interface ImageStoreDao extends GenericDao<ImageStoreVO, Long> {
     public ImageStoreVO findByName(String name);
     public List<ImageStoreVO> findByProvider(String provider);
-    public List<ImageStoreVO> findByScope(ScopeType scope);
+    public List<ImageStoreVO> findByScope(ZoneScope scope);
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/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 4d92fd3..91ffdaa 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
@@ -19,13 +19,14 @@ package org.apache.cloudstack.storage.datastore.db;
 
 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;
 
-public interface SnapshotDataStoreDao extends GenericDao<SnapshotDataStoreVO, Long>, StateDao<ObjectInDataStoreStateMachine.State, ObjectInDataStoreStateMachine.Event, SnapshotDataStoreVO>  {
+public interface SnapshotDataStoreDao extends GenericDao<SnapshotDataStoreVO, Long>, StateDao<ObjectInDataStoreStateMachine.State, ObjectInDataStoreStateMachine.Event, DataObjectInStore>  {
 
     public List<SnapshotDataStoreVO> listByStoreId(long id);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
index 0f9c95a..c257fb5 100644
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
@@ -99,8 +99,8 @@ public class SnapshotDataStoreVO implements StateObject<ObjectInDataStoreStateMa
 		return dataStoreId;
 	}
 
-	public void setHostId(long hostId) {
-		this.dataStoreId = hostId;
+	public void setDataStoreId(long storeId) {
+		this.dataStoreId = storeId;
 	}
 
 
@@ -151,7 +151,7 @@ public class SnapshotDataStoreVO implements StateObject<ObjectInDataStoreStateMa
 
 
 
-	protected SnapshotDataStoreVO() {
+	public SnapshotDataStoreVO() {
 
 	}
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/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 591b84c..29c7859 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
@@ -18,16 +18,23 @@ package org.apache.cloudstack.storage.datastore.db;
 
 import java.util.List;
 
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
+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;
 
-public interface TemplateDataStoreDao extends GenericDao<TemplateDataStoreVO, Long>, StateDao<ObjectInDataStoreStateMachine.State, ObjectInDataStoreStateMachine.Event, TemplateDataStoreVO>  {
+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 void deletePrimaryRecordsForStore(long id);
+
+    List<TemplateDataStoreVO> listByTemplateStoreStatus(long templateId, long storeId, State... states);
+
+    TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/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 4e48437..312fd11 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
@@ -32,7 +32,6 @@ import javax.persistence.TemporalType;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
 
-import com.cloud.storage.VMTemplateStorageResourceAssoc;
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 
 import com.cloud.utils.db.GenericDaoBase;
@@ -118,8 +117,8 @@ public class TemplateDataStoreVO implements StateObject<ObjectInDataStoreStateMa
 		return dataStoreId;
 	}
 
-	public void setHostId(long hostId) {
-		this.dataStoreId = hostId;
+	public void setDataStoreId(long storeId) {
+		this.dataStoreId = storeId;
 	}
 
     public long getTemplateId() {
@@ -158,6 +157,7 @@ public class TemplateDataStoreVO implements StateObject<ObjectInDataStoreStateMa
 	    lastUpdated = date;
 	}
 
+    @Override
     public void setInstallPath(String installPath) {
 	    this.installPath = installPath;
 	}
@@ -190,7 +190,7 @@ public class TemplateDataStoreVO implements StateObject<ObjectInDataStoreStateMa
 		this.setDownloadUrl(downloadUrl);
 	}
 
-	protected TemplateDataStoreVO() {
+	public TemplateDataStoreVO() {
 
 	}
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/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 709097e..58ffde1 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
@@ -19,12 +19,13 @@ package org.apache.cloudstack.storage.datastore.db;
 
 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;
 
-public interface VolumeDataStoreDao extends GenericDao<VolumeDataStoreVO, Long>, StateDao<ObjectInDataStoreStateMachine.State, ObjectInDataStoreStateMachine.Event, VolumeDataStoreVO>  {
+public interface VolumeDataStoreDao extends GenericDao<VolumeDataStoreVO, Long>, StateDao<ObjectInDataStoreStateMachine.State, ObjectInDataStoreStateMachine.Event, DataObjectInStore>  {
 
     public List<VolumeDataStoreVO> listByStoreId(long id);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/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 1fb6184..185b12b 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
@@ -121,8 +121,8 @@ public class VolumeDataStoreVO implements StateObject<ObjectInDataStoreStateMach
 		return dataStoreId;
 	}
 
-	public void setHostId(long hostId) {
-		this.dataStoreId = hostId;
+	public void setDataStoreId(long storeId) {
+		this.dataStoreId = storeId;
 	}
 
 
@@ -223,7 +223,7 @@ public class VolumeDataStoreVO implements StateObject<ObjectInDataStoreStateMach
 		this.format = format;
 	}
 
-	protected VolumeDataStoreVO() {
+	public VolumeDataStoreVO() {
 
 	}
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java
index 616e478..a7b9c42 100644
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java
+++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java
@@ -64,16 +64,16 @@ public class ImageDataFactoryImpl implements ImageDataFactory {
                 found = true;
             }
         } else {
-            DataObjectInStore obj = objMap.findObject(templ.getUuid(), DataObjectType.TEMPLATE, store.getUuid(), store.getRole());
+            DataObjectInStore obj = objMap.findObject(templ.getId(), DataObjectType.TEMPLATE, store.getId(), store.getRole());
             if (obj != null) {
                 found = true;
             }
         }
-        
+
         if (!found) {
             s_logger.debug("template " + templateId + " is not in store:" + store.getId() + ", type:" + store.getRole());
         }
-        
+
         TemplateObject tmpl =  TemplateObject.getTemplate(templ, store);
         return tmpl;
     }
@@ -82,7 +82,7 @@ public class ImageDataFactoryImpl implements ImageDataFactory {
         VMTemplateVO templ = imageDataDao.findById(templateId);
         if (templ.getImageDataStoreId() == null) {
             return this.getTemplate(templateId, null);
-        } 
+        }
         DataStore store = this.storeMgr.getDataStore(templ.getImageDataStoreId(), DataStoreRole.Image);
         return this.getTemplate(templateId, store);
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/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
index 5898b1b..f393fc4 100644
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageServiceImpl.java
+++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageServiceImpl.java
@@ -49,7 +49,7 @@ public class ImageServiceImpl implements ImageService {
     ObjectInDataStoreManager objectInDataStoreMgr;
     @Inject
     DataObjectManager dataObjectMgr;
-    
+
     class CreateTemplateContext<T> extends AsyncRpcConext<T> {
         final TemplateInfo srcTemplate;
         final DataStore store;
@@ -68,39 +68,30 @@ public class ImageServiceImpl implements ImageService {
             this.templateOnStore = templateOnStore;
         }
     }
-    
+
     @Override
     public AsyncCallFuture<CommandResult> createTemplateAsync(
             TemplateInfo template, DataStore store) {
         TemplateObject to = (TemplateObject) template;
         AsyncCallFuture<CommandResult> future = new AsyncCallFuture<CommandResult>();
-        try {
-            to.stateTransit(TemplateEvent.CreateRequested);
-        } catch (NoTransitionException e) {
-            s_logger.debug("Failed to transit state:", e);
-            CommandResult result = new CommandResult();
-            result.setResult(e.toString());
-            future.complete(result);
-            return future;
-        }
-        
+        // 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, 
+
+        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);
+        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, 
+
+    protected Void createTemplateCallback(AsyncCallbackDispatcher<ImageServiceImpl, CreateCmdResult> callback,
             CreateTemplateContext<CreateCmdResult> context) {
         TemplateObject template = (TemplateObject)context.srcTemplate;
         AsyncCallFuture<CommandResult> future = context.future;
@@ -118,7 +109,7 @@ public class ImageServiceImpl implements ImageService {
             future.complete(result);
             return null;
         }
-        
+
         try {
             templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed);
             template.stateTransit(TemplateEvent.OperationSucceeded);
@@ -128,7 +119,7 @@ public class ImageServiceImpl implements ImageService {
             future.complete(result);
             return null;
         }
-        
+
         future.complete(result);
         return null;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java
index 642821f..dbcfb76 100644
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java
+++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java
@@ -30,6 +30,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
 import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider;
 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;
 import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
 import org.apache.cloudstack.storage.image.ImageStoreDriver;
@@ -93,8 +94,8 @@ public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager
     }
 
     @Override
-    public List<DataStore> listImageStoresByScope(Scope scope) {
-        List<ImageStoreVO> stores = dataStoreDao.findByScope(scope.getScopeType());
+    public List<DataStore> listImageStoresByScope(ZoneScope scope) {
+        List<ImageStoreVO> stores = dataStoreDao.findByScope(scope);
         List<DataStore> imageStores = new ArrayList<DataStore>();
         for (ImageStoreVO store : stores) {
             imageStores.add(getImageStore(store.getId()));

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
index 90290d8..7e143cb 100644
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
+++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
@@ -94,7 +94,7 @@ public class ImageStoreImpl implements ImageStoreEntity {
 
     @Override
     public String getUri() {
-        return this.imageDataStoreVO.getProtocol() + "://" + "?" + EncodingType.ROLE + "=" + this.getRole();
+        return this.imageDataStoreVO.getUrl();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java
index fa7772a..0bd40d3 100644
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java
@@ -51,7 +51,7 @@ public class SnapshotDataFactoryImpl implements SnapshotDataFactory {
     @Override
     public SnapshotInfo getSnapshot(long snapshotId, DataStore store) {
         SnapshotVO snapshot = snapshotDao.findByIdIncludingRemoved(snapshotId);
-        DataObjectInStore obj = objMap.findObject(snapshot.getUuid(), DataObjectType.SNAPSHOT, store.getUuid(), store.getRole());
+        DataObjectInStore obj = objMap.findObject(snapshot.getId(), DataObjectType.SNAPSHOT, store.getId(), store.getRole());
         if (obj == null) {
             return null;
         }
@@ -71,7 +71,7 @@ public class SnapshotDataFactoryImpl implements SnapshotDataFactory {
     	}
     	return so;
     }
-    
+
     @Override
     public SnapshotInfo getSnapshot(DataObject obj, DataStore store) {
         SnapshotVO snapshot = snapshotDao.findByIdIncludingRemoved(obj.getId());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java
index 8f8d3c9..eb233aa 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java
@@ -27,6 +27,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.Scope;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
 import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager;
 import org.springframework.stereotype.Component;
 
@@ -63,8 +64,10 @@ public class DataStoreManagerImpl implements DataStoreManager {
         throw new CloudRuntimeException("un recognized type" + role);
     }
 
+
+
     @Override
-    public List<DataStore> getImageStoresByScope(Scope scope) {
+    public List<DataStore> getImageStoresByScope(ZoneScope scope) {
         return imageDataStoreMgr.listImageStoresByScope(scope);
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java
index d170f5c..17b782a 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java
@@ -29,8 +29,8 @@ public interface ObjectInDataStoreManager {
     public DataObject create(DataObject template, DataStore dataStore);
     public DataObject get(DataObject dataObj, DataStore store);
     public boolean update(DataObject vo, Event event) throws NoTransitionException;
-    DataObjectInStore findObject(String uuid, DataObjectType type,
-            String dataStoreUuid, DataStoreRole role);
+    DataObjectInStore findObject(long objId, DataObjectType type,
+            long dataStoreId, DataStoreRole role);
     DataObjectInStore findObject(DataObject obj, DataStore store);
     DataStore findStore(String objUuid, DataObjectType type,  DataStoreRole role);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
index 87ba1d2..80badc5 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
@@ -29,15 +29,19 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreState
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.storage.db.ObjectInDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
+import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
 import org.apache.cloudstack.storage.db.ObjectInDataStoreVO;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
 import com.cloud.storage.VMTemplateStoragePoolVO;
-import com.cloud.storage.dao.VMTemplateHostDao;
 import com.cloud.storage.dao.VMTemplatePoolDao;
-import com.cloud.storage.dao.VolumeHostDao;
+import com.cloud.utils.db.SearchCriteria;
 import com.cloud.utils.db.SearchCriteria.Op;
 import com.cloud.utils.db.SearchCriteria2;
 import com.cloud.utils.db.SearchCriteriaService;
@@ -56,11 +60,11 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
     @Inject
     VolumeDataFactory volumeFactory;
     @Inject
-    ObjectInDataStoreDao objectDataStoreDao;
+    TemplateDataStoreDao templateDataStoreDao;
     @Inject
-    VolumeHostDao volumeHostDao;
+    SnapshotDataStoreDao snapshotDataStoreDao;
     @Inject
-    VMTemplateHostDao templateHostDao;
+    VolumeDataStoreDao volumeDataStoreDao;
     @Inject
     VMTemplatePoolDao templatePoolDao;
     @Inject
@@ -101,28 +105,38 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
 
     @Override
     public DataObject create(DataObject obj, DataStore dataStore) {
-        if (obj.getType() == DataObjectType.TEMPLATE && dataStore.getRole() == DataStoreRole.Primary) {
-            VMTemplateStoragePoolVO vo = new VMTemplateStoragePoolVO(dataStore.getId(), obj.getId());
-            vo = templatePoolDao.persist(vo);
+        if (dataStore.getRole() == DataStoreRole.Primary) {
+            if ( obj.getType() == DataObjectType.TEMPLATE){
+                VMTemplateStoragePoolVO vo = new VMTemplateStoragePoolVO(dataStore.getId(), obj.getId());
+                vo = templatePoolDao.persist(vo);
+            }
         } else {
-            ObjectInDataStoreVO vo = new ObjectInDataStoreVO();
-            vo.setDataStoreRole(dataStore.getRole());
-            vo.setDataStoreUuid(dataStore.getUuid());
-            vo.setObjectType(obj.getType());
-            vo.setObjectUuid(obj.getUuid());
-            vo = objectDataStoreDao.persist(vo);
+            // Image store
+            switch ( obj.getType()){
+            case TEMPLATE:
+                TemplateDataStoreVO ts = new TemplateDataStoreVO();
+                ts.setTemplateId(obj.getId());
+                ts.setDataStoreId(dataStore.getId());
+                ts = templateDataStoreDao.persist(ts);
+                break;
+            case SNAPSHOT:
+                SnapshotDataStoreVO ss = new SnapshotDataStoreVO();
+                ss.setSnapshotId(obj.getId());
+                ss.setDataStoreId(dataStore.getId());
+                ss = snapshotDataStoreDao.persist(ss);
+                break;
+            case VOLUME:
+                VolumeDataStoreVO vs = new VolumeDataStoreVO();
+                vs.setVolumeId(obj.getId());
+                vs.setDataStoreId(dataStore.getId());
+                vs = volumeDataStoreDao.persist(vs);
+                break;
+            }
         }
 
-        if (obj.getType() == DataObjectType.TEMPLATE) {
-            return imageFactory.getTemplate(obj, dataStore);
-        } else if (obj.getType() == DataObjectType.VOLUME) {
-            return volumeFactory.getVolume(obj, dataStore); 
-        } else if (obj.getType() == DataObjectType.SNAPSHOT) {
-            return snapshotFactory.getSnapshot(obj, dataStore);
-        }
-        throw new CloudRuntimeException("unknown type");
+        return this.get(obj,  dataStore);
     }
-    
+
     @Override
     public boolean update(DataObject data, Event event)
             throws NoTransitionException {
@@ -132,8 +146,17 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
                     "can't find mapping in ObjectInDataStore table for: "
                             + data);
         }
-        
-        if (data.getType() == DataObjectType.TEMPLATE && data.getDataStore().getRole() == DataStoreRole.Primary) {
+
+        if ( data.getDataStore().getRole() == DataStoreRole.Image){
+            switch (data.getType()){
+            case TEMPLATE:
+                this.stateMachines.transitTo(obj, event, null, templateDataStoreDao);
+            case SNAPSHOT:
+                this.stateMachines.transitTo(obj, event, null, snapshotDataStoreDao);
+            case VOLUME:
+                this.stateMachines.transitTo(obj, event, null, volumeDataStoreDao);
+            }
+        } else if (data.getType() == DataObjectType.TEMPLATE && data.getDataStore().getRole() == DataStoreRole.Primary) {
             try {
             this.stateMachines.transitTo(obj, event, null,
                     templatePoolDao);
@@ -145,7 +168,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
                 }
             }
         } else {
-            this.stateMachines.transitTo(obj, event, null, objectDataStoreDao);
+            throw new CloudRuntimeException("Invalid data or store type: " + data.getType() + " " + data.getDataStore().getRole());
         }
         return true;
     }
@@ -155,47 +178,53 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
         if (dataObj.getType() == DataObjectType.TEMPLATE) {
             return imageFactory.getTemplate(dataObj, store);
         } else if (dataObj.getType() == DataObjectType.VOLUME) {
-            return volumeFactory.getVolume(dataObj, store); 
+            return volumeFactory.getVolume(dataObj, store);
+        } else if (dataObj.getType() == DataObjectType.SNAPSHOT) {
+            return snapshotFactory.getSnapshot(dataObj, store);
         }
+
         throw new CloudRuntimeException("unknown type");
     }
 
     @Override
     public DataObjectInStore findObject(DataObject obj, DataStore store) {
-        DataObjectInStore vo = null;
-        SearchCriteriaService<ObjectInDataStoreVO, ObjectInDataStoreVO> sc = SearchCriteria2.create(ObjectInDataStoreVO.class);
-        
-        if (store.getRole() == DataStoreRole.Image) {
-            sc.addAnd(sc.getEntity().getDataStoreUuid(), Op.EQ, store.getUuid());
-            sc.addAnd(sc.getEntity().getDataStoreRole(), Op.EQ, store.getRole());
-            sc.addAnd(sc.getEntity().getObjectUuid(), Op.EQ, obj.getUuid());
-            sc.addAnd(sc.getEntity().getObjectType(), Op.EQ, obj.getType());
-            vo = sc.find();
-        } else if (obj.getType() == DataObjectType.TEMPLATE && store.getRole() == DataStoreRole.Primary) {
-            vo = templatePoolDao.findByPoolTemplate(store.getId(), obj.getId());
-        } else {
-            s_logger.debug("unknown type: " + obj.getType() + " " + store.getRole());
-            throw new CloudRuntimeException("unknown type");
-        }
-        return vo;
+        return findObject(obj.getId(), obj.getType(), store.getId(), store.getRole());
     }
 
+
     @Override
-    public DataObjectInStore findObject(String uuid, DataObjectType type,
-            String dataStoreUuid, DataStoreRole role) {
+    public DataObjectInStore findObject(long objId, DataObjectType type,
+            long dataStoreId, DataStoreRole role) {
         DataObjectInStore vo = null;
-        SearchCriteriaService<ObjectInDataStoreVO, ObjectInDataStoreVO> sc = SearchCriteria2.create(ObjectInDataStoreVO.class);
-        
         if (role == DataStoreRole.Image) {
-            sc.addAnd(sc.getEntity().getDataStoreUuid(), Op.EQ, dataStoreUuid);
-            sc.addAnd(sc.getEntity().getDataStoreRole(), Op.EQ, role);
-            sc.addAnd(sc.getEntity().getObjectUuid(), Op.EQ, uuid);
-            sc.addAnd(sc.getEntity().getObjectType(), Op.EQ, type);
-            vo = sc.find();
+            switch (type){
+            case TEMPLATE:
+                SearchCriteria<TemplateDataStoreVO> ts =  templateDataStoreDao.createSearchCriteria();
+                ts.addAnd("templateId", SearchCriteria.Op.EQ, objId);
+                ts.addAnd("dataStoreId", SearchCriteria.Op.EQ, dataStoreId);
+                vo =  templateDataStoreDao.findOneBy(ts);
+            case SNAPSHOT:
+                SearchCriteria<SnapshotDataStoreVO> ss =  snapshotDataStoreDao.createSearchCriteria();
+                ss.addAnd("snapshotId", SearchCriteria.Op.EQ, objId);
+                ss.addAnd("dataStoreId", SearchCriteria.Op.EQ, objId);
+                vo =  snapshotDataStoreDao.findOneBy(ss);
+            case VOLUME:
+                SearchCriteria<VolumeDataStoreVO> vs =  volumeDataStoreDao.createSearchCriteria();
+                vs.addAnd("volumeId", SearchCriteria.Op.EQ, objId);
+                vs.addAnd("dataStoreId", SearchCriteria.Op.EQ, objId);
+                vo =  volumeDataStoreDao.findOneBy(vs);
+            }
+        } else if (type == DataObjectType.TEMPLATE && role == DataStoreRole.Primary) {
+            vo = templatePoolDao.findByPoolTemplate(dataStoreId, objId);
+        } else {
+            s_logger.debug("Invalid data or store type: " + type + " " + role);
+            throw new CloudRuntimeException("Invalid data or store type: " + type + " " + role);
         }
+
         return vo;
+
     }
-    
+
     @Override
     public DataStore findStore(String objUuid, DataObjectType type,  DataStoreRole role) {
         DataStore store = null;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java
index bb5e20f..2026346 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java
@@ -22,13 +22,14 @@ import java.util.List;
 
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
 import org.apache.cloudstack.storage.image.ImageStoreDriver;
 
 public interface ImageStoreProviderManager {
     ImageStoreEntity getImageStore(long dataStoreId);
     ImageStoreEntity getImageStore(String uuid);
     List<DataStore> listImageStores();
-    List<DataStore> listImageStoresByScope(Scope scope);
+    List<DataStore> listImageStoresByScope(ZoneScope scope);
     List<DataStore> listImageStoreByProvider(String provider);
     boolean registerDriver(String uuid, ImageStoreDriver driver);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/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 ab41a4b..5bcf2f3 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,8 @@ import java.util.Map;
 import javax.naming.ConfigurationException;
 
 
+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;
 import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
 import org.apache.log4j.Logger;
@@ -40,7 +42,6 @@ public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implem
     private static final Logger s_logger = Logger.getLogger(ImageStoreDaoImpl.class);
     private SearchBuilder<ImageStoreVO> nameSearch;
     private SearchBuilder<ImageStoreVO> providerSearch;
-    private SearchBuilder<ImageStoreVO> scopeSearch;
 
 
     @Override
@@ -55,10 +56,6 @@ public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implem
         providerSearch.and("providerName", providerSearch.entity().getProviderName(), SearchCriteria.Op.EQ);
         providerSearch.done();
 
-        scopeSearch = createSearchBuilder();
-        scopeSearch.and("scope", scopeSearch.entity().getScope(), SearchCriteria.Op.EQ);
-        scopeSearch.done();
-
         return true;
     }
 
@@ -77,9 +74,10 @@ public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implem
     }
 
     @Override
-    public List<ImageStoreVO> findByScope(ScopeType scope) {
-        SearchCriteria<ImageStoreVO> sc = scopeSearch.create();
-        sc.setParameters("scope", scope);
+    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());
         return listBy(sc);
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/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 a1c4871..6a6e04a 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
@@ -21,6 +21,7 @@ import java.util.Map;
 
 import javax.naming.ConfigurationException;
 
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
 import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
@@ -66,7 +67,8 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
 
     @Override
     public boolean updateState(State currentState, Event event,
-            State nextState, SnapshotDataStoreVO dataObj, Object data) {
+            State nextState, DataObjectInStore vo, Object data) {
+        SnapshotDataStoreVO dataObj = (SnapshotDataStoreVO)vo;
         Long oldUpdated = dataObj.getUpdatedCount();
         Date oldUpdatedTime = dataObj.getUpdated();
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/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 d7019d2..a429dc9 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
@@ -24,12 +24,12 @@ import javax.naming.ConfigurationException;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
+import com.cloud.storage.VMTemplateHostVO;
 import com.cloud.utils.db.GenericDaoBase;
 import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria;
@@ -43,6 +43,8 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
     private SearchBuilder<TemplateDataStoreVO> updateStateSearch;
     private SearchBuilder<TemplateDataStoreVO> storeSearch;
     private SearchBuilder<TemplateDataStoreVO> liveStoreSearch;
+    private SearchBuilder<TemplateDataStoreVO> storeTemplateStateSearch;
+    private SearchBuilder<TemplateDataStoreVO> storeTemplateSearch;
 
     @Override
     public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
@@ -62,12 +64,27 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
         updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ);
         updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), Op.EQ);
         updateStateSearch.done();
+
+        storeTemplateStateSearch = createSearchBuilder();
+        storeTemplateStateSearch.and("template_id", storeTemplateStateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
+        storeTemplateStateSearch.and("store_id", storeTemplateStateSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
+        storeTemplateStateSearch.and("states", storeTemplateStateSearch.entity().getState(), SearchCriteria.Op.IN);
+        storeTemplateStateSearch.and("destroyed", storeTemplateStateSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
+        storeTemplateStateSearch.done();
+
+        storeTemplateSearch = createSearchBuilder();
+        storeTemplateSearch.and("store_id", storeTemplateSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
+        storeTemplateSearch.and("template_id", storeTemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
+        storeTemplateSearch.and("destroyed", storeTemplateSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
+        storeTemplateSearch.done();
+
         return true;
     }
 
     @Override
     public boolean updateState(State currentState, Event event,
-            State nextState, TemplateDataStoreVO dataObj, Object data) {
+            State nextState, DataObjectInStore vo, Object data) {
+        TemplateDataStoreVO dataObj = (TemplateDataStoreVO)vo;
         Long oldUpdated = dataObj.getUpdatedCount();
         Date oldUpdatedTime = dataObj.getUpdated();
 
@@ -124,4 +141,26 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
         remove(sc);
         txn.commit();
     }
+
+
+    @Override
+    public List<TemplateDataStoreVO> listByTemplateStoreStatus(long templateId, long storeId, State... states) {
+        SearchCriteria<TemplateDataStoreVO> sc = storeTemplateStateSearch.create();
+        sc.setParameters("template_id", templateId);
+        sc.setParameters("store_id", storeId);
+        sc.setParameters("states", (Object[])states);
+        return search(sc, null);
+    }
+
+    @Override
+    public TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId) {
+        SearchCriteria<TemplateDataStoreVO> sc = storeTemplateSearch.create();
+        sc.setParameters("store_id", storeId);
+        sc.setParameters("template_id", templateId);
+        sc.setParameters("destroyed", false);
+        return findOneIncludingRemovedBy(sc);
+    }
+
+
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/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 b8127ee..9a93f98 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
@@ -67,7 +67,8 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase<VolumeDataStoreVO, Lo
     }
     @Override
     public boolean updateState(State currentState, Event event,
-            State nextState, VolumeDataStoreVO dataObj, Object data) {
+            State nextState, DataObjectInStore vo, Object data) {
+        VolumeDataStoreVO dataObj = (VolumeDataStoreVO)vo;
         Long oldUpdated = dataObj.getUpdatedCount();
         Date oldUpdatedTime = dataObj.getUpdated();
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/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 ceadb25..cde576b 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
@@ -54,7 +54,7 @@ public class VolumeObject implements VolumeInfo {
     public VolumeObject() {
         _volStateMachine = Volume.State.getStateMachine();
     }
-    
+
     protected void configure(DataStore dataStore, VolumeVO volumeVO) {
         this.volumeVO = volumeVO;
         this.dataStore = dataStore;
@@ -74,7 +74,7 @@ public class VolumeObject implements VolumeInfo {
     public void setPath(String uuid) {
         volumeVO.setPath(uuid);
     }
-    
+
     public void setSize(Long size) {
     	volumeVO.setSize(size);
     }
@@ -129,15 +129,15 @@ public class VolumeObject implements VolumeInfo {
         if (this.dataStore == null) {
             throw new CloudRuntimeException("datastore must be set before using this object");
         }
-        DataObjectInStore obj = ojbectInStoreMgr.findObject(this.volumeVO.getUuid(), DataObjectType.VOLUME, this.dataStore.getUuid(), this.dataStore.getRole());
+        DataObjectInStore obj = ojbectInStoreMgr.findObject(this.volumeVO.getId(), DataObjectType.VOLUME, this.dataStore.getId(), this.dataStore.getRole());
         if (obj.getState() != ObjectInDataStoreStateMachine.State.Ready) {
-            return this.dataStore.getUri() + 
-                    "&" + EncodingType.OBJTYPE + "=" + DataObjectType.VOLUME + 
-                    "&" + EncodingType.SIZE + "=" + this.volumeVO.getSize() + 
+            return this.dataStore.getUri() +
+                    "&" + EncodingType.OBJTYPE + "=" + DataObjectType.VOLUME +
+                    "&" + EncodingType.SIZE + "=" + this.volumeVO.getSize() +
                     "&" + EncodingType.NAME + "=" + this.volumeVO.getName();
         } else {
             return this.dataStore.getUri() +
-                    "&" + EncodingType.OBJTYPE + "=" + DataObjectType.VOLUME + 
+                    "&" + EncodingType.OBJTYPE + "=" + DataObjectType.VOLUME +
                     "&" + EncodingType.PATH + "=" + obj.getInstallPath();
         }
     }
@@ -178,7 +178,7 @@ public class VolumeObject implements VolumeInfo {
                     volEvent = Volume.Event.CopyRequested;
                 }
             }
-            
+
             if (event == ObjectInDataStoreStateMachine.Event.DestroyRequested) {
                 volEvent = Volume.Event.DestroyRequested;
             } else if (event == ObjectInDataStoreStateMachine.Event.ExpungeRequested) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/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 e55f0d7..d52af65 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
@@ -34,6 +34,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 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.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
@@ -72,7 +73,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
     @Inject
     VMTemplateDao templateDao;
     @Inject DownloadMonitor _downloadMonitor;
-    @Inject 
+    @Inject
     VMTemplateHostDao _vmTemplateHostDao;
     @Inject VolumeDao volumeDao;
     @Inject VolumeHostDao volumeHostDao;
@@ -82,8 +83,8 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
     @Inject SnapshotManager snapshotMgr;
 	@Inject
     private SwiftManager _swiftMgr;
-    @Inject 
-    private S3Manager _s3Mgr; 
+    @Inject
+    private S3Manager _s3Mgr;
     @Override
     public String grantAccess(DataObject data, EndPoint ep) {
         // TODO Auto-generated method stub
@@ -109,16 +110,13 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
             this.data = data;
         }
     }
-    
+
     @Override
     public void createAsync(DataObject data,
             AsyncCompletionCallback<CreateCmdResult> callback) {
         if (data.getType() == DataObjectType.TEMPLATE) {
-            List<VMTemplateZoneVO> templateZones = this.templateZoneDao.listByTemplateId(data.getId());
-            for (VMTemplateZoneVO templateZone : templateZones) {
-                VMTemplateVO template = this.templateDao.findById(data.getId());
-                _downloadMonitor.downloadTemplateToStorage(template, templateZone.getZoneId());
-            }
+            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;
@@ -130,7 +128,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
         CreateCmdResult result = new CreateCmdResult(null, null);
         callback.complete(result);
     }
-    
+
     private void deleteVolume(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
         // TODO Auto-generated method stub
         VolumeVO vol = volumeDao.findById(data.getId());
@@ -167,11 +165,11 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
             return;
         }
     }
-    
+
     private void deleteTemplate(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
-        
+
     }
-    
+
     private void deleteSnapshot(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
     	Long snapshotId = data.getId();
     	SnapshotVO snapshot = this.snapshotDao.findByIdIncludingRemoved(snapshotId);
@@ -214,7 +212,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
     	}
     	callback.complete(result);
     }
-    
+
     @Override
     public void deleteAsync(DataObject data,
             AsyncCompletionCallback<CommandResult> callback) {
@@ -244,7 +242,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
 	public void resize(DataObject data,
 			AsyncCompletionCallback<CreateCmdResult> callback) {
 		// TODO Auto-generated method stub
-		
+
 	}
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/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 c9e8521..0d84f58 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
@@ -34,6 +34,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 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.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
@@ -72,7 +73,7 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver {
     @Inject
     VMTemplateDao templateDao;
     @Inject DownloadMonitor _downloadMonitor;
-    @Inject 
+    @Inject
     VMTemplateHostDao _vmTemplateHostDao;
     @Inject VolumeDao volumeDao;
     @Inject VolumeHostDao volumeHostDao;
@@ -82,8 +83,8 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver {
     @Inject SnapshotManager snapshotMgr;
 	@Inject
     private SwiftManager _swiftMgr;
-    @Inject 
-    private S3Manager _s3Mgr; 
+    @Inject
+    private S3Manager _s3Mgr;
     @Override
     public String grantAccess(DataObject data, EndPoint ep) {
         // TODO Auto-generated method stub
@@ -109,16 +110,13 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver {
             this.data = data;
         }
     }
-    
+
     @Override
     public void createAsync(DataObject data,
             AsyncCompletionCallback<CreateCmdResult> callback) {
         if (data.getType() == DataObjectType.TEMPLATE) {
-            List<VMTemplateZoneVO> templateZones = this.templateZoneDao.listByTemplateId(data.getId());
-            for (VMTemplateZoneVO templateZone : templateZones) {
-                VMTemplateVO template = this.templateDao.findById(data.getId());
-                _downloadMonitor.downloadTemplateToStorage(template, templateZone.getZoneId());
-            }
+            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;
@@ -130,7 +128,7 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver {
         CreateCmdResult result = new CreateCmdResult(null, null);
         callback.complete(result);
     }
-    
+
     private void deleteVolume(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
         // TODO Auto-generated method stub
         VolumeVO vol = volumeDao.findById(data.getId());
@@ -167,11 +165,11 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver {
             return;
         }
     }
-    
+
     private void deleteTemplate(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
-        
+
     }
-    
+
     private void deleteSnapshot(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
     	Long snapshotId = data.getId();
     	SnapshotVO snapshot = this.snapshotDao.findByIdIncludingRemoved(snapshotId);
@@ -214,7 +212,7 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver {
     	}
     	callback.complete(result);
     }
-    
+
     @Override
     public void deleteAsync(DataObject data,
             AsyncCompletionCallback<CommandResult> callback) {
@@ -244,7 +242,7 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver {
 	public void resize(DataObject data,
 			AsyncCompletionCallback<CreateCmdResult> callback) {
 		// TODO Auto-generated method stub
-		
+
 	}
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/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 168e23a..36fd5fb 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
@@ -34,6 +34,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 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.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
@@ -72,7 +73,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver {
     @Inject
     VMTemplateDao templateDao;
     @Inject DownloadMonitor _downloadMonitor;
-    @Inject 
+    @Inject
     VMTemplateHostDao _vmTemplateHostDao;
     @Inject VolumeDao volumeDao;
     @Inject VolumeHostDao volumeHostDao;
@@ -82,8 +83,8 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver {
     @Inject SnapshotManager snapshotMgr;
 	@Inject
     private SwiftManager _swiftMgr;
-    @Inject 
-    private S3Manager _s3Mgr; 
+    @Inject
+    private S3Manager _s3Mgr;
     @Override
     public String grantAccess(DataObject data, EndPoint ep) {
         // TODO Auto-generated method stub
@@ -109,16 +110,13 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver {
             this.data = data;
         }
     }
-    
+
     @Override
     public void createAsync(DataObject data,
             AsyncCompletionCallback<CreateCmdResult> callback) {
         if (data.getType() == DataObjectType.TEMPLATE) {
-            List<VMTemplateZoneVO> templateZones = this.templateZoneDao.listByTemplateId(data.getId());
-            for (VMTemplateZoneVO templateZone : templateZones) {
-                VMTemplateVO template = this.templateDao.findById(data.getId());
-                _downloadMonitor.downloadTemplateToStorage(template, templateZone.getZoneId());
-            }
+            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;
@@ -130,7 +128,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver {
         CreateCmdResult result = new CreateCmdResult(null, null);
         callback.complete(result);
     }
-    
+
     private void deleteVolume(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
         // TODO Auto-generated method stub
         VolumeVO vol = volumeDao.findById(data.getId());
@@ -167,11 +165,11 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver {
             return;
         }
     }
-    
+
     private void deleteTemplate(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
-        
+
     }
-    
+
     private void deleteSnapshot(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
     	Long snapshotId = data.getId();
     	SnapshotVO snapshot = this.snapshotDao.findByIdIncludingRemoved(snapshotId);
@@ -214,7 +212,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver {
     	}
     	callback.complete(result);
     }
-    
+
     @Override
     public void deleteAsync(DataObject data,
             AsyncCompletionCallback<CommandResult> callback) {
@@ -244,7 +242,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver {
 	public void resize(DataObject data,
 			AsyncCompletionCallback<CreateCmdResult> callback) {
 		// TODO Auto-generated method stub
-		
+
 	}
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/server/src/com/cloud/storage/TemplateProfile.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/TemplateProfile.java b/server/src/com/cloud/storage/TemplateProfile.java
index 0b55f1f..e3943d9 100755
--- a/server/src/com/cloud/storage/TemplateProfile.java
+++ b/server/src/com/cloud/storage/TemplateProfile.java
@@ -21,7 +21,7 @@ import java.util.Map;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.storage.Storage.ImageFormat;
 
-public class TemplateProfile {	
+public class TemplateProfile {
 	Long userId;
 	String name;
 	String displayText;
@@ -45,9 +45,8 @@ public class TemplateProfile {
 	Long templateId;
 	VMTemplateVO template;
 	String templateTag;
-	Long imageStoreId;
 	Map details;
-	
+
 	public TemplateProfile(Long templateId, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHvm,
 			String url, Boolean isPublic, Boolean featured, Boolean isExtractable, ImageFormat format, Long guestOsId, Long zoneId,
 			HypervisorType hypervisorType, String accountName, Long domainId, Long accountId, String chksum, Boolean bootable, Map details, Boolean sshKeyEnabled) {
@@ -74,188 +73,184 @@ public class TemplateProfile {
 		this.details = details;
 		this.sshKeyEnbaled = sshKeyEnabled;
 	}
-	
+
 	public TemplateProfile(Long userId, VMTemplateVO template, Long zoneId) {
 		this.userId = userId;
 		this.template = template;
 		this.zoneId = zoneId;
 	}
-	
+
     public TemplateProfile(Long templateId, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHvm,
             String url, Boolean isPublic, Boolean featured, Boolean isExtractable, ImageFormat format, Long guestOsId, Long zoneId,
-            HypervisorType hypervisorType, String accountName, Long domainId, Long accountId, String chksum, Boolean bootable, String templateTag, Map details, Boolean sshKeyEnabled,
-            Long imageStoreId) {
+            HypervisorType hypervisorType, String accountName, Long domainId, Long accountId, String chksum, Boolean bootable, String templateTag, Map details, Boolean sshKeyEnabled) {
         this(templateId, userId, name, displayText, bits, passwordEnabled, requiresHvm, url, isPublic, featured, isExtractable, format, guestOsId, zoneId,
                 hypervisorType, accountName, domainId, accountId, chksum, bootable, details, sshKeyEnabled);
         this.templateTag = templateTag;
-        this.imageStoreId = imageStoreId;
-    }	
-	
+    }
+
 	public Long getTemplateId() {
 		return templateId;
 	}
 	public void setTemplateId(Long id) {
 		this.templateId = id;
 	}
-	
+
 	public Long getUserId() {
 		return userId;
 	}
 	public void setUserId(Long userId) {
 		this.userId = userId;
 	}
-	
+
 	public String getName() {
 		return name;
 	}
 	public void setName(String name) {
 		this.name = name;
 	}
-	
+
 	public String getDisplayText() {
 		return displayText;
 	}
 	public void setDisplayText(String text) {
 		this.displayText = text;
 	}
-	
+
 	public Integer getBits() {
 		return bits;
 	}
 	public void setBits(Integer bits) {
 		this.bits = bits;
 	}
-	
+
 	public Boolean getPasswordEnabled() {
 		return passwordEnabled;
 	}
 	public void setPasswordEnabled(Boolean enabled) {
 		this.passwordEnabled = enabled;
 	}
-	
+
 	public Boolean getRequiresHVM() {
 		return requiresHvm;
 	}
 	public void setRequiresHVM(Boolean hvm) {
 		this.requiresHvm = hvm;
 	}
-	
+
 	public String getUrl() {
 		return url;
 	}
 	public void setUrl(String url) {
 		this.url = url;
 	}
-	
+
 	public Boolean getIsPublic() {
 		return isPublic;
 	}
 	public void setIsPublic(Boolean is) {
 		this.isPublic = is;
 	}
-	
+
 	public Boolean getFeatured() {
 		return featured;
 	}
 	public void setFeatured(Boolean featured) {
 		this.featured = featured;
 	}
-	
+
 	public Boolean getIsExtractable() {
 		return isExtractable;
 	}
 	public void setIsExtractable(Boolean is) {
 		this.isExtractable = is;
 	}
-	
+
 	public ImageFormat getFormat() {
 		return format;
 	}
 	public void setFormat(ImageFormat format) {
 		this.format = format;
 	}
-	
+
 	public Long getGuestOsId() {
 		return guestOsId;
 	}
 	public void setGuestOsId(Long id) {
 		this.guestOsId = id;
 	}
-	
+
 	public Long getZoneId() {
 		return zoneId;
 	}
 	public void setZoneId(Long id) {
 		this.zoneId = id;
 	}
-	
+
 	public HypervisorType getHypervisorType() {
 		return hypervisorType;
 	}
 	public void setHypervisorType(HypervisorType type) {
 		this.hypervisorType = type;
 	}
-	
+
 	public Long getDomainId() {
 		return domainId;
 	}
 	public void setDomainId(Long id) {
 		this.domainId = id;
 	}
-	
+
 	public Long getAccountId() {
 		return accountId;
 	}
 	public void setAccountId(Long id) {
 		this.accountId = id;
 	}
-	
+
 	public String getCheckSum() {
 		return chksum;
 	}
 	public void setCheckSum(String chksum) {
 		this.chksum = chksum;
 	}
-	
+
 	public Boolean getBootable() {
 		return this.bootable;
 	}
 	public void setBootable(Boolean bootable) {
 		this.bootable = bootable;
 	}
-	
+
 	public VMTemplateVO getTemplate() {
 		return template;
 	}
 	public void setTemplate(VMTemplateVO template) {
 		this.template = template;
 	}
-	
+
     public String getTemplateTag() {
         return templateTag;
-    }    
+    }
 
     public void setTemplateTag(String templateTag) {
         this.templateTag = templateTag;
-    }  	
-	
+    }
+
     public Map getDetails() {
     	return this.details;
     }
-    
+
     public void setDetails(Map details) {
     	this.details = details;
     }
-    
+
     public void setSshKeyEnabled(Boolean enabled) {
     	this.sshKeyEnbaled = enabled;
     }
-    
+
     public Boolean getSshKeyEnabled() {
     	return this.sshKeyEnbaled;
     }
-    
-    public Long getImageStoreId() {
-        return this.imageStoreId;
-    }
+
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/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 1d48803..2741af1 100755
--- a/server/src/com/cloud/storage/download/DownloadListener.java
+++ b/server/src/com/cloud/storage/download/DownloadListener.java
@@ -24,6 +24,11 @@ import java.util.TimerTask;
 
 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.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
 import org.apache.log4j.Level;
 import org.apache.log4j.Logger;
 
@@ -74,7 +79,7 @@ public class DownloadListener implements Listener {
 	private static final class StatusTask extends TimerTask {
 		private final DownloadListener dl;
 		private final RequestType reqType;
-		
+
 		public StatusTask( DownloadListener dl,  RequestType req) {
 			this.reqType = req;
 			this.dl = dl;
@@ -86,10 +91,10 @@ public class DownloadListener implements Listener {
 
 		}
 	}
-	
+
 	private static final class TimeoutTask extends TimerTask {
 		private final DownloadListener dl;
-		
+
 		public TimeoutTask( DownloadListener dl) {
 			this.dl = dl;
 		}
@@ -104,7 +109,7 @@ public class DownloadListener implements Listener {
 	public static final Logger s_logger = Logger.getLogger(DownloadListener.class.getName());
 	public static final int SMALL_DELAY = 100;
     public static final long STATUS_POLL_INTERVAL = 10000L;
-	
+
 	public static final String DOWNLOADED=Status.DOWNLOADED.toString();
 	public static final String NOT_DOWNLOADED=Status.NOT_DOWNLOADED.toString();
 	public static final String DOWNLOAD_ERROR=Status.DOWNLOAD_ERROR.toString();
@@ -114,24 +119,25 @@ public class DownloadListener implements Listener {
 
 	private HostVO sserver;
 	private HostVO ssAgent;
+
 	private VMTemplateVO template;
 	private VolumeVO volume;
-	
 	private boolean downloadActive = true;
 
 	private VolumeHostDao volumeHostDao;
 	private VolumeDao _volumeDao;
 	private StorageManager _storageMgr;
 	private VMTemplateHostDao vmTemplateHostDao;
+	private TemplateDataStoreDao _vmTemplateStoreDao;
 	private VMTemplateDao _vmTemplateDao;
 	private ResourceLimitService _resourceLimitMgr;
 	private AccountManager _accountMgr;
 	private AlertManager _alertMgr;
 
 	private final DownloadMonitorImpl downloadMonitor;
-	
+
 	private DownloadState currState;
-	
+
 	private DownloadCommand cmd;
 
 	private Timer timer;
@@ -140,11 +146,15 @@ public class DownloadListener implements Listener {
 	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 DataStore sstore;
+    private Long templateStoreId;
+	private AsyncCompletionCallback<CreateCmdResult> callback;
+
 	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;
@@ -164,7 +174,30 @@ public class DownloadListener implements Listener {
 		this._alertMgr = _alertMgr;
 		updateDatabase(Status.NOT_DOWNLOADED, "");
 	}
-	
+
+	// 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._vmTemplateStoreDao = dao;
+        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._vmTemplateDao = templateDao;
+        this._resourceLimitMgr = _resourceLimitMgr;
+        this._accountMgr = _accountMgr;
+        this._alertMgr = _alertMgr;
+        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;
@@ -185,8 +218,8 @@ public class DownloadListener implements Listener {
 		this._alertMgr = _alertMgr;
 		updateDatabase(Status.NOT_DOWNLOADED, "");
 	}
-	
-	
+
+
 	public void setCurrState(VMTemplateHostVO.Status currState) {
 		this.currState = getState(currState.toString());
 	}
@@ -198,7 +231,7 @@ public class DownloadListener implements Listener {
 		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);
 	}
@@ -217,7 +250,7 @@ public class DownloadListener implements Listener {
             } catch (AgentUnavailableException e) {
             	s_logger.debug("Send command failed", e);
 				setDisconnected();
-            }			
+            }
 		}
 
 	}
@@ -253,7 +286,7 @@ public class DownloadListener implements Listener {
 			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());
@@ -269,7 +302,15 @@ public class DownloadListener implements Listener {
 		}
 		return templateHostId;
 	}
-	
+
+    private Long getTemplateStoreId() {
+        if (templateStoreId == null){
+            TemplateDataStoreVO templStore = _vmTemplateStoreDao.findByStoreTemplate(sstore.getId(), template.getId());
+            templateStoreId = templStore.getId();
+        }
+        return templateStoreId;
+    }
+
 	private Long getVolumeHostId() {
 		if (volumeHostId == null){
 			VolumeHostVO volHost = volumeHostDao.findByHostVolume(sserver.getId(), volume.getId());
@@ -282,14 +323,14 @@ public class DownloadListener implements Listener {
 	    downloadMonitor = monitor;
 	}
 
-	
+
 
 	@Override
 	public boolean isRecurring() {
 		return false;
 	}
 
-	
+
 	@Override
 	public boolean processAnswers(long agentId, long seq, Answer[] answers) {
 		boolean processed = false;
@@ -307,7 +348,7 @@ public class DownloadListener implements Listener {
     	}
         return processed;
 	}
-	
+
 	private synchronized void transition(DownloadEvent event, Object evtObj) {
 	    if (currState == null) {
 	        return;
@@ -328,7 +369,7 @@ public class DownloadListener implements Listener {
 
 	public synchronized void updateDatabase(DownloadAnswer answer) {
 		if (template != null){
-	        VMTemplateHostVO updateBuilder = vmTemplateHostDao.createForUpdate();
+	        TemplateDataStoreVO updateBuilder = _vmTemplateStoreDao.createForUpdate();
 			updateBuilder.setDownloadPercent(answer.getDownloadPct());
 			updateBuilder.setDownloadState(answer.getDownloadStatus());
 			updateBuilder.setLastUpdated(new Date());
@@ -338,9 +379,9 @@ public class DownloadListener implements Listener {
 			updateBuilder.setInstallPath(answer.getInstallPath());
 			updateBuilder.setSize(answer.getTemplateSize());
 			updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize());
-			
-			vmTemplateHostDao.update(getTemplateHostId(), updateBuilder);
-			
+
+			_vmTemplateStoreDao.update(getTemplateStoreId(), updateBuilder);
+
 			if (answer.getCheckSum() != null) {
 				VMTemplateVO templateDaoBuilder = _vmTemplateDao.createForUpdate();
 				templateDaoBuilder.setChecksum(answer.getCheckSum());
@@ -363,7 +404,14 @@ public class DownloadListener implements Listener {
                             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();
 			updateBuilder.setDownloadPercent(answer.getDownloadPct());
@@ -422,20 +470,21 @@ public class DownloadListener implements Listener {
 		setDisconnected();
 		return true;
 	}
-	
+
 	@Override
 	public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
 	    if (cmd instanceof StartupRoutingCommand) {
 	        downloadMonitor.handleSysTemplateDownload(agent);
 	    } else if ( cmd instanceof StartupStorageCommand) {
 	        StartupStorageCommand storage = (StartupStorageCommand)cmd;
-            if( storage.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE ||  
+            if( storage.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE ||
                     storage.getResourceType() == Storage.StorageResourceType.LOCAL_SECONDARY_STORAGE  ) {
                 downloadMonitor.addSystemVMTemplatesToHost(agent, storage.getTemplateInfo());
-                downloadMonitor.handleTemplateSync(agent);
+                // DO we need to do sync here since we have been doing sync in StartupSecondaryStorageCommand?
+               // downloadMonitor.handleTemplateSync(agent);
                 downloadMonitor.handleVolumeSync(agent);
             }
-	    } else if ( cmd instanceof StartupSecondaryStorageCommand ) {        
+	    } else if ( cmd instanceof StartupSecondaryStorageCommand ) {
 	        downloadMonitor.handleSync(agent.getDataCenterId());
 	    }
 	}
@@ -448,7 +497,7 @@ public class DownloadListener implements Listener {
 		return cmd;
 	}
 
-	
+
 	public void abandon() {
 		transition(DownloadEvent.ABANDON_DOWNLOAD, null);
 	}
@@ -467,7 +516,7 @@ public class DownloadListener implements Listener {
 		statusTask = new StatusTask(this, request);
 		timer.schedule(statusTask, STATUS_POLL_INTERVAL);
 	}
-	
+
 	public void scheduleTimeoutTask(long delay) {
 		if (timeoutTask != null) timeoutTask.cancel();
 
@@ -477,7 +526,7 @@ public class DownloadListener implements Listener {
 			log("Scheduling timeout at " + delay + " ms", Level.DEBUG);
 		}
 	}
-	
+
 	public void scheduleImmediateStatusCheck(RequestType request) {
 		if (statusTask != null) statusTask.cancel();
 		statusTask = new StatusTask(this, request);
@@ -495,7 +544,7 @@ public class DownloadListener implements Listener {
 	public Date getLastUpdated() {
 		return lastUpdated;
 	}
-	
+
 	public void setLastUpdated() {
 		lastUpdated  = new Date();
 	}
@@ -515,12 +564,12 @@ public class DownloadListener implements Listener {
 
 	public void logDownloadStart() {
 	}
-	
+
     @Override
     public boolean processTimeout(long agentId, long seq) {
     	return true;
     }
-    
+
     @Override
     public int getTimeout() {
     	return -1;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02686583/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 897befa..b209733 100644
--- a/server/src/com/cloud/storage/download/DownloadMonitor.java
+++ b/server/src/com/cloud/storage/download/DownloadMonitor.java
@@ -18,6 +18,10 @@ 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;
+
 
 import com.cloud.exception.StorageUnavailableException;
 import com.cloud.host.HostVO;
@@ -32,12 +36,12 @@ import com.cloud.utils.component.Manager;
  *
  */
 public interface DownloadMonitor extends Manager{
-	
-	public boolean downloadTemplateToStorage(VMTemplateVO template, Long zoneId);
-	
+
+	public boolean downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback<CreateCmdResult> callback);
+
 	public void cancelAllDownloads(Long templateId);
 
-	public void handleTemplateSync(HostVO host);
+	public void handleTemplateSync(DataStore store);
 
 	public boolean copyTemplate(VMTemplateVO template, HostVO sourceServer, HostVO destServer)
 			throws StorageUnavailableException;
@@ -50,6 +54,6 @@ public interface DownloadMonitor extends Manager{
 
 	boolean downloadVolumeToStorage(VolumeVO volume, Long zoneId, String url, String checkSum, ImageFormat format);
 
-	void handleVolumeSync(HostVO ssHost);	
+	void handleVolumeSync(HostVO ssHost);
 
 }
\ No newline at end of file