mirror of https://github.com/apache/cloudstack.git
change the top level async call using future
This commit is contained in:
parent
2e9c55f8f6
commit
2d6133c61e
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
}
|
||||
});
|
||||
});*/
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue