Skip to content

Commit 716a567

Browse files
committed
1st try to add async api in the storage component, it's ugly like hell
1 parent 01a4a51 commit 716a567

28 files changed

Lines changed: 473 additions & 52 deletions

File tree

engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java

Lines changed: 0 additions & 8 deletions
This file was deleted.

engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity.State;
2525
import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType;
26+
import org.apache.cloudstack.storage.EndPoint;
2627

2728
import com.cloud.hypervisor.Hypervisor.HypervisorType;
2829

engine/storage/image/src/org/apache/cloudstack/storage/image/ImageServiceImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import javax.inject.Inject;
2222

2323
import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity;
24-
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
24+
import org.apache.cloudstack.storage.EndPoint;
2525
import org.apache.cloudstack.storage.image.downloader.ImageDownloader;
2626
import org.apache.cloudstack.storage.image.manager.ImageDataStoreManager;
2727
import org.apache.cloudstack.storage.image.provider.ImageDataStoreProviderManager;

engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,20 @@
1818
*/
1919
package org.apache.cloudstack.storage.image.motion;
2020

21-
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
2221
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
22+
import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
23+
import org.apache.cloudstack.framework.async.AsyncCallbackHandler;
24+
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
25+
import org.apache.cloudstack.storage.EndPoint;
26+
import org.apache.cloudstack.storage.command.CommandResult;
2327
import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorage;
28+
import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageAnswer;
2429
import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO;
2530
import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
2631
import org.springframework.stereotype.Component;
2732

33+
import com.cloud.agent.api.Answer;
34+
2835
@Component
2936
public class DefaultImageMotionStrategy implements ImageMotionStrategy {
3037

@@ -48,4 +55,30 @@ public boolean copyTemplate(TemplateOnPrimaryDataStoreInfo templateStore, EndPoi
4855
return true;
4956
}
5057

58+
@Override
59+
public void copyTemplateAsync(TemplateOnPrimaryDataStoreInfo templateStore, EndPoint ep, AsyncCompletionCallback<CommandResult> callback) {
60+
ImageOnPrimayDataStoreTO imageTo = new ImageOnPrimayDataStoreTO(templateStore);
61+
CopyTemplateToPrimaryStorage copyCommand = new CopyTemplateToPrimaryStorage(imageTo);
62+
AsyncCallbackDispatcher<Answer> caller = new AsyncCallbackDispatcher<Answer>(this).setParentCallback(callback)
63+
.setOperationName("defaultImageStrategy.copytemplate.callback")
64+
.setContextParam("templateStore", templateStore);
65+
ep.sendMessageAsync(copyCommand, caller);
66+
}
67+
68+
@AsyncCallbackHandler(operationName="defaultImageStrategy.copytemplate.callback")
69+
public void copyTemplateCallBack(AsyncCallbackDispatcher callback) {
70+
AsyncCallbackDispatcher parentCall = callback.getParentCallback();
71+
CopyTemplateToPrimaryStorageAnswer answer = callback.getResult();
72+
CommandResult result = new CommandResult();
73+
74+
result.setSucess(answer.getResult());
75+
result.setResult(answer.getDetails());
76+
if (answer.getResult()) {
77+
TemplateOnPrimaryDataStoreInfo templateStore = callback.getContextParam("templateStore");
78+
templateStore.setPath(answer.getPath());
79+
}
80+
81+
parentCall.complete(result);
82+
}
83+
5184
}

engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionServiceImpl.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@
2222

2323
import javax.inject.Inject;
2424

25-
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
25+
import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
26+
import org.apache.cloudstack.framework.async.AsyncCallbackHandler;
27+
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
28+
import org.apache.cloudstack.storage.EndPoint;
29+
import org.apache.cloudstack.storage.command.CommandResult;
2630
import org.apache.cloudstack.storage.image.ImageService;
2731
import org.apache.cloudstack.storage.image.TemplateInfo;
2832
import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
@@ -67,4 +71,36 @@ public boolean copyTemplate(TemplateOnPrimaryDataStoreInfo templateStore) {
6771
imageService.grantTemplateAccess(template, ep);
6872
return ims.copyTemplate(templateStore, ep);
6973
}
74+
75+
@Override
76+
public void copyTemplateAsync(TemplateOnPrimaryDataStoreInfo templateStore, AsyncCompletionCallback<CommandResult> callback) {
77+
ImageMotionStrategy ims = null;
78+
for (ImageMotionStrategy strategy : motionStrategies) {
79+
if (strategy.canHandle(templateStore)) {
80+
ims = strategy;
81+
break;
82+
}
83+
}
84+
85+
if (ims == null) {
86+
throw new CloudRuntimeException("Can't find proper image motion strategy");
87+
}
88+
89+
EndPoint ep = ims.getEndPoint(templateStore);
90+
volumeService.grantAccess(templateStore, ep);
91+
TemplateInfo template = templateStore.getTemplate();
92+
imageService.grantTemplateAccess(template, ep);
93+
94+
AsyncCallbackDispatcher caller = new AsyncCallbackDispatcher(this)
95+
.setParentCallback(callback)
96+
.setOperationName("imagemotionService.copytemplate.callback");
97+
98+
ims.copyTemplateAsync(templateStore, ep, caller);
99+
}
100+
101+
@AsyncCallbackHandler(operationName="imagemotionService.copytemplate.callback")
102+
public void copyTemplateAsyncCallback(AsyncCallbackDispatcher callback) {
103+
AsyncCallbackDispatcher parentCaller = callback.getParentCallback();
104+
parentCaller.complete(callback.getResult());
105+
}
70106
}

engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionStrategy.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,17 @@
1818
*/
1919
package org.apache.cloudstack.storage.image.motion;
2020

21-
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
21+
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
22+
import org.apache.cloudstack.storage.EndPoint;
2223
import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
24+
import org.apache.cloudstack.storage.command.CommandResult;
2325

2426
public interface ImageMotionStrategy {
2527
public boolean canHandle(TemplateOnPrimaryDataStoreInfo templateStore);
2628

2729
public EndPoint getEndPoint(TemplateOnPrimaryDataStoreInfo templateStore);
2830

2931
public boolean copyTemplate(TemplateOnPrimaryDataStoreInfo templateStore, EndPoint ep);
32+
33+
public void copyTemplateAsync(TemplateOnPrimaryDataStoreInfo templateStore, EndPoint ep, AsyncCompletionCallback<CommandResult> callback);
3034
}

engine/storage/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@
4040
<artifactId>cloud-engine-components-api</artifactId>
4141
<version>${project.version}</version>
4242
</dependency>
43+
<dependency>
44+
<groupId>org.apache.cloudstack</groupId>
45+
<artifactId>cloud-framework-ipc</artifactId>
46+
<version>${project.version}</version>
47+
</dependency>
4348
<dependency>
4449
<groupId>org.apache.cloudstack</groupId>
4550
<artifactId>cloud-engine-api</artifactId>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.apache.cloudstack.storage;
2+
3+
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
4+
5+
import com.cloud.agent.api.Answer;
6+
import com.cloud.agent.api.Command;
7+
8+
public interface EndPoint {
9+
public Answer sendMessage(Command cmd);
10+
public void sendMessageAsync(Command cmd, AsyncCompletionCallback<Answer> callback);
11+
}

engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPoint.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020

2121
import javax.inject.Inject;
2222

23-
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
23+
import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
24+
import org.apache.cloudstack.framework.async.AsyncCallbackHandler;
25+
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
2426
import org.apache.log4j.Logger;
2527

2628
import com.cloud.agent.AgentManager;
@@ -31,12 +33,16 @@
3133

3234
public class HypervisorHostEndPoint implements EndPoint {
3335
private static final Logger s_logger = Logger.getLogger(HypervisorHostEndPoint.class);
34-
private long hostId;
36+
private final long hostId;
37+
private final String hostAddress;
3538
@Inject
3639
AgentManager agentMgr;
40+
@Inject
41+
HypervsiorHostEndPointRpcServer rpcServer;
3742

38-
public HypervisorHostEndPoint(long hostId) {
43+
public HypervisorHostEndPoint(long hostId, String hostAddress) {
3944
this.hostId = hostId;
45+
this.hostAddress = hostAddress;
4046
}
4147

4248
@Override
@@ -53,5 +59,18 @@ public Answer sendMessage(Command cmd) {
5359
}
5460
return answer;
5561
}
62+
63+
@Override
64+
public void sendMessageAsync(Command cmd, AsyncCompletionCallback<Answer> callback) {
65+
AsyncCallbackDispatcher dispatcher = new AsyncCallbackDispatcher(this).setContextParam("parentCallback", callback).
66+
setOperationName("hypervisorEndpoint.sendMessage.callback");
5667

68+
rpcServer.sendCommandAsync(this.hostAddress, cmd, dispatcher);
69+
}
70+
71+
@AsyncCallbackHandler(operationName="hypervisorEndpoint.sendMessage.callback")
72+
public void sendMessageCallback(AsyncCallbackDispatcher callback) {
73+
AsyncCallbackDispatcher parentDispatcher = callback.getContextParam("parentCallback");
74+
parentDispatcher.complete(callback.getResult());
75+
}
5776
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.cloudstack.storage;
20+
21+
import javax.inject.Inject;
22+
23+
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
24+
import org.apache.cloudstack.framework.rpc.RpcCallbackListener;
25+
import org.apache.cloudstack.framework.rpc.RpcException;
26+
import org.apache.cloudstack.framework.rpc.RpcProvider;
27+
import org.apache.cloudstack.framework.rpc.RpcServiceDispatcher;
28+
import org.springframework.stereotype.Component;
29+
30+
import com.cloud.agent.api.Answer;
31+
import com.cloud.agent.api.Command;
32+
33+
@Component
34+
public class HypervsiorHostEndPointRpcServer {
35+
@Inject
36+
private RpcProvider _rpcProvider;
37+
public HypervsiorHostEndPointRpcServer() {
38+
_rpcProvider.registerRpcServiceEndpoint(RpcServiceDispatcher.getDispatcher(this));
39+
}
40+
41+
public void sendCommandAsync(String host, final Command command, final AsyncCompletionCallback<Answer> callback) {
42+
_rpcProvider.newCall(host).addCallbackListener(new RpcCallbackListener<Answer>() {
43+
@Override
44+
public void onSuccess(Answer result) {
45+
callback.complete(result);
46+
}
47+
48+
@Override
49+
public void onFailure(RpcException e) {
50+
Answer answer = new Answer(command, false, e.toString());
51+
callback.complete(answer);
52+
}
53+
}).apply();
54+
}
55+
}

0 commit comments

Comments
 (0)