You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mc...@apache.org on 2013/04/20 04:37:49 UTC

git commit: updated refs/heads/object_store to 6f70fe2

Updated Branches:
  refs/heads/object_store b8229349f -> 6f70fe28e


Trigger system vm template download while adding image store. Just a
code skeleton, waiting for some code in EndPoint.

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

Branch: refs/heads/object_store
Commit: 6f70fe28e829dcbae0d16cbce7144c6440255391
Parents: b822934
Author: Min Chen <mi...@citrix.com>
Authored: Fri Apr 19 19:37:06 2013 -0700
Committer: Min Chen <mi...@citrix.com>
Committed: Fri Apr 19 19:37:06 2013 -0700

----------------------------------------------------------------------
 .../api/storage/DownloadSystemTemplateCommand.java |  154 +++++++++++++++
 .../resource/LocalNfsSecondaryStorageResource.java |   73 +++++++
 .../resource/NfsSecondaryStorageResource.java      |   24 ++--
 .../subsystem/api/storage/TemplateService.java     |    1 +
 .../storage/image/TemplateServiceImpl.java         |   24 +++
 .../src/com/cloud/storage/StorageManagerImpl.java  |    6 +
 .../cloud/storage/download/DownloadMonitor.java    |    5 +-
 .../storage/download/DownloadMonitorImpl.java      |   71 +++++++
 8 files changed, 345 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6f70fe28/api/src/com/cloud/agent/api/storage/DownloadSystemTemplateCommand.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/storage/DownloadSystemTemplateCommand.java b/api/src/com/cloud/agent/api/storage/DownloadSystemTemplateCommand.java
