From abf40435f3cb1d72535eb15067348e4c9253340d Mon Sep 17 00:00:00 2001 From: Edison Su Date: Sun, 21 Apr 2013 22:46:02 -0700 Subject: [PATCH] refactor downloadlistener, sync system vm templates when adding a new image store --- .../src/com/cloud/agent/Listener.java | 4 +- .../subsystem/api/storage/EndPoint.java | 2 + .../api/storage/TemplateService.java | 3 +- .../StorageCacheRandomAllocator.java | 2 + .../manager/StorageCacheManagerImpl.java | 23 +- .../storage/image/TemplateServiceImpl.java | 73 ++--- .../storage/image/store/TemplateObject.java | 31 +- .../storage/test/volumeServiceTest.java | 4 +- .../cloudstack/storage/LocalHostEndpoint.java | 48 ++- .../storage/RemoteHostEndPoint.java | 49 ++- .../datastore/ObjectInDataStoreManager.java | 1 - .../ObjectInDataStoreManagerImpl.java | 35 +-- .../storage/volume/VolumeObject.java | 2 +- .../storage/volume/VolumeServiceImpl.java | 9 +- .../cloud/resource/SimulatorDiscoverer.java | 3 +- .../SimulatorSecondaryDiscoverer.java | 3 +- .../vmware/manager/VmwareManagerImpl.java | 3 +- .../xen/discoverer/XcpServerDiscoverer.java | 2 +- .../CloudStackImageStoreDriverImpl.java | 65 +++- .../driver/S3ImageStoreDriverImpl.java | 6 +- .../driver/SwiftImageStoreDriverImpl.java | 6 +- server/pom.xml | 5 + .../com/cloud/agent/manager/AgentMonitor.java | 2 +- .../agent/manager/SynchronousListener.java | 4 +- .../com/cloud/capacity/CapacityManager.java | 3 +- .../cloud/capacity/CapacityManagerImpl.java | 13 +- .../capacity/ComputeCapacityListener.java | 4 +- .../capacity/StorageCapacityListener.java | 4 +- .../AgentBasedConsoleProxyManager.java | 4 +- .../src/com/cloud/consoleproxy/AgentHook.java | 4 +- .../consoleproxy/ConsoleProxyListener.java | 4 +- .../consoleproxy/ConsoleProxyManager.java | 4 +- .../consoleproxy/ConsoleProxyManagerImpl.java | 2 +- .../discoverer/LibvirtServerDiscoverer.java | 2 +- .../com/cloud/network/NetworkManagerImpl.java | 3 +- .../network/NetworkUsageManagerImpl.java | 2 +- .../cloud/network/SshKeysDistriMonitor.java | 4 +- .../VirtualNetworkApplianceManagerImpl.java | 3 +- .../security/SecurityGroupListener.java | 4 +- .../storage/LocalStoragePoolListener.java | 4 +- .../download/DownloadAbandonedState.java | 4 +- .../storage/download/DownloadActiveState.java | 2 +- .../storage/download/DownloadErrorState.java | 6 +- .../storage/download/DownloadListener.java | 286 ++---------------- .../storage/download/DownloadMonitor.java | 22 +- .../storage/download/DownloadMonitorImpl.java | 166 +++------- .../cloud/storage/download/DownloadState.java | 2 +- .../storage/listener/StoragePoolMonitor.java | 4 +- .../storage/listener/StorageSyncListener.java | 4 +- .../secondary/SecondaryStorageListener.java | 4 +- .../cloud/storage/upload/UploadListener.java | 3 +- .../template/HypervisorTemplateAdapter.java | 46 ++- .../cloud/vm/VirtualMachineManagerImpl.java | 2 +- 53 files changed, 417 insertions(+), 583 deletions(-) rename {core => api}/src/com/cloud/agent/Listener.java (96%) diff --git a/core/src/com/cloud/agent/Listener.java b/api/src/com/cloud/agent/Listener.java similarity index 96% rename from core/src/com/cloud/agent/Listener.java rename to api/src/com/cloud/agent/Listener.java index 47b9bc3011d..3b825bd7b4e 100755 --- a/core/src/com/cloud/agent/Listener.java +++ b/api/src/com/cloud/agent/Listener.java @@ -22,7 +22,7 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.StartupCommand; import com.cloud.exception.ConnectionException; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; /** @@ -72,7 +72,7 @@ public interface Listener { * @param agentId id of the agent * @throws ConnectionException if host has problems and needs to put into maintenance state. */ - void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException; + void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException; /** * This method is called by AgentManager when an agent disconnects diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java index 2ff45b1bf56..eb6da701208 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java @@ -18,6 +18,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import com.cloud.agent.Listener; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; @@ -25,4 +26,5 @@ public interface EndPoint { public long getId(); public Answer sendMessage(Command cmd); public void sendMessageAsync(Command cmd, AsyncCompletionCallback callback); + void sendMessageAsyncWithListener(Command cmd, Listener listner); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java index d7010fd9e2f..f04b14df050 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java @@ -20,6 +20,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.framework.async.AsyncCompletionCallback; @@ -40,7 +41,7 @@ public interface TemplateService { } - AsyncCallFuture createTemplateAsync(TemplateInfo template, DataStore store); + void createTemplateAsync(TemplateInfo template, DataStore store, AsyncCompletionCallback callback); AsyncCallFuture createTemplateFromSnapshotAsync(SnapshotInfo snapshot, TemplateInfo template, DataStore store); AsyncCallFuture createTemplateFromVolumeAsync(VolumeInfo volume, TemplateInfo template, DataStore store); AsyncCallFuture deleteTemplateAsync(TemplateInfo template); diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java index c357d239026..462f13fca77 100644 --- a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java +++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java @@ -25,12 +25,14 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; +import org.springframework.stereotype.Component; import com.cloud.storage.ScopeType; import com.cloud.utils.exception.CloudRuntimeException; import edu.emory.mathcs.backport.java.util.Collections; +@Component public class StorageCacheRandomAllocator implements StorageCacheAllocator { @Inject DataStoreManager dataStoreMgr; diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java index 150c28930f5..47fe4890220 100644 --- a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java +++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java @@ -37,6 +37,7 @@ import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.cache.allocator.StorageCacheAllocator; +import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.log4j.Logger; import com.cloud.utils.component.Manager; @@ -115,11 +116,11 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { private class CreateCacheObjectContext extends AsyncRpcConext { - final AsyncCallFuture future; + final AsyncCallFuture future; /** * @param callback */ - public CreateCacheObjectContext(AsyncCompletionCallback callback, AsyncCallFuture future) { + public CreateCacheObjectContext(AsyncCompletionCallback callback, AsyncCallFuture future) { super(callback); this.future = future; } @@ -130,22 +131,22 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { public DataObject createCacheObject(DataObject data, Scope scope) { DataStore cacheStore = this.getCacheStorage(scope); DataObject objOnCacheStore = cacheStore.create(data); - AsyncCallFuture future = new AsyncCallFuture(); - CreateCacheObjectContext context = new CreateCacheObjectContext(null, future); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + AsyncCallFuture future = new AsyncCallFuture(); + CreateCacheObjectContext context = new CreateCacheObjectContext(null, future); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setContext(context); - CommandResult result = null; + CopyCmdAnswer result = null; try { objOnCacheStore.processEvent(Event.CreateOnlyRequested); dataMotionSvr.copyAsync(data, objOnCacheStore, caller); result = future.get(); - if (result.isFailed()) { + if (!result.getResult()) { cacheStore.delete(data); } else { - objOnCacheStore.processEvent(Event.OperationSuccessed); + objOnCacheStore.processEvent(Event.OperationSuccessed, result); } } catch (InterruptedException e) { s_logger.debug("create cache storage failed: " + e.toString()); @@ -162,9 +163,9 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { return null; } - protected Void createCacheObjectCallBack(AsyncCallbackDispatcher callback, - CreateCacheObjectContext context) { - AsyncCallFuture future = context.future; + protected Void createCacheObjectCallBack(AsyncCallbackDispatcher callback, + CreateCacheObjectContext context) { + AsyncCallFuture future = context.future; future.complete(callback.getResult()); return null; } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 04003bfb577..0057012945a 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -34,19 +34,15 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult; - -import com.cloud.storage.template.TemplateProp; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; -import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; @@ -71,25 +67,22 @@ import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ResourceAllocationException; -import com.cloud.host.HostVO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.StoragePool; import com.cloud.storage.VMTemplateStoragePoolVO; -import com.cloud.storage.VMTemplateStorageResourceAssoc; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.secondary.SecondaryStorageVmManager; +import com.cloud.storage.template.TemplateProp; import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; import com.cloud.utils.UriUtils; -import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.NoTransitionException; import com.cloud.vm.UserVmVO; import com.cloud.vm.dao.UserVmDao; @@ -137,15 +130,11 @@ public class TemplateServiceImpl implements TemplateService { TemplateDataFactory _templateFactory; @Inject VMTemplatePoolDao _tmpltPoolDao; - - - class TemplateOpContext extends AsyncRpcConext { final TemplateObject template; final AsyncCallFuture future; - public TemplateOpContext(AsyncCompletionCallback callback, TemplateObject template, - AsyncCallFuture future) { + AsyncCallFuture future) { super(callback); this.template = template; this.future = future; @@ -154,30 +143,22 @@ public class TemplateServiceImpl implements TemplateService { public TemplateObject getTemplate() { return template; } - - public AsyncCallFuture getFuture() { - return future; - } - - } @Override - public AsyncCallFuture createTemplateAsync( - TemplateInfo template, DataStore store) { - AsyncCallFuture future = new AsyncCallFuture(); + public void createTemplateAsync( + TemplateInfo template, DataStore store, AsyncCompletionCallback callback) { // persist template_store_ref entry DataObject templateOnStore = store.create(template); // update template_store_ref state templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested); - TemplateOpContext context = new TemplateOpContext(null, - (TemplateObject)templateOnStore, future); + TemplateOpContext context = new TemplateOpContext(callback, + (TemplateObject)templateOnStore, null); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().createTemplateCallback(null, null)).setContext(context); store.getDriver().createAsync(templateOnStore, caller); - return future; } @Override @@ -185,26 +166,20 @@ public class TemplateServiceImpl implements TemplateService { Set toBeDownloaded = new HashSet(); List rtngTmplts = _templateDao.listAllSystemVMTemplates(); - List defaultBuiltin = _templateDao.listDefaultBuiltinTemplates(); for (VMTemplateVO rtngTmplt : rtngTmplts) { toBeDownloaded.add(rtngTmplt); } - for (VMTemplateVO builtinTmplt : defaultBuiltin) { - toBeDownloaded.add(builtinTmplt); - } - for (VMTemplateVO template : toBeDownloaded) { TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId()); if (tmpltHost == null || tmpltHost.getState() != ObjectInDataStoreStateMachine.State.Ready) { - _dlMonitor.downloadBootstrapSysTemplateToStorage(template, store, null); + TemplateInfo tmplt = this._templateFactory.getTemplate(template.getId()); + this.createTemplateAsync(tmplt, store, null); } } } - - - + @Override public void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId) { Set toBeDownloaded = new HashSet(); @@ -234,16 +209,13 @@ public class TemplateServiceImpl implements TemplateService { for (VMTemplateVO template: toBeDownloaded) { TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(ssHost.getId(), template.getId()); if (tmpltHost == null || tmpltHost.getState() != ObjectInDataStoreStateMachine.State.Ready) { - _dlMonitor.downloadTemplateToStorage(template, ssHost, null); + DataObject tmpl = this._templateFactory.getTemplate(template.getId(), ssHost); + _dlMonitor.downloadTemplateToStorage(tmpl, ssHost, null); } } } } - - - - @Override public void handleTemplateSync(DataStore store) { if (store == null) { @@ -394,7 +366,8 @@ public class TemplateServiceImpl implements TemplateService { } s_logger.debug("Template " + tmplt.getName() + " needs to be downloaded to " + store.getName()); //TODO: we should pass a callback here - _dlMonitor.downloadTemplateToStorage(tmplt, store, null); + DataObject tmpl = this._templateFactory.getTemplate(tmplt.getId(), store); + _dlMonitor.downloadTemplateToStorage(tmpl, store, null); } } } @@ -465,9 +438,9 @@ public class TemplateServiceImpl implements TemplateService { protected Void createTemplateCallback(AsyncCallbackDispatcher callback, - TemplateOpContext context) { + TemplateOpContext context) { TemplateObject template = (TemplateObject)context.getTemplate(); - AsyncCallFuture future = context.getFuture(); + AsyncCompletionCallback parentCallback = context.getParentCallback(); TemplateApiResult result = new TemplateApiResult(template); CreateCmdResult callbackResult = callback.getResult(); if (callbackResult.isFailed()) { @@ -478,7 +451,7 @@ public class TemplateServiceImpl implements TemplateService { s_logger.debug("Failed to update template state", e); } result.setResult(callbackResult.getResult()); - future.complete(result); + parentCallback.complete(result); return null; } @@ -488,11 +461,11 @@ public class TemplateServiceImpl implements TemplateService { } catch (NoTransitionException e) { s_logger.debug("Failed to transit state", e); result.setResult(e.toString()); - future.complete(result); + parentCallback.complete(result); return null; } - future.complete(result); + parentCallback.complete(result); return null; } @@ -520,7 +493,7 @@ public class TemplateServiceImpl implements TemplateService { } else { vo.processEvent(Event.OperationFailed); } - context.getFuture().complete(result); + context.future.complete(result); return null; } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index 15aad4ba3e7..3230724ba8c 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -29,13 +29,19 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreState import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; +import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.image.manager.ImageDataManager; import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; +import com.cloud.storage.DataStoreRole; +import com.cloud.storage.VMTemplateStoragePoolVO; import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.utils.component.ComponentContext; @@ -54,6 +60,7 @@ public class TemplateObject implements TemplateInfo { @Inject ObjectInDataStoreManager ojbectInStoreMgr; @Inject VMTemplatePoolDao templatePoolDao; + @Inject TemplateDataStoreDao templateStoreDao; public TemplateObject() { } @@ -163,7 +170,7 @@ public class TemplateObject implements TemplateInfo { @Override public void processEvent(Event event) { try { - ojbectInStoreMgr.update(this, event, null); + ojbectInStoreMgr.update(this, event); } catch (NoTransitionException e) { s_logger.debug("failed to update state", e); throw new CloudRuntimeException("Failed to update state" + e.toString()); @@ -173,7 +180,27 @@ public class TemplateObject implements TemplateInfo { @Override public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) { try { - ojbectInStoreMgr.update(this, event, answer); + if (this.getDataStore().getRole() == DataStoreRole.Primary) { + if (answer != null && answer instanceof CopyCmdAnswer) { + CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer; + VMTemplateStoragePoolVO templatePoolRef = templatePoolDao.findByPoolTemplate(this.getDataStore().getId(), this.getId()); + templatePoolRef.setDownloadPercent(100); + templatePoolRef.setDownloadState(Status.DOWNLOADED); + templatePoolRef.setLocalDownloadPath(cpyAnswer.getPath()); + templatePoolRef.setInstallPath(cpyAnswer.getPath()); + templatePoolDao.update(templatePoolRef.getId(), templatePoolRef); + } + } else if (this.getDataStore().getRole() == DataStoreRole.Image || + this.getDataStore().getRole() == DataStoreRole.ImageCache) { + if (answer != null && answer instanceof CopyCmdAnswer) { + CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer; + TemplateDataStoreVO templateStoreRef = this.templateStoreDao.findByStoreTemplate(this.getDataStore().getId(), + this.getId()); + templateStoreRef.setInstallPath(cpyAnswer.getPath()); + templateStoreDao.update(templateStoreRef.getId(), templateStoreRef); + } + } + ojbectInStoreMgr.update(this, event); } catch (NoTransitionException e) { s_logger.debug("failed to update state", e); throw new CloudRuntimeException("Failed to update state" + e.toString()); 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 37f0e47955e..e47eaec92eb 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 @@ -238,8 +238,8 @@ public class volumeServiceTest extends CloudStackTestNGBase { DataStore store = createImageStore(); VMTemplateVO image = createImageData(); TemplateInfo template = imageDataFactory.getTemplate(image.getId(), store); - AsyncCallFuture future = imageService.createTemplateAsync(template, store); - future.get(); + //AsyncCallFuture future = imageService.createTemplateAsync(template, store); + //future.get(); template = imageDataFactory.getTemplate(image.getId(), store); /*imageProviderMgr.configure("image Provider", new HashMap()); VMTemplateVO image = createImageData(); diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java index 665ed92ef54..f08a5977b2e 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java @@ -1,20 +1,28 @@ package org.apache.cloudstack.storage; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CopyCmd; +import com.cloud.agent.Listener; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; +import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.resource.ServerResource; +import com.cloud.storage.download.DownloadListener; import com.cloud.storage.resource.LocalNfsSecondaryStorageResource; import com.cloud.utils.component.ComponentContext; public class LocalHostEndpoint implements EndPoint { - + private ScheduledExecutorService executor; ServerResource resource; public LocalHostEndpoint() { resource = ComponentContext.inject(LocalNfsSecondaryStorageResource.class); + executor = Executors.newScheduledThreadPool(10); } @Override public long getId() { @@ -31,11 +39,45 @@ public class LocalHostEndpoint implements EndPoint { return new Answer(cmd, false, "unsupported command:" + cmd.toString()); } + private class CmdRunner implements Runnable { + final Command cmd; + final AsyncCompletionCallback callback; + public CmdRunner(Command cmd, AsyncCompletionCallback callback) { + this.cmd = cmd; + this.callback = callback; + } + @Override + public void run() { + Answer answer = sendMessage(cmd); + callback.complete(answer); + } + } + + private class CmdRunner2 implements Runnable { + final Command cmd; + final AsyncCompletionCallback callback; + public CmdRunner2(Command cmd, AsyncCompletionCallback callback) { + this.cmd = cmd; + this.callback = callback; + } + @Override + public void run() { + DownloadAnswer answer = (DownloadAnswer)sendMessage(cmd); + callback.complete(answer); + } + } @Override public void sendMessageAsync(Command cmd, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - + executor.schedule(new CmdRunner(cmd, callback), 10, TimeUnit.SECONDS); + } + + @Override + public void sendMessageAsyncWithListener(Command cmd, Listener listner) { + if (listner instanceof DownloadListener) { + DownloadListener listener = (DownloadListener)listner; + executor.schedule(new CmdRunner2(cmd, listener.getCallback()), 10, TimeUnit.SECONDS); + } } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java index aec7b520391..9ce4e759fc9 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java @@ -18,6 +18,10 @@ */ package org.apache.cloudstack.storage; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; @@ -25,11 +29,14 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; +import com.cloud.agent.Listener; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; +import com.cloud.agent.manager.Commands; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.OperationTimedoutException; import com.cloud.utils.component.ComponentContext; +import com.cloud.utils.exception.CloudRuntimeException; public class RemoteHostEndPoint implements EndPoint { private static final Logger s_logger = Logger.getLogger(RemoteHostEndPoint.class); @@ -39,9 +46,10 @@ public class RemoteHostEndPoint implements EndPoint { AgentManager agentMgr; @Inject HostEndpointRpcServer rpcServer; + private ScheduledExecutorService executor; protected RemoteHostEndPoint() { - + executor = Executors.newScheduledThreadPool(10); } private void configure(long hostId, String hostAddress) { @@ -65,11 +73,46 @@ public class RemoteHostEndPoint implements EndPoint { @Override public Answer sendMessage(Command cmd) { - return rpcServer.sendCommand(this, cmd); + String errMsg = null; + try { + return agentMgr.send(getId(), cmd); + } catch (AgentUnavailableException e) { + errMsg = e.toString(); + s_logger.debug("Failed to send command, due to Agent:" + getId() + ", " + e.toString()); + } catch (OperationTimedoutException e) { + errMsg = e.toString(); + s_logger.debug("Failed to send command, due to Agent:" + getId() + ", " + e.toString()); + } + throw new CloudRuntimeException("Failed to send command, due to Agent:" + getId() + ", " + errMsg); } + private class CmdRunner implements Runnable { + final Command cmd; + final AsyncCompletionCallback callback; + public CmdRunner(Command cmd, AsyncCompletionCallback callback) { + this.cmd = cmd; + this.callback = callback; + } + @Override + public void run() { + Answer answer = sendMessage(cmd); + callback.complete(answer); + } + + } + @Override public void sendMessageAsync(Command cmd, AsyncCompletionCallback callback) { - rpcServer.sendCommandAsync(this, cmd, callback); + executor.schedule(new CmdRunner(cmd, callback), 10, TimeUnit.SECONDS); + } + + @Override + public void sendMessageAsyncWithListener(Command cmd, Listener listener) { + try { + this.agentMgr.send(getId(), new Commands(cmd), listener); + } catch (AgentUnavailableException e) { + s_logger.debug("Failed to send command: " + e.toString()); + throw new CloudRuntimeException("Failed to send command: " + e.toString()); + } } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java index 876a06694b5..d53029a3474 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java @@ -29,7 +29,6 @@ import com.cloud.utils.fsm.NoTransitionException; public interface ObjectInDataStoreManager { public DataObject create(DataObject template, DataStore dataStore); public DataObject get(DataObject dataObj, DataStore store); - public boolean update(DataObject vo, Event event, Answer answer) throws NoTransitionException; public boolean update(DataObject vo, Event event) throws NoTransitionException; DataObjectInStore findObject(long objId, DataObjectType type, long dataStoreId, DataStoreRole role); diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index 52ed312c0d9..bf9a98d08f7 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -23,12 +23,11 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; -import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; @@ -40,15 +39,12 @@ import org.apache.cloudstack.storage.db.ObjectInDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.cloud.agent.api.Answer; import com.cloud.storage.DataStoreRole; import com.cloud.storage.VMTemplateStoragePoolVO; -import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VolumeDao; -import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.SearchCriteria2; import com.cloud.utils.db.SearchCriteriaService; @@ -162,7 +158,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { } @Override - public boolean update(DataObject data, Event event, Answer answer) + public boolean update(DataObject data, Event event) throws NoTransitionException { DataObjectInStore obj = this.findObject(data, data.getDataStore()); if (obj == null) { @@ -171,7 +167,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { + data); } - if ( data.getDataStore().getRole() == DataStoreRole.Image){ + if ( data.getDataStore().getRole() == DataStoreRole.Image || data.getDataStore().getRole() == DataStoreRole.ImageCache){ switch (data.getType()){ case TEMPLATE: this.stateMachines.transitTo(obj, event, null, templateDataStoreDao); @@ -181,22 +177,10 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { this.stateMachines.transitTo(obj, event, null, volumeDataStoreDao); } } else if (data.getType() == DataObjectType.TEMPLATE && data.getDataStore().getRole() == DataStoreRole.Primary) { - if (answer != null && answer instanceof CopyCmdAnswer) { - CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer; - VMTemplateStoragePoolVO templatePoolRef = templatePoolDao.findByPoolTemplate(data.getDataStore().getId(), data.getId()); - templatePoolRef.setDownloadPercent(100); - templatePoolRef.setDownloadState(Status.DOWNLOADED); - templatePoolRef.setLocalDownloadPath(cpyAnswer.getPath()); - templatePoolRef.setInstallPath(cpyAnswer.getPath()); - templatePoolDao.update(templatePoolRef.getId(), templatePoolRef); - } - try { - obj = this.findObject(data, data.getDataStore()); - this.stateMachines.transitTo(obj, event, null, - templatePoolDao); - } catch (NoTransitionException e) { - throw e; - } + + this.stateMachines.transitTo(obj, event, null, + templatePoolDao); + } else { throw new CloudRuntimeException("Invalid data or store type: " + data.getType() + " " + data.getDataStore().getRole()); } @@ -273,9 +257,4 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { return store; } - @Override - public boolean update(DataObject vo, Event event) throws NoTransitionException { - return this.update(vo, event, null); - } - } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index 34e080d5d52..2834ed03407 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -165,7 +165,7 @@ public class VolumeObject implements VolumeInfo { try { Volume.Event volEvent = null; if (this.dataStore.getRole() == DataStoreRole.Image) { - ojbectInStoreMgr.update(this, event, null); + ojbectInStoreMgr.update(this, event); if (event == ObjectInDataStoreStateMachine.Event.CreateRequested) { volEvent = Volume.Event.UploadRequested; } else if (event == ObjectInDataStoreStateMachine.Event.OperationSuccessed) { 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 d4087ed66f3..42c61f391a5 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 @@ -58,14 +58,14 @@ import com.cloud.agent.api.storage.ListVolumeAnswer; import com.cloud.agent.api.storage.ListVolumeCommand; import com.cloud.alert.AlertManager; import com.cloud.configuration.Config; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ResourceAllocationException; -import com.cloud.host.HostVO; import com.cloud.storage.StoragePool; -import com.cloud.storage.Volume; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.Volume; import com.cloud.storage.Volume.Type; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.VolumeDao; @@ -659,6 +659,9 @@ public class VolumeServiceImpl implements VolumeService { } else { vo.stateTransit(Volume.Event.OperationSucceeded); }*/ + + _resourceLimitMgr.incrementResourceCount(vo.getAccountId(), ResourceType.secondary_storage, + vo.getSize()); VolumeApiResult res = new VolumeApiResult(vo); context.future.complete(res); return null; @@ -805,7 +808,7 @@ public class VolumeServiceImpl implements VolumeService { } s_logger.debug("Volume " + volumeHost.getVolumeId() + " needs to be downloaded to " + store.getName()); //TODO: pass a callback later - _dlMonitor.downloadVolumeToStorage(_volumeDao.findById(volumeHost.getVolumeId()), store, volumeHost.getDownloadUrl(), volumeHost.getChecksum(), volumeHost.getFormat(), null); + _dlMonitor.downloadVolumeToStorage(this.volFactory.getVolume(volumeHost.getVolumeId()), store, volumeHost.getDownloadUrl(), volumeHost.getChecksum(), volumeHost.getFormat(), null); } } diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java index 00fe356103b..a9f61341c9d 100755 --- a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java +++ b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java @@ -44,6 +44,7 @@ import com.cloud.dc.ClusterVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.exception.ConnectionException; import com.cloud.exception.DiscoveryException; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; @@ -255,7 +256,7 @@ public class SimulatorDiscoverer extends DiscovererBase implements Discoverer, L } @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { /*if(forRebalance) return; diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java index 3a8cf17e24b..6bbd90f986f 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java +++ b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java @@ -36,6 +36,7 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupSecondaryStorageCommand; import com.cloud.agent.manager.MockStorageManager; import com.cloud.exception.ConnectionException; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.storage.SnapshotVO; @@ -158,7 +159,7 @@ public class SimulatorSecondaryDiscoverer extends SecondaryStorageDiscoverer imp } @Override - public void processConnect(HostVO host, StartupCommand cmd, + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index b2e37685d17..ba99da11996 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -54,6 +54,7 @@ import com.cloud.dc.ClusterVSMMapVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.ClusterVSMMapDao; import com.cloud.exception.DiscoveredWithErrorException; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; @@ -757,7 +758,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw } @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) { if(cmd instanceof StartupCommand) { if(host.getHypervisorType() == HypervisorType.VMware) { updateClusterNativeHAState(host, cmd); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java index 89bc1cf5708..195ab309872 100755 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java @@ -555,7 +555,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L } @Override - public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + public void processConnect(com.cloud.host.Host agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException { if (!(cmd instanceof StartupRoutingCommand )) { return; } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index fe556a2401d..0c078b1e316 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -18,6 +18,7 @@ */ package org.apache.cloudstack.storage.datastore.driver; +import java.util.Date; import java.util.List; import java.util.Set; @@ -32,6 +33,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; @@ -48,6 +50,7 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; +import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; @@ -155,21 +158,73 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { } } + private class createObjectContext extends AsyncRpcConext { + final DataObject data; + public createObjectContext(AsyncCompletionCallback callback, DataObject data) { + super(callback); + this.data = data; + } + + } @Override public void createAsync(DataObject data, AsyncCompletionCallback callback) { + createObjectContext context = new createObjectContext(callback, data); + AsyncCallbackDispatcher caller = + AsyncCallbackDispatcher.create(this); + caller.setContext(context); + caller.setCallback(callback); + if (data.getType() == DataObjectType.TEMPLATE) { TemplateObject tData = (TemplateObject)data; - _downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback); + _downloadMonitor.downloadTemplateToStorage(tData, tData.getDataStore(), caller); } else if (data.getType() == DataObjectType.VOLUME) { VolumeObject volInfo = (VolumeObject)data; RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload(); - _downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(), - payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback); + _downloadMonitor.downloadVolumeToStorage(volInfo, volInfo.getDataStore(), payload.getUrl(), + payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), caller); } + } + + protected Void createAsyncCallback(AsyncCallbackDispatcher callback, + createObjectContext context) { + DownloadAnswer answer = callback.getResult(); + DataObject obj = context.data; + DataStore store = obj.getDataStore(); - CreateCmdResult result = new CreateCmdResult(null, null); - callback.complete(result); + TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate(); + updateBuilder.setDownloadPercent(answer.getDownloadPct()); + updateBuilder.setDownloadState(answer.getDownloadStatus()); + updateBuilder.setLastUpdated(new Date()); + updateBuilder.setErrorString(answer.getErrorString()); + updateBuilder.setJobId(answer.getJobId()); + updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); + updateBuilder.setInstallPath(answer.getInstallPath()); + updateBuilder.setSize(answer.getTemplateSize()); + updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); + _templateStoreDao.update(store.getId(), updateBuilder); + + AsyncCompletionCallback caller = context.getParentCallback(); + + if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR || + answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED || + answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { + CreateCmdResult result = new CreateCmdResult(null, null); + result.setSucess(false); + result.setResult(answer.getErrorString()); + caller.complete(result); + } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { + if (answer.getCheckSum() != null) { + VMTemplateVO templateDaoBuilder = templateDao.createForUpdate(); + templateDaoBuilder.setChecksum(answer.getCheckSum()); + templateDao.update(obj.getId(), templateDaoBuilder); + } + + + CreateCmdResult result = new CreateCmdResult(null, null); + caller.complete(result); + } + return null; } private void deleteVolume(DataObject data, AsyncCompletionCallback callback) { diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 10734673e4e..6f5d554dac6 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -164,12 +164,12 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { AsyncCompletionCallback callback) { if (data.getType() == DataObjectType.TEMPLATE) { TemplateObject tData = (TemplateObject)data; - _downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback); + _downloadMonitor.downloadTemplateToStorage(tData, tData.getDataStore(), null); } else if (data.getType() == DataObjectType.VOLUME) { VolumeObject volInfo = (VolumeObject)data; RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload(); - _downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(), - payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback); + _downloadMonitor.downloadVolumeToStorage(volInfo, volInfo.getDataStore(), payload.getUrl(), + payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), null); } CreateCmdResult result = new CreateCmdResult(null, null); diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 88405d284ba..1b9ab2d485a 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -157,12 +157,12 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { AsyncCompletionCallback callback) { if (data.getType() == DataObjectType.TEMPLATE) { TemplateObject tData = (TemplateObject)data; - _downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback); + _downloadMonitor.downloadTemplateToStorage(tData, tData.getDataStore(), null); } else if (data.getType() == DataObjectType.VOLUME) { VolumeObject volInfo = (VolumeObject)data; RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload(); - _downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(), - payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback); + _downloadMonitor.downloadVolumeToStorage(volInfo, volInfo.getDataStore(), payload.getUrl(), + payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), null); } CreateCmdResult result = new CreateCmdResult(null, null); diff --git a/server/pom.xml b/server/pom.xml index a3971954475..a74450698ba 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -98,6 +98,11 @@ cloud-framework-events ${project.version} + + org.apache.cloudstack + cloud-framework-ipc + ${project.version} + install diff --git a/server/src/com/cloud/agent/manager/AgentMonitor.java b/server/src/com/cloud/agent/manager/AgentMonitor.java index f3f6669dae6..2c0266e6689 100755 --- a/server/src/com/cloud/agent/manager/AgentMonitor.java +++ b/server/src/com/cloud/agent/manager/AgentMonitor.java @@ -248,7 +248,7 @@ public class AgentMonitor extends Thread implements AgentMonitorService { } @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) { if (host.getType().equals(Host.Type.TrafficMonitor) || host.getType().equals(Host.Type.SecondaryStorage)) { return; diff --git a/server/src/com/cloud/agent/manager/SynchronousListener.java b/server/src/com/cloud/agent/manager/SynchronousListener.java index 074f5a84820..36987053a0f 100755 --- a/server/src/com/cloud/agent/manager/SynchronousListener.java +++ b/server/src/com/cloud/agent/manager/SynchronousListener.java @@ -24,7 +24,7 @@ import com.cloud.agent.api.AgentControlCommand; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.StartupCommand; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; import com.cloud.utils.Profiler; @@ -79,7 +79,7 @@ public class SynchronousListener implements Listener { } @Override - public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) { + public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) { } @Override diff --git a/server/src/com/cloud/capacity/CapacityManager.java b/server/src/com/cloud/capacity/CapacityManager.java index bdd9ccd155b..ab02e77ac19 100755 --- a/server/src/com/cloud/capacity/CapacityManager.java +++ b/server/src/com/cloud/capacity/CapacityManager.java @@ -18,6 +18,7 @@ package com.cloud.capacity; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.storage.VMTemplateVO; import com.cloud.utils.component.Manager; @@ -41,7 +42,7 @@ public interface CapacityManager extends Manager { */ boolean checkIfHostHasCapacity(long hostId, Integer cpu, long ram, boolean checkFromReservedCapacity, float cpuOverprovisioningFactor, float memoryOvercommitRatio, boolean considerReservedCapacity); - void updateCapacityForHost(HostVO host); + void updateCapacityForHost(Host host); /** * @param pool storage pool diff --git a/server/src/com/cloud/capacity/CapacityManagerImpl.java b/server/src/com/cloud/capacity/CapacityManagerImpl.java index 292ef0abd5c..7e9ff37c513 100755 --- a/server/src/com/cloud/capacity/CapacityManagerImpl.java +++ b/server/src/com/cloud/capacity/CapacityManagerImpl.java @@ -28,12 +28,6 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; -import com.cloud.dc.ClusterDetailsDao; -import com.cloud.dc.DataCenter; -import com.cloud.dc.dao.ClusterDao; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InsufficientServerCapacityException; -import com.cloud.resource.ResourceState; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -50,7 +44,10 @@ import com.cloud.capacity.dao.CapacityDao; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.ClusterDetailsDao; +import com.cloud.dc.dao.ClusterDao; import com.cloud.exception.ConnectionException; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; @@ -521,7 +518,7 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, @DB @Override - public void updateCapacityForHost(HostVO host){ + public void updateCapacityForHost(Host host){ // prepare the service offerings List offerings = _offeringsDao.listAllIncludingRemoved(); Map offeringsMap = new HashMap(); @@ -784,7 +781,7 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, } @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { // TODO Auto-generated method stub } diff --git a/server/src/com/cloud/capacity/ComputeCapacityListener.java b/server/src/com/cloud/capacity/ComputeCapacityListener.java index 16e154a80a6..7ca8fd74409 100755 --- a/server/src/com/cloud/capacity/ComputeCapacityListener.java +++ b/server/src/com/cloud/capacity/ComputeCapacityListener.java @@ -29,7 +29,7 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.capacity.dao.CapacityDao; import com.cloud.exception.ConnectionException; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; import com.cloud.utils.db.SearchCriteria; @@ -71,7 +71,7 @@ public class ComputeCapacityListener implements Listener { @Override - public void processConnect(HostVO server, StartupCommand startup, boolean forRebalance) throws ConnectionException { + public void processConnect(Host server, StartupCommand startup, boolean forRebalance) throws ConnectionException { if (!(startup instanceof StartupRoutingCommand)) { return; } diff --git a/server/src/com/cloud/capacity/StorageCapacityListener.java b/server/src/com/cloud/capacity/StorageCapacityListener.java index d5751a34cc9..d44e121866e 100755 --- a/server/src/com/cloud/capacity/StorageCapacityListener.java +++ b/server/src/com/cloud/capacity/StorageCapacityListener.java @@ -30,7 +30,7 @@ import com.cloud.agent.api.StartupStorageCommand; import com.cloud.capacity.dao.CapacityDao; import com.cloud.capacity.dao.CapacityDaoImpl; import com.cloud.exception.ConnectionException; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; import com.cloud.storage.Storage; import com.cloud.utils.db.SearchCriteria; @@ -71,7 +71,7 @@ public class StorageCapacityListener implements Listener { @Override - public void processConnect(HostVO server, StartupCommand startup, boolean forRebalance) throws ConnectionException { + public void processConnect(Host server, StartupCommand startup, boolean forRebalance) throws ConnectionException { if (!(startup instanceof StartupStorageCommand)) { return; diff --git a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java index 6f8575d751c..fe1dfe0ca3f 100755 --- a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java +++ b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java @@ -43,6 +43,7 @@ import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; @@ -229,7 +230,7 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol } @Override - public void onAgentConnect(HostVO host, StartupCommand cmd) { + public void onAgentConnect(Host host, StartupCommand cmd) { } @Override @@ -356,4 +357,5 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol @Override public void prepareStop(VirtualMachineProfile profile) { } + } diff --git a/server/src/com/cloud/consoleproxy/AgentHook.java b/server/src/com/cloud/consoleproxy/AgentHook.java index 5b6d585680c..29ec0456ac2 100644 --- a/server/src/com/cloud/consoleproxy/AgentHook.java +++ b/server/src/com/cloud/consoleproxy/AgentHook.java @@ -21,13 +21,13 @@ import com.cloud.agent.api.ConsoleAccessAuthenticationCommand; import com.cloud.agent.api.ConsoleProxyLoadReportCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupProxyCommand; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; public interface AgentHook { void onLoadReport(ConsoleProxyLoadReportCommand cmd); AgentControlAnswer onConsoleAccessAuthentication(ConsoleAccessAuthenticationCommand cmd); - void onAgentConnect(HostVO host, StartupCommand cmd); + void onAgentConnect(Host host, StartupCommand cmd); public void onAgentDisconnect(long agentId, Status state); public void startAgentHttpHandlerInVM(StartupProxyCommand startupCmd); diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyListener.java b/server/src/com/cloud/consoleproxy/ConsoleProxyListener.java index a3b72645794..2190dffe8c3 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyListener.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyListener.java @@ -25,7 +25,7 @@ import com.cloud.agent.api.ConsoleAccessAuthenticationCommand; import com.cloud.agent.api.ConsoleProxyLoadReportCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupProxyCommand; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; public class ConsoleProxyListener implements Listener { @@ -64,7 +64,7 @@ public class ConsoleProxyListener implements Listener { } @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) { _proxyMgr.onAgentConnect(host, cmd); if (cmd instanceof StartupProxyCommand) { diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java index 6ebf3bc61f4..459fda72685 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java @@ -20,7 +20,7 @@ import com.cloud.agent.api.AgentControlAnswer; import com.cloud.agent.api.ConsoleAccessAuthenticationCommand; import com.cloud.agent.api.ConsoleProxyLoadReportCommand; import com.cloud.agent.api.StartupCommand; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; import com.cloud.host.Host.Type; import com.cloud.info.ConsoleProxyInfo; @@ -55,6 +55,6 @@ public interface ConsoleProxyManager extends Manager { public void onLoadReport(ConsoleProxyLoadReportCommand cmd); public AgentControlAnswer onConsoleAccessAuthentication(ConsoleAccessAuthenticationCommand cmd); - public void onAgentConnect(HostVO host, StartupCommand cmd); + public void onAgentConnect(Host host, StartupCommand cmd); public void onAgentDisconnect(long agentId, Status state); } diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 1edd8692ec7..fa489ff7a2f 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -994,7 +994,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy } @Override - public void onAgentConnect(HostVO host, StartupCommand cmd) { + public void onAgentConnect(Host host, StartupCommand cmd) { // if (host.getType() == Type.ConsoleProxy) { // // TODO we can use this event to mark the proxy is up and // // functioning instead of diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java b/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java index 75b007c87d2..c92ff500b22 100644 --- a/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java +++ b/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java @@ -99,7 +99,7 @@ Listener, ResourceStateAdapter { } @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) { } @Override diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 62960116dce..ca5fb4ff817 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -92,7 +92,6 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.UnsupportedServiceException; import com.cloud.host.Host; -import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -3283,7 +3282,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L } @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { if (!(cmd instanceof StartupRoutingCommand)) { return; } diff --git a/server/src/com/cloud/network/NetworkUsageManagerImpl.java b/server/src/com/cloud/network/NetworkUsageManagerImpl.java index 80f898b0d7a..3ac77f98cfd 100755 --- a/server/src/com/cloud/network/NetworkUsageManagerImpl.java +++ b/server/src/com/cloud/network/NetworkUsageManagerImpl.java @@ -481,7 +481,7 @@ public class NetworkUsageManagerImpl extends ManagerBase implements NetworkUsage } @Override - public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) { + public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) { if (cmd instanceof StartupTrafficMonitorCommand) { long agentId = agent.getId(); s_logger.debug("Sending RecurringNetworkUsageCommand to " + agentId); diff --git a/server/src/com/cloud/network/SshKeysDistriMonitor.java b/server/src/com/cloud/network/SshKeysDistriMonitor.java index 82f72de8c3b..cd92ae66377 100755 --- a/server/src/com/cloud/network/SshKeysDistriMonitor.java +++ b/server/src/com/cloud/network/SshKeysDistriMonitor.java @@ -31,7 +31,7 @@ import com.cloud.agent.manager.Commands; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConnectionException; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -69,7 +69,7 @@ public class SshKeysDistriMonitor implements Listener { } @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { if (cmd instanceof StartupRoutingCommand) { if (((StartupRoutingCommand) cmd).getHypervisorType() == HypervisorType.KVM || ((StartupRoutingCommand) cmd).getHypervisorType() == HypervisorType.XenServer || diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index ab91059b0f3..36fcbb798aa 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -120,6 +120,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.StorageUnavailableException; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; @@ -3539,7 +3540,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { UserContext context = UserContext.current(); context.setAccountId(1); List routers = _routerDao.listIsolatedByHostId(host.getId()); diff --git a/server/src/com/cloud/network/security/SecurityGroupListener.java b/server/src/com/cloud/network/security/SecurityGroupListener.java index 32452532f55..0c101f257d4 100755 --- a/server/src/com/cloud/network/security/SecurityGroupListener.java +++ b/server/src/com/cloud/network/security/SecurityGroupListener.java @@ -38,7 +38,7 @@ import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.agent.api.SecurityGroupRuleAnswer.FailureReason; import com.cloud.agent.manager.Commands; import com.cloud.exception.AgentUnavailableException; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; import com.cloud.network.security.SecurityGroupWork.Step; import com.cloud.network.security.dao.SecurityGroupWorkDao; @@ -157,7 +157,7 @@ public class SecurityGroupListener implements Listener { @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) { if(s_logger.isInfoEnabled()) s_logger.info("Received a host startup notification"); diff --git a/server/src/com/cloud/storage/LocalStoragePoolListener.java b/server/src/com/cloud/storage/LocalStoragePoolListener.java index 244f7fbe271..088d601376c 100755 --- a/server/src/com/cloud/storage/LocalStoragePoolListener.java +++ b/server/src/com/cloud/storage/LocalStoragePoolListener.java @@ -32,7 +32,7 @@ import com.cloud.agent.api.StoragePoolInfo; import com.cloud.capacity.dao.CapacityDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.exception.ConnectionException; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.utils.db.DB; @@ -67,7 +67,7 @@ public class LocalStoragePoolListener implements Listener { @Override @DB - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { if (!(cmd instanceof StartupStorageCommand)) { return; } diff --git a/server/src/com/cloud/storage/download/DownloadAbandonedState.java b/server/src/com/cloud/storage/download/DownloadAbandonedState.java index 200683c4c33..ef053ce2737 100644 --- a/server/src/com/cloud/storage/download/DownloadAbandonedState.java +++ b/server/src/com/cloud/storage/download/DownloadAbandonedState.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.storage.download; +import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; @@ -34,7 +35,8 @@ public class DownloadAbandonedState extends DownloadInactiveState { public void onEntry(String prevState, DownloadEvent event, Object evtObj) { super.onEntry(prevState, event, evtObj); if (!prevState.equalsIgnoreCase(getName())){ - getDownloadListener().updateDatabase(Status.ABANDONED, "Download canceled"); + DownloadAnswer answer = new DownloadAnswer("Download canceled", Status.ABANDONED); + getDownloadListener().callback(answer); getDownloadListener().cancelStatusTask(); getDownloadListener().cancelTimeoutTask(); getDownloadListener().sendCommand(RequestType.ABORT); diff --git a/server/src/com/cloud/storage/download/DownloadActiveState.java b/server/src/com/cloud/storage/download/DownloadActiveState.java index f2cd5af4c71..09d103ef27c 100644 --- a/server/src/com/cloud/storage/download/DownloadActiveState.java +++ b/server/src/com/cloud/storage/download/DownloadActiveState.java @@ -64,7 +64,7 @@ public abstract class DownloadActiveState extends DownloadState { } if (event==DownloadEvent.DOWNLOAD_ANSWER) { - getDownloadListener().updateDatabase((DownloadAnswer)evtObj); + getDownloadListener().callback((DownloadAnswer)evtObj); getDownloadListener().setLastUpdated(); } diff --git a/server/src/com/cloud/storage/download/DownloadErrorState.java b/server/src/com/cloud/storage/download/DownloadErrorState.java index 0fdfd523ba5..e5c88205309 100644 --- a/server/src/com/cloud/storage/download/DownloadErrorState.java +++ b/server/src/com/cloud/storage/download/DownloadErrorState.java @@ -76,10 +76,12 @@ public class DownloadErrorState extends DownloadInactiveState { getDownloadListener().logDisconnect(); getDownloadListener().cancelStatusTask(); getDownloadListener().cancelTimeoutTask(); - getDownloadListener().updateDatabase(Status.DOWNLOAD_ERROR, "Storage agent or storage VM disconnected"); + DownloadAnswer answer = new DownloadAnswer("Storage agent or storage VM disconnected", Status.DOWNLOAD_ERROR); + getDownloadListener().callback(answer); getDownloadListener().log("Entering download error state because the storage host disconnected", Level.WARN); } else if (event==DownloadEvent.TIMEOUT_CHECK){ - getDownloadListener().updateDatabase(Status.DOWNLOAD_ERROR, "Timeout waiting for response from storage host"); + DownloadAnswer answer = new DownloadAnswer("Timeout waiting for response from storage host", Status.DOWNLOAD_ERROR); + getDownloadListener().callback(answer); getDownloadListener().log("Entering download error state: timeout waiting for response from storage host", Level.WARN); } getDownloadListener().setDownloadInactive(Status.DOWNLOAD_ERROR); diff --git a/server/src/com/cloud/storage/download/DownloadListener.java b/server/src/com/cloud/storage/download/DownloadListener.java index 3eb223325cb..e54e879110e 100755 --- a/server/src/com/cloud/storage/download/DownloadListener.java +++ b/server/src/com/cloud/storage/download/DownloadListener.java @@ -25,17 +25,15 @@ import java.util.TimerTask; import javax.inject.Inject; -import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; -import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; -import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.log4j.Level; import org.apache.log4j.Logger; @@ -47,35 +45,19 @@ import com.cloud.agent.api.Command; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.agent.api.StartupSecondaryStorageCommand; -import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.storage.DownloadCommand; import com.cloud.agent.api.storage.DownloadCommand.ResourceType; import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; -import com.cloud.alert.AlertManager; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConnectionException; -import com.cloud.exception.ResourceAllocationException; -import com.cloud.host.HostVO; -import com.cloud.host.dao.HostDao; +import com.cloud.host.Host; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.resource.ResourceManager; -import com.cloud.storage.Storage; -import com.cloud.storage.StorageManager; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.VolumeHostVO; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; -import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.dao.VolumeHostDao; import com.cloud.storage.download.DownloadState.DownloadEvent; -import com.cloud.user.AccountManager; -import com.cloud.user.ResourceLimitService; -import com.cloud.utils.UriUtils; import com.cloud.utils.exception.CloudRuntimeException; /** @@ -125,25 +107,11 @@ public class DownloadListener implements Listener { public static final String DOWNLOAD_IN_PROGRESS=Status.DOWNLOAD_IN_PROGRESS.toString(); public static final String DOWNLOAD_ABANDONED=Status.ABANDONED.toString(); + private EndPoint _ssAgent; - private HostVO _sserver; - private HostVO _ssAgent; + private DataObject object; - private VMTemplateVO _template; - private VolumeVO _volume; private boolean _downloadActive = true; - - private VolumeHostDao _volumeHostDao; - private VolumeDataStoreDao _volumeStoreDao; - private VolumeDao _volumeDao; - private StorageManager _storageMgr; - private VMTemplateHostDao _vmTemplateHostDao; - private TemplateDataStoreDao _vmTemplateStoreDao; - private VMTemplateDao _vmTemplateDao; - private ResourceLimitService _resourceLimitMgr; - private AccountManager _accountMgr; - private AlertManager _alertMgr; - private final DownloadMonitorImpl _downloadMonitor; private DownloadState _currState; @@ -158,13 +126,7 @@ public class DownloadListener implements Listener { private String _jobId; private final Map _stateMap = new HashMap(); - private Long _templateHostId; - private Long _volumeHostId; - - private DataStore _sstore; - private Long _templateStoreId; - private Long _volumeStoreId; - private AsyncCompletionCallback _callback; + private AsyncCompletionCallback _callback; @Inject private ResourceManager _resourceMgr; @@ -175,71 +137,25 @@ public class DownloadListener implements Listener { @Inject private VolumeService _volumeSrv; - public DownloadListener(HostVO ssAgent, HostVO host, VMTemplateVO template, Timer _timer, VMTemplateHostDao dao, Long templHostId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VMTemplateDao templateDao, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr) { - this._ssAgent = ssAgent; - this._sserver = host; - this._template = template; - this._vmTemplateHostDao = dao; - this._downloadMonitor = downloadMonitor; - this._cmd = cmd; - this._templateHostId = templHostId; - initStateMachine(); - this._currState=getState(Status.NOT_DOWNLOADED.toString()); - this._timer = _timer; - this._timeoutTask = new TimeoutTask(this); - this._timer.schedule(_timeoutTask, 3*STATUS_POLL_INTERVAL); - this._vmTemplateDao = templateDao; - this._resourceLimitMgr = _resourceLimitMgr; - this._accountMgr = _accountMgr; - this._alertMgr = _alertMgr; - updateDatabase(Status.NOT_DOWNLOADED, ""); - } - // TODO: this constructor should be the one used for template only, remove other template constructor later - public DownloadListener(HostVO ssAgent, DataStore store, VMTemplateVO template, Timer _timer, TemplateDataStoreDao dao, Long templStoreId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VMTemplateDao templateDao, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr, AsyncCompletionCallback callback) { + public DownloadListener(EndPoint ssAgent, DataStore store, DataObject object, Timer _timer, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, AsyncCompletionCallback callback) { this._ssAgent = ssAgent; - this._sstore = store; - this._template = template; - this._vmTemplateStoreDao = dao; + this.object = object; this._downloadMonitor = downloadMonitor; this._cmd = cmd; - this._templateStoreId = templStoreId; initStateMachine(); this._currState=getState(Status.NOT_DOWNLOADED.toString()); this._timer = _timer; this._timeoutTask = new TimeoutTask(this); this._timer.schedule(_timeoutTask, 3*STATUS_POLL_INTERVAL); - this._vmTemplateDao = templateDao; - this._resourceLimitMgr = _resourceLimitMgr; - this._accountMgr = _accountMgr; - this._alertMgr = _alertMgr; this._callback = callback; - updateDatabase(Status.NOT_DOWNLOADED, ""); + DownloadAnswer answer = new DownloadAnswer("", Status.NOT_DOWNLOADED); + callback(answer); + } + + public AsyncCompletionCallback getCallback() { + return this._callback; } - - - public DownloadListener(HostVO ssAgent, DataStore store, VolumeVO volume, Timer _timer, VolumeDataStoreDao dao, Long volStoreId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VolumeDao volumeDao, StorageManager storageMgr, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr, AsyncCompletionCallback callback) { - this._ssAgent = ssAgent; - this._sstore = store; - this._volume = volume; - this._volumeStoreDao = dao; - this._downloadMonitor = downloadMonitor; - this._cmd = cmd; - this._volumeStoreId = volStoreId; - initStateMachine(); - this._currState=getState(Status.NOT_DOWNLOADED.toString()); - this._timer = _timer; - this._timeoutTask = new TimeoutTask(this); - this._timer.schedule(_timeoutTask, 3*STATUS_POLL_INTERVAL); - this._volumeDao = volumeDao; - this._storageMgr = storageMgr; - this._resourceLimitMgr = _resourceLimitMgr; - this._accountMgr = _accountMgr; - this._alertMgr = _alertMgr; - this._callback = callback; - updateDatabase(Status.NOT_DOWNLOADED, ""); - } - public void setCurrState(VMTemplateHostVO.Status currState) { this._currState = getState(currState.toString()); @@ -264,7 +180,7 @@ public class DownloadListener implements Listener { } try { DownloadProgressCommand dcmd = new DownloadProgressCommand(getCommand(), getJobId(), reqType); - if (_template == null){ + if (this.object.getType() == DataObjectType.VOLUME) { dcmd.setResourceType(ResourceType.VOLUME); } _downloadMonitor.send(_ssAgent.getId(), dcmd, this); @@ -285,59 +201,12 @@ public class DownloadListener implements Listener { } public void logDisconnect() { - if (_template != null){ - s_logger.warn("Unable to monitor download progress of " + _template.getName() + " at host " + _sserver.getName()); - }else { - s_logger.warn("Unable to monitor download progress of " + _volume.getName() + " at host " + _sserver.getName()); - } - } - - public synchronized void updateDatabase(Status state, String errorString) { - if (_template != null){ - VMTemplateHostVO vo = _vmTemplateHostDao.createForUpdate(); - vo.setDownloadState(state); - vo.setLastUpdated(new Date()); - vo.setErrorString(errorString); - _vmTemplateHostDao.update(getTemplateHostId(), vo); - }else { - VolumeHostVO vo = _volumeHostDao.createForUpdate(); - vo.setDownloadState(state); - vo.setLastUpdated(new Date()); - vo.setErrorString(errorString); - _volumeHostDao.update(getVolumeHostId(), vo); - } + s_logger.warn("Unable to monitor download progress of " + this.object.getType() + ": " + + this.object.getId() + " at host " + _ssAgent.getId()); } public void log(String message, Level level) { - if (_template != null){ - s_logger.log(level, message + ", template=" + _template.getName() + " at host " + _sserver.getName()); - }else { - s_logger.log(level, message + ", volume=" + _volume.getName() + " at host " + _sserver.getName()); - } - } - - private Long getTemplateHostId() { - if (_templateHostId == null){ - VMTemplateHostVO templHost = _vmTemplateHostDao.findByHostTemplate(_sserver.getId(), _template.getId()); - _templateHostId = templHost.getId(); - } - return _templateHostId; - } - - private Long getTemplateStoreId() { - if (_templateStoreId == null){ - TemplateDataStoreVO templStore = _vmTemplateStoreDao.findByStoreTemplate(_sstore.getId(), _template.getId()); - _templateStoreId = templStore.getId(); - } - return _templateStoreId; - } - - private Long getVolumeHostId() { - if (_volumeHostId == null){ - VolumeHostVO volHost = _volumeHostDao.findByHostVolume(_sserver.getId(), _volume.getId()); - _volumeHostId = volHost.getId(); - } - return _volumeHostId; + s_logger.log(level, message + ", " + this.object.getType() + ": " + this.object.getId() + " at host " + _ssAgent.getId()); } public DownloadListener(DownloadMonitorImpl monitor) { @@ -388,112 +257,10 @@ public class DownloadListener implements Listener { } } - public synchronized void updateDatabase(DownloadAnswer answer) { - if (_template != null){ - TemplateDataStoreVO updateBuilder = _vmTemplateStoreDao.createForUpdate(); - updateBuilder.setDownloadPercent(answer.getDownloadPct()); - updateBuilder.setDownloadState(answer.getDownloadStatus()); - updateBuilder.setLastUpdated(new Date()); - updateBuilder.setErrorString(answer.getErrorString()); - updateBuilder.setJobId(answer.getJobId()); - updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); - updateBuilder.setInstallPath(answer.getInstallPath()); - updateBuilder.setSize(answer.getTemplateSize()); - updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); - - // only invoke callback when Download is completed or errored so that callback will update template_store_ref state column - Status dndStatus = answer.getDownloadStatus(); - // if (dndStatus == Status.DOWNLOAD_ERROR || dndStatus == Status.DOWNLOADED ){ - if ( _callback != null ){ - if (dndStatus == Status.DOWNLOAD_ERROR){ - CreateCmdResult result = new CreateCmdResult(null, null); - result.setSucess(false); - result.setResult("Download template failed"); - _callback.complete(result); - } else if (dndStatus == Status.DOWNLOADED){ - CreateCmdResult result = new CreateCmdResult(null, null); - _callback.complete(result); - } - } - else{ - // no callback specified, just update state here - if (dndStatus == Status.DOWNLOAD_ERROR){ - updateBuilder.setState(ObjectInDataStoreStateMachine.State.Failed); - } else if (dndStatus == Status.DOWNLOAD_IN_PROGRESS){ - updateBuilder.setState(ObjectInDataStoreStateMachine.State.Creating2); - } else if (dndStatus == Status.DOWNLOADED){ - updateBuilder.setState(ObjectInDataStoreStateMachine.State.Ready); - } - } - // } - _vmTemplateStoreDao.update(getTemplateStoreId(), updateBuilder); - - if (answer.getCheckSum() != null) { - VMTemplateVO templateDaoBuilder = _vmTemplateDao.createForUpdate(); - templateDaoBuilder.setChecksum(answer.getCheckSum()); - _vmTemplateDao.update(_template.getId(), templateDaoBuilder); - } - - if (answer.getTemplateSize() > 0) { - //long hostId = vmTemplateHostDao.findByTemplateId(template.getId()).getHostId(); - long accountId = _template.getAccountId(); - try { - _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(accountId), - com.cloud.configuration.Resource.ResourceType.secondary_storage, - answer.getTemplateSize() - UriUtils.getRemoteSize(_template.getUrl())); - } catch (ResourceAllocationException e) { - s_logger.warn(e.getMessage()); - _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, _sserver.getDataCenterId(), - null, e.getMessage(), e.getMessage()); - } finally { - _resourceLimitMgr.recalculateResourceCount(accountId, _accountMgr.getAccount(accountId).getDomainId(), - com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); - } - } - - } else { - VolumeHostVO updateBuilder = _volumeHostDao.createForUpdate(); - updateBuilder.setDownloadPercent(answer.getDownloadPct()); - updateBuilder.setDownloadState(answer.getDownloadStatus()); - updateBuilder.setLastUpdated(new Date()); - updateBuilder.setErrorString(answer.getErrorString()); - updateBuilder.setJobId(answer.getJobId()); - updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); - updateBuilder.setInstallPath(answer.getInstallPath()); - updateBuilder.setSize(answer.getTemplateSize()); - updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); - - _volumeHostDao.update(getVolumeHostId(), updateBuilder); - - // Update volume size in Volume table. - VolumeVO updateVolume = _volumeDao.createForUpdate(); - updateVolume.setSize(answer.getTemplateSize()); - _volumeDao.update(_volume.getId(), updateVolume); - - if (answer.getTemplateSize() > 0) { - try { - String url = _volumeHostDao.findByVolumeId(_volume.getId()).getDownloadUrl(); - _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(_volume.getAccountId()), - com.cloud.configuration.Resource.ResourceType.secondary_storage, - answer.getTemplateSize() - UriUtils.getRemoteSize(url)); - } catch (ResourceAllocationException e) { - s_logger.warn(e.getMessage()); - _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, _volume.getDataCenterId(), - _volume.getPodId(), e.getMessage(), e.getMessage()); - } finally { - _resourceLimitMgr.recalculateResourceCount(_volume.getAccountId(), _volume.getDomainId(), - com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); - } - } - - /*if (answer.getCheckSum() != null) { - VMTemplateVO templateDaoBuilder = _vmTemplateDao.createForUpdate(); - templateDaoBuilder.setChecksum(answer.getCheckSum()); - _vmTemplateDao.update(template.getId(), templateDaoBuilder); - }*/ - } - } - + public void callback(DownloadAnswer answer) { + this._callback.complete(answer); + } + @Override public boolean processCommands(long agentId, long seq, Command[] req) { return false; @@ -511,7 +278,7 @@ public class DownloadListener implements Listener { } @Override - public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException { if (cmd instanceof StartupRoutingCommand) { List hypers = _resourceMgr.listAvailHypervisorInZone(agent.getId(), agent.getDataCenterId()); HypervisorType hostHyper = agent.getHypervisorType(); @@ -601,11 +368,6 @@ public class DownloadListener implements Listener { public void setDownloadInactive(Status reason) { _downloadActive=false; - if (_template != null){ - _downloadMonitor.handleDownloadEvent(_sserver, _template, reason); - }else { - _downloadMonitor.handleDownloadEvent(_sserver, _volume, reason); - } } public void cancelTimeoutTask() { diff --git a/server/src/com/cloud/storage/download/DownloadMonitor.java b/server/src/com/cloud/storage/download/DownloadMonitor.java index efbdbe2c5c6..7bc210f2c83 100644 --- a/server/src/com/cloud/storage/download/DownloadMonitor.java +++ b/server/src/com/cloud/storage/download/DownloadMonitor.java @@ -16,15 +16,15 @@ // under the License. package com.cloud.storage.download; -import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; - +import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.exception.StorageUnavailableException; +import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VolumeVO; -import com.cloud.storage.Storage.ImageFormat; import com.cloud.utils.component.Manager; /** @@ -34,19 +34,15 @@ import com.cloud.utils.component.Manager; public interface DownloadMonitor extends Manager{ // when ssvm is not available yet - public void downloadBootstrapSysTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback); + public void downloadBootstrapSysTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback); - public void downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback); + public void downloadTemplateToStorage(DataObject template, DataStore store, AsyncCompletionCallback callback); - public void cancelAllDownloads(Long templateId); + //public void cancelAllDownloads(Long templateId); - public boolean copyTemplate(VMTemplateVO template, DataStore sourceStore, DataStore Store) - throws StorageUnavailableException; + //public boolean copyTemplate(VMTemplateVO template, DataStore sourceStore, DataStore Store) + // throws StorageUnavailableException; - //void addSystemVMTemplatesToHost(HostVO host, Map templateInfos); - - //public boolean downloadVolumeToStorage(VolumeVO volume, Long zoneId, String url, String checkSum, ImageFormat format); - - public void downloadVolumeToStorage(VolumeVO volume, DataStore store, String url, String checkSum, ImageFormat format, AsyncCompletionCallback callback); + public void downloadVolumeToStorage(DataObject volume, DataStore store, String url, String checkSum, ImageFormat format, AsyncCompletionCallback callback); } \ No newline at end of file diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index c7b360aa77a..b72c2021316 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -27,14 +27,14 @@ import java.util.concurrent.ConcurrentHashMap; import javax.ejb.Local; import javax.inject.Inject; -import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; +import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; -import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; @@ -45,55 +45,35 @@ import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; import com.cloud.agent.api.Command; - +import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.storage.DownloadCommand; - import com.cloud.agent.api.storage.DownloadCommand.Proxy; import com.cloud.agent.api.storage.DownloadCommand.ResourceType; +import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; import com.cloud.agent.api.storage.DownloadSystemTemplateCommand; - -import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.agent.manager.Commands; import com.cloud.alert.AlertManager; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.dc.dao.ClusterDao; -import com.cloud.dc.dao.DataCenterDao; -import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventUtils; -import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.AgentUnavailableException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.StorageUnavailableException; import com.cloud.host.HostVO; -import com.cloud.host.dao.HostDao; -import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.resource.ResourceManager; import com.cloud.storage.Storage.ImageFormat; - import com.cloud.storage.StorageManager; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc; -import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.Volume; import com.cloud.storage.VolumeHostVO; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.StoragePoolHostDao; -import com.cloud.storage.dao.SwiftDao; import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; -import com.cloud.storage.dao.VMTemplatePoolDao; -import com.cloud.storage.dao.VMTemplateSwiftDao; -import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeHostDao; - import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.storage.template.TemplateConstants; import com.cloud.template.TemplateManager; -import com.cloud.user.Account; +import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; import com.cloud.utils.component.ManagerBase; @@ -101,37 +81,17 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.vm.SecondaryStorageVm; -import com.cloud.vm.SecondaryStorageVmVO; import com.cloud.vm.UserVmManager; -import com.cloud.vm.VirtualMachine.State; -import com.cloud.vm.dao.SecondaryStorageVmDao; import com.cloud.vm.dao.UserVmDao; -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; - @Component @Local(value = { DownloadMonitor.class }) public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor { static final Logger s_logger = Logger.getLogger(DownloadMonitorImpl.class); - @Inject - VMTemplateHostDao _vmTemplateHostDao; @Inject TemplateDataStoreDao _vmTemplateStoreDao; @Inject - VMTemplateZoneDao _vmTemplateZoneDao; - @Inject - VMTemplatePoolDao _vmTemplatePoolDao; - @Inject - VMTemplateSwiftDao _vmTemplateSwiftlDao; - @Inject - StoragePoolHostDao _poolHostDao; - @Inject - SecondaryStorageVmDao _secStorageVmDao; - @Inject ImageStoreDao _imageStoreDao; @Inject VolumeDao _volumeDao; @@ -147,9 +107,6 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor SecondaryStorageVmManager _ssvmMgr; @Inject StorageManager _storageMgr; - - @Inject - private final DataCenterDao _dcDao = null; @Inject VMTemplateDao _templateDao = null; @Inject @@ -164,17 +121,6 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor @Inject TemplateManager templateMgr; - @Inject - private UsageEventDao _usageEventDao; - - @Inject - private ClusterDao _clusterDao; - @Inject - private HostDao _hostDao; - @Inject - private ResourceManager _resourceMgr; - @Inject - private SwiftDao _swiftDao; @Inject protected ResourceLimitService _resourceLimitMgr; @Inject @@ -254,6 +200,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } // TODO: consider using dataMotionStrategy later + /* @Override public boolean copyTemplate(VMTemplateVO template, DataStore sourceStore, DataStore destStore) throws StorageUnavailableException { @@ -363,15 +310,15 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor VMTemplateVO tmplt = _templateDao.findById(srcTmpltStore.getTemplateId()); HypervisorType hyperType = tmplt.getHypervisorType(); - /*No secondary storage vm yet*/ + if (hyperType != null && hyperType == HypervisorType.KVM) { //return "file://" + sourceServer.getParent() + "/" + srcTmpltStore.getInstallPath(); return "file://" + "/" + srcTmpltStore.getInstallPath(); } return null; - } + }*/ - private void initiateTemplateDownload(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback) { + private void initiateTemplateDownload(DataObject template, DataStore store, AsyncCompletionCallback callback) { boolean downloadJobExists = false; TemplateDataStoreVO vmTemplateStore = null; @@ -380,7 +327,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor // This method can be invoked other places, for example, // handleTemplateSync, in that case, vmTemplateStore may be null vmTemplateStore = new TemplateDataStoreVO(store.getId(), template.getId(), new Date(), 0, - VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, template.getUrl()); + VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, template.getUri()); _vmTemplateStoreDao.persist(vmTemplateStore); } else if ((vmTemplateStore.getJobId() != null) && (vmTemplateStore.getJobId().length() > 2)) { downloadJobExists = true; @@ -390,7 +337,8 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor String secUrl = store.getUri(); if (vmTemplateStore != null) { start(); - DownloadCommand dcmd = new DownloadCommand(store.getTO(), secUrl, template, maxTemplateSizeInBytes); + VirtualMachineTemplate tmpl = this._templateDao.findById(template.getId()); + DownloadCommand dcmd = new DownloadCommand(store.getTO(), secUrl, tmpl, maxTemplateSizeInBytes); dcmd.setProxy(getHttpProxy()); if (downloadJobExists) { dcmd = new DownloadProgressCommand(dcmd, vmTemplateStore.getJobId(), RequestType.GET_OR_RESTART); @@ -398,13 +346,13 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor if (vmTemplateStore.isCopy()) { dcmd.setCreds(TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd); } - HostVO ssAhost = _ssvmMgr.pickSsvmHost(store); - if (ssAhost == null) { + EndPoint ep = _epSelector.select(template); + if (ep == null) { s_logger.warn("There is no secondary storage VM for downloading template to image store " + store.getName()); return; } - DownloadListener dl = new DownloadListener(ssAhost, store, template, _timer, _vmTemplateStoreDao, vmTemplateStore.getId(), this, dcmd, - _templateDao, _resourceLimitMgr, _alertMgr, _accountMgr, callback); + DownloadListener dl = new DownloadListener(ep, store, template, _timer, this, dcmd, + callback); if (downloadJobExists) { // due to handling existing download job issues, we still keep // downloadState in template_store_ref to avoid big change in @@ -422,9 +370,9 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } try { - send(ssAhost.getId(), dcmd, dl); - } catch (AgentUnavailableException e) { - s_logger.warn("Unable to start /resume download of template " + template.getUniqueName() + " to " + store.getName(), e); + ep.sendMessageAsyncWithListener(dcmd, dl); + } catch (Exception e) { + s_logger.warn("Unable to start /resume download of template " + template.getId() + " to " + store.getName(), e); dl.setDisconnected(); dl.scheduleStatusCheck(RequestType.GET_OR_RESTART); } @@ -433,7 +381,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor @Override - public void downloadBootstrapSysTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback) { + public void downloadBootstrapSysTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback) { boolean downloadJobExists = false; TemplateDataStoreVO vmTemplateStore = null; @@ -495,18 +443,18 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } @Override - public void downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback) { + public void downloadTemplateToStorage(DataObject template, DataStore store, AsyncCompletionCallback callback) { long templateId = template.getId(); if (isTemplateUpdateable(templateId, store.getId())) { - if (template != null && template.getUrl() != null) { + if (template != null && template.getUri() != null) { initiateTemplateDownload(template, store, callback); } } } @Override - public void downloadVolumeToStorage(VolumeVO volume, DataStore store, String url, String checkSum, ImageFormat format, - AsyncCompletionCallback callback) { + public void downloadVolumeToStorage(DataObject volume, DataStore store, String url, String checkSum, ImageFormat format, + AsyncCompletionCallback callback) { boolean downloadJobExists = false; VolumeDataStoreVO volumeHost = null; @@ -523,20 +471,20 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor String secUrl = store.getUri(); if (volumeHost != null) { start(); - DownloadCommand dcmd = new DownloadCommand(secUrl, volume, maxVolumeSizeInBytes, checkSum, url, format); + Volume vol = this._volumeDao.findById(volume.getId()); + DownloadCommand dcmd = new DownloadCommand(secUrl, vol, maxVolumeSizeInBytes, checkSum, url, format); dcmd.setProxy(getHttpProxy()); if (downloadJobExists) { dcmd = new DownloadProgressCommand(dcmd, volumeHost.getJobId(), RequestType.GET_OR_RESTART); dcmd.setResourceType(ResourceType.VOLUME); } - HostVO ssAhost = _ssvmMgr.pickSsvmHost(store); - if (ssAhost == null) { + EndPoint ep = this._epSelector.select(volume); + if (ep == null) { s_logger.warn("There is no secondary storage VM for image store " + store.getName()); return; } - DownloadListener dl = new DownloadListener(ssAhost, store, volume, _timer, _volumeStoreDao, volumeHost.getId(), this, dcmd, _volumeDao, - _storageMgr, _resourceLimitMgr, _alertMgr, _accountMgr, callback); + DownloadListener dl = new DownloadListener(ep, store, volume, _timer, this, dcmd, callback); if (downloadJobExists) { dl.setCurrState(volumeHost.getDownloadState()); @@ -550,59 +498,26 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } try { - send(ssAhost.getId(), dcmd, dl); - } catch (AgentUnavailableException e) { - s_logger.warn("Unable to start /resume download of volume " + volume.getName() + " to " + store.getName(), e); + ep.sendMessageAsyncWithListener(dcmd, dl); + } catch (Exception e) { + s_logger.warn("Unable to start /resume download of volume " + volume.getId() + " to " + store.getName(), e); dl.setDisconnected(); dl.scheduleStatusCheck(RequestType.GET_OR_RESTART); } } } - @DB - public void handleDownloadEvent(HostVO host, VMTemplateVO template, Status dnldStatus) { - if ((dnldStatus == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) || (dnldStatus == Status.ABANDONED)) { - VMTemplateHostVO vmTemplateHost = new VMTemplateHostVO(host.getId(), template.getId()); - synchronized (_listenerMap) { - _listenerMap.remove(vmTemplateHost); - } - } - - VMTemplateHostVO vmTemplateHost = _vmTemplateHostDao.findByHostTemplate(host.getId(), template.getId()); - - Transaction txn = Transaction.currentTxn(); - txn.start(); - - if (dnldStatus == Status.DOWNLOADED) { - long size = -1; - if (vmTemplateHost != null) { - size = vmTemplateHost.getPhysicalSize(); - template.setSize(size); - this._templateDao.update(template.getId(), template); - } else { - s_logger.warn("Failed to get size for template" + template.getName()); - } - String eventType = EventTypes.EVENT_TEMPLATE_CREATE; - if ((template.getFormat()).equals(ImageFormat.ISO)) { - eventType = EventTypes.EVENT_ISO_CREATE; - } - if (template.getAccountId() != Account.ACCOUNT_ID_SYSTEM) { - UsageEventUtils.publishUsageEvent(eventType, template.getAccountId(), host.getDataCenterId(), template.getId(), template.getName(), - null, template.getSourceTemplateId(), size, template.getClass().getName(), template.getUuid()); - } - } - txn.commit(); - } @DB - public void handleDownloadEvent(HostVO host, VolumeVO volume, Status dnldStatus) { - if ((dnldStatus == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) || (dnldStatus == Status.ABANDONED)) { + public void handleDownloadEvent(HostVO host, DataObject object, Status dnldStatus) { + /* if ((dnldStatus == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) || (dnldStatus == Status.ABANDONED)) { VolumeHostVO volumeHost = new VolumeHostVO(host.getId(), volume.getId()); synchronized (_listenerVolumeMap) { _listenerVolumeMap.remove(volumeHost); } - } + }*/ + /* VolumeHostVO volumeHost = _volumeHostDao.findByHostVolume(host.getId(), volume.getId()); Transaction txn = Transaction.currentTxn(); @@ -631,6 +546,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); } txn.commit(); + */ } /* @@ -657,7 +573,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } */ - @Override + /*@Override public void cancelAllDownloads(Long templateId) { List downloadsInProgress = _vmTemplateHostDao.listByTemplateStates(templateId, VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS, VMTemplateHostVO.Status.NOT_DOWNLOADED); @@ -673,7 +589,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } } } - } + }*/ /* private void checksumSync(long hostId){ diff --git a/server/src/com/cloud/storage/download/DownloadState.java b/server/src/com/cloud/storage/download/DownloadState.java index 471ab6124f7..9d404f02e37 100644 --- a/server/src/com/cloud/storage/download/DownloadState.java +++ b/server/src/com/cloud/storage/download/DownloadState.java @@ -62,7 +62,7 @@ public abstract class DownloadState { getDownloadListener().log("onEntry, event type=" + event + ", curr state=" + getName(), Level.TRACE); } if (event==DownloadEvent.DOWNLOAD_ANSWER) { - getDownloadListener().updateDatabase((DownloadAnswer)evtObj); + getDownloadListener().callback((DownloadAnswer)evtObj); } } diff --git a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java index e035fd7c26f..8c894402c17 100755 --- a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java +++ b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java @@ -32,7 +32,7 @@ import com.cloud.agent.api.Command; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.exception.ConnectionException; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.OCFS2Manager; @@ -71,7 +71,7 @@ public class StoragePoolMonitor implements Listener { } @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { if (cmd instanceof StartupRoutingCommand) { StartupRoutingCommand scCmd = (StartupRoutingCommand)cmd; if (scCmd.getHypervisorType() == HypervisorType.XenServer || scCmd.getHypervisorType() == HypervisorType.KVM || diff --git a/server/src/com/cloud/storage/listener/StorageSyncListener.java b/server/src/com/cloud/storage/listener/StorageSyncListener.java index d9282a35ad7..5b7c7f75980 100755 --- a/server/src/com/cloud/storage/listener/StorageSyncListener.java +++ b/server/src/com/cloud/storage/listener/StorageSyncListener.java @@ -24,7 +24,7 @@ import com.cloud.agent.api.AgentControlCommand; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.StartupCommand; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; public class StorageSyncListener implements Listener { @@ -51,7 +51,7 @@ public class StorageSyncListener implements Listener { } @Override - public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) { + public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) { } @Override diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java b/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java index 6635b3cf317..d524f29008d 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java @@ -27,7 +27,7 @@ import com.cloud.agent.api.Command; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupSecondaryStorageCommand; import com.cloud.agent.api.StartupStorageCommand; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; import com.cloud.storage.Storage; @@ -68,7 +68,7 @@ public class SecondaryStorageListener implements Listener { } @Override - public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) { + public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) { if ((cmd instanceof StartupStorageCommand) ) { StartupStorageCommand scmd = (StartupStorageCommand)cmd; if (scmd.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE ) { diff --git a/server/src/com/cloud/storage/upload/UploadListener.java b/server/src/com/cloud/storage/upload/UploadListener.java index ee13cf9b0d8..891610f46f6 100755 --- a/server/src/com/cloud/storage/upload/UploadListener.java +++ b/server/src/com/cloud/storage/upload/UploadListener.java @@ -47,6 +47,7 @@ import com.cloud.api.ApiDBUtils; import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobResult; import com.cloud.exception.AgentUnavailableException; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.storage.Storage; import com.cloud.storage.Upload.Status; @@ -248,7 +249,7 @@ public class UploadListener implements Listener { } @Override - public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) { + public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) { if (!(cmd instanceof StartupStorageCommand)) { return; } diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index 34efdcb40ca..cb0bee9cc76 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -35,16 +35,21 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; 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; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.DeleteTemplateCommand; +import com.cloud.alert.AlertManager; import com.cloud.configuration.Resource.ResourceType; import com.cloud.dc.DataCenterVO; import com.cloud.event.EventTypes; @@ -80,6 +85,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te @Inject TemplateService imageService; @Inject TemplateDataFactory imageFactory; @Inject TemplateManager templateMgr; + @Inject AlertManager alertMgr; @Override public String getName() { @@ -181,23 +187,37 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te throw new CloudRuntimeException("Unable to find image store to download template "+ profile.getTemplate()); } for (DataStore imageStore : imageStores) { - AsyncCallFuture future = this.imageService - .createTemplateAsync(this.imageFactory.getTemplate(template.getId(), imageStore), imageStore); - try { - future.get(); - } catch (InterruptedException e) { - s_logger.debug("create template Failed", e); - throw new CloudRuntimeException("create template Failed", e); - } catch (ExecutionException e) { - s_logger.debug("create template Failed", e); - throw new CloudRuntimeException("create template Failed", e); - } + TemplateInfo tmpl = this.imageFactory.getTemplate(template.getId(), imageStore); + CreateTemplateContext context = new CreateTemplateContext(null, tmpl); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(this.createTemplateAsyncCallBack(null, null)); + caller.setContext(context); + this.imageService + .createTemplateAsync(tmpl, imageStore, caller); } _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template); - _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.secondary_storage, - UriUtils.getRemoteSize(profile.getUrl())); + return template; } + + private class CreateTemplateContext extends AsyncRpcConext { + final TemplateInfo template; + public CreateTemplateContext(AsyncCompletionCallback callback, TemplateInfo template) { + super(callback); + this.template = template; + } + } + + protected Void createTemplateAsyncCallBack(AsyncCallbackDispatcher callback, CreateTemplateContext context) { + TemplateInfo template = context.template; + VMTemplateVO tmplt = this._tmpltDao.findById(template.getId()); + long accountId = tmplt.getAccountId(); + _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.secondary_storage, + template.getSize()); + + return null; + } @Override @DB public boolean delete(TemplateProfile profile) { diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index af2271660fa..ea20dd57773 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -2285,7 +2285,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } @Override - public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException { if (!(cmd instanceof StartupRoutingCommand)) { return; }