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/11/04 21:32:14 UTC

git commit: updated refs/heads/master to 9a62239

Updated Branches:
  refs/heads/master 84b5bfff7 -> 9a62239a9


CLOUDSTACK-5017: Throw CloudRuntimeException in case of template/volume 
download when ssvm is not ready so that caller can remove some leftover
entries in template_store_ref and volume_store_ref.


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

Branch: refs/heads/master
Commit: 9a62239a92c5eafca6fafee1fbccd413bdfb91af
Parents: 84b5bff
Author: Min Chen <mi...@citrix.com>
Authored: Mon Nov 4 12:31:31 2013 -0800
Committer: Min Chen <mi...@citrix.com>
Committed: Mon Nov 4 12:32:05 2013 -0800

----------------------------------------------------------------------
 .../storage/image/TemplateServiceImpl.java      | 48 +++++++++++++-----
 .../storage/volume/VolumeServiceImpl.java       | 52 ++++++++++++++------
 .../storage/download/DownloadMonitorImpl.java   |  6 ++-
 3 files changed, 79 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9a62239a/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 3e3c6d8..308347d 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
@@ -172,12 +172,26 @@ public class TemplateServiceImpl implements TemplateService {
             return;
         }
 
-        TemplateOpContext<TemplateApiResult> context = new TemplateOpContext<TemplateApiResult>(callback,
-                templateOnStore, null);
-
-        AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
-        caller.setCallback(caller.getTarget().createTemplateCallback(null, null)).setContext(context);
-        store.getDriver().createAsync(store, templateOnStore, caller);
+        try {
+            TemplateOpContext<TemplateApiResult> context = new TemplateOpContext<TemplateApiResult>(callback,
+                    templateOnStore, null);
+
+            AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
+            caller.setCallback(caller.getTarget().createTemplateCallback(null, null)).setContext(context);
+            store.getDriver().createAsync(store, templateOnStore, caller);
+        } catch (CloudRuntimeException ex) {
+            // clean up already persisted template_store_ref entry in case of createTemplateCallback is never called
+            TemplateDataStoreVO templateStoreVO = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId());
+            if (templateStoreVO != null) {
+                TemplateInfo tmplObj = _templateFactory.getTemplate(template, store);
+                tmplObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
+            }
+            TemplateApiResult result = new TemplateApiResult(template);
+            result.setResult(ex.getMessage());
+            if (callback != null) {
+                callback.complete(result);
+            }
+        }
     }
 
     @Override
