Updated Branches:
  refs/heads/javelin 01a4a51ab -> 716a5673d

1st try to add async api in the storage component, it's ugly like hell


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

Branch: refs/heads/javelin
Commit: 716a5673d0b5a7ec46ade3c40c3965f080f024b4
Parents: 01a4a51
Author: Edison Su <[email protected]>
Authored: Fri Dec 14 18:25:40 2012 -0800
Committer: Edison Su <[email protected]>
Committed: Fri Dec 14 18:25:40 2012 -0800

----------------------------------------------------------------------
 .../engine/subsystem/api/storage/EndPoint.java     |    8 -
 .../api/storage/PrimaryDataStoreInfo.java          |    1 +
 .../cloudstack/storage/image/ImageServiceImpl.java |    2 +-
 .../image/motion/DefaultImageMotionStrategy.java   |   35 +++++-
 .../image/motion/ImageMotionServiceImpl.java       |   38 ++++++-
 .../storage/image/motion/ImageMotionStrategy.java  |    6 +-
 engine/storage/pom.xml                             |    5 +
 .../org/apache/cloudstack/storage/EndPoint.java    |   11 ++
 .../cloudstack/storage/HypervisorHostEndPoint.java |   25 +++-
 .../storage/HypervsiorHostEndPointRpcServer.java   |   55 ++++++++
 .../cloudstack/storage/command/CommandResult.java  |   46 +++++++
 .../CopyTemplateToPrimaryStorageAnswer.java        |   10 ++-
 .../storage/datastore/PrimaryDataStore.java        |    8 +-
 .../cloudstack/storage/image/ImageService.java     |    2 +-
 .../storage/image/motion/ImageMotionService.java   |    3 +
 .../cloudstack/storage/volume/VolumeService.java   |    6 +-
 .../storage/datastore/DefaultPrimaryDataStore.java |    4 +-
 .../driver/DefaultPrimaryDataStoreDriverImpl.java  |    2 +-
 .../datastore/driver/PrimaryDataStoreDriver.java   |    2 +-
 .../storage/volume/VolumeServiceImpl.java          |  101 +++++++++++----
 .../cloudstack/storage/volume/test/Server.java     |   39 ++++++
 .../cloudstack/storage/volume/test/Server1.java    |   27 ++++
 .../storage/volume/test/TestInProcessAsync.java    |   40 ++++++
 .../storage/volume/test/resource/testContext.xml   |   31 ++++-
 framework/ipc/pom.xml                              |    1 +
 .../framework/async/AsyncCallbackDispatcher.java   |   11 ++-
 .../sampleserver/SampleManagerComponent2.java      |    4 +
 .../driver/SolidfirePrimaryDataStoreDriver.java    |    2 +-
 28 files changed, 473 insertions(+), 52 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/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
deleted file mode 100644
index cecc6f5..0000000
--- 
a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.apache.cloudstack.engine.subsystem.api.storage;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-
-public interface EndPoint {
-       public Answer sendMessage(Command cmd);
-}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java
----------------------------------------------------------------------
diff --git 
a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java
 
b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java
index 27ea41c..e53b6a2 100644
--- 
a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java
+++ 
b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java
@@ -23,6 +23,7 @@ import java.util.List;
 
 import 
org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity.State;
 import 
org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType;
+import org.apache.cloudstack.storage.EndPoint;
 
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageServiceImpl.java
 
b/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageServiceImpl.java
index 38f669b..6499db1 100644
--- 
a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageServiceImpl.java
+++ 
b/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageServiceImpl.java
@@ -21,7 +21,7 @@ package org.apache.cloudstack.storage.image;
 import javax.inject.Inject;
 
 import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.storage.EndPoint;
 import org.apache.cloudstack.storage.image.downloader.ImageDownloader;
 import org.apache.cloudstack.storage.image.manager.ImageDataStoreManager;
 import 
org.apache.cloudstack.storage.image.provider.ImageDataStoreProviderManager;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java
----------------------------------------------------------------------
diff --git 
a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java
 
b/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java
index 625cdc9..be541b5 100644
--- 
a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java
+++ 
b/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java
@@ -18,13 +18,20 @@
  */
 package org.apache.cloudstack.storage.image.motion;
 
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
+import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
+import org.apache.cloudstack.framework.async.AsyncCallbackHandler;
+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.command.CopyTemplateToPrimaryStorage;
+import 
org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageAnswer;
 import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO;
 import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
 import org.springframework.stereotype.Component;
 
