Updated Branches: refs/heads/javelin 2e9c55f8f -> 2d6133c61
change the top level async call using future Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/2d6133c6 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/2d6133c6 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/2d6133c6 Branch: refs/heads/javelin Commit: 2d6133c61e2334b854b2cda863c53c7e0322226c Parents: 2e9c55f Author: Edison Su <[email protected]> Authored: Fri Jan 4 17:17:40 2013 -0800 Committer: Edison Su <[email protected]> Committed: Fri Jan 4 17:17:57 2013 -0800 ---------------------------------------------------------------------- .../cloudstack/storage/test/volumeServiceTest.java | 5 +- .../storage/volume/VolumeEntityImpl.java | 67 +++------ .../cloudstack/storage/volume/VolumeService.java | 8 +- .../storage/volume/VolumeServiceImpl.java | 109 ++++++++++---- .../storage/volume/test/ConfiguratorTest.java | 2 +- framework/ipc/pom.xml | 16 ++- .../framework/codestyle/AsyncSampleCallee.java | 7 +- .../AsyncSampleEventDrivenStyleCaller.java | 114 ++++++++++++--- .../codestyle/AsyncSampleListenerStyleCaller.java | 4 +- 9 files changed, 219 insertions(+), 113 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2d6133c6/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java ---------------------------------------------------------------------- diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java index cb915c2..2aec905 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java @@ -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()); http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2d6133c6/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java ---------------------------------------------------------------------- diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java index f3e07e7..b90a6d6 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java @@ -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); - } - return true; - } - - - public Object createVolumeFromTemplateAsyncCallback(AsyncCallbackDispatcher<VolumeEntityImpl, VolumeInfo> callback, Object context) { - synchronized (volumeInfo) { - volumeInfo.notify(); + throw new CloudRuntimeException("wait result failed", e); + } catch (ExecutionException e) { + throw new CloudRuntimeException("wait result failed", e); } - 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); - } - } - - public Void createVolumeCallback(AsyncCallbackDispatcher<VolumeApiResult, VolumeApiResult> callback, Object context) { - synchronized (volumeInfo) { - this.result = callback.getResult(); - volumeInfo.notify(); + throw new CloudRuntimeException("wait volume info failed", e); + } catch (ExecutionException e) { + throw new CloudRuntimeException("wait volume failed", e); } - 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() { http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2d6133c6/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 6d5118a..2bd2127 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeService.java +++ b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeService.java @@ -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); } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2d6133c6/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 445e6b3..fa047e8 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 @@ -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 http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2d6133c6/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java ---------------------------------------------------------------------- diff --git a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java index 48bf880..4ad20d5 100644 --- a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java +++ b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java @@ -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") http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2d6133c6/framework/ipc/pom.xml ---------------------------------------------------------------------- diff --git a/framework/ipc/pom.xml b/framework/ipc/pom.xml index b630f47..1f5de3d 100644 --- a/framework/ipc/pom.xml +++ b/framework/ipc/pom.xml @@ -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> http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2d6133c6/framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleCallee.java ---------------------------------------------------------------------- diff --git a/framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleCallee.java b/framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleCallee.java index f1a4b10..8833da2 100644 --- a/framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleCallee.java +++ b/framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleCallee.java @@ -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); + } } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2d6133c6/framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleEventDrivenStyleCaller.java ---------------------------------------------------------------------- diff --git a/framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleEventDrivenStyleCaller.java b/framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleEventDrivenStyleCaller.java index 1176eb2..db39588 100644 --- a/framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleEventDrivenStyleCaller.java +++ b/framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleEventDrivenStyleCaller.java @@ -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(); + + } 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 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(); - } + public static void main(String[] args) { + AsyncSampleEventDrivenStyleCaller caller = new AsyncSampleEventDrivenStyleCaller(); + caller.MethodThatWillCallAsyncMethod(); + } } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2d6133c6/framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleListenerStyleCaller.java ---------------------------------------------------------------------- diff --git a/framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleListenerStyleCaller.java b/framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleListenerStyleCaller.java index e4e7af8..4a84f06 100644 --- a/framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleListenerStyleCaller.java +++ b/framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleListenerStyleCaller.java @@ -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 } - }); + });*/ } }