new file mode 100644
index 0000000..d7efcc0
--- /dev/null
+++ b/api/src/com/cloud/agent/api/storage/DownloadSystemTemplateCommand.java
@@ -0,0 +1,154 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.agent.api.storage;
+
+import java.net.URI;
+
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.storage.DownloadCommand.Proxy;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.template.VirtualMachineTemplate;
+
+
+public class DownloadSystemTemplateCommand extends Command {
+	public static class PasswordAuth {
+		String userName;
+		String password;
+		public PasswordAuth() {
+
+		}
+		public PasswordAuth(String user, String password) {
+			this.userName = user;
+			this.password = password;
+		}
+		public String getUserName() {
+			return userName;
+		}
+		public String getPassword() {
+			return password;
+		}
+	}
+
+
+	private PasswordAuth auth;
+	private Proxy _proxy;
+	private DataStoreTO _store;
+    private Long resourceId;
+    private Long accountId;
+    private String url;
+    private Long maxDownloadSizeInBytes;
+
+	protected DownloadSystemTemplateCommand() {
+	}
+
+
+
+	public DownloadSystemTemplateCommand(DataStoreTO store, String secUrl, VirtualMachineTemplate template, Long maxDownloadSizeInBytes) {
+	    this._store = store;
+	    this.accountId = template.getAccountId();
+	    this.url = secUrl;
+	    this.maxDownloadSizeInBytes = maxDownloadSizeInBytes;
+	    this.resourceId = template.getId();
+	}
+
+
+	public DownloadSystemTemplateCommand(DataStoreTO store, String secUrl, String url, VirtualMachineTemplate template, String user, String passwd, Long maxDownloadSizeInBytes) {
+        this._store = store;
+        this.accountId = template.getAccountId();
+        this.url = secUrl;
+        this.maxDownloadSizeInBytes = maxDownloadSizeInBytes;
+        this.resourceId = template.getId();
+		auth = new PasswordAuth(user, passwd);
+	}
+
+
+
+
+	public PasswordAuth getAuth() {
+		return auth;
+	}
+
+	public void setCreds(String userName, String passwd) {
+		auth = new PasswordAuth(userName, passwd);
+	}
+
+	public Proxy getProxy() {
+		return _proxy;
+	}
+
+	public void setProxy(Proxy proxy) {
+		_proxy = proxy;
+	}
+
+	public Long getMaxDownloadSizeInBytes() {
+		return maxDownloadSizeInBytes;
+	}
+
+
+    public DataStoreTO getDataStore() {
+        return _store;
+    }
+
+
+    public void setDataStore(DataStoreTO _store) {
+        this._store = _store;
+    }
+
+
+    public Long getResourceId() {
+        return resourceId;
+    }
+
+
+    public void setResourceId(Long resourceId) {
+        this.resourceId = resourceId;
+    }
+
+
+
+    public Long getAccountId() {
+        return accountId;
+    }
+
+
+
+    public void setAccountId(Long accountId) {
+        this.accountId = accountId;
+    }
+
+
+
+    public String getUrl() {
+        return url;
+    }
+
+
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+
+
+    @Override
+    public boolean executeInSequence() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6f70fe28/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java
index f0c4310..c258332 100644
--- a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java
+++ b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java
@@ -1,9 +1,82 @@
 package com.cloud.storage.resource;
 
+import static com.cloud.utils.StringUtils.join;
+import static java.lang.String.format;
+import static java.util.Arrays.asList;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+
 import org.springframework.stereotype.Component;
 
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.storage.DownloadSystemTemplateCommand;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.S3TO;
+import com.cloud.agent.api.to.SwiftTO;
+import com.cloud.utils.S3Utils;
+import com.cloud.utils.UriUtils;
+import com.cloud.utils.exception.CloudRuntimeException;
+
 @Component
 public class LocalNfsSecondaryStorageResource extends
 		NfsSecondaryStorageResource {
 
+    @Override
+    public Answer executeRequest(Command cmd) {
+        if (cmd instanceof DownloadSystemTemplateCommand){
+            return execute((DownloadSystemTemplateCommand)cmd);
+        } else {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+    }
+
+    private Answer execute(DownloadSystemTemplateCommand cmd){
+        DataStoreTO dstore = cmd.getDataStore();
+        if ( dstore instanceof S3TO ){
+            //TODO: how to handle download progress for S3
+            S3TO s3 = (S3TO)cmd.getDataStore();
+            String url = cmd.getUrl();
+            String user = null;
+            String password = null;
+            if (cmd.getAuth() != null) {
+                user = cmd.getAuth().getUserName();
+                password = new String(cmd.getAuth().getPassword());
+            }
+            // get input stream from the given url
+            InputStream in = UriUtils.getInputStreamFromUrl(url, user, password);
+            URI uri;
+            URL urlObj;
+            try {
+                uri = new URI(url);
+                urlObj = new URL(url);
+            } catch (URISyntaxException e) {
+                throw new CloudRuntimeException("URI is incorrect: " + url);
+            } catch (MalformedURLException e) {
+                throw new CloudRuntimeException("URL is incorrect: " + url);
+            }
+
+            final String bucket = s3.getBucketName();
+            String key = join(asList(determineS3TemplateDirectory(cmd.getAccountId(), cmd.getResourceId()), urlObj.getFile()), S3Utils.SEPARATOR);
+            S3Utils.putObject(s3, in, bucket, key);
+            return new Answer(cmd, true, format("Uploaded the contents of input stream from %1$s for template id %2$s to S3 bucket %3$s", url,
+                    cmd.getResourceId(), bucket));
+        }
+        else if ( dstore instanceof NfsTO ){
+            return new Answer(cmd, false, "Nfs needs to be pre-installed with system vm templates");
+        }
+        else if ( dstore instanceof SwiftTO ){
+            //TODO: need to move code from execute(uploadTemplateToSwiftFromSecondaryStorageCommand) here, but we need to handle
+            // source is url, most likely we need to modify our existing swiftUpload python script.
+            return new Answer(cmd, false, "Swift is not currently support DownloadCommand");
+        }
+        else{
+            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6f70fe28/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java
index 3ad0758..e8abcbf 100755
--- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java
+++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java
@@ -221,7 +221,7 @@ SecondaryStorageResource {
             return Answer.createUnsupportedCommandAnswer(cmd);
         }
     }
-    
+
     protected Answer downloadFromS3ToNfs(CopyCmd cmd, DataTO srcData, S3TO s3,
     		DataTO destData, NfsTO destImageStore) {
           final String storagePath = destImageStore.getUrl();
@@ -264,27 +264,27 @@ SecondaryStorageResource {
               return new Answer(cmd, false, errMsg);
           }
     }
-    
+
     protected Answer downloadFromSwiftToNfs(CopyCmd cmd, DataTO srcData, SwiftTO srcImageStore,
     		DataTO destData, NfsTO destImageStore) {
     	return Answer.createUnsupportedCommandAnswer(cmd);
-    } 
-    
+    }
+
     protected Answer execute(CopyCmd cmd) {
     	DataTO srcData = cmd.getSrcTO();
     	DataTO destData = cmd.getDestTO();
     	DataStoreTO srcDataStore = srcData.getDataStore();
     	DataStoreTO destDataStore = destData.getDataStore();
-    	
-    	if (srcDataStore.getRole() == DataStoreRole.Image 
+
+    	if (srcDataStore.getRole() == DataStoreRole.Image
     			&& destDataStore.getRole() == DataStoreRole.ImageCache
     			) {
-    		
+
     		if (!(destDataStore instanceof NfsTO)) {
     			s_logger.debug("only support nfs as cache storage");
-    			return Answer.createUnsupportedCommandAnswer(cmd); 
+    			return Answer.createUnsupportedCommandAnswer(cmd);
     		}
-    		
+
     		if (srcDataStore instanceof S3TO) {
     			return downloadFromS3ToNfs(cmd, srcData, (S3TO)srcDataStore,
     					destData, (NfsTO)destDataStore);
@@ -292,15 +292,15 @@ SecondaryStorageResource {
     			return downloadFromSwiftToNfs(cmd, srcData, (SwiftTO)srcDataStore,
     					destData, (NfsTO)destDataStore);
     		} else {
-    			return Answer.createUnsupportedCommandAnswer(cmd); 
+    			return Answer.createUnsupportedCommandAnswer(cmd);
     		}
-    		
+
     	}
     	return Answer.createUnsupportedCommandAnswer(cmd);
     }
 
     @SuppressWarnings("unchecked")
-    private String determineS3TemplateDirectory(final Long accountId,
+    protected String determineS3TemplateDirectory(final Long accountId,
             final Long templateId) {
         return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId),
                 S3Utils.SEPARATOR);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6f70fe28/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 6bb58e0..ec027fe 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
@@ -32,4 +32,5 @@ public interface TemplateService {
 
     void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId);
     void handleTemplateSync(DataStore store);
+    void downloadBootstrapSysTemplate(DataStore store);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6f70fe28/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 c16e47c..0a24960 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
@@ -185,6 +185,30 @@ public class TemplateServiceImpl implements TemplateService {
         return future;
     }
 
+    @Override
+    public void downloadBootstrapSysTemplate(DataStore store) {
+        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);
+            }
+        }
+    }
+
+
 
     @Override
     public void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6f70fe28/server/src/com/cloud/storage/StorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java
index fb3d320..2236575 100755
--- a/server/src/com/cloud/storage/StorageManagerImpl.java
+++ b/server/src/com/cloud/storage/StorageManagerImpl.java
@@ -60,6 +60,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider;
 import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
@@ -325,6 +326,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
     DataStoreManager _dataStoreMgr;
     @Inject
     DataStoreProviderManager _dataStoreProviderMgr;
+    @Inject
+    private TemplateService _imageSrv;
 
     protected List<StoragePoolAllocator> _storagePoolAllocators;
     public List<StoragePoolAllocator> getStoragePoolAllocators() {
@@ -1986,6 +1989,9 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
             throw new CloudRuntimeException("Failed to add data store", e);
         }
 
+        // trigger system vm template download
+        this._imageSrv.downloadBootstrapSysTemplate(store);
+
         return (ImageStore) _dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Image);
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6f70fe28/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 e709e90..efbdbe2 100644
--- a/server/src/com/cloud/storage/download/DownloadMonitor.java
+++ b/server/src/com/cloud/storage/download/DownloadMonitor.java
@@ -33,7 +33,10 @@ import com.cloud.utils.component.Manager;
  */
 public interface DownloadMonitor extends Manager{
 
-	public void downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback<CreateCmdResult> callback);
+    // 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);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6f70fe28/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 6af8db5..c7b360a 100755
--- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
+++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
@@ -30,6 +30,9 @@ import javax.inject.Inject;
 import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
 import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
 import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
@@ -48,6 +51,7 @@ 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.RequestType;
+import com.cloud.agent.api.storage.DownloadSystemTemplateCommand;
 
 import com.cloud.agent.api.storage.DownloadProgressCommand;
 import com.cloud.agent.manager.Commands;
@@ -177,6 +181,10 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
     protected UserVmDao _userVmDao;
     @Inject
     protected AccountManager _accountMgr;
+    @Inject
+    EndPointSelector _epSelector;
+    @Inject
+    TemplateDataFactory tmplFactory;
 
     private Boolean _sslCopy = new Boolean(false);
     private String _copyAuthPasswd;
@@ -423,6 +431,69 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
         }
     }
 