+import com.cloud.agent.api.Answer;
+
 @Component
 public class DefaultImageMotionStrategy implements ImageMotionStrategy {
 
@@ -48,4 +55,30 @@ public class DefaultImageMotionStrategy implements 
ImageMotionStrategy {
         return true;
     }
 
+    @Override
+    public void copyTemplateAsync(TemplateOnPrimaryDataStoreInfo 
templateStore, EndPoint ep, AsyncCompletionCallback<CommandResult> callback) {
+        ImageOnPrimayDataStoreTO imageTo = new 
ImageOnPrimayDataStoreTO(templateStore);
+        CopyTemplateToPrimaryStorage copyCommand = new 
CopyTemplateToPrimaryStorage(imageTo);
+        AsyncCallbackDispatcher<Answer> caller = new 
AsyncCallbackDispatcher<Answer>(this).setParentCallback(callback)
+                .setOperationName("defaultImageStrategy.copytemplate.callback")
+                .setContextParam("templateStore", templateStore);
+        ep.sendMessageAsync(copyCommand, caller);
+    }
+    
+    
@AsyncCallbackHandler(operationName="defaultImageStrategy.copytemplate.callback")
+    public void copyTemplateCallBack(AsyncCallbackDispatcher callback) {
+        AsyncCallbackDispatcher parentCall = callback.getParentCallback();
+        CopyTemplateToPrimaryStorageAnswer answer = callback.getResult();
+        CommandResult result = new CommandResult();
+       
+        result.setSucess(answer.getResult());
+        result.setResult(answer.getDetails());
+        if (answer.getResult()) {
+            TemplateOnPrimaryDataStoreInfo templateStore = 
callback.getContextParam("templateStore");
+            templateStore.setPath(answer.getPath());
+        }
+        
+        parentCall.complete(result);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionServiceImpl.java
 
b/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionServiceImpl.java
index 85db4dc..85baba6 100644
--- 
a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionServiceImpl.java
+++ 
b/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionServiceImpl.java
@@ -22,7 +22,11 @@ import java.util.List;
 
 import javax.inject.Inject;
 
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
+import org.apache.cloudstack.framework.async.AsyncCallbackHandler;
+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.ImageService;
 import org.apache.cloudstack.storage.image.TemplateInfo;
 import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
@@ -67,4 +71,36 @@ public class ImageMotionServiceImpl implements 
ImageMotionService {
         imageService.grantTemplateAccess(template, ep);
         return ims.copyTemplate(templateStore, ep);
     }
+
+    @Override
+    public void copyTemplateAsync(TemplateOnPrimaryDataStoreInfo 
templateStore, AsyncCompletionCallback<CommandResult> callback) {
+        ImageMotionStrategy ims = null;
+        for (ImageMotionStrategy strategy : motionStrategies) {
+            if (strategy.canHandle(templateStore)) {
+                ims = strategy;
+                break;
+            }
+        }
+
+        if (ims == null) {
+            throw new CloudRuntimeException("Can't find proper image motion 
strategy");
+        }
+
+        EndPoint ep = ims.getEndPoint(templateStore);
+        volumeService.grantAccess(templateStore, ep);
+        TemplateInfo template = templateStore.getTemplate();
+        imageService.grantTemplateAccess(template, ep);
+        
+        AsyncCallbackDispatcher caller = new AsyncCallbackDispatcher(this)
+            .setParentCallback(callback)
+            .setOperationName("imagemotionService.copytemplate.callback");
+        
+        ims.copyTemplateAsync(templateStore, ep, caller);
+    }
+    
+    
@AsyncCallbackHandler(operationName="imagemotionService.copytemplate.callback")
+    public void copyTemplateAsyncCallback(AsyncCallbackDispatcher callback) {
+        AsyncCallbackDispatcher parentCaller = callback.getParentCallback();
+        parentCaller.complete(callback.getResult());
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionStrategy.java
----------------------------------------------------------------------
diff --git 
a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionStrategy.java
 
b/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionStrategy.java
index e1df9e2..f1f4c7b 100644
--- 
a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionStrategy.java
+++ 
b/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionStrategy.java
@@ -18,8 +18,10 @@
  */
 package org.apache.cloudstack.storage.image.motion;
 
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.storage.EndPoint;
 import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
+import org.apache.cloudstack.storage.command.CommandResult;
 
 public interface ImageMotionStrategy {
     public boolean canHandle(TemplateOnPrimaryDataStoreInfo templateStore);
@@ -27,4 +29,6 @@ public interface ImageMotionStrategy {
     public EndPoint getEndPoint(TemplateOnPrimaryDataStoreInfo templateStore);
 
     public boolean copyTemplate(TemplateOnPrimaryDataStoreInfo templateStore, 
EndPoint ep);
+    
+    public void copyTemplateAsync(TemplateOnPrimaryDataStoreInfo 
templateStore, EndPoint ep, AsyncCompletionCallback<CommandResult> callback);
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/engine/storage/pom.xml
----------------------------------------------------------------------
diff --git a/engine/storage/pom.xml b/engine/storage/pom.xml
index 95eeade..e8a2eb7 100644
--- a/engine/storage/pom.xml
+++ b/engine/storage/pom.xml
@@ -42,6 +42,11 @@
     </dependency>
     <dependency>
       <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-framework-ipc</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
       <artifactId>cloud-engine-api</artifactId>
       <version>${project.version}</version>
     </dependency>

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/engine/storage/src/org/apache/cloudstack/storage/EndPoint.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/EndPoint.java 
b/engine/storage/src/org/apache/cloudstack/storage/EndPoint.java
new file mode 100644
index 0000000..e92877c
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/EndPoint.java
@@ -0,0 +1,11 @@
+package org.apache.cloudstack.storage;
+
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+
+public interface EndPoint {
+       public Answer sendMessage(Command cmd);
+       public void sendMessageAsync(Command cmd, 
AsyncCompletionCallback<Answer> callback);
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPoint.java
----------------------------------------------------------------------
diff --git 
a/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPoint.java 
b/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPoint.java
index a7c1041..5b42259 100644
--- 
a/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPoint.java
+++ 
b/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPoint.java
@@ -20,7 +20,9 @@ package org.apache.cloudstack.storage;
 
 import javax.inject.Inject;
 
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
+import org.apache.cloudstack.framework.async.AsyncCallbackHandler;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
@@ -31,12 +33,16 @@ import com.cloud.exception.OperationTimedoutException;
 
 public class HypervisorHostEndPoint implements EndPoint {
     private static final Logger s_logger = 
Logger.getLogger(HypervisorHostEndPoint.class);
-    private long hostId;
+    private final long hostId;
+    private final String hostAddress;
     @Inject
     AgentManager agentMgr;
+    @Inject
+    HypervsiorHostEndPointRpcServer rpcServer;
 
-    public HypervisorHostEndPoint(long hostId) {
+    public HypervisorHostEndPoint(long hostId, String hostAddress) {
         this.hostId = hostId;
+        this.hostAddress = hostAddress;
     }
 
     @Override
@@ -53,5 +59,18 @@ public class HypervisorHostEndPoint implements EndPoint {
         }
         return answer;
     }
+    
+    @Override
+    public void sendMessageAsync(Command cmd, AsyncCompletionCallback<Answer> 
callback) {
+        AsyncCallbackDispatcher dispatcher = new 
AsyncCallbackDispatcher(this).setContextParam("parentCallback", callback).
+                setOperationName("hypervisorEndpoint.sendMessage.callback");
 
+        rpcServer.sendCommandAsync(this.hostAddress, cmd, dispatcher);
+    }
+    
+    
@AsyncCallbackHandler(operationName="hypervisorEndpoint.sendMessage.callback")
+    public void sendMessageCallback(AsyncCallbackDispatcher callback) {
+        AsyncCallbackDispatcher parentDispatcher = 
callback.getContextParam("parentCallback");
+        parentDispatcher.complete(callback.getResult());
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/engine/storage/src/org/apache/cloudstack/storage/HypervsiorHostEndPointRpcServer.java
----------------------------------------------------------------------
diff --git 
a/engine/storage/src/org/apache/cloudstack/storage/HypervsiorHostEndPointRpcServer.java
 
b/engine/storage/src/org/apache/cloudstack/storage/HypervsiorHostEndPointRpcServer.java
new file mode 100644
index 0000000..c1b5760
--- /dev/null
+++ 
b/engine/storage/src/org/apache/cloudstack/storage/HypervsiorHostEndPointRpcServer.java
@@ -0,0 +1,55 @@
+/*
+ * 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 org.apache.cloudstack.storage;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.framework.rpc.RpcCallbackListener;
+import org.apache.cloudstack.framework.rpc.RpcException;
+import org.apache.cloudstack.framework.rpc.RpcProvider;
+import org.apache.cloudstack.framework.rpc.RpcServiceDispatcher;
+import org.springframework.stereotype.Component;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+
+@Component
+public class HypervsiorHostEndPointRpcServer {
+    @Inject
+    private RpcProvider _rpcProvider;
+    public HypervsiorHostEndPointRpcServer() {
+        
_rpcProvider.registerRpcServiceEndpoint(RpcServiceDispatcher.getDispatcher(this));
+    }
+    
+    public void sendCommandAsync(String host, final Command command, final 
AsyncCompletionCallback<Answer> callback) {
+        _rpcProvider.newCall(host).addCallbackListener(new 
RpcCallbackListener<Answer>() {
+            @Override
+            public void onSuccess(Answer result) {
+                callback.complete(result);
+            }
+
+            @Override
+            public void onFailure(RpcException e) {
+                Answer answer = new Answer(command, false, e.toString());
+                callback.complete(answer);
+            }
+        }).apply();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/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
new file mode 100644
index 0000000..5fe8a7e
--- /dev/null
+++ 
b/engine/storage/src/org/apache/cloudstack/storage/command/CommandResult.java
@@ -0,0 +1,46 @@
+/*
+ * 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 org.apache.cloudstack.storage.command;
+
+public class CommandResult {
+    private boolean success;
+    private String result;
+    
+    public CommandResult() {
+        this.success = false;
+        this.result = "";
+    }
+    
+    public boolean isSuccess() {
+        return this.success;
+    }
+    
+    public void setSucess(boolean success) {
+        this.success = success;
+    }
+    
+    public String getResult() {
+        return this.result;
+    }
+    
+    public void setResult(String result) {
+        this.result = result;
+    }
+}
+ 
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/engine/storage/src/org/apache/cloudstack/storage/command/CopyTemplateToPrimaryStorageAnswer.java
----------------------------------------------------------------------
diff --git 
a/engine/storage/src/org/apache/cloudstack/storage/command/CopyTemplateToPrimaryStorageAnswer.java
 
b/engine/storage/src/org/apache/cloudstack/storage/command/CopyTemplateToPrimaryStorageAnswer.java
index 5a91117..f67c102 100644
--- 
a/engine/storage/src/org/apache/cloudstack/storage/command/CopyTemplateToPrimaryStorageAnswer.java
+++ 
b/engine/storage/src/org/apache/cloudstack/storage/command/CopyTemplateToPrimaryStorageAnswer.java
@@ -3,5 +3,13 @@ package org.apache.cloudstack.storage.command;
 import com.cloud.agent.api.Answer;
 
 public class CopyTemplateToPrimaryStorageAnswer extends Answer {
-
+    private final String path;
+    
+    public CopyTemplateToPrimaryStorageAnswer(String path) {
+        this.path = path;
+    }
+    
+    public String getPath() {
+        return this.path;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/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 befb9d6..9005bc0 100644
--- 
a/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java
+++ 
b/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java
@@ -20,10 +20,12 @@ package org.apache.cloudstack.storage.datastore;
 
 import java.util.List;
 
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import 
org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType;
+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;
 import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
 
@@ -37,7 +39,9 @@ public interface PrimaryDataStore extends 
PrimaryDataStoreInfo {
     VolumeInfo createVolume(VolumeInfo vo, VolumeDiskType diskType);
 
     VolumeInfo createVoluemFromBaseImage(VolumeInfo volume, 
TemplateOnPrimaryDataStoreInfo templateStore);
-
+    
+    void createVoluemFromBaseImageAsync(VolumeInfo volume, 
TemplateOnPrimaryDataStoreInfo templateStore, 
AsyncCompletionCallback<CommandResult> callback);
+    
     List<EndPoint> getEndPoints();
 
     boolean exists(VolumeInfo vi);

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/engine/storage/src/org/apache/cloudstack/storage/image/ImageService.java
----------------------------------------------------------------------
diff --git 
a/engine/storage/src/org/apache/cloudstack/storage/image/ImageService.java 
b/engine/storage/src/org/apache/cloudstack/storage/image/ImageService.java
index d657715..feff9c6 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/image/ImageService.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/image/ImageService.java
@@ -19,7 +19,7 @@
 package org.apache.cloudstack.storage.image;
 
 import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.storage.EndPoint;
 
 public interface ImageService {
     TemplateEntity registerTemplate(long templateId, long imageStoreId);

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/engine/storage/src/org/apache/cloudstack/storage/image/motion/ImageMotionService.java
----------------------------------------------------------------------
diff --git 
a/engine/storage/src/org/apache/cloudstack/storage/image/motion/ImageMotionService.java
 
b/engine/storage/src/org/apache/cloudstack/storage/image/motion/ImageMotionService.java
index 9f48115..1f60e4a 100644
--- 
a/engine/storage/src/org/apache/cloudstack/storage/image/motion/ImageMotionService.java
+++ 
b/engine/storage/src/org/apache/cloudstack/storage/image/motion/ImageMotionService.java
@@ -18,10 +18,13 @@
  */
 package org.apache.cloudstack.storage.image.motion;
 
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.storage.command.CommandResult;
 import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
 
 public interface ImageMotionService {
     boolean copyTemplate(TemplateOnPrimaryDataStoreInfo templateStore);
 
+    void copyTemplateAsync(TemplateOnPrimaryDataStoreInfo templateStore, 
AsyncCompletionCallback<CommandResult> callback);
     boolean copyIso(String isoUri, String destIsoUri);
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/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 ab77e99..716c260 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeService.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeService.java
@@ -19,10 +19,11 @@
 package org.apache.cloudstack.storage.volume;
 
 import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import 
org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType;
 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.image.TemplateInfo;
 
 public interface VolumeService {
@@ -73,5 +74,6 @@ public interface VolumeService {
 
     VolumeEntity getVolumeEntity(long volumeId);
 
-    VolumeInfo createVolumeFromTemplate(VolumeInfo volume, long dataStoreId, 
VolumeDiskType diskType, TemplateInfo template);
+    void createVolumeFromTemplateAsync(VolumeInfo volume, long dataStoreId, 
VolumeDiskType diskType, TemplateInfo template, 
+            AsyncCompletionCallback<VolumeInfo> callback);
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/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 5029a48..37162e7 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
@@ -6,12 +6,12 @@ import java.util.List;
 import javax.inject.Inject;
 
 import 
org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity.State;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
 import 
org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle;
 import 
org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import 
org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType;
+import org.apache.cloudstack.storage.EndPoint;
 import org.apache.cloudstack.storage.HypervisorHostEndPoint;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreVO;
 import 
org.apache.cloudstack.storage.datastore.driver.DefaultPrimaryDataStoreDriverImpl;
@@ -101,7 +101,7 @@ public class DefaultPrimaryDataStore implements 
PrimaryDataStore {
         List<EndPoint> endpoints = new ArrayList<EndPoint>();
         List<HostVO> hosts = hostDao.findHypervisorHostInCluster(clusterId);
         for (HostVO host : hosts) {
-            HypervisorHostEndPoint ep = new 
HypervisorHostEndPoint(host.getId());
+            HypervisorHostEndPoint ep = new 
HypervisorHostEndPoint(host.getId(), host.getPrivateIpAddress());
             ComponentInject.inject(ep);
             endpoints.add(ep);
         }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/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 7c109e7..8588ca3 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
@@ -3,8 +3,8 @@ package org.apache.cloudstack.storage.datastore.driver;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.storage.EndPoint;
 import org.apache.cloudstack.storage.command.CreateVolumeAnswer;
 import org.apache.cloudstack.storage.command.CreateVolumeCommand;
 import org.apache.cloudstack.storage.command.CreateVolumeFromBaseImageCommand;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/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 685bb69..0b25e9b 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
@@ -2,7 +2,7 @@ package org.apache.cloudstack.storage.datastore.driver;
 
 import java.util.Map;
 
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.storage.EndPoint;
 import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
 import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
 import org.apache.cloudstack.storage.volume.VolumeObject;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/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 2340185..f119a59 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
@@ -22,11 +22,15 @@ import javax.inject.Inject;
 
 import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity;
 import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import 
org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType;
 import org.apache.cloudstack.engine.subsystem.api.storage.type.BaseImage;
 import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType;
+import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
+import org.apache.cloudstack.framework.async.AsyncCallbackHandler;
+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.datastore.PrimaryDataStore;
 import org.apache.cloudstack.storage.datastore.manager.PrimaryDataStoreManager;
 import org.apache.cloudstack.storage.image.TemplateEntityImpl;
@@ -132,7 +136,7 @@ public class VolumeServiceImpl implements VolumeService {
         return null;
     }
 
-    protected TemplateOnPrimaryDataStoreObject 
createBaseImage(PrimaryDataStore dataStore, TemplateInfo template) {
+    protected void createBaseImageAsync(PrimaryDataStore dataStore, 
TemplateInfo template, 
AsyncCompletionCallback<TemplateOnPrimaryDataStoreObject> callback) {
         TemplateOnPrimaryDataStoreObject templateOnPrimaryStoreObj = 
(TemplateOnPrimaryDataStoreObject) 
templatePrimaryStoreMgr.createTemplateOnPrimaryDataStore(template, dataStore);
         
templateOnPrimaryStoreObj.stateTransit(TemplateOnPrimaryDataStoreStateMachine.Event.CreateRequested);
         templateOnPrimaryStoreObj.updateStatus(Status.CREATING);
@@ -146,27 +150,38 @@ public class VolumeServiceImpl implements VolumeService {
         }
 
         templateOnPrimaryStoreObj.updateStatus(Status.DOWNLOAD_IN_PROGRESS);
-        try {
-            imageMotion.copyTemplate(templateOnPrimaryStoreObj);
+
+        AsyncCallbackDispatcher caller = new AsyncCallbackDispatcher(this)
+            .setParentCallback(callback)
+            .setOperationName("volumeservice.createbaseimage.callback")
+            .setContextParam("templateOnPrimary", templateOnPrimaryStoreObj);
+
+        imageMotion.copyTemplateAsync(templateOnPrimaryStoreObj, caller);
+    }
+
+    
@AsyncCallbackHandler(operationName="volumeservice.createbaseimage.callback")
+    public void createBaseImageCallback(AsyncCallbackDispatcher callback) {
+        CommandResult result = callback.getResult();
+        TemplateOnPrimaryDataStoreObject templateOnPrimaryStoreObj = 
callback.getContextParam("templateOnPrimary");
+        if (result.isSuccess()) {
             templateOnPrimaryStoreObj.updateStatus(Status.DOWNLOADED);
             
templateOnPrimaryStoreObj.stateTransit(TemplateOnPrimaryDataStoreStateMachine.Event.OperationSuccessed);
-        } catch (Exception e) {
+        } else {
             templateOnPrimaryStoreObj.updateStatus(Status.ABANDONED);
             
templateOnPrimaryStoreObj.stateTransit(TemplateOnPrimaryDataStoreStateMachine.Event.OperationFailed);
-            throw new CloudRuntimeException(e.toString());
         }
-
-        return templateOnPrimaryStoreObj;
+        
+        AsyncCallbackDispatcher parentCaller = callback.getParentCallback();
+        VolumeInfo volume = parentCaller.getContextParam("volume");
+        PrimaryDataStore pd = parentCaller.getContextParam("primary");
+        AsyncCallbackDispatcher caller = new AsyncCallbackDispatcher(this)
+              .setParentCallback(parentCaller)
+              
.setOperationName("volumeservice.createvolumefrombaseimage.callback");
+        
+        createVolumeFromBaseImageAsync(volume, templateOnPrimaryStoreObj, pd, 
caller);
     }
-
-    @Override
-    public VolumeInfo createVolumeFromTemplate(VolumeInfo volume, long 
dataStoreId, VolumeDiskType diskType, TemplateInfo template) {
-        PrimaryDataStore pd = dataStoreMgr.getPrimaryDataStore(dataStoreId);
-        TemplateOnPrimaryDataStoreInfo templateOnPrimaryStore = 
pd.getTemplate(template);
-        if (templateOnPrimaryStore == null) {
-            templateOnPrimaryStore = createBaseImage(pd, template);
-        }
-
+    
+    protected void createVolumeFromBaseImageAsync(VolumeInfo volume, 
TemplateOnPrimaryDataStoreInfo templateOnPrimaryStore, PrimaryDataStore pd, 
AsyncCompletionCallback<VolumeObject> callback) {
         VolumeObject vo = (VolumeObject) volume;
         try {
             vo.stateTransit(Volume.Event.CreateRequested);
@@ -174,14 +189,54 @@ public class VolumeServiceImpl implements VolumeService {
             throw new CloudRuntimeException(e.toString());
         }
 
-        try {
-            volume = pd.createVoluemFromBaseImage(volume, 
templateOnPrimaryStore);
-            vo.stateTransit(Volume.Event.OperationSucceeded);
-        } catch (Exception e) {
+
+        AsyncCallbackDispatcher caller = new AsyncCallbackDispatcher(this)
+        .setParentCallback(callback)
+        .setOperationName("volumeservice.createVolumeFromBaseImageCallback")
+        .setContextParam("volume", vo);
+
+        pd.createVoluemFromBaseImageAsync(volume, templateOnPrimaryStore, 
caller);
+    }
+    
+    
@AsyncCallbackHandler(operationName="volumeservice.createVolumeFromBaseImageCallback")
+    public void createVolumeFromBaseImageCallback(AsyncCallbackDispatcher 
callback) {
+        VolumeObject vo = callback.getContextParam("volume");
+        CommandResult result = callback.getResult();
+        if (result.isSuccess()) {
+            vo.stateTransit(Volume.Event.OperationSucceeded); 
+        } else {
             vo.stateTransit(Volume.Event.OperationFailed);
-            throw new CloudRuntimeException(e.toString());
         }
-        return volume;
+        
+        AsyncCallbackDispatcher parentCall = callback.getParentCallback();
+        parentCall.complete(vo);
+    }
+    
+    
@AsyncCallbackHandler(operationName="volumeservice.createvolumefrombaseimage.callback")
+    public void createVolumeFromBaseImageAsyncCallback(AsyncCallbackDispatcher 
callback) {
+        AsyncCallbackDispatcher parentCall = callback.getParentCallback();
+        VolumeObject vo = callback.getResult();
+        parentCall.complete(vo);
+    }
+
+    @Override
+    public void createVolumeFromTemplateAsync(VolumeInfo volume, long 
dataStoreId, VolumeDiskType diskType, TemplateInfo template, 
AsyncCompletionCallback<VolumeInfo> callback) {
+        PrimaryDataStore pd = dataStoreMgr.getPrimaryDataStore(dataStoreId);
+        TemplateOnPrimaryDataStoreInfo templateOnPrimaryStore = 
pd.getTemplate(template);
+        if (templateOnPrimaryStore == null) {
+            AsyncCallbackDispatcher caller = new 
AsyncCallbackDispatcher(this).setParentCallback(callback)
+                    .setOperationName("volumeservice.createbaseimage.callback")
+                    .setContextParam("volume", volume)
+                    .setContextParam("primary", pd);
+             createBaseImageAsync(pd, template, caller);
+            return;
+        }
+
+        AsyncCallbackDispatcher caller = new AsyncCallbackDispatcher(this)
+            .setParentCallback(callback)
+            
.setOperationName("volumeservice.createvolumefrombaseimage.callback");
+            
+        createVolumeFromBaseImageAsync(volume, templateOnPrimaryStore, pd, 
caller);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/Server.java
----------------------------------------------------------------------
diff --git 
a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/Server.java
 
b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/Server.java
new file mode 100644
index 0000000..a863cc8
--- /dev/null
+++ 
b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/Server.java
@@ -0,0 +1,39 @@
+/*
+ * 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 org.apache.cloudstack.storage.volume.test;
+
+import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
+import org.apache.cloudstack.framework.async.AsyncCallbackHandler;
+
+public class Server {
+    Server1 svr;
+    public Server() {
+        svr = new Server1();
+    }
+    void foo() {
+        svr.foo1("foo", new 
AsyncCallbackDispatcher(this).setOperationName("callback").setContextParam("name",
 "foo"));
+    }
+    @AsyncCallbackHandler(operationName="callback")
+    void foocallback(AsyncCallbackDispatcher callback) {
+        System.out.println(callback.getContextParam("name"));
+        String result = callback.getResult();
+        System.out.println(result);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/Server1.java
----------------------------------------------------------------------
diff --git 
a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/Server1.java
 
b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/Server1.java
new file mode 100644
index 0000000..bf56e6e
--- /dev/null
+++ 
b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/Server1.java
@@ -0,0 +1,27 @@
+/*
+ * 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 org.apache.cloudstack.storage.volume.test;
+
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+
+public class Server1 {
+    public void foo1(String name, AsyncCompletionCallback<String> callback) {
+        callback.complete("success");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/TestInProcessAsync.java
----------------------------------------------------------------------
diff --git 
a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/TestInProcessAsync.java
 
b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/TestInProcessAsync.java
new file mode 100644
index 0000000..6741871
--- /dev/null
+++ 
b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/TestInProcessAsync.java
@@ -0,0 +1,40 @@
+/*
+ * 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 org.apache.cloudstack.storage.volume.test;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations="classpath:/resource/testContext.xml")
+public class TestInProcessAsync {
+    Server svr;
+    @Before 
+    public void setup() {
+        svr = new Server();
+    }
+    
+    @Test
+    public void testRpc() {
+        svr.foo();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/engine/storage/volume/test/resource/testContext.xml
----------------------------------------------------------------------
diff --git a/engine/storage/volume/test/resource/testContext.xml 
b/engine/storage/volume/test/resource/testContext.xml
index 562bef8..83fe842 100644
--- a/engine/storage/volume/test/resource/testContext.xml
+++ b/engine/storage/volume/test/resource/testContext.xml
@@ -18,8 +18,9 @@
   <context:component-scan base-package="com.cloud.utils.component" />
   <context:component-scan base-package="com.cloud.host.dao" />
   <context:component-scan base-package="com.cloud.dc.dao" />
-
-  <context:component-scan base-package=" com.cloud.upgrade.dao" />
+  <context:component-scan base-package="com.cloud.dc.dao" />
+  <context:component-scan base-package="org.apache.cloudstack.framework" />
+  
   <tx:annotation-driven transaction-manager="transactionManager" />
   <bean class="org.apache.cloudstack.storage.volume.test.TestConfiguration" />
   <aop:config proxy-target-class="true">
@@ -31,4 +32,30 @@
 
   <bean id="transactionContextBuilder" 
class="com.cloud.utils.db.TransactionContextBuilder" />
   
+  <bean id="onwireRegistry" 
class="org.apache.cloudstack.framework.serializer.OnwireClassRegistry"
+    init-method="scan" >
+    <property name="packages">
+      <list>
+        <value>org.apache.cloudstack.framework</value>
+      </list>
+    </property>
+  </bean>
+  
+  <bean id="messageSerializer" 
class="org.apache.cloudstack.framework.serializer.JsonMessageSerializer">
+    <property name="onwireClassRegistry" ref="onwireRegistry" />
+  </bean>
+
+  <bean id="transportProvider" 
class="org.apache.cloudstack.framework.server.ServerTransportProvider"  
init-method="initialize">
+    <property name="workerPoolSize" value="5" />
+    <property name="nodeId" value="Node1" />
+    <property name="messageSerializer" ref="messageSerializer" />
+  </bean>
+  
+  <bean id="rpcProvider" 
class="org.apache.cloudstack.framework.rpc.RpcProviderImpl" 
init-method="initialize">
+    <constructor-arg ref="transportProvider" />
+    <property name="messageSerializer" ref="messageSerializer" />
+  </bean>
+
+  <bean id="eventBus" class = 
"org.apache.cloudstack.framework.eventbus.EventBusBase" />
+  
 </beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/framework/ipc/pom.xml
----------------------------------------------------------------------
diff --git a/framework/ipc/pom.xml b/framework/ipc/pom.xml
index 7caf360..435cfee 100644
--- a/framework/ipc/pom.xml
+++ b/framework/ipc/pom.xml
@@ -34,5 +34,6 @@
   <build>
     <defaultGoal>install</defaultGoal>
     <sourceDirectory>src</sourceDirectory>
+    <testSourceDirectory>src</testSourceDirectory>
   </build>
 </project>

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java
----------------------------------------------------------------------
diff --git 
a/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java
 
b/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java
index 72bf9d2..23c0b81 100644
--- 
a/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java
+++ 
b/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java
@@ -28,7 +28,7 @@ import java.util.Map;
 @SuppressWarnings("rawtypes")
 public class AsyncCallbackDispatcher implements AsyncCompletionCallback {
        private static Map<Class<?>, Map<String, Method>> s_handlerCache = new 
HashMap<Class<?>, Map<String, Method>>();
-       
+       private final String parentCallbackKey = "parentCallback";
        private Map<String, Object> _contextMap = new HashMap<String, Object>();
        private String _operationName;
        private Object _targetObject;
@@ -45,6 +45,15 @@ public class AsyncCallbackDispatcher implements 
AsyncCompletionCallback {
                return this;
        }
        
+       public <T> AsyncCallbackDispatcher 
setParentCallback(AsyncCompletionCallback<T> parentCallback) {
+           _contextMap.put(parentCallbackKey, parentCallback);
+           return this;
+       }
+       
+       public AsyncCallbackDispatcher getParentCallback() {
+          return (AsyncCallbackDispatcher)_contextMap.get(parentCallbackKey);
+       }
+       
        public AsyncCallbackDispatcher attachDriver(AsyncCallbackDriver driver) 
{
                assert(driver != null);
                _driver = driver;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/framework/ipc/test/org/apache/cloudstack/framework/sampleserver/SampleManagerComponent2.java
----------------------------------------------------------------------
diff --git 
a/framework/ipc/test/org/apache/cloudstack/framework/sampleserver/SampleManagerComponent2.java
 
b/framework/ipc/test/org/apache/cloudstack/framework/sampleserver/SampleManagerComponent2.java
index 9fa06f5..dc482c0 100644
--- 
a/framework/ipc/test/org/apache/cloudstack/framework/sampleserver/SampleManagerComponent2.java
+++ 
b/framework/ipc/test/org/apache/cloudstack/framework/sampleserver/SampleManagerComponent2.java
@@ -69,4 +69,8 @@ public class SampleManagerComponent2 {
        @EventHandler(topic="storage.prepare")
        void onPrepareNetwork(String sender, String topic, Object args) {
        }
+       
+       void test() {
+               
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/716a5673/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 5076578..915e671 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
@@ -2,7 +2,7 @@ package org.apache.cloudstack.storage.datastore.driver;
 
 import java.util.Map;
 
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.storage.EndPoint;
 import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
 import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
 import org.apache.cloudstack.storage.volume.VolumeObject;

Reply via email to