change the top level async call using future

This commit is contained in:
Edison Su 2013-01-04 17:17:40 -08:00
parent 2e9c55f8f6
commit 2d6133c61e
9 changed files with 219 additions and 113 deletions

View File

@ -171,7 +171,7 @@ public class volumeServiceTest extends CloudStackTestNGBase {
host.setClusterId(cluster.getId());
host = hostDao.persist(host);
primaryStore = createPrimaryDataStore();
//CreateVolumeAnswer createVolumeFromImageAnswer = new CreateVolumeAnswer(UUID.randomUUID().toString());
@ -280,8 +280,8 @@ public class volumeServiceTest extends CloudStackTestNGBase {
@Test(priority=2)
public void createVolumeFromTemplate() {
primaryStore = createPrimaryDataStore();
TemplateEntity te = createTemplate();
primaryStore = createPrimaryDataStore();
VolumeVO volume = createVolume(te.getId(), primaryStore.getId());
VolumeEntity ve = volumeService.getVolumeEntity(volume.getId());
ve.createVolumeFromTemplate(primaryStore.getId(), new VHD(), te);
@ -290,6 +290,7 @@ public class volumeServiceTest extends CloudStackTestNGBase {
@Test(priority=3)
public void createDataDisk() {
primaryStore = createPrimaryDataStore();
VolumeVO volume = createVolume(null, primaryStore.getId());
VolumeEntity ve = volumeService.getVolumeEntity(volume.getId());
ve.createVolume(primaryStore.getId(), new VHD());

View File

@ -22,6 +22,7 @@ import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import org.apache.cloudstack.engine.cloud.entity.api.SnapshotEntity;
import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity;
@ -30,6 +31,7 @@ import org.apache.cloudstack.engine.datacenter.entity.api.StorageEntity;
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.AsyncCallFuture;
import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.storage.datastore.PrimaryDataStoreEntityImpl;
@ -170,81 +172,52 @@ public class VolumeEntityImpl implements VolumeEntity {
@Override
public boolean createVolumeFromTemplate(long dataStoreId, VolumeDiskType diskType, TemplateEntity template) {
TemplateInfo ti = ((TemplateEntityImpl)template).getTemplateInfo();
AsyncCallbackDispatcher<VolumeEntityImpl, VolumeInfo> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().createVolumeFromTemplateAsyncCallback(null, null));
vs.createVolumeFromTemplateAsync(volumeInfo, dataStoreId, diskType, ti, caller);
AsyncCallFuture<VolumeApiResult> future = vs.createVolumeFromTemplateAsync(volumeInfo, dataStoreId, diskType, ti);
try {
synchronized (volumeInfo) {
volumeInfo.wait();
result = future.get();
if (!result.isSuccess()) {
throw new CloudRuntimeException("create volume from template failed: " + result.getResult());
}
return true;
} catch (InterruptedException e) {
throw new CloudRuntimeException("wait volume info failed", e);
throw new CloudRuntimeException("wait result failed", e);
} catch (ExecutionException e) {
throw new CloudRuntimeException("wait result failed", e);
}
return true;
}
public Object createVolumeFromTemplateAsyncCallback(AsyncCallbackDispatcher<VolumeEntityImpl, VolumeInfo> callback, Object context) {
synchronized (volumeInfo) {
volumeInfo.notify();
}
return null;
}
@Override
public boolean createVolume(long dataStoreId, VolumeDiskType diskType) {
AsyncCallbackDispatcher<VolumeEntityImpl, VolumeApiResult> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().createVolumeCallback(null, null));
vs.createVolumeAsync(volumeInfo, dataStoreId, diskType, caller);
AsyncCallFuture<VolumeApiResult> future = vs.createVolumeAsync(volumeInfo, dataStoreId, diskType);
try {
synchronized (volumeInfo) {
volumeInfo.wait();
}
result = future.get();
if (result.isSuccess()) {
return true;
} else {
throw new CloudRuntimeException("Failed to create volume:" + result.getResult());
}
} catch (InterruptedException e) {
throw new CloudRuntimeException("wait volume info failed", e);
throw new CloudRuntimeException("wait volume info failed", e);
} catch (ExecutionException e) {
throw new CloudRuntimeException("wait volume failed", e);
}
}
public Void createVolumeCallback(AsyncCallbackDispatcher<VolumeApiResult, VolumeApiResult> callback, Object context) {
synchronized (volumeInfo) {
this.result = callback.getResult();
volumeInfo.notify();
}
return null;
}
@Override
public void destroy() {
AsyncCallbackDispatcher<VolumeEntityImpl, VolumeApiResult> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().destroyCallback(null, null));
vs.deleteVolumeAsync(volumeInfo, caller);
AsyncCallFuture<VolumeApiResult> future = vs.deleteVolumeAsync(volumeInfo);
try {
synchronized (volumeInfo) {
volumeInfo.wait();
}
result = future.get();
if (!result.isSuccess()) {
throw new CloudRuntimeException("Failed to create volume:" + result.getResult());
}
} catch (InterruptedException e) {
throw new CloudRuntimeException("wait volume info failed", e);
throw new CloudRuntimeException("wait to delete volume info failed", e);
} catch (ExecutionException e) {
throw new CloudRuntimeException("wait to delete volume failed", e);
}
}
public Void destroyCallback(AsyncCallbackDispatcher<VolumeApiResult, VolumeApiResult> callback, Object context) {
synchronized (volumeInfo) {
this.result = callback.getResult();
volumeInfo.notify();
}
return null;
}
@Override
public Map<String, String> getDetails() {

View File

@ -22,6 +22,7 @@ import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
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.AsyncCallFuture;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.storage.EndPoint;
import org.apache.cloudstack.storage.command.CommandResult;
@ -51,7 +52,7 @@ public interface VolumeService {
*
* @return the volume object
*/
void createVolumeAsync(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType, AsyncCompletionCallback<VolumeApiResult> callback);
AsyncCallFuture<VolumeApiResult> createVolumeAsync(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType);
/**
* Delete volume
@ -60,7 +61,7 @@ public interface VolumeService {
* @return
* @throws ConcurrentOperationException
*/
void deleteVolumeAsync(VolumeInfo volume, AsyncCompletionCallback<VolumeApiResult> callback);
AsyncCallFuture<VolumeApiResult> deleteVolumeAsync(VolumeInfo volume);
/**
*
@ -86,6 +87,5 @@ public interface VolumeService {
VolumeEntity getVolumeEntity(long volumeId);
void createVolumeFromTemplateAsync(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType, TemplateInfo template,
AsyncCompletionCallback<VolumeApiResult> callback);
AsyncCallFuture<VolumeApiResult> createVolumeFromTemplateAsync(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType, TemplateInfo template);
}

View File

@ -24,6 +24,7 @@ import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
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.AsyncCallFuture;
import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.framework.async.AsyncRpcConext;
@ -33,6 +34,7 @@ import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
import org.apache.cloudstack.storage.datastore.manager.PrimaryDataStoreManager;
import org.apache.cloudstack.storage.image.TemplateInfo;
import org.apache.cloudstack.storage.image.motion.ImageMotionService;
import org.apache.cloudstack.storage.volume.VolumeService.VolumeApiResult;
import org.apache.cloudstack.storage.volume.db.VolumeDao2;
import org.apache.cloudstack.storage.volume.db.VolumeVO;
@ -62,43 +64,57 @@ public class VolumeServiceImpl implements VolumeService {
private class CreateVolumeContext<T> extends AsyncRpcConext<T> {
private VolumeObject volume;
private AsyncCallFuture<VolumeApiResult> future;
/**
* @param callback
*/
public CreateVolumeContext(AsyncCompletionCallback<T> callback, VolumeObject volume) {
public CreateVolumeContext(AsyncCompletionCallback<T> callback, VolumeObject volume, AsyncCallFuture<VolumeApiResult> future) {
super(callback);
this.volume = volume;
this.future = future;
}
public VolumeObject getVolume() {
return this.volume;
}
public AsyncCallFuture<VolumeApiResult> getFuture() {
return this.future;
}
}
@Override
public void createVolumeAsync(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType, AsyncCompletionCallback<VolumeApiResult> callback) {
public AsyncCallFuture<VolumeApiResult> createVolumeAsync(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType) {
PrimaryDataStore dataStore = dataStoreMgr.getPrimaryDataStore(dataStoreId);
AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
VolumeApiResult result = new VolumeApiResult(volume);
if (dataStore == null) {
throw new CloudRuntimeException("Can't find dataStoreId: " + dataStoreId);
result.setResult("Can't find dataStoreId: " + dataStoreId);
future.complete(result);
return future;
}
if (dataStore.exists(volume)) {
throw new CloudRuntimeException("Volume: " + volume.getId() + " already exists on primary data store: " + dataStoreId);
result.setResult("Volume: " + volume.getId() + " already exists on primary data store: " + dataStoreId);
future.complete(result);
return future;
}
VolumeObject vo = (VolumeObject) volume;
vo.stateTransit(Volume.Event.CreateRequested);
CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(callback, vo);
CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, vo, future);
AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().createVolumeCallback(null, null))
.setContext(context);
dataStore.createVolumeAsync(vo, diskType, caller);
return future;
}
public Void createVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> callback, CreateVolumeContext<VolumeApiResult> context) {
protected Void createVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> callback, CreateVolumeContext<VolumeApiResult> context) {
CommandResult result = callback.getResult();
VolumeObject vo = context.getVolume();
VolumeApiResult volResult = new VolumeApiResult(vo);
@ -109,43 +125,54 @@ public class VolumeServiceImpl implements VolumeService {
volResult.setResult(result.getResult());
}
context.getParentCallback().complete(volResult);
context.getFuture().complete(volResult);
return null;
}
private class DeleteVolumeContext<T> extends AsyncRpcConext<T> {
private final VolumeObject volume;
private AsyncCallFuture<VolumeApiResult> future;
/**
* @param callback
*/
public DeleteVolumeContext(AsyncCompletionCallback<T> callback, VolumeObject volume) {
public DeleteVolumeContext(AsyncCompletionCallback<T> callback, VolumeObject volume, AsyncCallFuture<VolumeApiResult> future) {
super(callback);
this.volume = volume;
this.future = future;
}
public VolumeObject getVolume() {
return this.volume;
}
public AsyncCallFuture<VolumeApiResult> getFuture() {
return this.future;
}
}
@DB
@Override
public void deleteVolumeAsync(VolumeInfo volume, AsyncCompletionCallback<VolumeApiResult> callback) {
public AsyncCallFuture<VolumeApiResult> deleteVolumeAsync(VolumeInfo volume) {
VolumeObject vo = (VolumeObject)volume;
AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
VolumeApiResult result = new VolumeApiResult(volume);
PrimaryDataStore dataStore = vo.getDataStore();
vo.stateTransit(Volume.Event.DestroyRequested);
if (dataStore == null) {
vo.stateTransit(Volume.Event.OperationSucceeded);
volDao.remove(vo.getId());
return;
future.complete(result);
return future;
}
DeleteVolumeContext<VolumeApiResult> context = new DeleteVolumeContext<VolumeApiResult>(callback, vo);
DeleteVolumeContext<VolumeApiResult> context = new DeleteVolumeContext<VolumeApiResult>(null, vo, future);
AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().deleteVolumeCallback(null, null))
.setContext(context);
dataStore.deleteVolumeAsync(volume, caller);
return future;
}
public Void deleteVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> callback, DeleteVolumeContext<VolumeApiResult> context) {
@ -159,7 +186,7 @@ public class VolumeServiceImpl implements VolumeService {
vo.stateTransit(Volume.Event.OperationFailed);
apiResult.setResult(result.getResult());
}
context.getParentCallback().complete(apiResult);
context.getFuture().complete(apiResult);
return null;
}
@ -212,11 +239,14 @@ public class VolumeServiceImpl implements VolumeService {
private final VolumeInfo volume;
private final PrimaryDataStore dataStore;
private final TemplateOnPrimaryDataStoreObject template;
public CreateBaseImageContext(AsyncCompletionCallback<T> callback, VolumeInfo volume, PrimaryDataStore datastore, TemplateOnPrimaryDataStoreObject template) {
private final AsyncCallFuture<VolumeApiResult> future;
public CreateBaseImageContext(AsyncCompletionCallback<T> callback, VolumeInfo volume, PrimaryDataStore datastore, TemplateOnPrimaryDataStoreObject template,
AsyncCallFuture<VolumeApiResult> future) {
super(callback);
this.volume = volume;
this.dataStore = datastore;
this.template = template;
this.future = future;
}
public VolumeInfo getVolume() {
@ -231,9 +261,13 @@ public class VolumeServiceImpl implements VolumeService {
return this.template;
}
public AsyncCallFuture<VolumeApiResult> getFuture() {
return this.future;
}
}
@DB
protected void createBaseImageAsync(VolumeInfo volume, PrimaryDataStore dataStore, TemplateInfo template, AsyncCompletionCallback<VolumeApiResult> callback) {
protected void createBaseImageAsync(VolumeInfo volume, PrimaryDataStore dataStore, TemplateInfo template, AsyncCallFuture<VolumeApiResult> future) {
TemplateOnPrimaryDataStoreObject templateOnPrimaryStoreObj = (TemplateOnPrimaryDataStoreObject) templatePrimaryStoreMgr.createTemplateOnPrimaryDataStore(template, dataStore);
templateOnPrimaryStoreObj.stateTransit(TemplateOnPrimaryDataStoreStateMachine.Event.CreateRequested);
templateOnPrimaryStoreObj.updateStatus(Status.CREATING);
@ -243,12 +277,15 @@ public class VolumeServiceImpl implements VolumeService {
} catch (Exception e) {
templateOnPrimaryStoreObj.updateStatus(Status.ABANDONED);
templateOnPrimaryStoreObj.stateTransit(TemplateOnPrimaryDataStoreStateMachine.Event.OperationFailed);
throw new CloudRuntimeException(e.toString());
VolumeApiResult result = new VolumeApiResult(volume);
result.setResult(e.toString());
future.complete(result);
return;
}
templateOnPrimaryStoreObj.updateStatus(Status.DOWNLOAD_IN_PROGRESS);
CreateBaseImageContext<VolumeApiResult> context = new CreateBaseImageContext<VolumeApiResult>(callback, volume, dataStore, templateOnPrimaryStoreObj);
CreateBaseImageContext<VolumeApiResult> context = new CreateBaseImageContext<VolumeApiResult>(null, volume, dataStore, templateOnPrimaryStoreObj, future);
AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().createBaseImageCallback(null, null))
.setContext(context);
@ -257,7 +294,7 @@ public class VolumeServiceImpl implements VolumeService {
}
@DB
public Object createBaseImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> callback, CreateBaseImageContext<VolumeApiResult> context) {
protected Void createBaseImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> callback, CreateBaseImageContext<VolumeApiResult> context) {
CommandResult result = callback.getResult();
TemplateOnPrimaryDataStoreObject templateOnPrimaryStoreObj = context.getTemplate();
if (result.isSuccess()) {
@ -266,36 +303,45 @@ public class VolumeServiceImpl implements VolumeService {
templateOnPrimaryStoreObj.stateTransit(TemplateOnPrimaryDataStoreStateMachine.Event.OperationFailed);
}
AsyncCompletionCallback<VolumeApiResult> parentCaller = context.getParentCallback();
AsyncCallFuture<VolumeApiResult> future = context.getFuture();
VolumeInfo volume = context.getVolume();
PrimaryDataStore pd = context.getDataStore();
createVolumeFromBaseImageAsync(volume, templateOnPrimaryStoreObj, pd, parentCaller);
createVolumeFromBaseImageAsync(volume, templateOnPrimaryStoreObj, pd, future);
return null;
}
private class CreateVolumeFromBaseImageContext<T> extends AsyncRpcConext<T> {
private final VolumeObject vo;
public CreateVolumeFromBaseImageContext(AsyncCompletionCallback<T> callback, VolumeObject vo) {
private final AsyncCallFuture<VolumeApiResult> future;
public CreateVolumeFromBaseImageContext(AsyncCompletionCallback<T> callback, VolumeObject vo, AsyncCallFuture<VolumeApiResult> future) {
super(callback);
this.vo = vo;
this.future = future;
}
public VolumeObject getVolumeObject() {
return this.vo;
}
public AsyncCallFuture<VolumeApiResult> getFuture() {
return this.future;
}
}
@DB
protected void createVolumeFromBaseImageAsync(VolumeInfo volume, TemplateOnPrimaryDataStoreInfo templateOnPrimaryStore, PrimaryDataStore pd, AsyncCompletionCallback<VolumeApiResult> callback) {
protected void createVolumeFromBaseImageAsync(VolumeInfo volume, TemplateOnPrimaryDataStoreInfo templateOnPrimaryStore, PrimaryDataStore pd, AsyncCallFuture<VolumeApiResult> future) {
VolumeObject vo = (VolumeObject) volume;
try {
vo.stateTransit(Volume.Event.CreateRequested);
} catch (Exception e) {
throw new CloudRuntimeException(e.toString());
VolumeApiResult result = new VolumeApiResult(volume);
result.setResult(e.toString());
future.complete(result);
return;
}
CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<VolumeApiResult>(callback, vo);
CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<VolumeApiResult>(null, vo, future);
AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().createVolumeFromBaseImageCallback(null, null))
.setContext(context);
@ -314,24 +360,27 @@ public class VolumeServiceImpl implements VolumeService {
vo.stateTransit(Volume.Event.OperationFailed);
volResult.setResult(result.getResult());
}
AsyncCompletionCallback<VolumeApiResult> parentCall = context.getParentCallback();
parentCall.complete(volResult);
AsyncCallFuture<VolumeApiResult> future = context.getFuture();
future.complete(volResult);
return null;
}
@DB
@Override
public void createVolumeFromTemplateAsync(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType, TemplateInfo template, AsyncCompletionCallback<VolumeApiResult> callback) {
public AsyncCallFuture<VolumeApiResult> createVolumeFromTemplateAsync(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType, TemplateInfo template) {
PrimaryDataStore pd = dataStoreMgr.getPrimaryDataStore(dataStoreId);
TemplateOnPrimaryDataStoreInfo templateOnPrimaryStore = pd.getTemplate(template);
AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
VolumeApiResult result = new VolumeApiResult(volume);
if (templateOnPrimaryStore == null) {
createBaseImageAsync(volume, pd, template, callback);
return;
createBaseImageAsync(volume, pd, template, future);
return future;
}
createVolumeFromBaseImageAsync(volume, templateOnPrimaryStore, pd, callback);
createVolumeFromBaseImageAsync(volume, templateOnPrimaryStore, pd, future);
return future;
}
@Override

View File

@ -43,7 +43,7 @@ import com.cloud.dc.dao.ClusterDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:/resource/testContext.xml")
@ContextConfiguration(locations="classpath:/testContext.xml")
public class ConfiguratorTest {
@Inject
@Qualifier("defaultProvider")

View File

@ -11,10 +11,13 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-framework-ipc</artifactId>
<version>4.1.0-SNAPSHOT</version>
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine</artifactId>
<version>4.1.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>
<!-- <dependency> <groupId>org.hornetq</groupId> <artifactId>hornetq-core-client</artifactId>
<version>snap-r9548</version> </dependency> -->
@ -35,6 +38,11 @@
<build>
<defaultGoal>install</defaultGoal>
<sourceDirectory>src</sourceDirectory>
<testSourceDirectory>src</testSourceDirectory>
<testSourceDirectory>${project.basedir}/test</testSourceDirectory>
<testResources>
<testResource>
<directory>${project.basedir}/test/resources</directory>
</testResource>
</testResources>
</build>
</project>

View File

@ -19,17 +19,22 @@
package org.apache.cloudstack.framework.codestyle;
import org.apache.cloudstack.framework.async.AsyncCallFuture;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
public class AsyncSampleCallee {
AsyncSampleCallee _driver;
public AsyncCallFuture<String> createVolume(Object realParam) {
String result = "result object";
String result = realParam.toString();
AsyncCallFuture<String> call = new AsyncCallFuture<String>();
call.complete(result);
return call;
}
public void createVolumeAsync(String param, AsyncCompletionCallback<String> callback) {
callback.complete(param);
}
}

View File

@ -18,31 +18,101 @@
*/
package org.apache.cloudstack.framework.codestyle;
import java.util.concurrent.ExecutionException;
import org.apache.cloudstack.framework.async.AsyncCallFuture;
import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
import org.apache.cloudstack.framework.async.AsyncCallbackDriver;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.framework.async.AsyncRpcConext;
import org.junit.Assert;
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:/SampleManagementServerAppContext.xml")
public class AsyncSampleEventDrivenStyleCaller {
AsyncSampleCallee _ds = new AsyncSampleCallee();
AsyncCallbackDriver _callbackDriver;
@SuppressWarnings("unchecked")
public void MethodThatWillCallAsyncMethod() {
String vol = new String("Hello");
AsyncCallbackDispatcher<AsyncSampleEventDrivenStyleCaller, Object> caller = AsyncCallbackDispatcher.create(this);
_ds.createVolume(vol, caller
.setCallback(caller.getTarget().HandleVolumeCreateAsyncCallback(null, null))
.setContext(vol)
);
}
private AsyncSampleCallee _ds;
AsyncCallbackDriver _callbackDriver;
@Before
public void setup() {
_ds = new AsyncSampleCallee();
}
@SuppressWarnings("unchecked")
@Test
public void MethodThatWillCallAsyncMethod() {
String vol = new String("Hello");
AsyncCallbackDispatcher<AsyncSampleEventDrivenStyleCaller, Object> caller = AsyncCallbackDispatcher.create(this);
AsyncCallFuture<String> future = _ds.createVolume(vol);
try {
String result = future.get();
Assert.assertEquals(result, vol);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private class TestContext<T> extends AsyncRpcConext<T> {
private boolean finished;
private String result;
/**
* @param callback
*/
public TestContext(AsyncCompletionCallback<T> callback) {
super(callback);
this.finished = false;
}
public void setResult(String result) {
this.result = result;
synchronized (this) {
this.finished = true;
this.notify();
}
}
public String getResult() {
synchronized (this) {
if (!this.finished) {
try {
this.wait();
public Void HandleVolumeCreateAsyncCallback(AsyncCallbackDispatcher<AsyncSampleEventDrivenStyleCaller, Object> callback, String context) {
Object resultVol = callback.getResult();
return null;
}
public static void main(String[] args) {
AsyncSampleEventDrivenStyleCaller caller = new AsyncSampleEventDrivenStyleCaller();
caller.MethodThatWillCallAsyncMethod();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return this.result;
}
}
}
@Test
public void installCallback() {
TestContext<String> context = new TestContext<String>(null);
AsyncCallbackDispatcher<AsyncSampleEventDrivenStyleCaller, Object> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().HandleVolumeCreateAsyncCallback(null, null))
.setContext(context);
String test = "test";
_ds.createVolumeAsync(test, caller);
Assert.assertEquals(test, context.getResult());
}
protected Void HandleVolumeCreateAsyncCallback(AsyncCallbackDispatcher<AsyncSampleEventDrivenStyleCaller, String> callback, TestContext<String> context) {
String resultVol = callback.getResult();
context.setResult(resultVol);
return null;
}
public static void main(String[] args) {
AsyncSampleEventDrivenStyleCaller caller = new AsyncSampleEventDrivenStyleCaller();
caller.MethodThatWillCallAsyncMethod();
}
}

View File

@ -26,13 +26,13 @@ public class AsyncSampleListenerStyleCaller {
public void MethodThatWillCallAsyncMethod() {
String vol = new String();
_ds.createVolume(vol,
/* _ds.createVolume(vol,
new AsyncCompletionCallback<String>() {
@Override
public void complete(String resultObject) {
// TODO Auto-generated method stub
}
});
});*/
}
}