You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ed...@apache.org on 2013/04/22 07:46:42 UTC

[1/2] refactor downloadlistener, sync system vm templates when adding a new image store

Updated Branches:
  refs/heads/object_store 0229c75b5 -> abf40435f


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index ab91059..36fcbb7 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -120,6 +120,7 @@ import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.OperationTimedoutException;
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.exception.StorageUnavailableException;
+import com.cloud.host.Host;
 import com.cloud.host.HostVO;
 import com.cloud.host.Status;
 import com.cloud.host.dao.HostDao;
@@ -3539,7 +3540,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
     }
 
     @Override
-    public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
+    public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
         UserContext context = UserContext.current();
         context.setAccountId(1);
         List<DomainRouterVO> routers = _routerDao.listIsolatedByHostId(host.getId());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/network/security/SecurityGroupListener.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/security/SecurityGroupListener.java b/server/src/com/cloud/network/security/SecurityGroupListener.java
index 3245253..0c101f2 100755
--- a/server/src/com/cloud/network/security/SecurityGroupListener.java
+++ b/server/src/com/cloud/network/security/SecurityGroupListener.java
@@ -38,7 +38,7 @@ import com.cloud.agent.api.StartupRoutingCommand;
 import com.cloud.agent.api.SecurityGroupRuleAnswer.FailureReason;
 import com.cloud.agent.manager.Commands;
 import com.cloud.exception.AgentUnavailableException;
-import com.cloud.host.HostVO;
+import com.cloud.host.Host;
 import com.cloud.host.Status;
 import com.cloud.network.security.SecurityGroupWork.Step;
 import com.cloud.network.security.dao.SecurityGroupWorkDao;
