mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
1st try to add async api in the storage component, it's ugly like hell
This commit is contained in:
parent
01a4a51abf
commit
716a5673d0
@ -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);
|
||||
}
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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);
|
||||
}
|
||||
@ -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
|
||||
@ -53,5 +59,18 @@ 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());
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -37,7 +39,9 @@ public interface PrimaryDataStore extends PrimaryDataStoreInfo {
|
||||
VolumeInfo createVolume(VolumeInfo vo, VolumeDiskType diskType);
|
||||
|
||||
VolumeInfo createVoluemFromBaseImage(VolumeInfo volume, TemplateOnPrimaryDataStoreInfo templateStore);
|
||||
|
||||
|
||||
void createVoluemFromBaseImageAsync(VolumeInfo volume, TemplateOnPrimaryDataStoreInfo templateStore, AsyncCompletionCallback<CommandResult> callback);
|
||||
|
||||
List<EndPoint> getEndPoints();
|
||||
|
||||
boolean exists(VolumeInfo vi);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
vo.stateTransit(Volume.Event.OperationSucceeded);
|
||||
} catch (Exception e) {
|
||||
|
||||
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);
|
||||
} 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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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.upgrade.dao" />
|
||||
<context:component-scan base-package="com.cloud.dc.dao" />
|
||||
<context:component-scan base-package="org.apache.cloudstack.framework" />
|
||||
|
||||
<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>
|
||||
@ -34,5 +34,6 @@
|
||||
<build>
|
||||
<defaultGoal>install</defaultGoal>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
<testSourceDirectory>src</testSourceDirectory>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -69,4 +69,8 @@ public class SampleManagerComponent2 {
|
||||
@EventHandler(topic="storage.prepare")
|
||||
void onPrepareNetwork(String sender, String topic, Object args) {
|
||||
}
|
||||
|
||||
void test() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user