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

This commit is contained in:
Edison Su 2012-12-14 18:25:40 -08:00
parent 01a4a51abf
commit 716a5673d0
28 changed files with 475 additions and 54 deletions

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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());
}
}

View File

@ -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);
}

View File

@ -40,6 +40,11 @@
<artifactId>cloud-engine-components-api</artifactId>
<version>${project.version}</version>
</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>

View File

@ -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);
}

View File

@ -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
@ -54,4 +60,17 @@ 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());
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
@ -38,6 +40,8 @@ public interface PrimaryDataStore extends PrimaryDataStoreInfo {
VolumeInfo createVoluemFromBaseImage(VolumeInfo volume, TemplateOnPrimaryDataStoreInfo templateStore);
void createVoluemFromBaseImageAsync(VolumeInfo volume, TemplateOnPrimaryDataStoreInfo templateStore, AsyncCompletionCallback<CommandResult> callback);
List<EndPoint> getEndPoints();
boolean exists(VolumeInfo vi);

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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);
templateOnPrimaryStoreObj.updateStatus(Status.DOWNLOADED);
templateOnPrimaryStoreObj.stateTransit(TemplateOnPrimaryDataStoreStateMachine.Event.OperationSuccessed);
} catch (Exception e) {
templateOnPrimaryStoreObj.updateStatus(Status.ABANDONED);
templateOnPrimaryStoreObj.stateTransit(TemplateOnPrimaryDataStoreStateMachine.Event.OperationFailed);
throw new CloudRuntimeException(e.toString());
}
return templateOnPrimaryStoreObj;
AsyncCallbackDispatcher caller = new AsyncCallbackDispatcher(this)
.setParentCallback(callback)
.setOperationName("volumeservice.createbaseimage.callback")
.setContextParam("templateOnPrimary", templateOnPrimaryStoreObj);
imageMotion.copyTemplateAsync(templateOnPrimaryStoreObj, 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);
@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);
} else {
templateOnPrimaryStoreObj.updateStatus(Status.ABANDONED);
templateOnPrimaryStoreObj.stateTransit(TemplateOnPrimaryDataStoreStateMachine.Event.OperationFailed);
}
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);
}
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);
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);
} catch (Exception e) {
} 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

View File

@ -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);
}
}

View File

@ -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");
}
}

View File

@ -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();
}
}

View File

@ -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.dc.dao" />
<context:component-scan base-package="org.apache.cloudstack.framework" />
<context:component-scan base-package=" com.cloud.upgrade.dao" />
<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>

View File

@ -34,5 +34,6 @@
<build>
<defaultGoal>install</defaultGoal>
<sourceDirectory>src</sourceDirectory>
<testSourceDirectory>src</testSourceDirectory>
</build>
</project>

View File

@ -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;

View File

@ -69,4 +69,8 @@ public class SampleManagerComponent2 {
@EventHandler(topic="storage.prepare")
void onPrepareNetwork(String sender, String topic, Object args) {
}
void test() {
}
}

View File

@ -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;