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/01/03 02:44:15 UTC

[1/2] git commit: add create volume

add create volume


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

Branch: refs/heads/javelin
Commit: 5d1e97e407144c1ef2ca1afde66763f96558ed3f
Parents: a4e0c4f
Author: Edison Su <su...@gmail.com>
Authored: Wed Jan 2 17:32:38 2013 -0800
Committer: Edison Su <su...@gmail.com>
Committed: Wed Jan 2 17:32:54 2013 -0800

----------------------------------------------------------------------
 .../engine/cloud/entity/api/VolumeEntity.java      |    1 +
 .../cloudstack/storage/command/CommandResult.java  |    3 +
 .../storage/command/CreateVolumeCommand.java       |    2 +-
 .../storage/datastore/PrimaryDataStore.java        |    2 +-
 .../storage/volume/VolumeEntityImpl.java           |   31 ++++++++++-
 .../cloudstack/storage/volume/VolumeService.java   |   16 +++++-
 .../storage/datastore/DefaultPrimaryDataStore.java |   12 ++--
 .../driver/DefaultPrimaryDataStoreDriverImpl.java  |   45 ++++++++++++--
 .../datastore/driver/PrimaryDataStoreDriver.java   |    2 +-
 .../storage/volume/VolumeServiceImpl.java          |   45 ++++++++++++---
 .../driver/SolidfirePrimaryDataStoreDriver.java    |    2 +-
 11 files changed, 133 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5d1e97e4/engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/VolumeEntity.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/VolumeEntity.java b/engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/VolumeEntity.java