@@ -732,11 +746,23 @@ public class TemplateServiceImpl implements TemplateService {
         if (s_logger.isDebugEnabled()) {
             s_logger.debug("Invoke datastore driver createAsync to create template on destination store");
         }
-        TemplateOpContext<TemplateApiResult> context = new TemplateOpContext<TemplateApiResult>(null,
-                (TemplateObject) templateOnStore, future);
-        AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
-        caller.setCallback(caller.getTarget().copyTemplateCrossZoneCallBack(null, null)).setContext(context);
-        destStore.getDriver().createAsync(destStore, templateOnStore, caller);
+        try {
+            TemplateOpContext<TemplateApiResult> context = new TemplateOpContext<TemplateApiResult>(null,
+                    (TemplateObject)templateOnStore, future);
+            AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
+            caller.setCallback(caller.getTarget().copyTemplateCrossZoneCallBack(null, null)).setContext(context);
+            destStore.getDriver().createAsync(destStore, templateOnStore, caller);
+        } catch (CloudRuntimeException ex) {
+            // clean up already persisted template_store_ref entry in case of createTemplateCallback is never called
+            TemplateDataStoreVO templateStoreVO = _vmTemplateStoreDao.findByStoreTemplate(destStore.getId(), srcTemplate.getId());
+            if (templateStoreVO != null) {
+                TemplateInfo tmplObj = _templateFactory.getTemplate(srcTemplate, destStore);
+                tmplObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
+            }
+            TemplateApiResult res = new TemplateApiResult((TemplateObject)templateOnStore);
+            res.setResult(ex.getMessage());
+            future.complete(res);
+        }
         return future;
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9a62239a/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 79e8cc8..86e49f9 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
@@ -40,6 +40,7 @@ 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.ObjectInDataStoreStateMachine;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
 import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
@@ -55,7 +56,6 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 import org.apache.cloudstack.storage.command.CommandResult;
 import org.apache.cloudstack.storage.command.CopyCmdAnswer;
 import org.apache.cloudstack.storage.command.DeleteCommand;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
 import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager;
 import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
@@ -165,12 +165,24 @@ public class VolumeServiceImpl implements VolumeService {
         DataObject volumeOnStore = dataStore.create(volume);
         volumeOnStore.processEvent(Event.CreateOnlyRequested);
 
-        CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volumeOnStore,
-                future);
-        AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
-        caller.setCallback(caller.getTarget().createVolumeCallback(null, null)).setContext(context);
-
-        dataStore.getDriver().createAsync(dataStore, volumeOnStore, caller);
+        try {
+            CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volumeOnStore,
+                    future);
+            AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
+            caller.setCallback(caller.getTarget().createVolumeCallback(null, null)).setContext(context);
+
+            dataStore.getDriver().createAsync(dataStore, volumeOnStore, caller);
+        } catch (CloudRuntimeException ex) {
+            // clean up already persisted volume_store_ref entry in case of createVolumeCallback is never called
+            VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(dataStore.getId(), volume.getId());
+            if (volStoreVO != null) {
+                VolumeInfo volObj = volFactory.getVolume(volume, dataStore);
+                volObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
+            }
+            VolumeApiResult volResult = new VolumeApiResult((VolumeObject)volumeOnStore);
+            volResult.setResult(ex.getMessage());
+            future.complete(volResult);
+        }
         return future;
     }
 
@@ -1022,13 +1034,25 @@ public class VolumeServiceImpl implements VolumeService {
 
         volumeOnStore.processEvent(Event.CreateOnlyRequested);
 
-        CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volumeOnStore,
-                future);
-        AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
-        caller.setCallback(caller.getTarget().registerVolumeCallback(null, null));
-        caller.setContext(context);
-
-        store.getDriver().createAsync(store, volumeOnStore, caller);
+        try {
+            CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volumeOnStore,
+                    future);
+            AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
+            caller.setCallback(caller.getTarget().registerVolumeCallback(null, null));
+            caller.setContext(context);
+
+            store.getDriver().createAsync(store, volumeOnStore, caller);
+        } catch (CloudRuntimeException ex) {
+            // clean up already persisted volume_store_ref entry in case of createVolumeCallback is never called
+            VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(store.getId(), volume.getId());
+            if (volStoreVO != null) {
+                VolumeInfo volObj = volFactory.getVolume(volume, store);
+                volObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
+            }
+            VolumeApiResult res = new VolumeApiResult((VolumeObject)volumeOnStore);
+            res.setResult(ex.getMessage());
+            future.complete(res);
+        }
         return future;
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9a62239a/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 d455f1e..89b3407 100755
--- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
+++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
@@ -67,6 +67,7 @@ import com.cloud.storage.upload.UploadListener;
 import com.cloud.template.VirtualMachineTemplate;
 import com.cloud.utils.component.ComponentContext;
 import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.exception.CloudRuntimeException;
 
 @Component
 @Local(value = { DownloadMonitor.class })
@@ -169,8 +170,9 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
             }
             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;
+                String errMsg = "There is no secondary storage VM for downloading template to image store " + store.getName();
+                s_logger.warn(errMsg);
+                throw new CloudRuntimeException(errMsg);
             }
             DownloadListener dl = new DownloadListener(ep, store, template, _timer, this, dcmd,
                     callback);