+
+    @Override
+    public void downloadBootstrapSysTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback<CreateCmdResult> callback) {
+        boolean downloadJobExists = false;
+        TemplateDataStoreVO vmTemplateStore = null;
+
+        vmTemplateStore = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId());
+        if (vmTemplateStore == null) {
+            // This method can be invoked other places, for example,
+            // handleTemplateSync, in that case, vmTemplateStore may be null
+            vmTemplateStore = new TemplateDataStoreVO(store.getId(), template.getId(), new Date(), 0,
+                    VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, template.getUrl());
+            _vmTemplateStoreDao.persist(vmTemplateStore);
+        } else if ((vmTemplateStore.getJobId() != null) && (vmTemplateStore.getJobId().length() > 2)) {
+            downloadJobExists = true;
+        }
+
+        Long maxTemplateSizeInBytes = getMaxTemplateSizeInBytes();
+        String secUrl = store.getUri();
+        if (vmTemplateStore != null) {
+            start();
+            DownloadSystemTemplateCommand dcmd = new DownloadSystemTemplateCommand(store.getTO(), secUrl, template, maxTemplateSizeInBytes);
+            dcmd.setProxy(getHttpProxy());
+            // TODO: handle S3 download progress
+            // if (downloadJobExists) {
+            // dcmd = new DownloadProgressCommand(dcmd,
+            // vmTemplateStore.getJobId(), RequestType.GET_OR_RESTART);
+            // }
+            if (vmTemplateStore.isCopy()) {
+                dcmd.setCreds(TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd);
+            }
+            EndPoint endPoint = _epSelector.select(this.tmplFactory.getTemplate(template.getId(), store));
+            if (endPoint == null) {
+                s_logger.warn("There is no endpoint to send download template command");
+                return;
+            }
+            // TODO: wait for Edison's code to pass a listener to
+            // LocalHostEndPoint
+            /*
+            DownloadListener dl = new DownloadListener(ssAhost, store, template, _timer, _vmTemplateStoreDao, vmTemplateStore.getId(), this, dcmd,
+                    _templateDao, _resourceLimitMgr, _alertMgr, _accountMgr, callback);
+            if (downloadJobExists) {
+                // due to handling existing download job issues, we still keep
+                // downloadState in template_store_ref to avoid big change in
+                // DownloadListener to use
+                // new ObjectInDataStore.State transition. TODO: fix this later
+                // to be able to remove downloadState from template_store_ref.
+                dl.setCurrState(vmTemplateStore.getDownloadState());
+            }
+            DownloadListener old = null;
+            synchronized (_listenerTemplateMap) {
+                old = _listenerTemplateMap.put(vmTemplateStore, dl);
+            }
+            if (old != null) {
+                old.abandon();
+            }
+            */
+            // endPoint.sendMessageAsync(dcmd, callback);
+            endPoint.sendMessage(dcmd); // wait for Edison's callback code
+
+        }
+    }
+
     @Override
     public void downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback<CreateCmdResult> callback) {
         long templateId = template.getId();