index 4f883c0..47fb638 100755
--- a/engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/VolumeEntity.java
+++ b/engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/VolumeEntity.java
@@ -83,4 +83,5 @@ public interface VolumeEntity extends CloudStackEntity {
     StorageEntity getDataStore();
     
     boolean createVolumeFromTemplate(long dataStoreId, VolumeDiskType diskType, TemplateEntity template);
+    boolean createVolume(long dataStoreId, VolumeDiskType diskType);
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5d1e97e4/engine/storage/src/org/apache/cloudstack/storage/command/CommandResult.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/CommandResult.java b/engine/storage/src/org/apache/cloudstack/storage/command/CommandResult.java
index 5fe8a7e..998f35d 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/command/CommandResult.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/command/CommandResult.java
@@ -41,6 +41,9 @@ public class CommandResult {
     
     public void setResult(String result) {
         this.result = result;
+        if (result != null) {
+            this.success = false;
+        }
     }
 }
  
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5d1e97e4/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeCommand.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeCommand.java b/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeCommand.java
index 3d8880f..e42d265 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeCommand.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeCommand.java
@@ -22,7 +22,7 @@ import org.apache.cloudstack.storage.to.VolumeTO;
 
 import com.cloud.agent.api.Command;
 
-public class CreateVolumeCommand extends Command {
+public class CreateVolumeCommand extends Command implements StorageSubSystemCommand {
     protected VolumeTO volumeInfo;
 
     public CreateVolumeCommand(VolumeTO volumeInfo) {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5d1e97e4/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java
index a945e28..fca9791 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java
@@ -38,7 +38,7 @@ public interface PrimaryDataStore extends PrimaryDataStoreInfo {
 
     boolean deleteVolume(VolumeInfo volume);
 
-    VolumeInfo createVolume(VolumeInfo vo, VolumeDiskType diskType);
+    void createVolumeAsync(VolumeInfo vo, VolumeDiskType diskType, AsyncCompletionCallback<CommandResult> callback);
 
     VolumeInfo createVoluemFromBaseImage(VolumeInfo volume, TemplateOnPrimaryDataStoreInfo templateStore);
     

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5d1e97e4/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java
index 8883e8e..5449534 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java
@@ -35,12 +35,14 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 import org.apache.cloudstack.storage.datastore.PrimaryDataStoreEntityImpl;
 import org.apache.cloudstack.storage.image.TemplateEntityImpl;
 import org.apache.cloudstack.storage.image.TemplateInfo;
+import org.apache.cloudstack.storage.volume.VolumeService.VolumeApiResult;
 
 import com.cloud.utils.exception.CloudRuntimeException;
 
 public class VolumeEntityImpl implements VolumeEntity {
     private VolumeInfo volumeInfo;
     private final VolumeService vs;
+    private VolumeApiResult result;
     
     protected VolumeEntityImpl() {
         this.vs = null;
@@ -217,11 +219,38 @@ public class VolumeEntityImpl implements VolumeEntity {
     }
     
    
-    public Object createVolumeFromTemplateAsyncCallback(AsyncCompletionCallback<VolumeInfo> callback, Object context) {
+    private Void createVolumeFromTemplateAsyncCallback(AsyncCompletionCallback<VolumeInfo> callback, Object context) {
         synchronized (volumeInfo) {
             volumeInfo.notify();
         }
         return null;
     }
 
+    @Override
+    public boolean createVolume(long dataStoreId, VolumeDiskType diskType) {
+        AsyncCallbackDispatcher<VolumeEntityImpl> caller = AsyncCallbackDispatcher.create(this);
+        caller.setCallback(caller.getTarget().createVolumeCallback(null, null));
+        vs.createVolumeAsync(volumeInfo, dataStoreId, diskType, caller);
+        try {
+            synchronized (volumeInfo) {
+                volumeInfo.wait();
+            }
+            if (result.isSuccess()) {
+                return true;
+            } else {
+                throw new CloudRuntimeException("Failed to create volume:" + result.getResult());
+            }
+        } catch (InterruptedException e) {
+           throw new CloudRuntimeException("wait volume info failed", e);
+        }
+    }
+    
+    private Void createVolumeCallback(AsyncCallbackDispatcher<VolumeApiResult> callback, Object context) {
+        synchronized (volumeInfo) {
+            this.result = callback.getResult();
+            volumeInfo.notify();
+        }
+        return null;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5d1e97e4/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeService.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeService.java b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeService.java
index 716c260..fcf6f98 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeService.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeService.java
@@ -24,9 +24,21 @@ import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskTyp
 import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType;
 import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 import org.apache.cloudstack.storage.EndPoint;
+import org.apache.cloudstack.storage.command.CommandResult;
 import org.apache.cloudstack.storage.image.TemplateInfo;
 
 public interface VolumeService {
+    
+    public class VolumeApiResult extends CommandResult {
+        private final VolumeInfo volume;
+        public VolumeApiResult(VolumeInfo volume) {
+            this.volume = volume;
+        }
+        
+        public VolumeInfo getVolume() {
+            return this.volume;
+        }
+    }
     /**
 	 * 
 	 */
@@ -39,7 +51,7 @@ public interface VolumeService {
      * 
      * @return the volume object
      */
-    VolumeInfo createVolume(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType);
+    void createVolumeAsync(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType, AsyncCompletionCallback<VolumeApiResult> callback);
 
     /**
      * Delete volume
@@ -75,5 +87,5 @@ public interface VolumeService {
     VolumeEntity getVolumeEntity(long volumeId);
 
     void createVolumeFromTemplateAsync(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType, TemplateInfo template, 
-            AsyncCompletionCallback<VolumeInfo> callback);
+            AsyncCompletionCallback<VolumeApiResult> callback);
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5d1e97e4/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/DefaultPrimaryDataStore.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/DefaultPrimaryDataStore.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/DefaultPrimaryDataStore.java
index 13b6f4a..3d3ce68 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/DefaultPrimaryDataStore.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/DefaultPrimaryDataStore.java
@@ -34,6 +34,8 @@ import com.cloud.host.HostVO;
 import com.cloud.host.dao.HostDao;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.utils.component.ComponentInject;
+import com.cloud.utils.exception.CloudRuntimeException;
+
 import edu.emory.mathcs.backport.java.util.Collections;
 
 public class DefaultPrimaryDataStore implements PrimaryDataStore {
@@ -155,8 +157,7 @@ public class DefaultPrimaryDataStore implements PrimaryDataStore {
 
     @Override
     public boolean isVolumeDiskTypeSupported(VolumeDiskType diskType) {
-        // TODO Auto-generated method stub
-        return false;
+        return true;
     }
 
     @Override
@@ -170,14 +171,13 @@ public class DefaultPrimaryDataStore implements PrimaryDataStore {
     }
 
     @Override
-    public VolumeObject createVolume(VolumeInfo vi, VolumeDiskType diskType) {
+    public void createVolumeAsync(VolumeInfo vi, VolumeDiskType diskType, AsyncCompletionCallback<CommandResult> callback) {
         if (!isVolumeDiskTypeSupported(diskType)) {
-            return null;
+            throw new CloudRuntimeException("disk type " + diskType + " is not supported");
         }
         VolumeObject vo = (VolumeObject) vi;
         vo.setVolumeDiskType(diskType);
-        this.driver.createVolume(vo);
-        return vo;
+        this.driver.createVolumeAsync(vo, callback);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5d1e97e4/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java
index 9506d7c..e88d707 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java
@@ -41,18 +41,49 @@ public class DefaultPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
         this.dataStore = dataStore;
     }
     
+    private class CreateVolumeContext<T> extends AsyncRpcConext<T> {
+        private final VolumeObject volume;
+        /**
+         * @param callback
+         */
+        public CreateVolumeContext(AsyncCompletionCallback<T> callback, VolumeObject volume) {
+            super(callback);
+            this.volume = volume;
+        }
+        
+        public VolumeObject getVolume() {
+            return this.volume;
+        }
+        
+    }
+    
     @Override
-    public boolean createVolume(VolumeObject vol) {
-        // The default driver will send createvolume command to one of hosts
-        // which can access its datastore
+    public void createVolumeAsync(VolumeObject vol, AsyncCompletionCallback<CommandResult> callback) {
         List<EndPoint> endPoints = vol.getDataStore().getEndPoints();
+        EndPoint ep = endPoints.get(0);
         VolumeInfo volInfo = vol;
         CreateVolumeCommand createCmd = new CreateVolumeCommand(this.dataStore.getVolumeTO(volInfo));
-        Answer answer = sendOutCommand(createCmd, endPoints);
+        
+        CreateVolumeContext<CommandResult> context = new CreateVolumeContext<CommandResult>(callback, vol);
+        AsyncCallbackDispatcher<DefaultPrimaryDataStoreDriverImpl> caller = AsyncCallbackDispatcher.create(this);
+        caller.setContext(context)
+            .setCallback(caller.getTarget().createVolumeAsyncCallback(null, null));
 
-        CreateVolumeAnswer volAnswer = (CreateVolumeAnswer) answer;
-        vol.setPath(volAnswer.getVolumeUuid());
-        return true;
+        ep.sendMessageAsync(createCmd, caller);
+    }
+    
+    protected Void createVolumeAsyncCallback(AsyncCallbackDispatcher<DefaultPrimaryDataStoreDriverImpl> callback, CreateVolumeContext<CommandResult> context) {
+        CommandResult result = new CommandResult();
+        CreateVolumeAnswer volAnswer = (CreateVolumeAnswer) callback.getResult();
+        if (volAnswer.getResult()) {
+            VolumeObject volume = context.getVolume();
+            volume.setPath(volAnswer.getVolumeUuid());
+        } else {
+            result.setResult(volAnswer.getDetails());
+        }
+        
+        context.getParentCallback().complete(result);
+        return null;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5d1e97e4/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java
index 04694aa..96e629e 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java
@@ -10,7 +10,7 @@ import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
 import org.apache.cloudstack.storage.volume.VolumeObject;
 
 public interface PrimaryDataStoreDriver {
-    boolean createVolume(VolumeObject vol);
+    void createVolumeAsync(VolumeObject vol, AsyncCompletionCallback<CommandResult> callback);
 
     void createVolumeFromBaseImageAsync(VolumeObject volume, TemplateOnPrimaryDataStoreInfo template, AsyncCompletionCallback<CommandResult> callback);
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5d1e97e4/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 b5687fd..d5d2681 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
@@ -59,28 +59,58 @@ public class VolumeServiceImpl implements VolumeService {
     public VolumeServiceImpl() {
     }
     
+    private class CreateVolumeContext<T> extends AsyncRpcConext<T> {
+
+        private VolumeObject volume;
+        /**
+         * @param callback
+         */
+        public CreateVolumeContext(AsyncCompletionCallback<T> callback, VolumeObject volume) {
+            super(callback);
+            this.volume = volume;
+        }
+        
+        public VolumeObject getVolume() {
+            return this.volume;
+        }
+        
+    }
+    
     @Override
-    public VolumeInfo createVolume(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType) {
+    public void createVolumeAsync(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType, AsyncCompletionCallback<VolumeApiResult> callback) {
         PrimaryDataStore dataStore = dataStoreMgr.getPrimaryDataStore(dataStoreId);
         if (dataStore == null) {
             throw new CloudRuntimeException("Can't find dataStoreId: " + dataStoreId);
         }
 
         if (dataStore.exists(volume)) {
-            return volume;
+            throw new CloudRuntimeException("Volume: " + volume.getId() + " already exists on primary data store: " + dataStoreId);
         }
 
         VolumeObject vo = (VolumeObject) volume;
         vo.stateTransit(Volume.Event.CreateRequested);
 
-        try {
-            VolumeInfo vi = dataStore.createVolume(vo, diskType);
+        CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(callback, vo);
+        AsyncCallbackDispatcher<VolumeServiceImpl> caller = AsyncCallbackDispatcher.create(this);
+        caller.setCallback(caller.getTarget().createVolumeCallback(null, null))
+        .setContext(context);
+        
+        dataStore.createVolumeAsync(vo, diskType, caller);
+    }
+    
+    protected Void createVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl> callback, CreateVolumeContext<VolumeApiResult> context) {
+        CommandResult result = callback.getResult();
+        VolumeObject vo = context.getVolume();
+        VolumeApiResult volResult = new VolumeApiResult(vo);
+        if (result.isSuccess()) {
             vo.stateTransit(Volume.Event.OperationSucceeded);
-            return vi;
-        } catch (Exception e) {
+        } else {
             vo.stateTransit(Volume.Event.OperationFailed);
-            throw new CloudRuntimeException(e.toString());
+            volResult.setResult(result.getResult());
         }
+        
+        context.getParentCallback().complete(volResult);
+        return null;
     }
 
     @DB
@@ -240,7 +270,6 @@ public class VolumeServiceImpl implements VolumeService {
         }
         
         AsyncCompletionCallback<VolumeInfo> parentCall = context.getParentCallback();
-        parentCall.complete(vo);
         return null;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5d1e97e4/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
----------------------------------------------------------------------
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
index d2d229b..a891ffe 100644
--- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
+++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
@@ -12,7 +12,7 @@ import org.apache.cloudstack.storage.volume.VolumeObject;
 public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
 
 	@Override
-	public boolean createVolume(VolumeObject vol) {
+	public boolean createVolumeAsync(VolumeObject vol) {
 		// TODO Auto-generated method stub
 		return false;
 	}