@@ -157,7 +157,7 @@ public class SecurityGroupListener implements Listener {
 
 
     @Override
-    public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) {
+    public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) {
         if(s_logger.isInfoEnabled())
             s_logger.info("Received a host startup notification");
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/storage/LocalStoragePoolListener.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/LocalStoragePoolListener.java b/server/src/com/cloud/storage/LocalStoragePoolListener.java
index 244f7fb..088d601 100755
--- a/server/src/com/cloud/storage/LocalStoragePoolListener.java
+++ b/server/src/com/cloud/storage/LocalStoragePoolListener.java
@@ -32,7 +32,7 @@ import com.cloud.agent.api.StoragePoolInfo;
 import com.cloud.capacity.dao.CapacityDao;
 import com.cloud.dc.dao.DataCenterDao;
 import com.cloud.exception.ConnectionException;
-import com.cloud.host.HostVO;
+import com.cloud.host.Host;
 import com.cloud.host.Status;
 import com.cloud.storage.dao.StoragePoolHostDao;
 import com.cloud.utils.db.DB;
@@ -67,7 +67,7 @@ public class LocalStoragePoolListener implements Listener {
     
     @Override
     @DB
-    public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
+    public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
         if (!(cmd instanceof StartupStorageCommand)) {
             return;
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/storage/download/DownloadAbandonedState.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/download/DownloadAbandonedState.java b/server/src/com/cloud/storage/download/DownloadAbandonedState.java
index 200683c..ef053ce 100644
--- a/server/src/com/cloud/storage/download/DownloadAbandonedState.java
+++ b/server/src/com/cloud/storage/download/DownloadAbandonedState.java
@@ -16,6 +16,7 @@
 // under the License.
 package com.cloud.storage.download;
 
+import com.cloud.agent.api.storage.DownloadAnswer;
 import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType;
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 
@@ -34,7 +35,8 @@ public class DownloadAbandonedState extends DownloadInactiveState {
 	public void onEntry(String prevState, DownloadEvent event, Object evtObj) {
 		super.onEntry(prevState, event, evtObj);
 		if (!prevState.equalsIgnoreCase(getName())){
-			getDownloadListener().updateDatabase(Status.ABANDONED, "Download canceled");
+			DownloadAnswer answer = new DownloadAnswer("Download canceled", Status.ABANDONED);
+			getDownloadListener().callback(answer);
 			getDownloadListener().cancelStatusTask();
 			getDownloadListener().cancelTimeoutTask();
 			getDownloadListener().sendCommand(RequestType.ABORT);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/storage/download/DownloadActiveState.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/download/DownloadActiveState.java b/server/src/com/cloud/storage/download/DownloadActiveState.java
index f2cd5af..09d103e 100644
--- a/server/src/com/cloud/storage/download/DownloadActiveState.java
+++ b/server/src/com/cloud/storage/download/DownloadActiveState.java
@@ -64,7 +64,7 @@ public abstract class DownloadActiveState extends DownloadState {
 		}
 		
 		if (event==DownloadEvent.DOWNLOAD_ANSWER) {
-			getDownloadListener().updateDatabase((DownloadAnswer)evtObj);
+			getDownloadListener().callback((DownloadAnswer)evtObj);
 			getDownloadListener().setLastUpdated();
 		}
 		

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/storage/download/DownloadErrorState.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/download/DownloadErrorState.java b/server/src/com/cloud/storage/download/DownloadErrorState.java
index 0fdfd52..e5c8820 100644
--- a/server/src/com/cloud/storage/download/DownloadErrorState.java
+++ b/server/src/com/cloud/storage/download/DownloadErrorState.java
@@ -76,10 +76,12 @@ public class DownloadErrorState extends DownloadInactiveState {
 			getDownloadListener().logDisconnect();
 			getDownloadListener().cancelStatusTask();
 			getDownloadListener().cancelTimeoutTask();
-			getDownloadListener().updateDatabase(Status.DOWNLOAD_ERROR, "Storage agent or storage VM disconnected");  
+			DownloadAnswer answer = new DownloadAnswer("Storage agent or storage VM disconnected", Status.DOWNLOAD_ERROR);
+			getDownloadListener().callback(answer);  
 			getDownloadListener().log("Entering download error state because the storage host disconnected", Level.WARN);
 		} else if (event==DownloadEvent.TIMEOUT_CHECK){
-			getDownloadListener().updateDatabase(Status.DOWNLOAD_ERROR, "Timeout waiting for response from storage host");
+			DownloadAnswer answer = new DownloadAnswer("Timeout waiting for response from storage host", Status.DOWNLOAD_ERROR);
+			getDownloadListener().callback(answer);
 			getDownloadListener().log("Entering download error state: timeout waiting for response from storage host", Level.WARN);
 		}
 		getDownloadListener().setDownloadInactive(Status.DOWNLOAD_ERROR);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/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 3eb2233..e54e879 100755
--- a/server/src/com/cloud/storage/download/DownloadListener.java
+++ b/server/src/com/cloud/storage/download/DownloadListener.java
@@ -25,17 +25,15 @@ 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.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 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;
 
@@ -47,35 +45,19 @@ import com.cloud.agent.api.Command;
 import com.cloud.agent.api.StartupCommand;
 import com.cloud.agent.api.StartupRoutingCommand;
 import com.cloud.agent.api.StartupSecondaryStorageCommand;
-import com.cloud.agent.api.StartupStorageCommand;
 import com.cloud.agent.api.storage.DownloadAnswer;
 import com.cloud.agent.api.storage.DownloadCommand;
 import com.cloud.agent.api.storage.DownloadCommand.ResourceType;
 import com.cloud.agent.api.storage.DownloadProgressCommand;
 import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType;
-import com.cloud.alert.AlertManager;
 import com.cloud.exception.AgentUnavailableException;
 import com.cloud.exception.ConnectionException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
+import com.cloud.host.Host;
 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;
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.VolumeHostVO;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplateHostDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.dao.VolumeHostDao;
 import com.cloud.storage.download.DownloadState.DownloadEvent;
-import com.cloud.user.AccountManager;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.utils.UriUtils;
 import com.cloud.utils.exception.CloudRuntimeException;
 
 /**
@@ -125,25 +107,11 @@ public class DownloadListener implements Listener {
 	public static final String DOWNLOAD_IN_PROGRESS=Status.DOWNLOAD_IN_PROGRESS.toString();
 	public static final String DOWNLOAD_ABANDONED=Status.ABANDONED.toString();
 
+	private EndPoint _ssAgent;
 
-	private HostVO _sserver;
-	private HostVO _ssAgent;
+	private DataObject object;
 
-	private VMTemplateVO _template;
-	private VolumeVO _volume;
 	private boolean _downloadActive = true;
-
-	private VolumeHostDao _volumeHostDao;
-	private VolumeDataStoreDao _volumeStoreDao;
-	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;
@@ -158,13 +126,7 @@ public class DownloadListener implements Listener {
 	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 Long _volumeStoreId;
-	private AsyncCompletionCallback<CreateCmdResult> _callback;
+	private AsyncCompletionCallback<DownloadAnswer> _callback;
 
     @Inject
     private ResourceManager _resourceMgr;
@@ -175,71 +137,25 @@ public class DownloadListener implements Listener {
     @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;
-		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;
-		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) {
+    public DownloadListener(EndPoint ssAgent, DataStore store, DataObject object, Timer _timer, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, AsyncCompletionCallback<DownloadAnswer> callback) {
         this._ssAgent = ssAgent;
-        this._sstore = store;
-        this._template = template;
-        this._vmTemplateStoreDao = dao;
+        this.object = object;
         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, "");
+        DownloadAnswer answer = new DownloadAnswer("", Status.NOT_DOWNLOADED);
+        callback(answer);
+    }
+    
+    public AsyncCompletionCallback<DownloadAnswer> getCallback() {
+    	return this._callback;
     }
-
-
-	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._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());
@@ -264,7 +180,7 @@ public class DownloadListener implements Listener {
 			}
 			try {
 				DownloadProgressCommand dcmd = new DownloadProgressCommand(getCommand(), getJobId(), reqType);
-				if (_template == null){
+				if (this.object.getType() == DataObjectType.VOLUME) {
 					dcmd.setResourceType(ResourceType.VOLUME);
 				}
 	            _downloadMonitor.send(_ssAgent.getId(), dcmd, this);
@@ -285,59 +201,12 @@ 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());
-		}else {
-			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();
-			vo.setDownloadState(state);
-			vo.setLastUpdated(new Date());
-			vo.setErrorString(errorString);
-			_vmTemplateHostDao.update(getTemplateHostId(), vo);
-		}else {
-		    VolumeHostVO vo = _volumeHostDao.createForUpdate();
-			vo.setDownloadState(state);
-			vo.setLastUpdated(new Date());
-			vo.setErrorString(errorString);
-			_volumeHostDao.update(getVolumeHostId(), vo);
-		}
+			s_logger.warn("Unable to monitor download progress of " + this.object.getType() + ": " + 
+					this.object.getId() + " at host " + _ssAgent.getId());
 	}
 
 	public void log(String message, Level level) {
-		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());
-		}
-	}
-
-	private Long getTemplateHostId() {
-		if (_templateHostId == null){
-			VMTemplateHostVO templHost = _vmTemplateHostDao.findByHostTemplate(_sserver.getId(), _template.getId());
-			_templateHostId = templHost.getId();
-		}
-		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());
-			_volumeHostId = volHost.getId();
-		}
-		return _volumeHostId;
+		s_logger.log(level, message + ", " + this.object.getType() + ": " + this.object.getId() + " at host " + _ssAgent.getId());
 	}
 
 	public DownloadListener(DownloadMonitorImpl monitor) {
@@ -388,112 +257,10 @@ public class DownloadListener implements Listener {
 		}
 	}
 
-	public synchronized void updateDatabase(DownloadAnswer answer) {
-		if (_template != null){
-	        TemplateDataStoreVO updateBuilder = _vmTemplateStoreDao.createForUpdate();
-			updateBuilder.setDownloadPercent(answer.getDownloadPct());
-			updateBuilder.setDownloadState(answer.getDownloadStatus());
-			updateBuilder.setLastUpdated(new Date());
-			updateBuilder.setErrorString(answer.getErrorString());
-			updateBuilder.setJobId(answer.getJobId());
-			updateBuilder.setLocalDownloadPath(answer.getDownloadPath());
-			updateBuilder.setInstallPath(answer.getInstallPath());
-			updateBuilder.setSize(answer.getTemplateSize());
-			updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize());
-
-            // 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);
-			}
-
-            if (answer.getTemplateSize() > 0) {
-                //long hostId = vmTemplateHostDao.findByTemplateId(template.getId()).getHostId();
-                long accountId = _template.getAccountId();
-                try {
-                    _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(accountId),
-                            com.cloud.configuration.Resource.ResourceType.secondary_storage,
-                            answer.getTemplateSize() - UriUtils.getRemoteSize(_template.getUrl()));
-                } catch (ResourceAllocationException e) {
-                    s_logger.warn(e.getMessage());
-                    _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());
-                }
-            }
-
-		} else {
-	        VolumeHostVO updateBuilder = _volumeHostDao.createForUpdate();
-			updateBuilder.setDownloadPercent(answer.getDownloadPct());
-			updateBuilder.setDownloadState(answer.getDownloadStatus());
-			updateBuilder.setLastUpdated(new Date());
-			updateBuilder.setErrorString(answer.getErrorString());
-			updateBuilder.setJobId(answer.getJobId());
-			updateBuilder.setLocalDownloadPath(answer.getDownloadPath());
-			updateBuilder.setInstallPath(answer.getInstallPath());
-			updateBuilder.setSize(answer.getTemplateSize());
-			updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize());
-
-			_volumeHostDao.update(getVolumeHostId(), updateBuilder);
-
-			// Update volume size in Volume table.
-			VolumeVO updateVolume = _volumeDao.createForUpdate();
-			updateVolume.setSize(answer.getTemplateSize());
-			_volumeDao.update(_volume.getId(), updateVolume);
-
-            if (answer.getTemplateSize() > 0) {
-                try {
-                    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());
-                } finally {
-                    _resourceLimitMgr.recalculateResourceCount(_volume.getAccountId(), _volume.getDomainId(),
-                            com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
-                }
-            }
-
-			/*if (answer.getCheckSum() != null) {
-				VMTemplateVO templateDaoBuilder = _vmTemplateDao.createForUpdate();
-				templateDaoBuilder.setChecksum(answer.getCheckSum());
-				_vmTemplateDao.update(template.getId(), templateDaoBuilder);
-			}*/
-		}
- 	}
-
+	public void callback(DownloadAnswer answer) {
+		this._callback.complete(answer);
+	}
+	
 	@Override
 	public boolean processCommands(long agentId, long seq, Command[] req) {
 		return false;
@@ -511,7 +278,7 @@ public class DownloadListener implements Listener {
 	}
 
 	@Override
-	public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
+	public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
 	    if (cmd instanceof StartupRoutingCommand) {
 	        List<HypervisorType> hypers = _resourceMgr.listAvailHypervisorInZone(agent.getId(), agent.getDataCenterId());
 	        HypervisorType hostHyper = agent.getHypervisorType();
@@ -601,11 +368,6 @@ public class DownloadListener implements Listener {
 
 	public void setDownloadInactive(Status reason) {
 		_downloadActive=false;
-		if (_template != null){
-			_downloadMonitor.handleDownloadEvent(_sserver, _template, reason);
-		}else {
-			_downloadMonitor.handleDownloadEvent(_sserver, _volume, reason);
-		}
 	}
 
 	public void cancelTimeoutTask() {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/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 efbdbe2..7bc210f 100644
--- a/server/src/com/cloud/storage/download/DownloadMonitor.java
+++ b/server/src/com/cloud/storage/download/DownloadMonitor.java
@@ -16,15 +16,15 @@
 // under the License.
 package com.cloud.storage.download;
 
-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.framework.async.AsyncCompletionCallback;
 
-
+import com.cloud.agent.api.storage.DownloadAnswer;
 import com.cloud.exception.StorageUnavailableException;
+import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.VolumeVO;
-import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.utils.component.Manager;
 
 /**
@@ -34,19 +34,15 @@ import com.cloud.utils.component.Manager;
 public interface DownloadMonitor extends Manager{
 
     // when ssvm is not available yet
-    public void downloadBootstrapSysTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback<CreateCmdResult> callback);
-
-    public void downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback<CreateCmdResult> callback);
-
-	public void cancelAllDownloads(Long templateId);
+    public void downloadBootstrapSysTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback<DownloadAnswer> callback);
 
-	public boolean copyTemplate(VMTemplateVO template, DataStore sourceStore, DataStore Store)
-			throws StorageUnavailableException;
+    public void downloadTemplateToStorage(DataObject template, DataStore store, AsyncCompletionCallback<DownloadAnswer> callback);
 
-    //void addSystemVMTemplatesToHost(HostVO host, Map<String, TemplateProp> templateInfos);
+	//public void cancelAllDownloads(Long templateId);
 
-	//public boolean downloadVolumeToStorage(VolumeVO volume, Long zoneId, String url, String checkSum, ImageFormat format);
+	//public boolean copyTemplate(VMTemplateVO template, DataStore sourceStore, DataStore Store)
+	//		throws StorageUnavailableException;
 
-	public void downloadVolumeToStorage(VolumeVO volume, DataStore store, String url, String checkSum, ImageFormat format, AsyncCompletionCallback<CreateCmdResult> callback);
+	public void downloadVolumeToStorage(DataObject volume, DataStore store, String url, String checkSum, ImageFormat format, AsyncCompletionCallback<DownloadAnswer> callback);
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/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 c7b360a..b72c202 100755
--- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
+++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
@@ -27,14 +27,14 @@ import java.util.concurrent.ConcurrentHashMap;
 import javax.ejb.Local;
 import javax.inject.Inject;
 
-import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
 import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
 import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
@@ -45,55 +45,35 @@ import org.springframework.stereotype.Component;
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.Listener;
 import com.cloud.agent.api.Command;
-
+import com.cloud.agent.api.storage.DownloadAnswer;
 import com.cloud.agent.api.storage.DownloadCommand;
-
 import com.cloud.agent.api.storage.DownloadCommand.Proxy;
 import com.cloud.agent.api.storage.DownloadCommand.ResourceType;
+import com.cloud.agent.api.storage.DownloadProgressCommand;
 import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType;
 import com.cloud.agent.api.storage.DownloadSystemTemplateCommand;
-
-import com.cloud.agent.api.storage.DownloadProgressCommand;
 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.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.event.EventTypes;
-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.StorageUnavailableException;
 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.ImageFormat;
-
 import com.cloud.storage.StorageManager;
 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.VMTemplateVO;
+import com.cloud.storage.Volume;
 import com.cloud.storage.VolumeHostVO;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.SwiftDao;
 import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplateHostDao;
-import com.cloud.storage.dao.VMTemplatePoolDao;
-import com.cloud.storage.dao.VMTemplateSwiftDao;
-import com.cloud.storage.dao.VMTemplateZoneDao;
 import com.cloud.storage.dao.VolumeDao;
 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.template.TemplateManager;
-import com.cloud.user.Account;
+import com.cloud.template.VirtualMachineTemplate;
 import com.cloud.user.AccountManager;
 import com.cloud.user.ResourceLimitService;
 import com.cloud.utils.component.ManagerBase;
@@ -101,37 +81,17 @@ import com.cloud.utils.db.DB;
 import com.cloud.utils.db.JoinBuilder;
 import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.SecondaryStorageVm;
-import com.cloud.vm.SecondaryStorageVmVO;
 import com.cloud.vm.UserVmManager;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.dao.SecondaryStorageVmDao;
 import com.cloud.vm.dao.UserVmDao;
 
-import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-
 @Component
 @Local(value = { DownloadMonitor.class })
 public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor {
     static final Logger s_logger = Logger.getLogger(DownloadMonitorImpl.class);
 
     @Inject
-    VMTemplateHostDao _vmTemplateHostDao;
-    @Inject
     TemplateDataStoreDao _vmTemplateStoreDao;
     @Inject
-    VMTemplateZoneDao _vmTemplateZoneDao;
-    @Inject
-    VMTemplatePoolDao _vmTemplatePoolDao;
-    @Inject
-    VMTemplateSwiftDao _vmTemplateSwiftlDao;
-    @Inject
-    StoragePoolHostDao _poolHostDao;
-    @Inject
-    SecondaryStorageVmDao _secStorageVmDao;
-    @Inject
     ImageStoreDao _imageStoreDao;
     @Inject
     VolumeDao _volumeDao;
@@ -147,9 +107,6 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
     SecondaryStorageVmManager _ssvmMgr;
     @Inject
     StorageManager _storageMgr;
-
-    @Inject
-    private final DataCenterDao _dcDao = null;
     @Inject
     VMTemplateDao _templateDao = null;
     @Inject
@@ -165,17 +122,6 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
     TemplateManager templateMgr;
 
     @Inject
-    private UsageEventDao _usageEventDao;
-
-    @Inject
-    private ClusterDao _clusterDao;
-    @Inject
-    private HostDao _hostDao;
-    @Inject
-    private ResourceManager _resourceMgr;
-    @Inject
-    private SwiftDao _swiftDao;
-    @Inject
     protected ResourceLimitService _resourceLimitMgr;
     @Inject
     protected UserVmDao _userVmDao;
@@ -254,6 +200,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
     }
 
     // TODO: consider using dataMotionStrategy later
+    /*
     @Override
     public boolean copyTemplate(VMTemplateVO template, DataStore sourceStore, DataStore destStore) throws StorageUnavailableException {
 
@@ -363,15 +310,15 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
 
         VMTemplateVO tmplt = _templateDao.findById(srcTmpltStore.getTemplateId());
         HypervisorType hyperType = tmplt.getHypervisorType();
-        /*No secondary storage vm yet*/
+        
         if (hyperType != null && hyperType == HypervisorType.KVM) {
             //return "file://" + sourceServer.getParent() + "/" + srcTmpltStore.getInstallPath();
             return "file://"  + "/" + srcTmpltStore.getInstallPath();
         }
         return null;
-    }
+    }*/
 
-    private void initiateTemplateDownload(VMTemplateVO template, DataStore store, AsyncCompletionCallback<CreateCmdResult> callback) {
+    private void initiateTemplateDownload(DataObject template, DataStore store, AsyncCompletionCallback<DownloadAnswer> callback) {
         boolean downloadJobExists = false;
         TemplateDataStoreVO vmTemplateStore = null;
 
@@ -380,7 +327,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
             // 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());
+                    VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, template.getUri());
             _vmTemplateStoreDao.persist(vmTemplateStore);
         } else if ((vmTemplateStore.getJobId() != null) && (vmTemplateStore.getJobId().length() > 2)) {
             downloadJobExists = true;
@@ -390,7 +337,8 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
         String secUrl = store.getUri();
         if (vmTemplateStore != null) {
             start();
-            DownloadCommand dcmd = new DownloadCommand(store.getTO(), secUrl, template, maxTemplateSizeInBytes);
+            VirtualMachineTemplate tmpl = this._templateDao.findById(template.getId());
+            DownloadCommand dcmd = new DownloadCommand(store.getTO(), secUrl, tmpl, maxTemplateSizeInBytes);
             dcmd.setProxy(getHttpProxy());
             if (downloadJobExists) {
                 dcmd = new DownloadProgressCommand(dcmd, vmTemplateStore.getJobId(), RequestType.GET_OR_RESTART);
@@ -398,13 +346,13 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
             if (vmTemplateStore.isCopy()) {
                 dcmd.setCreds(TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd);
             }
-            HostVO ssAhost = _ssvmMgr.pickSsvmHost(store);
-            if (ssAhost == null) {
+            EndPoint ep = _epSelector.select(template);
+            if (ep == null) {
                 s_logger.warn("There is no secondary storage VM for downloading template to image store " + store.getName());
                 return;
             }
-            DownloadListener dl = new DownloadListener(ssAhost, store, template, _timer, _vmTemplateStoreDao, vmTemplateStore.getId(), this, dcmd,
-                    _templateDao, _resourceLimitMgr, _alertMgr, _accountMgr, callback);
+            DownloadListener dl = new DownloadListener(ep, store, template, _timer, this, dcmd,
+                     callback);
             if (downloadJobExists) {
                 // due to handling existing download job issues, we still keep
                 // downloadState in template_store_ref to avoid big change in
@@ -422,9 +370,9 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
             }
 
             try {
-                send(ssAhost.getId(), dcmd, dl);
-            } catch (AgentUnavailableException e) {
-                s_logger.warn("Unable to start /resume download of template " + template.getUniqueName() + " to " + store.getName(), e);
+                ep.sendMessageAsyncWithListener(dcmd, dl);
+            } catch (Exception e) {
+                s_logger.warn("Unable to start /resume download of template " + template.getId() + " to " + store.getName(), e);
                 dl.setDisconnected();
                 dl.scheduleStatusCheck(RequestType.GET_OR_RESTART);
             }
@@ -433,7 +381,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
 
 
     @Override
-    public void downloadBootstrapSysTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback<CreateCmdResult> callback) {
+    public void downloadBootstrapSysTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback<DownloadAnswer> callback) {
         boolean downloadJobExists = false;
         TemplateDataStoreVO vmTemplateStore = null;
 
@@ -495,18 +443,18 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
     }
 
     @Override
-    public void downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback<CreateCmdResult> callback) {
+    public void downloadTemplateToStorage(DataObject template, DataStore store, AsyncCompletionCallback<DownloadAnswer> callback) {
         long templateId = template.getId();
         if (isTemplateUpdateable(templateId, store.getId())) {
-            if (template != null && template.getUrl() != null) {
+            if (template != null && template.getUri() != null) {
                 initiateTemplateDownload(template, store, callback);
             }
         }
     }
 
     @Override
-    public void downloadVolumeToStorage(VolumeVO volume, DataStore store, String url, String checkSum, ImageFormat format,
-            AsyncCompletionCallback<CreateCmdResult> callback) {
+    public void downloadVolumeToStorage(DataObject volume, DataStore store, String url, String checkSum, ImageFormat format,
+            AsyncCompletionCallback<DownloadAnswer> callback) {
         boolean downloadJobExists = false;
         VolumeDataStoreVO volumeHost = null;
 
@@ -523,20 +471,20 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
         String secUrl = store.getUri();
         if (volumeHost != null) {
             start();
-            DownloadCommand dcmd = new DownloadCommand(secUrl, volume, maxVolumeSizeInBytes, checkSum, url, format);
+            Volume vol = this._volumeDao.findById(volume.getId());
+            DownloadCommand dcmd = new DownloadCommand(secUrl, vol, maxVolumeSizeInBytes, checkSum, url, format);
             dcmd.setProxy(getHttpProxy());
             if (downloadJobExists) {
                 dcmd = new DownloadProgressCommand(dcmd, volumeHost.getJobId(), RequestType.GET_OR_RESTART);
                 dcmd.setResourceType(ResourceType.VOLUME);
             }
 
-            HostVO ssAhost = _ssvmMgr.pickSsvmHost(store);
-            if (ssAhost == null) {
+            EndPoint ep = this._epSelector.select(volume);
+            if (ep == null) {
                 s_logger.warn("There is no secondary storage VM for image store " + store.getName());
                 return;
             }
-            DownloadListener dl = new DownloadListener(ssAhost, store, volume, _timer, _volumeStoreDao, volumeHost.getId(), this, dcmd, _volumeDao,
-                    _storageMgr, _resourceLimitMgr, _alertMgr, _accountMgr, callback);
+            DownloadListener dl = new DownloadListener(ep, store, volume, _timer, this, dcmd, callback);
 
             if (downloadJobExists) {
                 dl.setCurrState(volumeHost.getDownloadState());
@@ -550,59 +498,26 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
             }
 
             try {
-                send(ssAhost.getId(), dcmd, dl);
-            } catch (AgentUnavailableException e) {
-                s_logger.warn("Unable to start /resume download of volume " + volume.getName() + " to " + store.getName(), e);
+                ep.sendMessageAsyncWithListener(dcmd, dl);
+            } catch (Exception e) {
+                s_logger.warn("Unable to start /resume download of volume " + volume.getId() + " to " + store.getName(), e);
                 dl.setDisconnected();
                 dl.scheduleStatusCheck(RequestType.GET_OR_RESTART);
             }
         }
     }
 
-    @DB
-    public void handleDownloadEvent(HostVO host, VMTemplateVO template, Status dnldStatus) {
-        if ((dnldStatus == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) || (dnldStatus == Status.ABANDONED)) {
-            VMTemplateHostVO vmTemplateHost = new VMTemplateHostVO(host.getId(), template.getId());
-            synchronized (_listenerMap) {
-                _listenerMap.remove(vmTemplateHost);
-            }
-        }
-
-        VMTemplateHostVO vmTemplateHost = _vmTemplateHostDao.findByHostTemplate(host.getId(), template.getId());
-
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-
-        if (dnldStatus == Status.DOWNLOADED) {
-            long size = -1;
-            if (vmTemplateHost != null) {
-                size = vmTemplateHost.getPhysicalSize();
-                template.setSize(size);
-                this._templateDao.update(template.getId(), template);
-            } else {
-                s_logger.warn("Failed to get size for template" + template.getName());
-            }
-            String eventType = EventTypes.EVENT_TEMPLATE_CREATE;
-            if ((template.getFormat()).equals(ImageFormat.ISO)) {
-                eventType = EventTypes.EVENT_ISO_CREATE;
-            }
-            if (template.getAccountId() != Account.ACCOUNT_ID_SYSTEM) {
-                UsageEventUtils.publishUsageEvent(eventType, template.getAccountId(), host.getDataCenterId(), template.getId(), template.getName(),
-                        null, template.getSourceTemplateId(), size, template.getClass().getName(), template.getUuid());
-            }
-        }
-        txn.commit();
-    }
 
     @DB
-    public void handleDownloadEvent(HostVO host, VolumeVO volume, Status dnldStatus) {
-        if ((dnldStatus == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) || (dnldStatus == Status.ABANDONED)) {
+    public void handleDownloadEvent(HostVO host, DataObject object, Status dnldStatus) {
+       /* if ((dnldStatus == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) || (dnldStatus == Status.ABANDONED)) {
             VolumeHostVO volumeHost = new VolumeHostVO(host.getId(), volume.getId());
             synchronized (_listenerVolumeMap) {
                 _listenerVolumeMap.remove(volumeHost);
             }
-        }
+        }*/
 
+        /*
         VolumeHostVO volumeHost = _volumeHostDao.findByHostVolume(host.getId(), volume.getId());
 
         Transaction txn = Transaction.currentTxn();
@@ -631,6 +546,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
                     com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
         }
         txn.commit();
+        */
     }
 
     /*
@@ -657,7 +573,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
     }
     */
 
-    @Override
+    /*@Override
     public void cancelAllDownloads(Long templateId) {
         List<VMTemplateHostVO> downloadsInProgress = _vmTemplateHostDao.listByTemplateStates(templateId,
                 VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS, VMTemplateHostVO.Status.NOT_DOWNLOADED);
@@ -673,7 +589,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
                 }
             }
         }
-    }
+    }*/
 
     /*
     private void checksumSync(long hostId){

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/storage/download/DownloadState.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/download/DownloadState.java b/server/src/com/cloud/storage/download/DownloadState.java
index 471ab61..9d404f0 100644
--- a/server/src/com/cloud/storage/download/DownloadState.java
+++ b/server/src/com/cloud/storage/download/DownloadState.java
@@ -62,7 +62,7 @@ public abstract class DownloadState {
 			getDownloadListener().log("onEntry, event type=" + event + ", curr state=" + getName(), Level.TRACE);
 		}
 		if (event==DownloadEvent.DOWNLOAD_ANSWER) {
-			getDownloadListener().updateDatabase((DownloadAnswer)evtObj);
+			getDownloadListener().callback((DownloadAnswer)evtObj);
 		}
 	}
 	

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
index e035fd7..8c89440 100755
--- a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
+++ b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
@@ -32,7 +32,7 @@ import com.cloud.agent.api.Command;
 import com.cloud.agent.api.StartupCommand;
 import com.cloud.agent.api.StartupRoutingCommand;
 import com.cloud.exception.ConnectionException;
-import com.cloud.host.HostVO;
+import com.cloud.host.Host;
 import com.cloud.host.Status;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.storage.OCFS2Manager;
@@ -71,7 +71,7 @@ public class StoragePoolMonitor implements Listener {
     }
 
     @Override
-    public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
+    public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
         if (cmd instanceof StartupRoutingCommand) {
             StartupRoutingCommand scCmd = (StartupRoutingCommand)cmd;
             if (scCmd.getHypervisorType() == HypervisorType.XenServer || scCmd.getHypervisorType() ==  HypervisorType.KVM ||

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/storage/listener/StorageSyncListener.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/listener/StorageSyncListener.java b/server/src/com/cloud/storage/listener/StorageSyncListener.java
index d9282a3..5b7c7f7 100755
--- a/server/src/com/cloud/storage/listener/StorageSyncListener.java
+++ b/server/src/com/cloud/storage/listener/StorageSyncListener.java
@@ -24,7 +24,7 @@ import com.cloud.agent.api.AgentControlCommand;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.Command;
 import com.cloud.agent.api.StartupCommand;
-import com.cloud.host.HostVO;
+import com.cloud.host.Host;
 import com.cloud.host.Status;
 
 public class StorageSyncListener implements Listener {
@@ -51,7 +51,7 @@ public class StorageSyncListener implements Listener {
     }
     
     @Override
-    public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) {
+    public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) {
     }
     
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java b/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java
index 6635b3c..d524f29 100755
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java
+++ b/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java
@@ -27,7 +27,7 @@ import com.cloud.agent.api.Command;
 import com.cloud.agent.api.StartupCommand;
 import com.cloud.agent.api.StartupSecondaryStorageCommand;
 import com.cloud.agent.api.StartupStorageCommand;
-import com.cloud.host.HostVO;
+import com.cloud.host.Host;
 import com.cloud.host.Status;
 import com.cloud.storage.Storage;
 
@@ -68,7 +68,7 @@ public class SecondaryStorageListener implements Listener {
     }
 
     @Override
-    public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) {
+    public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) {
         if ((cmd instanceof StartupStorageCommand) ) {
             StartupStorageCommand scmd = (StartupStorageCommand)cmd;
             if (scmd.getResourceType() ==  Storage.StorageResourceType.SECONDARY_STORAGE ) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/storage/upload/UploadListener.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/upload/UploadListener.java b/server/src/com/cloud/storage/upload/UploadListener.java
index ee13cf9..891610f 100755
--- a/server/src/com/cloud/storage/upload/UploadListener.java
+++ b/server/src/com/cloud/storage/upload/UploadListener.java
@@ -47,6 +47,7 @@ import com.cloud.api.ApiDBUtils;
 import com.cloud.async.AsyncJobManager;
 import com.cloud.async.AsyncJobResult;
 import com.cloud.exception.AgentUnavailableException;
+import com.cloud.host.Host;
 import com.cloud.host.HostVO;
 import com.cloud.storage.Storage;
 import com.cloud.storage.Upload.Status;
@@ -248,7 +249,7 @@ public class UploadListener implements Listener {
 	}
 
 	@Override
-	public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) {
+	public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) {
 		if (!(cmd instanceof StartupStorageCommand)) {
 	        return;
 	    }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/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 34efdcb..cb0bee9 100755
--- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java
+++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java
@@ -35,16 +35,21 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult;
 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.TemplateDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
 import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult;
 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.db.TemplateDataStoreVO;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.storage.DeleteTemplateCommand;
+import com.cloud.alert.AlertManager;
 import com.cloud.configuration.Resource.ResourceType;
 import com.cloud.dc.DataCenterVO;
 import com.cloud.event.EventTypes;
@@ -80,6 +85,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te
     @Inject TemplateService imageService;
     @Inject TemplateDataFactory imageFactory;
     @Inject TemplateManager templateMgr;
+    @Inject AlertManager alertMgr;
 
     @Override
     public String getName() {
@@ -181,23 +187,37 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te
 		    throw new CloudRuntimeException("Unable to find image store to download template "+ profile.getTemplate());
 		}
         for (DataStore imageStore : imageStores) {
-            AsyncCallFuture<TemplateApiResult> future = this.imageService
-                    .createTemplateAsync(this.imageFactory.getTemplate(template.getId(), imageStore), imageStore);
-            try {
-                future.get();
-            } catch (InterruptedException e) {
-                s_logger.debug("create template Failed", e);
-                throw new CloudRuntimeException("create template Failed", e);
-            } catch (ExecutionException e) {
-                s_logger.debug("create template Failed", e);
-                throw new CloudRuntimeException("create template Failed", e);
-            }
+        	TemplateInfo tmpl = this.imageFactory.getTemplate(template.getId(), imageStore);
+        	CreateTemplateContext<TemplateApiResult> context = new CreateTemplateContext<TemplateApiResult>(null, tmpl);
+        	AsyncCallbackDispatcher<HypervisorTemplateAdapter, TemplateApiResult> caller = AsyncCallbackDispatcher.create(this);
+        	caller.setCallback(this.createTemplateAsyncCallBack(null, null));
+        	caller.setContext(context);
+           this.imageService
+                    .createTemplateAsync(tmpl, imageStore, caller);
         }
         _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
-        _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.secondary_storage,
-                UriUtils.getRemoteSize(profile.getUrl()));
+       
         return template;
     }
+	
+	private class CreateTemplateContext<T> extends AsyncRpcConext<T> {
+		final TemplateInfo template;
+		public CreateTemplateContext(AsyncCompletionCallback<T> callback, TemplateInfo template) {
+			super(callback);
+			this.template = template;
+		}
+	}
+	
+	protected Void createTemplateAsyncCallBack(AsyncCallbackDispatcher<HypervisorTemplateAdapter, 
+			TemplateApiResult> callback, CreateTemplateContext<TemplateApiResult> context) {
+		TemplateInfo template = context.template;
+		VMTemplateVO tmplt = this._tmpltDao.findById(template.getId());
+		long accountId = tmplt.getAccountId();
+		_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.secondary_storage,
+		              	template.getSize());
+		
+		return null;
+	}
 
 	@Override @DB
 	public boolean delete(TemplateProfile profile) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
index af22716..ea20dd5 100755
--- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -2285,7 +2285,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     }
 
     @Override
-    public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
+    public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
         if (!(cmd instanceof StartupRoutingCommand)) {
             return;
         }


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

Posted by ed...@apache.org.
refactor downloadlistener, sync system vm templates when adding a new image store


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

Branch: refs/heads/object_store
Commit: abf40435f3cb1d72535eb15067348e4c9253340d
Parents: 0229c75
Author: Edison Su <ed...@citrix.com>
Authored: Sun Apr 21 22:46:02 2013 -0700
Committer: Edison Su <ed...@citrix.com>
Committed: Sun Apr 21 22:46:02 2013 -0700

----------------------------------------------------------------------
 api/src/com/cloud/agent/Listener.java              |  119 ++++++
 core/src/com/cloud/agent/Listener.java             |  119 ------
 .../engine/subsystem/api/storage/EndPoint.java     |    2 +
 .../subsystem/api/storage/TemplateService.java     |    3 +-
 .../allocator/StorageCacheRandomAllocator.java     |    2 +
 .../cache/manager/StorageCacheManagerImpl.java     |   23 +-
 .../storage/image/TemplateServiceImpl.java         |   73 ++---
 .../storage/image/store/TemplateObject.java        |   31 ++-
 .../cloudstack/storage/test/volumeServiceTest.java |    4 +-
 .../cloudstack/storage/LocalHostEndpoint.java      |   48 +++-
 .../cloudstack/storage/RemoteHostEndPoint.java     |   49 +++-
 .../datastore/ObjectInDataStoreManager.java        |    1 -
 .../datastore/ObjectInDataStoreManagerImpl.java    |   35 +--
 .../cloudstack/storage/volume/VolumeObject.java    |    2 +-
 .../storage/volume/VolumeServiceImpl.java          |    9 +-
 .../com/cloud/resource/SimulatorDiscoverer.java    |    3 +-
 .../resource/SimulatorSecondaryDiscoverer.java     |    3 +-
 .../vmware/manager/VmwareManagerImpl.java          |    3 +-
 .../xen/discoverer/XcpServerDiscoverer.java        |    2 +-
 .../driver/CloudStackImageStoreDriverImpl.java     |   67 +++-
 .../datastore/driver/S3ImageStoreDriverImpl.java   |    6 +-
 .../driver/SwiftImageStoreDriverImpl.java          |    6 +-
 server/pom.xml                                     |    5 +
 .../src/com/cloud/agent/manager/AgentMonitor.java  |    2 +-
 .../cloud/agent/manager/SynchronousListener.java   |    4 +-
 server/src/com/cloud/capacity/CapacityManager.java |    3 +-
 .../com/cloud/capacity/CapacityManagerImpl.java    |   13 +-
 .../cloud/capacity/ComputeCapacityListener.java    |    4 +-
 .../cloud/capacity/StorageCapacityListener.java    |    4 +-
 .../AgentBasedConsoleProxyManager.java             |    4 +-
 server/src/com/cloud/consoleproxy/AgentHook.java   |    4 +-
 .../cloud/consoleproxy/ConsoleProxyListener.java   |    4 +-
 .../cloud/consoleproxy/ConsoleProxyManager.java    |    4 +-
 .../consoleproxy/ConsoleProxyManagerImpl.java      |    2 +-
 .../kvm/discoverer/LibvirtServerDiscoverer.java    |    2 +-
 .../src/com/cloud/network/NetworkManagerImpl.java  |    3 +-
 .../com/cloud/network/NetworkUsageManagerImpl.java |    2 +-
 .../com/cloud/network/SshKeysDistriMonitor.java    |    4 +-
 .../router/VirtualNetworkApplianceManagerImpl.java |    3 +-
 .../network/security/SecurityGroupListener.java    |    4 +-
 .../cloud/storage/LocalStoragePoolListener.java    |    4 +-
 .../storage/download/DownloadAbandonedState.java   |    4 +-
 .../storage/download/DownloadActiveState.java      |    2 +-
 .../cloud/storage/download/DownloadErrorState.java |    6 +-
 .../cloud/storage/download/DownloadListener.java   |  286 ++-------------
 .../cloud/storage/download/DownloadMonitor.java    |   22 +-
 .../storage/download/DownloadMonitorImpl.java      |  166 ++-------
 .../com/cloud/storage/download/DownloadState.java  |    2 +-
 .../cloud/storage/listener/StoragePoolMonitor.java |    4 +-
 .../storage/listener/StorageSyncListener.java      |    4 +-
 .../secondary/SecondaryStorageListener.java        |    4 +-
 .../com/cloud/storage/upload/UploadListener.java   |    3 +-
 .../cloud/template/HypervisorTemplateAdapter.java  |   46 ++-
 .../com/cloud/vm/VirtualMachineManagerImpl.java    |    2 +-
 54 files changed, 535 insertions(+), 701 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/api/src/com/cloud/agent/Listener.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/Listener.java b/api/src/com/cloud/agent/Listener.java
new file mode 100755
index 0000000..3b825bd
--- /dev/null
+++ b/api/src/com/cloud/agent/Listener.java
@@ -0,0 +1,119 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.agent;
+
+import com.cloud.agent.api.AgentControlAnswer;
+import com.cloud.agent.api.AgentControlCommand;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.exception.ConnectionException;
+import com.cloud.host.Host;
+import com.cloud.host.Status;
+
+/**
+ * There are several types of events that the AgentManager forwards
+ * 
+ *   1. Agent Connect & Disconnect
+ *   2. Commands sent by the agent.
+ *   3. Answers sent by the agent.
+ */
+public interface Listener {
+
+	/**
+	 * 
+	 * @param agentId id of the agent
+	 * @param seq sequence number return by the send() method.
+	 * @param answers answers to the commands.
+	 * @return true if processed.  false if not.
+	 */
+    boolean processAnswers(long agentId, long seq, Answer[] answers);
+
+    /**
+     * This method is called by the AgentManager when an agent sent
+     * a command to the server.  In order to process these commands,
+     * the Listener must be registered for host commands.
+     * 
+     * @param agentId id of the agent.
+     * @param seq sequence number of the command sent.
+     * @param commands commands that were sent.
+     * @return true if you processed the commands.  false if not.
+     */
+    boolean processCommands(long agentId, long seq, Command[] commands);
+    
+    /**
+     * process control command sent from agent under its management
+     * @param agentId
+     * @param cmd
+     * @return
+     */
+    AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd);
+
+    /**
+     * This method is called by AgentManager when an agent made a
+     * connection to this server if the listener has
+     * been registered for host events.
+     * @param cmd command sent by the agent to the server on startup.
+     * @param forRebalance TODO
+     * @param agentId id of the agent
+     * @throws ConnectionException if host has problems and needs to put into maintenance state.
+     */
+    void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException;
+    
+    /**
+     * This method is called by AgentManager when an agent disconnects
+     * from this server if the listener has been registered for host events.
+     * 
+     * If the Listener is passed to the send() method, this method is
+     * also called by AgentManager if the agent disconnected.
+     * 
+     * @param agentId id of the agent
+     * @param state the current state of the agent.
+     */
+    boolean processDisconnect(long agentId, Status state);
+        
+    /**
+     * If this Listener is passed to the send() method, this method
+     * is called by AgentManager after processing an answer
+     * from the agent.  Returning true means you're expecting more
+     * answers from the agent using the same sequence number.
+     * 
+     * @return true if expecting more answers using the same sequence number.
+     */
+    boolean isRecurring();
+
+    /**
+     * If the Listener is passed to the send() method, this method is
+     * called to determine how long to wait for the reply.  The value
+     * is in seconds.  -1 indicates to wait forever.  0 indicates to
+     * use the default timeout.  If the timeout is
+     * reached, processTimeout on this same Listener is called.
+     * 
+     * @return timeout in seconds before processTimeout is called.
+     */
+    int getTimeout();
+
+    /**
+     * If the Listener is passed to the send() method, this method is
+     * called by the AgentManager to process a command timeout.
+     * @param agentId id of the agent
+     * @param seq sequence number returned by the send().
+     * @return true if processed; false if not.
+     */
+    boolean processTimeout(long agentId, long seq);
+  
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/core/src/com/cloud/agent/Listener.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/Listener.java b/core/src/com/cloud/agent/Listener.java
deleted file mode 100755
index 47b9bc3..0000000
--- a/core/src/com/cloud/agent/Listener.java
+++ /dev/null
@@ -1,119 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.agent;
-
-import com.cloud.agent.api.AgentControlAnswer;
-import com.cloud.agent.api.AgentControlCommand;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.exception.ConnectionException;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-
-/**
- * There are several types of events that the AgentManager forwards
- * 
- *   1. Agent Connect & Disconnect
- *   2. Commands sent by the agent.
- *   3. Answers sent by the agent.
- */
-public interface Listener {
-
-	/**
-	 * 
-	 * @param agentId id of the agent
-	 * @param seq sequence number return by the send() method.
-	 * @param answers answers to the commands.
-	 * @return true if processed.  false if not.
-	 */
-    boolean processAnswers(long agentId, long seq, Answer[] answers);
-
-    /**
-     * This method is called by the AgentManager when an agent sent
-     * a command to the server.  In order to process these commands,
-     * the Listener must be registered for host commands.
-     * 
-     * @param agentId id of the agent.
-     * @param seq sequence number of the command sent.
-     * @param commands commands that were sent.
-     * @return true if you processed the commands.  false if not.
-     */
-    boolean processCommands(long agentId, long seq, Command[] commands);
-    
-    /**
-     * process control command sent from agent under its management
-     * @param agentId
-     * @param cmd
-     * @return
-     */
-    AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd);
-
-    /**
-     * This method is called by AgentManager when an agent made a
-     * connection to this server if the listener has
-     * been registered for host events.
-     * @param cmd command sent by the agent to the server on startup.
-     * @param forRebalance TODO
-     * @param agentId id of the agent
-     * @throws ConnectionException if host has problems and needs to put into maintenance state.
-     */
-    void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException;
-    
-    /**
-     * This method is called by AgentManager when an agent disconnects
-     * from this server if the listener has been registered for host events.
-     * 
-     * If the Listener is passed to the send() method, this method is
-     * also called by AgentManager if the agent disconnected.
-     * 
-     * @param agentId id of the agent
-     * @param state the current state of the agent.
-     */
-    boolean processDisconnect(long agentId, Status state);
-        
-    /**
-     * If this Listener is passed to the send() method, this method
-     * is called by AgentManager after processing an answer
-     * from the agent.  Returning true means you're expecting more
-     * answers from the agent using the same sequence number.
-     * 
-     * @return true if expecting more answers using the same sequence number.
-     */
-    boolean isRecurring();
-
-    /**
-     * If the Listener is passed to the send() method, this method is
-     * called to determine how long to wait for the reply.  The value
-     * is in seconds.  -1 indicates to wait forever.  0 indicates to
-     * use the default timeout.  If the timeout is
-     * reached, processTimeout on this same Listener is called.
-     * 
-     * @return timeout in seconds before processTimeout is called.
-     */
-    int getTimeout();
-
-    /**
-     * If the Listener is passed to the send() method, this method is
-     * called by the AgentManager to process a command timeout.
-     * @param agentId id of the agent
-     * @param seq sequence number returned by the send().
-     * @return true if processed; false if not.
-     */
-    boolean processTimeout(long agentId, long seq);
-  
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java
index 2ff45b1..eb6da70 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java
@@ -18,6 +18,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage;
 
 import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 
+import com.cloud.agent.Listener;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.Command;
 
@@ -25,4 +26,5 @@ public interface EndPoint {
     public long getId();
 	public Answer sendMessage(Command cmd);
 	public void sendMessageAsync(Command cmd, AsyncCompletionCallback<Answer> callback);
+	void sendMessageAsyncWithListener(Command cmd, Listener listner);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/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
index d7010fd..f04b14d 100644
--- 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
@@ -20,6 +20,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage;
 
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
 import org.apache.cloudstack.framework.async.AsyncCallFuture;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 
 
 
@@ -40,7 +41,7 @@ public interface TemplateService {
     }
 
 
-    AsyncCallFuture<TemplateApiResult> createTemplateAsync(TemplateInfo template, DataStore store);
+    void createTemplateAsync(TemplateInfo template, DataStore store, AsyncCompletionCallback<TemplateApiResult> callback);
     AsyncCallFuture<TemplateApiResult> createTemplateFromSnapshotAsync(SnapshotInfo snapshot, TemplateInfo template, DataStore store);
     AsyncCallFuture<TemplateApiResult> createTemplateFromVolumeAsync(VolumeInfo volume, TemplateInfo template, DataStore store);
     AsyncCallFuture<TemplateApiResult> deleteTemplateAsync(TemplateInfo template);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java
----------------------------------------------------------------------
diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java
index c357d23..462f13f 100644
--- a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java
+++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java
@@ -25,12 +25,14 @@ import javax.inject.Inject;
 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.Scope;
+import org.springframework.stereotype.Component;
 
 import com.cloud.storage.ScopeType;
 import com.cloud.utils.exception.CloudRuntimeException;
 
 import edu.emory.mathcs.backport.java.util.Collections;
 
+@Component
 public class StorageCacheRandomAllocator implements StorageCacheAllocator {
     @Inject
     DataStoreManager dataStoreMgr;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java
index 150c289..47fe489 100644
--- a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java
+++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java
@@ -37,6 +37,7 @@ 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.cache.allocator.StorageCacheAllocator;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
 import org.apache.log4j.Logger;
 
 import com.cloud.utils.component.Manager;
@@ -115,11 +116,11 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager {
 
     
     private class CreateCacheObjectContext<T> extends AsyncRpcConext<T> {
-        final AsyncCallFuture<CommandResult> future;
+        final AsyncCallFuture<CopyCmdAnswer> future;
         /**
          * @param callback
          */
-        public CreateCacheObjectContext(AsyncCompletionCallback<T> callback, AsyncCallFuture<CommandResult> future) {
+        public CreateCacheObjectContext(AsyncCompletionCallback<T> callback, AsyncCallFuture<CopyCmdAnswer> future) {
             super(callback);
             this.future = future;
         }
@@ -130,22 +131,22 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager {
 	public DataObject createCacheObject(DataObject data, Scope scope) {
 		DataStore cacheStore = this.getCacheStorage(scope);
 		DataObject objOnCacheStore = cacheStore.create(data);
-		AsyncCallFuture<CommandResult> future = new AsyncCallFuture<CommandResult>();
-		CreateCacheObjectContext<CommandResult> context = new CreateCacheObjectContext<CommandResult>(null, future);
-		AsyncCallbackDispatcher<StorageCacheManagerImpl, CommandResult> caller = AsyncCallbackDispatcher.create(this); 
+		AsyncCallFuture<CopyCmdAnswer> future = new AsyncCallFuture<CopyCmdAnswer>();
+		CreateCacheObjectContext<CopyCmdAnswer> context = new CreateCacheObjectContext<CopyCmdAnswer>(null, future);
+		AsyncCallbackDispatcher<StorageCacheManagerImpl, CopyCmdAnswer> caller = AsyncCallbackDispatcher.create(this); 
 		caller.setContext(context);
 		
-		CommandResult result = null;
+		CopyCmdAnswer result = null;
 		try {
 		    objOnCacheStore.processEvent(Event.CreateOnlyRequested);
 		    
 		    dataMotionSvr.copyAsync(data, objOnCacheStore, caller);
 		    result = future.get();
 		    
-		    if (result.isFailed()) {
+		    if (!result.getResult()) {
 		        cacheStore.delete(data);
 		    } else {
-		        objOnCacheStore.processEvent(Event.OperationSuccessed);
+		        objOnCacheStore.processEvent(Event.OperationSuccessed, result);
 		    }
         } catch (InterruptedException e) {
             s_logger.debug("create cache storage failed: " + e.toString());
@@ -162,9 +163,9 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager {
 		return null;
 	}
 	
-	protected Void createCacheObjectCallBack(AsyncCallbackDispatcher<StorageCacheManagerImpl, CommandResult> callback, 
-	        CreateCacheObjectContext<CommandResult> context) {
-	    AsyncCallFuture<CommandResult> future = context.future;
+	protected Void createCacheObjectCallBack(AsyncCallbackDispatcher<StorageCacheManagerImpl, CopyCmdAnswer> callback, 
+	        CreateCacheObjectContext<CopyCmdAnswer> context) {
+	    AsyncCallFuture<CopyCmdAnswer> future = context.future;
 	    future.complete(callback.getResult());
 	    return null;
 	}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/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
index 04003bf..0057012 100644
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
+++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
@@ -34,19 +34,15 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService;
 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.TemplateDataFactory;
-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.ObjectInDataStoreStateMachine.Event;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
 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.TemplateService.TemplateApiResult;
-
-import com.cloud.storage.template.TemplateProp;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
 import org.apache.cloudstack.framework.async.AsyncCallFuture;
 import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
 import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
@@ -71,25 +67,22 @@ 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.StoragePool;
 import com.cloud.storage.VMTemplateStoragePoolVO;
-import com.cloud.storage.VMTemplateStorageResourceAssoc;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.VMTemplateZoneVO;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.storage.dao.VMTemplatePoolDao;
 import com.cloud.storage.dao.VMTemplateZoneDao;
 import com.cloud.storage.dao.VolumeDao;
 import com.cloud.storage.download.DownloadMonitor;
 import com.cloud.storage.secondary.SecondaryStorageVmManager;
+import com.cloud.storage.template.TemplateProp;
 import com.cloud.user.AccountManager;
 import com.cloud.user.ResourceLimitService;
 import com.cloud.utils.UriUtils;
-import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.fsm.NoTransitionException;
 import com.cloud.vm.UserVmVO;
 import com.cloud.vm.dao.UserVmDao;
@@ -137,15 +130,11 @@ public class TemplateServiceImpl implements TemplateService {
     TemplateDataFactory _templateFactory;
     @Inject VMTemplatePoolDao _tmpltPoolDao;
 
-
-
-
     class TemplateOpContext<T> extends AsyncRpcConext<T> {
         final TemplateObject template;
         final AsyncCallFuture<TemplateApiResult> future;
-
         public TemplateOpContext(AsyncCompletionCallback<T> callback, TemplateObject template,
-                AsyncCallFuture<TemplateApiResult> future) {
+        		AsyncCallFuture<TemplateApiResult> future) {
             super(callback);
             this.template = template;
             this.future = future;
@@ -154,30 +143,22 @@ public class TemplateServiceImpl implements TemplateService {
         public TemplateObject getTemplate() {
             return template;
         }
-
-        public AsyncCallFuture<TemplateApiResult> getFuture() {
-            return future;
-        }
-
-
     }
 
     @Override
-    public AsyncCallFuture<TemplateApiResult> createTemplateAsync(
-            TemplateInfo template, DataStore store) {
-        AsyncCallFuture<TemplateApiResult> future = new AsyncCallFuture<TemplateApiResult>();
+    public void createTemplateAsync(
+            TemplateInfo template, DataStore store, AsyncCompletionCallback<TemplateApiResult> callback) {
         // persist template_store_ref entry
         DataObject templateOnStore = store.create(template);
         // update template_store_ref state
         templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested);
 
-        TemplateOpContext<TemplateApiResult> context = new TemplateOpContext<TemplateApiResult>(null,
-                (TemplateObject)templateOnStore, future);
+        TemplateOpContext<TemplateApiResult> context = new TemplateOpContext<TemplateApiResult>(callback,
+                (TemplateObject)templateOnStore, null);
 
         AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
         caller.setCallback(caller.getTarget().createTemplateCallback(null, null)).setContext(context);
         store.getDriver().createAsync(templateOnStore, caller);
-        return future;
     }
 
     @Override
@@ -185,26 +166,20 @@ public class TemplateServiceImpl implements TemplateService {
         Set<VMTemplateVO> toBeDownloaded = new HashSet<VMTemplateVO>();
 
         List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
-        List<VMTemplateVO> defaultBuiltin = _templateDao.listDefaultBuiltinTemplates();
 
         for (VMTemplateVO rtngTmplt : rtngTmplts) {
             toBeDownloaded.add(rtngTmplt);
         }
 
-        for (VMTemplateVO builtinTmplt : defaultBuiltin) {
-            toBeDownloaded.add(builtinTmplt);
-        }
-
         for (VMTemplateVO template : toBeDownloaded) {
             TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId());
             if (tmpltHost == null || tmpltHost.getState() != ObjectInDataStoreStateMachine.State.Ready) {
-                _dlMonitor.downloadBootstrapSysTemplateToStorage(template, store, null);
+            	TemplateInfo tmplt = this._templateFactory.getTemplate(template.getId());
+                this.createTemplateAsync(tmplt, store, null);
             }
         }
     }
-
-
-
+    
     @Override
     public void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId) {
         Set<VMTemplateVO> toBeDownloaded = new HashSet<VMTemplateVO>();
@@ -234,16 +209,13 @@ public class TemplateServiceImpl implements TemplateService {
             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);
+                	DataObject tmpl = this._templateFactory.getTemplate(template.getId(), ssHost);
+                    _dlMonitor.downloadTemplateToStorage(tmpl, ssHost, null);
                 }
             }
         }
     }
 
-
-
-
-
     @Override
     public void handleTemplateSync(DataStore store) {
         if (store == null) {
@@ -394,7 +366,8 @@ public class TemplateServiceImpl implements TemplateService {
                     }
                     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);
+                    DataObject tmpl = this._templateFactory.getTemplate(tmplt.getId(), store);
+                    _dlMonitor.downloadTemplateToStorage(tmpl, store, null);
                 }
             }
         }
@@ -465,9 +438,9 @@ public class TemplateServiceImpl implements TemplateService {
 
 
     protected Void createTemplateCallback(AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> callback,
-            TemplateOpContext<CreateCmdResult> context) {
+            TemplateOpContext<TemplateApiResult> context) {
         TemplateObject template = (TemplateObject)context.getTemplate();
-        AsyncCallFuture<TemplateApiResult> future = context.getFuture();
+        AsyncCompletionCallback<TemplateApiResult> parentCallback = context.getParentCallback();
         TemplateApiResult result = new TemplateApiResult(template);
         CreateCmdResult callbackResult = callback.getResult();
         if (callbackResult.isFailed()) {
@@ -478,7 +451,7 @@ public class TemplateServiceImpl implements TemplateService {
                s_logger.debug("Failed to update template state", e);
             }
             result.setResult(callbackResult.getResult());
-            future.complete(result);
+            parentCallback.complete(result);
             return null;
         }
 
@@ -488,11 +461,11 @@ public class TemplateServiceImpl implements TemplateService {
         } catch (NoTransitionException e) {
             s_logger.debug("Failed to transit state", e);
             result.setResult(e.toString());
-            future.complete(result);
+            parentCallback.complete(result);
             return null;
         }
 
-        future.complete(result);
+        parentCallback.complete(result);
         return null;
     }
 
@@ -520,7 +493,7 @@ public class TemplateServiceImpl implements TemplateService {
         } else {
             vo.processEvent(Event.OperationFailed);
          }
-        context.getFuture().complete(result);
+        context.future.complete(result);
         return null;
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java
----------------------------------------------------------------------
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java
index 15aad4b..3230724 100644
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java
+++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java
@@ -29,13 +29,19 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreState
 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.disktype.DiskFormat;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
 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.image.manager.ImageDataManager;
 import org.apache.cloudstack.storage.to.TemplateObjectTO;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.api.Answer;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.VMTemplateStoragePoolVO;
 import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.storage.dao.VMTemplatePoolDao;
 import com.cloud.utils.component.ComponentContext;
@@ -54,6 +60,7 @@ public class TemplateObject implements TemplateInfo {
     @Inject
     ObjectInDataStoreManager ojbectInStoreMgr;
     @Inject VMTemplatePoolDao templatePoolDao;
+    @Inject TemplateDataStoreDao templateStoreDao;
 
     public TemplateObject() {
     }
@@ -163,7 +170,7 @@ public class TemplateObject implements TemplateInfo {
     @Override
     public void processEvent(Event event) {
         try {
-            ojbectInStoreMgr.update(this, event, null);
+            ojbectInStoreMgr.update(this, event);
         } catch (NoTransitionException e) {
             s_logger.debug("failed to update state", e);
             throw new CloudRuntimeException("Failed to update state" + e.toString());
@@ -173,7 +180,27 @@ public class TemplateObject implements TemplateInfo {
     @Override
     public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) {
         try {
-            ojbectInStoreMgr.update(this, event, answer);
+        	if (this.getDataStore().getRole() == DataStoreRole.Primary) {
+        		if (answer != null && answer instanceof CopyCmdAnswer) {
+        			CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
+        			VMTemplateStoragePoolVO templatePoolRef = templatePoolDao.findByPoolTemplate(this.getDataStore().getId(), this.getId());
+        			templatePoolRef.setDownloadPercent(100);
+        			templatePoolRef.setDownloadState(Status.DOWNLOADED);
+        			templatePoolRef.setLocalDownloadPath(cpyAnswer.getPath());
+        			templatePoolRef.setInstallPath(cpyAnswer.getPath());
+        			templatePoolDao.update(templatePoolRef.getId(), templatePoolRef);
+        		}
+        	} else if (this.getDataStore().getRole() == DataStoreRole.Image || 
+        			this.getDataStore().getRole() == DataStoreRole.ImageCache) {
+        		if (answer != null && answer instanceof CopyCmdAnswer) {
+        			CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
+        			TemplateDataStoreVO templateStoreRef = this.templateStoreDao.findByStoreTemplate(this.getDataStore().getId(),
+        					this.getId());
+        			templateStoreRef.setInstallPath(cpyAnswer.getPath());
+        			templateStoreDao.update(templateStoreRef.getId(), templateStoreRef);
+        		}
+        	}
+            ojbectInStoreMgr.update(this, event);
         } catch (NoTransitionException e) {
             s_logger.debug("failed to update state", e);
             throw new CloudRuntimeException("Failed to update state" + e.toString());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/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 37f0e47..e47eaec 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
@@ -238,8 +238,8 @@ public class volumeServiceTest extends CloudStackTestNGBase {
 		    DataStore store = createImageStore();
 		    VMTemplateVO image = createImageData();
 		    TemplateInfo template = imageDataFactory.getTemplate(image.getId(), store);
-		    AsyncCallFuture<TemplateApiResult> future = imageService.createTemplateAsync(template, store);
-		    future.get();
+		    //AsyncCallFuture<TemplateApiResult> future = imageService.createTemplateAsync(template, store);
+		    //future.get();
 		    template = imageDataFactory.getTemplate(image.getId(), store);
 			/*imageProviderMgr.configure("image Provider", new HashMap<String, Object>());
 			VMTemplateVO image = createImageData();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java
index 665ed92..f08a597 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java
@@ -1,20 +1,28 @@
 package org.apache.cloudstack.storage;
 
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 import org.apache.cloudstack.storage.command.CopyCmd;
 
+import com.cloud.agent.Listener;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.Command;
+import com.cloud.agent.api.storage.DownloadAnswer;
 import com.cloud.resource.ServerResource;
+import com.cloud.storage.download.DownloadListener;
 import com.cloud.storage.resource.LocalNfsSecondaryStorageResource;
 import com.cloud.utils.component.ComponentContext;
 
 public class LocalHostEndpoint implements EndPoint {
-	
+	private ScheduledExecutorService executor;
 	ServerResource resource;
 	public LocalHostEndpoint() {
 		resource = ComponentContext.inject(LocalNfsSecondaryStorageResource.class);
+		executor = Executors.newScheduledThreadPool(10);
 	}
 	@Override
 	public long getId() {
@@ -31,11 +39,45 @@ public class LocalHostEndpoint implements EndPoint {
 		return new Answer(cmd, false, "unsupported command:" + cmd.toString());
 	}
 
+	private class CmdRunner implements Runnable {
+		final Command cmd;
+		final AsyncCompletionCallback<Answer> callback;
+		public CmdRunner(Command cmd, AsyncCompletionCallback<Answer> callback) {
+			this.cmd = cmd;
+			this.callback = callback;
+		}
+		@Override
+		public void run() {
+			Answer answer = sendMessage(cmd);
+			callback.complete(answer);
+		}
+	}
+	
+	private class CmdRunner2 implements Runnable {
+		final Command cmd;
+		final AsyncCompletionCallback<DownloadAnswer> callback;
+		public CmdRunner2(Command cmd, AsyncCompletionCallback<DownloadAnswer> callback) {
+			this.cmd = cmd;
+			this.callback = callback;
+		}
+		@Override
+		public void run() {
+			DownloadAnswer answer = (DownloadAnswer)sendMessage(cmd);
+			callback.complete(answer);
+		}
+	}
 	@Override
 	public void sendMessageAsync(Command cmd,
 			AsyncCompletionCallback<Answer> callback) {
-		// TODO Auto-generated method stub
-
+		 executor.schedule(new CmdRunner(cmd, callback), 10, TimeUnit.SECONDS);
+	}
+	
+	@Override
+	public void sendMessageAsyncWithListener(Command cmd, Listener listner) {
+		if (listner instanceof DownloadListener) {
+			DownloadListener listener = (DownloadListener)listner;
+			executor.schedule(new CmdRunner2(cmd, listener.getCallback()), 10, TimeUnit.SECONDS);
+		}
 	}
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java
index aec7b52..9ce4e75 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java
@@ -18,6 +18,10 @@
  */
 package org.apache.cloudstack.storage;
 
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
 import javax.inject.Inject;
 
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
@@ -25,11 +29,14 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 import org.apache.log4j.Logger;
 
 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.manager.Commands;
 import com.cloud.exception.AgentUnavailableException;
 import com.cloud.exception.OperationTimedoutException;
 import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.exception.CloudRuntimeException;
 
 public class RemoteHostEndPoint implements EndPoint {
     private static final Logger s_logger = Logger.getLogger(RemoteHostEndPoint.class);
@@ -39,9 +46,10 @@ public class RemoteHostEndPoint implements EndPoint {
     AgentManager agentMgr;
     @Inject
     HostEndpointRpcServer rpcServer;
+    private ScheduledExecutorService executor;
 
     protected RemoteHostEndPoint() {
-      
+    	executor = Executors.newScheduledThreadPool(10);
     }
     
     private void configure(long hostId, String hostAddress) {
@@ -65,11 +73,46 @@ public class RemoteHostEndPoint implements EndPoint {
 
     @Override
     public Answer sendMessage(Command cmd) {
-        return rpcServer.sendCommand(this, cmd);
+    	String errMsg = null;
+    	try {
+			return agentMgr.send(getId(), cmd);
+		} catch (AgentUnavailableException e) {
+			errMsg = e.toString();
+			s_logger.debug("Failed to send command, due to Agent:" + getId() + ", " + e.toString());
+		} catch (OperationTimedoutException e) {
+			errMsg = e.toString();
+			s_logger.debug("Failed to send command, due to Agent:" + getId() + ", " + e.toString());
+		}
+    	throw new CloudRuntimeException("Failed to send command, due to Agent:" + getId() + ", " + errMsg);
     }
     
+    private class CmdRunner implements Runnable {
+		final Command cmd;
+		final AsyncCompletionCallback<Answer> callback;
+		public CmdRunner(Command cmd, AsyncCompletionCallback<Answer> callback) {
+			this.cmd = cmd;
+			this.callback = callback;
+		}
+		@Override
+		public void run() {
+			Answer answer = sendMessage(cmd);
+			callback.complete(answer);
+		}
+		
+	}
+    
     @Override
     public void sendMessageAsync(Command cmd, AsyncCompletionCallback<Answer> callback) {
-        rpcServer.sendCommandAsync(this, cmd, callback);
+    	executor.schedule(new CmdRunner(cmd, callback), 10, TimeUnit.SECONDS);
+    }
+    
+    @Override
+    public void sendMessageAsyncWithListener(Command cmd, Listener listener) {
+    	try {
+    		this.agentMgr.send(getId(), new Commands(cmd), listener);
+    	} catch (AgentUnavailableException e) {
+    		s_logger.debug("Failed to send command: " + e.toString());
+    		throw new CloudRuntimeException("Failed to send command: " + e.toString());
+    	}
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/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 876a066..d53029a 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java
@@ -29,7 +29,6 @@ import com.cloud.utils.fsm.NoTransitionException;
 public interface ObjectInDataStoreManager {
     public DataObject create(DataObject template, DataStore dataStore);
     public DataObject get(DataObject dataObj, DataStore store);
-    public boolean update(DataObject vo, Event event, Answer answer) throws NoTransitionException;
     public boolean update(DataObject vo, Event event) throws NoTransitionException;
     DataObjectInStore findObject(long objId, DataObjectType type,
             long dataStoreId, DataStoreRole role);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/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 52ed312..bf9a98d 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
@@ -23,12 +23,11 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
 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.TemplateDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.storage.command.CopyCmdAnswer;
 import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
@@ -40,15 +39,12 @@ import org.apache.cloudstack.storage.db.ObjectInDataStoreVO;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
-import com.cloud.agent.api.Answer;
 import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.VMTemplateStoragePoolVO;
-import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 import com.cloud.storage.dao.SnapshotDao;
 import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.storage.dao.VMTemplatePoolDao;
 import com.cloud.storage.dao.VolumeDao;
-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;
@@ -162,7 +158,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
     }
 
     @Override
-    public boolean update(DataObject data, Event event, Answer answer)
+    public boolean update(DataObject data, Event event)
             throws NoTransitionException {
         DataObjectInStore obj = this.findObject(data, data.getDataStore());
         if (obj == null) {
@@ -171,7 +167,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
                             + data);
         }
 
-        if ( data.getDataStore().getRole() == DataStoreRole.Image){
+        if ( data.getDataStore().getRole() == DataStoreRole.Image || data.getDataStore().getRole() == DataStoreRole.ImageCache){
             switch (data.getType()){
             case TEMPLATE:
                 this.stateMachines.transitTo(obj, event, null, templateDataStoreDao);
@@ -181,22 +177,10 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
                 this.stateMachines.transitTo(obj, event, null, volumeDataStoreDao);
             }
         } else if (data.getType() == DataObjectType.TEMPLATE && data.getDataStore().getRole() == DataStoreRole.Primary) {
-            if (answer != null && answer instanceof CopyCmdAnswer) {
-                CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
-                VMTemplateStoragePoolVO templatePoolRef = templatePoolDao.findByPoolTemplate(data.getDataStore().getId(), data.getId());
-                templatePoolRef.setDownloadPercent(100);
-                templatePoolRef.setDownloadState(Status.DOWNLOADED);
-                templatePoolRef.setLocalDownloadPath(cpyAnswer.getPath());
-                templatePoolRef.setInstallPath(cpyAnswer.getPath());
-                templatePoolDao.update(templatePoolRef.getId(), templatePoolRef);
-            }
-            try {
-                obj = this.findObject(data, data.getDataStore());
-                this.stateMachines.transitTo(obj, event, null,
-                        templatePoolDao);
-            } catch (NoTransitionException e) {
-                throw e;
-            }
+
+        	this.stateMachines.transitTo(obj, event, null,
+        			templatePoolDao);
+
         } else {
             throw new CloudRuntimeException("Invalid data or store type: " + data.getType() + " " + data.getDataStore().getRole());
         }
@@ -273,9 +257,4 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
         return store;
     }
 
-    @Override
-    public boolean update(DataObject vo, Event event) throws NoTransitionException {
-       return this.update(vo, event, null);
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/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 34e080d..2834ed0 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
@@ -165,7 +165,7 @@ public class VolumeObject implements VolumeInfo {
         try {
             Volume.Event volEvent = null;
             if (this.dataStore.getRole() == DataStoreRole.Image) {
-                ojbectInStoreMgr.update(this, event, null);
+                ojbectInStoreMgr.update(this, event);
                 if (event == ObjectInDataStoreStateMachine.Event.CreateRequested) {
                     volEvent = Volume.Event.UploadRequested;
                 } else if (event == ObjectInDataStoreStateMachine.Event.OperationSuccessed) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/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 d4087ed..42c61f3 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
@@ -58,14 +58,14 @@ 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.Resource.ResourceType;
 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;
 import com.cloud.storage.Volume.Type;
 import com.cloud.storage.VolumeVO;
 import com.cloud.storage.dao.VolumeDao;
@@ -659,6 +659,9 @@ public class VolumeServiceImpl implements VolumeService {
         } else {
             vo.stateTransit(Volume.Event.OperationSucceeded);
         }*/
+        
+    	_resourceLimitMgr.incrementResourceCount(vo.getAccountId(), ResourceType.secondary_storage,
+              	vo.getSize());
         VolumeApiResult res = new VolumeApiResult(vo);
         context.future.complete(res);
         return null;
@@ -805,7 +808,7 @@ public class VolumeServiceImpl implements VolumeService {
                 }
                 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);
+                _dlMonitor.downloadVolumeToStorage(this.volFactory.getVolume(volumeHost.getVolumeId()), store,  volumeHost.getDownloadUrl(), volumeHost.getChecksum(), volumeHost.getFormat(), null);
             }
         }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java
index 00fe356..a9f6134 100755
--- a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java
+++ b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java
@@ -44,6 +44,7 @@ import com.cloud.dc.ClusterVO;
 import com.cloud.dc.dao.ClusterDao;
 import com.cloud.exception.ConnectionException;
 import com.cloud.exception.DiscoveryException;
+import com.cloud.host.Host;
 import com.cloud.host.HostVO;
 import com.cloud.host.Status;
 import com.cloud.host.dao.HostDao;
@@ -255,7 +256,7 @@ public class SimulatorDiscoverer extends DiscovererBase implements Discoverer, L
     }
 
     @Override
-    public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
+    public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
 
         /*if(forRebalance)
 		return;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java
index 3a8cf17..6bbd90f 100644
--- a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java
+++ b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java
@@ -36,6 +36,7 @@ import com.cloud.agent.api.StartupCommand;
 import com.cloud.agent.api.StartupSecondaryStorageCommand;
 import com.cloud.agent.manager.MockStorageManager;
 import com.cloud.exception.ConnectionException;
+import com.cloud.host.Host;
 import com.cloud.host.HostVO;
 import com.cloud.host.Status;
 import com.cloud.storage.SnapshotVO;
@@ -158,7 +159,7 @@ public class SimulatorSecondaryDiscoverer extends SecondaryStorageDiscoverer imp
     }
 
     @Override
-    public void processConnect(HostVO host, StartupCommand cmd,
+    public void processConnect(Host host, StartupCommand cmd,
             boolean forRebalance) throws ConnectionException {
 
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
index b2e3768..ba99da1 100755
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
@@ -54,6 +54,7 @@ import com.cloud.dc.ClusterVSMMapVO;
 import com.cloud.dc.dao.ClusterDao;
 import com.cloud.dc.dao.ClusterVSMMapDao;
 import com.cloud.exception.DiscoveredWithErrorException;
+import com.cloud.host.Host;
 import com.cloud.host.HostVO;
 import com.cloud.host.Status;
 import com.cloud.host.dao.HostDao;
@@ -757,7 +758,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
     }
 
     @Override
-    public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) {
+    public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) {
         if(cmd instanceof StartupCommand) {
             if(host.getHypervisorType() == HypervisorType.VMware) {
                 updateClusterNativeHAState(host, cmd);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java
index 89bc1cf..195ab30 100755
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java
@@ -555,7 +555,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L
     }
 
     @Override
-    public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
+    public void processConnect(com.cloud.host.Host agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
         if (!(cmd instanceof StartupRoutingCommand )) {
             return;
         }       

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/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 fe556a2..0c078b1 100644
--- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java
+++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java
@@ -18,6 +18,7 @@
  */
 package org.apache.cloudstack.storage.datastore.driver;
 
+import java.util.Date;
 import java.util.List;
 import java.util.Set;
 
@@ -32,6 +33,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataTO;
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+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.db.TemplateDataStoreDao;
@@ -48,6 +50,7 @@ import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.DeleteSnapshotBackupCommand;
 import com.cloud.agent.api.storage.DeleteTemplateCommand;
 import com.cloud.agent.api.storage.DeleteVolumeCommand;
+import com.cloud.agent.api.storage.DownloadAnswer;
 import com.cloud.agent.api.to.DataStoreTO;
 import com.cloud.agent.api.to.NfsTO;
 import com.cloud.agent.api.to.S3TO;
@@ -155,21 +158,73 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
         }
     }
 
+    private class createObjectContext<T> extends AsyncRpcConext<T> {
+    	final DataObject data;
+		public createObjectContext(AsyncCompletionCallback<T> callback, DataObject data) {
+			super(callback);
+			this.data = data;
+		}
+    	
+    }
     @Override
     public void createAsync(DataObject data,
             AsyncCompletionCallback<CreateCmdResult> callback) {
+    	createObjectContext<CreateCmdResult> context = new createObjectContext<CreateCmdResult>(callback, data);
+        AsyncCallbackDispatcher<CloudStackImageStoreDriverImpl, DownloadAnswer> caller = 
+        		AsyncCallbackDispatcher.create(this);
+        caller.setContext(context);
+        caller.setCallback(callback);
+        
         if (data.getType() == DataObjectType.TEMPLATE) {
             TemplateObject tData = (TemplateObject)data;
-            _downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback);
+            _downloadMonitor.downloadTemplateToStorage(tData, tData.getDataStore(), caller);
         } else if (data.getType() == DataObjectType.VOLUME) {
             VolumeObject volInfo = (VolumeObject)data;
             RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload();
-            _downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(),
-                    payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback);
+            _downloadMonitor.downloadVolumeToStorage(volInfo, volInfo.getDataStore(), payload.getUrl(),
+                    payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), caller);
         }
-
-        CreateCmdResult result = new CreateCmdResult(null, null);
-        callback.complete(result);
+    }
+    
+    protected Void createAsyncCallback(AsyncCallbackDispatcher<CloudStackImageStoreDriverImpl, DownloadAnswer> callback, 
+    		createObjectContext<CreateCmdResult> context) {
+    	DownloadAnswer answer = callback.getResult();
+    	DataObject obj = context.data;
+    	DataStore store = obj.getDataStore();
+
+    	TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate();
+    	updateBuilder.setDownloadPercent(answer.getDownloadPct());
+    	updateBuilder.setDownloadState(answer.getDownloadStatus());
+    	updateBuilder.setLastUpdated(new Date());
+    	updateBuilder.setErrorString(answer.getErrorString());
+    	updateBuilder.setJobId(answer.getJobId());
+    	updateBuilder.setLocalDownloadPath(answer.getDownloadPath());
+    	updateBuilder.setInstallPath(answer.getInstallPath());
+    	updateBuilder.setSize(answer.getTemplateSize());
+    	updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize());
+    	_templateStoreDao.update(store.getId(), updateBuilder);
+    	
+    	AsyncCompletionCallback<CreateCmdResult> caller = context.getParentCallback();
+    	
+    	if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR ||
+    			answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED ||
+    			answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) {
+    		CreateCmdResult result = new CreateCmdResult(null, null);
+    		result.setSucess(false);
+    		result.setResult(answer.getErrorString());
+    		caller.complete(result);
+    	} else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
+    		if (answer.getCheckSum() != null) {
+    			VMTemplateVO templateDaoBuilder = templateDao.createForUpdate();
+    			templateDaoBuilder.setChecksum(answer.getCheckSum());
+    			templateDao.update(obj.getId(), templateDaoBuilder);
+    		}
+    		
+    		
+    		CreateCmdResult result = new CreateCmdResult(null, null);
+    		caller.complete(result);
+    	}
+    	return null;
     }
 
     private void deleteVolume(DataObject data, AsyncCompletionCallback<CommandResult> callback) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/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 1073467..6f5d554 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
@@ -164,12 +164,12 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver {
             AsyncCompletionCallback<CreateCmdResult> callback) {
         if (data.getType() == DataObjectType.TEMPLATE) {
             TemplateObject tData = (TemplateObject)data;
-            _downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback);
+            _downloadMonitor.downloadTemplateToStorage(tData, tData.getDataStore(), null);
         } else if (data.getType() == DataObjectType.VOLUME) {
             VolumeObject volInfo = (VolumeObject)data;
             RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload();
-            _downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(),
-                    payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback);
+            _downloadMonitor.downloadVolumeToStorage(volInfo, volInfo.getDataStore(), payload.getUrl(),
+                    payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), null);
         }
 
         CreateCmdResult result = new CreateCmdResult(null, null);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/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 88405d2..1b9ab2d 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
@@ -157,12 +157,12 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver {
             AsyncCompletionCallback<CreateCmdResult> callback) {
         if (data.getType() == DataObjectType.TEMPLATE) {
             TemplateObject tData = (TemplateObject)data;
-            _downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback);
+            _downloadMonitor.downloadTemplateToStorage(tData, tData.getDataStore(), null);
         } else if (data.getType() == DataObjectType.VOLUME) {
             VolumeObject volInfo = (VolumeObject)data;
             RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload();
-            _downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(),
-                    payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback);
+            _downloadMonitor.downloadVolumeToStorage(volInfo, volInfo.getDataStore(), payload.getUrl(),
+                    payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), null);
         }
 
         CreateCmdResult result = new CreateCmdResult(null, null);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/pom.xml
----------------------------------------------------------------------
diff --git a/server/pom.xml b/server/pom.xml
index a397195..a744506 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -98,6 +98,11 @@
       <artifactId>cloud-framework-events</artifactId>
       <version>${project.version}</version>
     </dependency>
+     <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-framework-ipc</artifactId>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
   <build>
     <defaultGoal>install</defaultGoal>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/agent/manager/AgentMonitor.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/agent/manager/AgentMonitor.java b/server/src/com/cloud/agent/manager/AgentMonitor.java
index f3f6669..2c0266e 100755
--- a/server/src/com/cloud/agent/manager/AgentMonitor.java
+++ b/server/src/com/cloud/agent/manager/AgentMonitor.java
@@ -248,7 +248,7 @@ public class AgentMonitor extends Thread implements AgentMonitorService {
     }
 
     @Override
-    public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) {
+    public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) {
         if (host.getType().equals(Host.Type.TrafficMonitor) ||
                 host.getType().equals(Host.Type.SecondaryStorage)) {
             return;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/agent/manager/SynchronousListener.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/agent/manager/SynchronousListener.java b/server/src/com/cloud/agent/manager/SynchronousListener.java
index 074f5a8..3698705 100755
--- a/server/src/com/cloud/agent/manager/SynchronousListener.java
+++ b/server/src/com/cloud/agent/manager/SynchronousListener.java
@@ -24,7 +24,7 @@ import com.cloud.agent.api.AgentControlCommand;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.Command;
 import com.cloud.agent.api.StartupCommand;
-import com.cloud.host.HostVO;
+import com.cloud.host.Host;
 import com.cloud.host.Status;
 import com.cloud.utils.Profiler;
 
@@ -79,7 +79,7 @@ public class SynchronousListener implements Listener {
     }
     
     @Override
-    public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) {
+    public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) {
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/capacity/CapacityManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/capacity/CapacityManager.java b/server/src/com/cloud/capacity/CapacityManager.java
index bdd9ccd..ab02e77 100755
--- a/server/src/com/cloud/capacity/CapacityManager.java
+++ b/server/src/com/cloud/capacity/CapacityManager.java
@@ -18,6 +18,7 @@ package com.cloud.capacity;
 
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 
+import com.cloud.host.Host;
 import com.cloud.host.HostVO;
 import com.cloud.storage.VMTemplateVO;
 import com.cloud.utils.component.Manager;
@@ -41,7 +42,7 @@ public interface CapacityManager extends Manager {
      */
     boolean checkIfHostHasCapacity(long hostId, Integer cpu, long ram, boolean checkFromReservedCapacity, float cpuOverprovisioningFactor, float memoryOvercommitRatio, boolean considerReservedCapacity);
 
-	void updateCapacityForHost(HostVO host);
+	void updateCapacityForHost(Host host);
     
 	/**
      * @param pool storage pool

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/capacity/CapacityManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/capacity/CapacityManagerImpl.java b/server/src/com/cloud/capacity/CapacityManagerImpl.java
index 292ef0a..7e9ff37 100755
--- a/server/src/com/cloud/capacity/CapacityManagerImpl.java
+++ b/server/src/com/cloud/capacity/CapacityManagerImpl.java
@@ -28,12 +28,6 @@ import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InsufficientServerCapacityException;
-import com.cloud.resource.ResourceState;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
@@ -50,7 +44,10 @@ import com.cloud.capacity.dao.CapacityDao;
 import com.cloud.configuration.Config;
 import com.cloud.configuration.ConfigurationManager;
 import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.dc.ClusterDetailsDao;
+import com.cloud.dc.dao.ClusterDao;
 import com.cloud.exception.ConnectionException;
+import com.cloud.host.Host;
 import com.cloud.host.HostVO;
 import com.cloud.host.Status;
 import com.cloud.host.dao.HostDao;
@@ -521,7 +518,7 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
     
     @DB
     @Override
-	public void updateCapacityForHost(HostVO host){
+	public void updateCapacityForHost(Host host){
     	// prepare the service offerings
         List<ServiceOfferingVO> offerings = _offeringsDao.listAllIncludingRemoved();
         Map<Long, ServiceOfferingVO> offeringsMap = new HashMap<Long, ServiceOfferingVO>();
@@ -784,7 +781,7 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
     }
 
     @Override
-    public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
+    public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
         // TODO Auto-generated method stub
 
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/capacity/ComputeCapacityListener.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/capacity/ComputeCapacityListener.java b/server/src/com/cloud/capacity/ComputeCapacityListener.java
index 16e154a..7ca8fd7 100755
--- a/server/src/com/cloud/capacity/ComputeCapacityListener.java
+++ b/server/src/com/cloud/capacity/ComputeCapacityListener.java
@@ -29,7 +29,7 @@ import com.cloud.agent.api.StartupCommand;
 import com.cloud.agent.api.StartupRoutingCommand;
 import com.cloud.capacity.dao.CapacityDao;
 import com.cloud.exception.ConnectionException;
-import com.cloud.host.HostVO;
+import com.cloud.host.Host;
 import com.cloud.host.Status;
 import com.cloud.utils.db.SearchCriteria;
 
@@ -71,7 +71,7 @@ public class ComputeCapacityListener implements Listener {
 
 
     @Override
-    public void processConnect(HostVO server, StartupCommand startup, boolean forRebalance) throws ConnectionException {
+    public void processConnect(Host server, StartupCommand startup, boolean forRebalance) throws ConnectionException {
         if (!(startup instanceof StartupRoutingCommand)) {
             return;
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/capacity/StorageCapacityListener.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/capacity/StorageCapacityListener.java b/server/src/com/cloud/capacity/StorageCapacityListener.java
index d5751a3..d44e121 100755
--- a/server/src/com/cloud/capacity/StorageCapacityListener.java
+++ b/server/src/com/cloud/capacity/StorageCapacityListener.java
@@ -30,7 +30,7 @@ import com.cloud.agent.api.StartupStorageCommand;
 import com.cloud.capacity.dao.CapacityDao;
 import com.cloud.capacity.dao.CapacityDaoImpl;
 import com.cloud.exception.ConnectionException;
-import com.cloud.host.HostVO;
+import com.cloud.host.Host;
 import com.cloud.host.Status;
 import com.cloud.storage.Storage;
 import com.cloud.utils.db.SearchCriteria;
@@ -71,7 +71,7 @@ public class StorageCapacityListener implements Listener {
 
 
     @Override
-    public void processConnect(HostVO server, StartupCommand startup, boolean forRebalance) throws ConnectionException {
+    public void processConnect(Host server, StartupCommand startup, boolean forRebalance) throws ConnectionException {
         
         if (!(startup instanceof StartupStorageCommand)) {
             return;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java
index 6f8575d..fe1dfe0 100755
--- a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java
+++ b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java
@@ -43,6 +43,7 @@ import com.cloud.deploy.DeployDestination;
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InsufficientCapacityException;
 import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.host.Host;
 import com.cloud.host.HostVO;
 import com.cloud.host.Status;
 import com.cloud.host.dao.HostDao;
@@ -229,7 +230,7 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol
     }
 
     @Override
-    public void onAgentConnect(HostVO host, StartupCommand cmd) {
+    public void onAgentConnect(Host host, StartupCommand cmd) {
     }
 
     @Override
@@ -356,4 +357,5 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol
     @Override
     public void prepareStop(VirtualMachineProfile<ConsoleProxyVO> profile) {
     }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/consoleproxy/AgentHook.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/AgentHook.java b/server/src/com/cloud/consoleproxy/AgentHook.java
index 5b6d585..29ec045 100644
--- a/server/src/com/cloud/consoleproxy/AgentHook.java
+++ b/server/src/com/cloud/consoleproxy/AgentHook.java
@@ -21,13 +21,13 @@ import com.cloud.agent.api.ConsoleAccessAuthenticationCommand;
 import com.cloud.agent.api.ConsoleProxyLoadReportCommand;
 import com.cloud.agent.api.StartupCommand;
 import com.cloud.agent.api.StartupProxyCommand;
-import com.cloud.host.HostVO;
+import com.cloud.host.Host;
 import com.cloud.host.Status;
 
 public interface AgentHook {
     void onLoadReport(ConsoleProxyLoadReportCommand cmd);
     AgentControlAnswer onConsoleAccessAuthentication(ConsoleAccessAuthenticationCommand cmd);
-    void onAgentConnect(HostVO host, StartupCommand cmd);
+    void onAgentConnect(Host host, StartupCommand cmd);
     
     public void onAgentDisconnect(long agentId, Status state);
 	public void startAgentHttpHandlerInVM(StartupProxyCommand startupCmd);	

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/consoleproxy/ConsoleProxyListener.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyListener.java b/server/src/com/cloud/consoleproxy/ConsoleProxyListener.java
index a3b7264..2190dff 100755
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyListener.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyListener.java
@@ -25,7 +25,7 @@ import com.cloud.agent.api.ConsoleAccessAuthenticationCommand;
 import com.cloud.agent.api.ConsoleProxyLoadReportCommand;
 import com.cloud.agent.api.StartupCommand;
 import com.cloud.agent.api.StartupProxyCommand;
-import com.cloud.host.HostVO;
+import com.cloud.host.Host;
 import com.cloud.host.Status;
 
 public class ConsoleProxyListener implements Listener {
@@ -64,7 +64,7 @@ public class ConsoleProxyListener implements Listener {
     }
 
     @Override
-    public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) {
+    public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) {
         _proxyMgr.onAgentConnect(host, cmd);
     	
     	if (cmd instanceof StartupProxyCommand) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java
index 6ebf3bc..459fda7 100755
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java
@@ -20,7 +20,7 @@ import com.cloud.agent.api.AgentControlAnswer;
 import com.cloud.agent.api.ConsoleAccessAuthenticationCommand;
 import com.cloud.agent.api.ConsoleProxyLoadReportCommand;
 import com.cloud.agent.api.StartupCommand;
-import com.cloud.host.HostVO;
+import com.cloud.host.Host;
 import com.cloud.host.Status;
 import com.cloud.host.Host.Type;
 import com.cloud.info.ConsoleProxyInfo;
@@ -55,6 +55,6 @@ public interface ConsoleProxyManager extends Manager {
 	public void onLoadReport(ConsoleProxyLoadReportCommand cmd);
 	public AgentControlAnswer onConsoleAccessAuthentication(ConsoleAccessAuthenticationCommand cmd);
 	
-    public void onAgentConnect(HostVO host, StartupCommand cmd);
+    public void onAgentConnect(Host host, StartupCommand cmd);
 	public void onAgentDisconnect(long agentId, Status state);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
index 1edd869..fa489ff 100755
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
@@ -994,7 +994,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
     }
 
     @Override
-    public void onAgentConnect(HostVO host, StartupCommand cmd) {
+    public void onAgentConnect(Host host, StartupCommand cmd) {
         // if (host.getType() == Type.ConsoleProxy) {
         // // TODO we can use this event to mark the proxy is up and
         // // functioning instead of

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java b/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java
index 75b007c..c92ff50 100644
--- a/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java
+++ b/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java
@@ -99,7 +99,7 @@ Listener, ResourceStateAdapter {
     }
 
     @Override
-    public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) {
+    public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) {
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/network/NetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java
index 6296011..ca5fb4f 100755
--- a/server/src/com/cloud/network/NetworkManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkManagerImpl.java
@@ -92,7 +92,6 @@ import com.cloud.exception.ResourceAllocationException;
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.exception.UnsupportedServiceException;
 import com.cloud.host.Host;
-import com.cloud.host.HostVO;
 import com.cloud.host.Status;
 import com.cloud.host.dao.HostDao;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
@@ -3283,7 +3282,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
     }
 
     @Override
-    public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
+    public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
         if (!(cmd instanceof StartupRoutingCommand)) {
             return;
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/network/NetworkUsageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkUsageManagerImpl.java b/server/src/com/cloud/network/NetworkUsageManagerImpl.java
index 80f898b..3ac77f9 100755
--- a/server/src/com/cloud/network/NetworkUsageManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkUsageManagerImpl.java
@@ -481,7 +481,7 @@ public class NetworkUsageManagerImpl extends ManagerBase implements NetworkUsage
         }
 
         @Override
-        public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) {
+        public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) {
             if (cmd instanceof StartupTrafficMonitorCommand) {
                 long agentId = agent.getId();
                 s_logger.debug("Sending RecurringNetworkUsageCommand to " + agentId);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/abf40435/server/src/com/cloud/network/SshKeysDistriMonitor.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/SshKeysDistriMonitor.java b/server/src/com/cloud/network/SshKeysDistriMonitor.java
index 82f72de..cd92ae6 100755
--- a/server/src/com/cloud/network/SshKeysDistriMonitor.java
+++ b/server/src/com/cloud/network/SshKeysDistriMonitor.java
@@ -31,7 +31,7 @@ import com.cloud.agent.manager.Commands;
 import com.cloud.configuration.dao.ConfigurationDao;
 import com.cloud.exception.AgentUnavailableException;
 import com.cloud.exception.ConnectionException;
-import com.cloud.host.HostVO;
+import com.cloud.host.Host;
 import com.cloud.host.Status;
 import com.cloud.host.dao.HostDao;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
@@ -69,7 +69,7 @@ public class SshKeysDistriMonitor implements Listener {
 	    }
 	    
 	    @Override
-	    public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
+	    public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
 	    	if (cmd instanceof StartupRoutingCommand) {
 	    		if (((StartupRoutingCommand) cmd).getHypervisorType() == HypervisorType.KVM ||
                     ((StartupRoutingCommand) cmd).getHypervisorType() == HypervisorType.XenServer ||