mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	Finally, get async api call works for storage subsystem
This commit is contained in:
		
							parent
							
								
									716a5673d0
								
							
						
					
					
						commit
						aefb657c41
					
				| @ -16,17 +16,19 @@ | |||||||
|  * specific language governing permissions and limitations |  * specific language governing permissions and limitations | ||||||
|  * under the License. |  * under the License. | ||||||
|  */ |  */ | ||||||
| package org.apache.cloudstack.storage.scope; | package org.apache.cloudstack.engine.subsystem.api.storage; | ||||||
| 
 | 
 | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.Scope; |  | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; |  | ||||||
| 
 | 
 | ||||||
| public class ClusterScope implements Scope { | public class ClusterScope implements Scope { | ||||||
|     private ScopeType type = ScopeType.CLUSTER; |     private ScopeType type = ScopeType.CLUSTER; | ||||||
|     private long clusterId; |     private long clusterId; | ||||||
|  |     private long podId; | ||||||
|  |     private long zoneId; | ||||||
|      |      | ||||||
|     public ClusterScope(long clusterId) { |     public ClusterScope(long clusterId, long podId, long zoneId) { | ||||||
|         this.clusterId = clusterId; |         this.clusterId = clusterId; | ||||||
|  |         this.podId = podId; | ||||||
|  |         this.zoneId = zoneId; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     @Override |     @Override | ||||||
| @ -39,4 +41,12 @@ public class ClusterScope implements Scope { | |||||||
|         return this.clusterId; |         return this.clusterId; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     public long getPodId() { | ||||||
|  |         return this.podId; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public long getZoneId() { | ||||||
|  |         return this.zoneId; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| } | } | ||||||
| @ -16,10 +16,8 @@ | |||||||
|  * specific language governing permissions and limitations |  * specific language governing permissions and limitations | ||||||
|  * under the License. |  * under the License. | ||||||
|  */ |  */ | ||||||
| package org.apache.cloudstack.storage.scope; | package org.apache.cloudstack.engine.subsystem.api.storage; | ||||||
| 
 | 
 | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.Scope; |  | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; |  | ||||||
| 
 | 
 | ||||||
| public class HostScope implements Scope { | public class HostScope implements Scope { | ||||||
|     private ScopeType type = ScopeType.HOST; |     private ScopeType type = ScopeType.HOST; | ||||||
| @ -19,13 +19,12 @@ | |||||||
| package org.apache.cloudstack.engine.subsystem.api.storage; | package org.apache.cloudstack.engine.subsystem.api.storage; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| import java.util.List; |  | ||||||
| 
 |  | ||||||
| import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity.State; |  | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType; | import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType; | ||||||
| import org.apache.cloudstack.storage.EndPoint; | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| import com.cloud.hypervisor.Hypervisor.HypervisorType; | import com.cloud.hypervisor.Hypervisor.HypervisorType; | ||||||
|  | import com.cloud.storage.Volume; | ||||||
| 
 | 
 | ||||||
| public interface PrimaryDataStoreInfo { | public interface PrimaryDataStoreInfo { | ||||||
| 	public boolean isHypervisorSupported(HypervisorType hypervisor); | 	public boolean isHypervisorSupported(HypervisorType hypervisor); | ||||||
| @ -33,10 +32,10 @@ public interface PrimaryDataStoreInfo { | |||||||
| 	public boolean isVolumeDiskTypeSupported(VolumeDiskType diskType); | 	public boolean isVolumeDiskTypeSupported(VolumeDiskType diskType); | ||||||
| 	public long getCapacity(); | 	public long getCapacity(); | ||||||
| 	public long getAvailableCapacity(); | 	public long getAvailableCapacity(); | ||||||
| 	public List<EndPoint> getEndPoints(); | 
 | ||||||
| 	public long getId(); | 	public long getId(); | ||||||
| 	public String getUuid(); | 	public String getUuid(); | ||||||
| 	public State getManagedState(); | 	public Volume.State getManagedState(); | ||||||
| 	public String getName(); | 	public String getName(); | ||||||
| 	public String getType(); | 	public String getType(); | ||||||
| 	public PrimaryDataStoreLifeCycle getLifeCycle(); | 	public PrimaryDataStoreLifeCycle getLifeCycle(); | ||||||
|  | |||||||
| @ -23,7 +23,7 @@ import java.util.Map; | |||||||
| public interface PrimaryDataStoreLifeCycle { | public interface PrimaryDataStoreLifeCycle { | ||||||
|     public boolean initialize(Map<String, String> dsInfos); |     public boolean initialize(Map<String, String> dsInfos); | ||||||
| 
 | 
 | ||||||
|     public boolean attach(Scope scope); |     public boolean attachCluster(ClusterScope scope); | ||||||
| 
 | 
 | ||||||
|     public boolean dettach(); |     public boolean dettach(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -16,10 +16,8 @@ | |||||||
|  * specific language governing permissions and limitations |  * specific language governing permissions and limitations | ||||||
|  * under the License. |  * under the License. | ||||||
|  */ |  */ | ||||||
| package org.apache.cloudstack.storage.scope; | package org.apache.cloudstack.engine.subsystem.api.storage; | ||||||
| 
 | 
 | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.Scope; |  | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; |  | ||||||
| 
 | 
 | ||||||
| public class ZoneScope implements Scope { | public class ZoneScope implements Scope { | ||||||
|     private ScopeType type = ScopeType.ZONE; |     private ScopeType type = ScopeType.ZONE; | ||||||
| @ -18,7 +18,6 @@ | |||||||
|  */ |  */ | ||||||
| package org.apache.cloudstack.storage.image.motion; | package org.apache.cloudstack.storage.image.motion; | ||||||
| 
 | 
 | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; |  | ||||||
| import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; | import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; | ||||||
| import org.apache.cloudstack.framework.async.AsyncCallbackHandler; | import org.apache.cloudstack.framework.async.AsyncCallbackHandler; | ||||||
| import org.apache.cloudstack.framework.async.AsyncCompletionCallback; | import org.apache.cloudstack.framework.async.AsyncCompletionCallback; | ||||||
| @ -26,12 +25,11 @@ import org.apache.cloudstack.storage.EndPoint; | |||||||
| import org.apache.cloudstack.storage.command.CommandResult; | import org.apache.cloudstack.storage.command.CommandResult; | ||||||
| import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorage; | import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorage; | ||||||
| import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageAnswer; | import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageAnswer; | ||||||
|  | import org.apache.cloudstack.storage.datastore.PrimaryDataStore; | ||||||
| import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO; | import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO; | ||||||
| import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo; | import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo; | ||||||
| import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||||
| 
 | 
 | ||||||
| import com.cloud.agent.api.Answer; |  | ||||||
| 
 |  | ||||||
| @Component | @Component | ||||||
| public class DefaultImageMotionStrategy implements ImageMotionStrategy { | public class DefaultImageMotionStrategy implements ImageMotionStrategy { | ||||||
| 
 | 
 | ||||||
| @ -43,7 +41,7 @@ public class DefaultImageMotionStrategy implements ImageMotionStrategy { | |||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public EndPoint getEndPoint(TemplateOnPrimaryDataStoreInfo templateStore) { |     public EndPoint getEndPoint(TemplateOnPrimaryDataStoreInfo templateStore) { | ||||||
|         PrimaryDataStoreInfo pdi = templateStore.getPrimaryDataStore(); |         PrimaryDataStore pdi = templateStore.getPrimaryDataStore(); | ||||||
|         return pdi.getEndPoints().get(0); |         return pdi.getEndPoints().get(0); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -59,7 +57,7 @@ public class DefaultImageMotionStrategy implements ImageMotionStrategy { | |||||||
|     public void copyTemplateAsync(TemplateOnPrimaryDataStoreInfo templateStore, EndPoint ep, AsyncCompletionCallback<CommandResult> callback) { |     public void copyTemplateAsync(TemplateOnPrimaryDataStoreInfo templateStore, EndPoint ep, AsyncCompletionCallback<CommandResult> callback) { | ||||||
|         ImageOnPrimayDataStoreTO imageTo = new ImageOnPrimayDataStoreTO(templateStore); |         ImageOnPrimayDataStoreTO imageTo = new ImageOnPrimayDataStoreTO(templateStore); | ||||||
|         CopyTemplateToPrimaryStorage copyCommand = new CopyTemplateToPrimaryStorage(imageTo); |         CopyTemplateToPrimaryStorage copyCommand = new CopyTemplateToPrimaryStorage(imageTo); | ||||||
|         AsyncCallbackDispatcher<Answer> caller = new AsyncCallbackDispatcher<Answer>(this).setParentCallback(callback) |         AsyncCallbackDispatcher caller = new AsyncCallbackDispatcher(this).setParentCallback(callback) | ||||||
|                 .setOperationName("defaultImageStrategy.copytemplate.callback") |                 .setOperationName("defaultImageStrategy.copytemplate.callback") | ||||||
|                 .setContextParam("templateStore", templateStore); |                 .setContextParam("templateStore", templateStore); | ||||||
|         ep.sendMessageAsync(copyCommand, caller); |         ep.sendMessageAsync(copyCommand, caller); | ||||||
| @ -71,11 +69,13 @@ public class DefaultImageMotionStrategy implements ImageMotionStrategy { | |||||||
|         CopyTemplateToPrimaryStorageAnswer answer = callback.getResult(); |         CopyTemplateToPrimaryStorageAnswer answer = callback.getResult(); | ||||||
|         CommandResult result = new CommandResult(); |         CommandResult result = new CommandResult(); | ||||||
|         |         | ||||||
|  |         if (!answer.getResult()) { | ||||||
|             result.setSucess(answer.getResult()); |             result.setSucess(answer.getResult()); | ||||||
|             result.setResult(answer.getDetails()); |             result.setResult(answer.getDetails()); | ||||||
|         if (answer.getResult()) { |         } else { | ||||||
|             TemplateOnPrimaryDataStoreInfo templateStore = callback.getContextParam("templateStore"); |             TemplateOnPrimaryDataStoreInfo templateStore = callback.getContextParam("templateStore"); | ||||||
|             templateStore.setPath(answer.getPath()); |             templateStore.setPath(answer.getPath()); | ||||||
|  |             result.setSucess(true); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         parentCall.complete(result); |         parentCall.complete(result); | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| package org.apache.cloudstack.storage.test; | package org.apache.cloudstack.storage.test; | ||||||
| 
 | 
 | ||||||
|  | import org.apache.cloudstack.storage.HostEndpointRpcServer; | ||||||
| import org.mockito.Mockito; | import org.mockito.Mockito; | ||||||
| import org.springframework.context.annotation.Bean; | import org.springframework.context.annotation.Bean; | ||||||
| 
 | 
 | ||||||
| @ -20,6 +21,11 @@ public class ChildTestConfiguration extends TestConfiguration { | |||||||
| 	public AgentManager agentMgr() { | 	public AgentManager agentMgr() { | ||||||
| 		return new DirectAgentManagerSimpleImpl(); | 		return new DirectAgentManagerSimpleImpl(); | ||||||
| 	} | 	} | ||||||
|  | 	 | ||||||
|  |     @Bean | ||||||
|  |     public HostEndpointRpcServer rpcServer() { | ||||||
|  |         return new MockHypervsiorHostEndPointRpcServer(); | ||||||
|  |     } | ||||||
| /*	@Override | /*	@Override | ||||||
| 	@Bean | 	@Bean | ||||||
| 	public PrimaryDataStoreDao primaryDataStoreDao() { | 	public PrimaryDataStoreDao primaryDataStoreDao() { | ||||||
|  | |||||||
| @ -0,0 +1,69 @@ | |||||||
|  | /* | ||||||
|  |  * Licensed to the Apache Software Foundation (ASF) under one | ||||||
|  |  * or more contributor license agreements.  See the NOTICE file | ||||||
|  |  * distributed with this work for additional information | ||||||
|  |  * regarding copyright ownership.  The ASF licenses this file | ||||||
|  |  * to you under the Apache License, Version 2.0 (the | ||||||
|  |  * "License"); you may not use this file except in compliance | ||||||
|  |  * with the License.  You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, | ||||||
|  |  * software distributed under the License is distributed on an | ||||||
|  |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||||||
|  |  * KIND, either express or implied.  See the License for the | ||||||
|  |  * specific language governing permissions and limitations | ||||||
|  |  * under the License. | ||||||
|  |  */ | ||||||
|  | package org.apache.cloudstack.storage.test; | ||||||
|  | 
 | ||||||
|  | import java.util.UUID; | ||||||
|  | import java.util.concurrent.Executors; | ||||||
|  | import java.util.concurrent.ScheduledExecutorService; | ||||||
|  | import java.util.concurrent.TimeUnit; | ||||||
|  | 
 | ||||||
|  | import org.apache.cloudstack.framework.async.AsyncCompletionCallback; | ||||||
|  | import org.apache.cloudstack.storage.HostEndpointRpcServer; | ||||||
|  | import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorage; | ||||||
|  | import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageAnswer; | ||||||
|  | import org.apache.cloudstack.storage.command.CreateVolumeAnswer; | ||||||
|  | import org.apache.cloudstack.storage.command.CreateVolumeFromBaseImageCommand; | ||||||
|  | 
 | ||||||
|  | import com.cloud.agent.api.Answer; | ||||||
|  | import com.cloud.agent.api.Command; | ||||||
|  | 
 | ||||||
|  | public class MockHypervsiorHostEndPointRpcServer implements HostEndpointRpcServer { | ||||||
|  |     private ScheduledExecutorService executor; | ||||||
|  |     public MockHypervsiorHostEndPointRpcServer() { | ||||||
|  |         executor = Executors.newScheduledThreadPool(10); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     protected class MockRpcCallBack implements Runnable { | ||||||
|  |         private final Command cmd; | ||||||
|  |         private final AsyncCompletionCallback<Answer> callback;  | ||||||
|  |         public MockRpcCallBack(Command cmd, final AsyncCompletionCallback<Answer> callback) { | ||||||
|  |             this.cmd = cmd; | ||||||
|  |             this.callback = callback; | ||||||
|  |         } | ||||||
|  |         @Override | ||||||
|  |         public void run() { | ||||||
|  |             try { | ||||||
|  |             Answer answer = new Answer(cmd, false, "unknown command"); | ||||||
|  |             if (cmd instanceof CopyTemplateToPrimaryStorage) { | ||||||
|  |                 answer = new CopyTemplateToPrimaryStorageAnswer(cmd, UUID.randomUUID().toString()); | ||||||
|  |             } else if (cmd instanceof CreateVolumeFromBaseImageCommand) { | ||||||
|  |                 answer = new CreateVolumeAnswer(cmd, UUID.randomUUID().toString()); | ||||||
|  |             } | ||||||
|  |              | ||||||
|  |            callback.complete(answer); | ||||||
|  |             } catch (Exception e) { | ||||||
|  |                 e.printStackTrace(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |     } | ||||||
|  |     public void sendCommandAsync(String host, final Command command, final AsyncCompletionCallback<Answer> callback) { | ||||||
|  |         executor.schedule(new MockRpcCallBack(command, callback), 10, TimeUnit.SECONDS); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,7 +1,5 @@ | |||||||
| package org.apache.cloudstack.storage.test; | package org.apache.cloudstack.storage.test; | ||||||
| 
 | 
 | ||||||
| import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; |  | ||||||
| import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl; |  | ||||||
| import org.springframework.context.annotation.Bean; | import org.springframework.context.annotation.Bean; | ||||||
| import org.springframework.context.annotation.Configuration; | import org.springframework.context.annotation.Configuration; | ||||||
| 
 | 
 | ||||||
| @ -14,8 +12,4 @@ public class TestConfiguration { | |||||||
| 	public HostDao hostDao() { | 	public HostDao hostDao() { | ||||||
| 		return new HostDaoImpl(); | 		return new HostDaoImpl(); | ||||||
| 	} | 	} | ||||||
| 	@Bean |  | ||||||
| 	public PrimaryDataStoreDao primaryDataStoreDao() { |  | ||||||
| 		return new PrimaryDataStoreDaoImpl(); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -34,9 +34,11 @@ import javax.naming.ConfigurationException; | |||||||
| 
 | 
 | ||||||
| import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity; | import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity; | ||||||
| import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity; | import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity; | ||||||
|  | import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; | import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle; | import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle; | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; | import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; | ||||||
|  | import org.apache.cloudstack.engine.subsystem.api.storage.Scope; | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.disktype.QCOW2; | import org.apache.cloudstack.engine.subsystem.api.storage.disktype.QCOW2; | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VHD; | import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VHD; | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VMDK; | import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VMDK; | ||||||
| @ -131,6 +133,7 @@ public class volumeServiceTest { | |||||||
| 	AgentManager agentMgr; | 	AgentManager agentMgr; | ||||||
| 	Long dcId; | 	Long dcId; | ||||||
| 	Long clusterId; | 	Long clusterId; | ||||||
|  | 	Long podId; | ||||||
| 	@Before | 	@Before | ||||||
| 	public void setUp() { | 	public void setUp() { | ||||||
| 		//create data center | 		//create data center | ||||||
| @ -142,6 +145,7 @@ public class volumeServiceTest { | |||||||
| 
 | 
 | ||||||
| 		HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), "192.168.56.1", "192.168.56.0/24", 8, "test"); | 		HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), "192.168.56.1", "192.168.56.0/24", 8, "test"); | ||||||
| 		pod = podDao.persist(pod); | 		pod = podDao.persist(pod); | ||||||
|  | 		podId = pod.getId(); | ||||||
| 		//create xen cluster | 		//create xen cluster | ||||||
| 		ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster"); | 		ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster"); | ||||||
| 		cluster.setHypervisorType(HypervisorType.XenServer.toString()); | 		cluster.setHypervisorType(HypervisorType.XenServer.toString()); | ||||||
| @ -168,9 +172,9 @@ public class volumeServiceTest { | |||||||
| 		results.add(host); | 		results.add(host); | ||||||
| 		Mockito.when(hostDao.listAll()).thenReturn(results); | 		Mockito.when(hostDao.listAll()).thenReturn(results); | ||||||
| 		Mockito.when(hostDao.findHypervisorHostInCluster(Mockito.anyLong())).thenReturn(results); | 		Mockito.when(hostDao.findHypervisorHostInCluster(Mockito.anyLong())).thenReturn(results); | ||||||
| 		CreateVolumeAnswer createVolumeFromImageAnswer = new CreateVolumeAnswer(UUID.randomUUID().toString()); | 		//CreateVolumeAnswer createVolumeFromImageAnswer = new CreateVolumeAnswer(UUID.randomUUID().toString()); | ||||||
| 
 | 
 | ||||||
| 		try { | 		/*try { | ||||||
| 			Mockito.when(agentMgr.send(Mockito.anyLong(), Mockito.any(CreateVolumeFromBaseImageCommand.class))).thenReturn(createVolumeFromImageAnswer); | 			Mockito.when(agentMgr.send(Mockito.anyLong(), Mockito.any(CreateVolumeFromBaseImageCommand.class))).thenReturn(createVolumeFromImageAnswer); | ||||||
| 		} catch (AgentUnavailableException e) { | 		} catch (AgentUnavailableException e) { | ||||||
| 			// TODO Auto-generated catch block | 			// TODO Auto-generated catch block | ||||||
| @ -178,7 +182,7 @@ public class volumeServiceTest { | |||||||
| 		} catch (OperationTimedoutException e) { | 		} catch (OperationTimedoutException e) { | ||||||
| 			// TODO Auto-generated catch block | 			// TODO Auto-generated catch block | ||||||
| 			e.printStackTrace(); | 			e.printStackTrace(); | ||||||
| 		} | 		}*/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 		//Mockito.when(primaryStoreDao.findById(Mockito.anyLong())).thenReturn(primaryStore); | 		//Mockito.when(primaryStoreDao.findById(Mockito.anyLong())).thenReturn(primaryStore); | ||||||
| @ -238,6 +242,9 @@ public class volumeServiceTest { | |||||||
| 			params.put("clusterId", clusterId.toString()); | 			params.put("clusterId", clusterId.toString()); | ||||||
| 			params.put("name", "my primary data store"); | 			params.put("name", "my primary data store"); | ||||||
| 			PrimaryDataStoreInfo primaryDataStoreInfo = provider.registerDataStore(params); | 			PrimaryDataStoreInfo primaryDataStoreInfo = provider.registerDataStore(params); | ||||||
|  | 			PrimaryDataStoreLifeCycle lc = primaryDataStoreInfo.getLifeCycle(); | ||||||
|  | 			ClusterScope scope = new ClusterScope(clusterId, podId, dcId); | ||||||
|  | 			lc.attachCluster(scope); | ||||||
| 			return primaryDataStoreInfo; | 			return primaryDataStoreInfo; | ||||||
| 		} catch (ConfigurationException e) { | 		} catch (ConfigurationException e) { | ||||||
| 			return null; | 			return null; | ||||||
|  | |||||||
| @ -39,4 +39,30 @@ | |||||||
|    |    | ||||||
|   <bean class="org.apache.cloudstack.storage.test.ChildTestConfiguration" /> |   <bean class="org.apache.cloudstack.storage.test.ChildTestConfiguration" /> | ||||||
|    |    | ||||||
|  |   <bean id="onwireRegistry" class="org.apache.cloudstack.framework.serializer.OnwireClassRegistry" | ||||||
|  |     init-method="scan" > | ||||||
|  |     <property name="packages"> | ||||||
|  |       <list> | ||||||
|  |         <value>org.apache.cloudstack.framework</value> | ||||||
|  |       </list> | ||||||
|  |     </property> | ||||||
|  |   </bean> | ||||||
|  |    | ||||||
|  |   <bean id="messageSerializer" class="org.apache.cloudstack.framework.serializer.JsonMessageSerializer"> | ||||||
|  |     <property name="onwireClassRegistry" ref="onwireRegistry" /> | ||||||
|  |   </bean> | ||||||
|  | 
 | ||||||
|  |   <bean id="transportProvider" class="org.apache.cloudstack.framework.server.ServerTransportProvider"  init-method="initialize"> | ||||||
|  |     <property name="workerPoolSize" value="5" /> | ||||||
|  |     <property name="nodeId" value="Node1" /> | ||||||
|  |     <property name="messageSerializer" ref="messageSerializer" /> | ||||||
|  |   </bean> | ||||||
|  |    | ||||||
|  |   <bean id="rpcProvider" class="org.apache.cloudstack.framework.rpc.RpcProviderImpl" init-method="initialize"> | ||||||
|  |     <constructor-arg ref="transportProvider" /> | ||||||
|  |     <property name="messageSerializer" ref="messageSerializer" /> | ||||||
|  |   </bean> | ||||||
|  | 
 | ||||||
|  |   <bean id="eventBus" class = "org.apache.cloudstack.framework.eventbus.EventBusBase" /> | ||||||
|  | 
 | ||||||
| </beans> | </beans> | ||||||
|  | |||||||
| @ -0,0 +1,28 @@ | |||||||
|  | /* | ||||||
|  |  * Licensed to the Apache Software Foundation (ASF) under one | ||||||
|  |  * or more contributor license agreements.  See the NOTICE file | ||||||
|  |  * distributed with this work for additional information | ||||||
|  |  * regarding copyright ownership.  The ASF licenses this file | ||||||
|  |  * to you under the Apache License, Version 2.0 (the | ||||||
|  |  * "License"); you may not use this file except in compliance | ||||||
|  |  * with the License.  You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, | ||||||
|  |  * software distributed under the License is distributed on an | ||||||
|  |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||||||
|  |  * KIND, either express or implied.  See the License for the | ||||||
|  |  * specific language governing permissions and limitations | ||||||
|  |  * under the License. | ||||||
|  |  */ | ||||||
|  | package org.apache.cloudstack.storage; | ||||||
|  | 
 | ||||||
|  | import org.apache.cloudstack.framework.async.AsyncCompletionCallback; | ||||||
|  | 
 | ||||||
|  | import com.cloud.agent.api.Answer; | ||||||
|  | import com.cloud.agent.api.Command; | ||||||
|  | 
 | ||||||
|  | public interface HostEndpointRpcServer { | ||||||
|  |     void sendCommandAsync(String host, final Command command, final AsyncCompletionCallback<Answer> callback); | ||||||
|  | } | ||||||
| @ -38,7 +38,7 @@ public class HypervisorHostEndPoint implements EndPoint { | |||||||
|     @Inject |     @Inject | ||||||
|     AgentManager agentMgr; |     AgentManager agentMgr; | ||||||
|     @Inject |     @Inject | ||||||
|     HypervsiorHostEndPointRpcServer rpcServer; |     HostEndpointRpcServer rpcServer; | ||||||
| 
 | 
 | ||||||
|     public HypervisorHostEndPoint(long hostId, String hostAddress) { |     public HypervisorHostEndPoint(long hostId, String hostAddress) { | ||||||
|         this.hostId = hostId; |         this.hostId = hostId; | ||||||
|  | |||||||
| @ -31,13 +31,16 @@ import com.cloud.agent.api.Answer; | |||||||
| import com.cloud.agent.api.Command; | import com.cloud.agent.api.Command; | ||||||
| 
 | 
 | ||||||
| @Component | @Component | ||||||
| public class HypervsiorHostEndPointRpcServer { | public class HypervsiorHostEndPointRpcServer implements HostEndpointRpcServer { | ||||||
|     @Inject |      | ||||||
|     private RpcProvider _rpcProvider; |     private RpcProvider _rpcProvider; | ||||||
|     public HypervsiorHostEndPointRpcServer() { |     @Inject | ||||||
|  |     public HypervsiorHostEndPointRpcServer(RpcProvider rpcProvider) { | ||||||
|  |         _rpcProvider = rpcProvider; | ||||||
|         _rpcProvider.registerRpcServiceEndpoint(RpcServiceDispatcher.getDispatcher(this)); |         _rpcProvider.registerRpcServiceEndpoint(RpcServiceDispatcher.getDispatcher(this)); | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     @Override | ||||||
|     public void sendCommandAsync(String host, final Command command, final AsyncCompletionCallback<Answer> callback) { |     public void sendCommandAsync(String host, final Command command, final AsyncCompletionCallback<Answer> callback) { | ||||||
|         _rpcProvider.newCall(host).addCallbackListener(new RpcCallbackListener<Answer>() { |         _rpcProvider.newCall(host).addCallbackListener(new RpcCallbackListener<Answer>() { | ||||||
|             @Override |             @Override | ||||||
|  | |||||||
| @ -1,11 +1,13 @@ | |||||||
| package org.apache.cloudstack.storage.command; | package org.apache.cloudstack.storage.command; | ||||||
| 
 | 
 | ||||||
| import com.cloud.agent.api.Answer; | import com.cloud.agent.api.Answer; | ||||||
|  | import com.cloud.agent.api.Command; | ||||||
| 
 | 
 | ||||||
| public class CopyTemplateToPrimaryStorageAnswer extends Answer { | public class CopyTemplateToPrimaryStorageAnswer extends Answer { | ||||||
|     private final String path; |     private final String path; | ||||||
|      |      | ||||||
|     public CopyTemplateToPrimaryStorageAnswer(String path) { |     public CopyTemplateToPrimaryStorageAnswer(Command cmd, String path) { | ||||||
|  |         super(cmd); | ||||||
|         this.path = path; |         this.path = path; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  | |||||||
| @ -19,6 +19,7 @@ | |||||||
| package org.apache.cloudstack.storage.command; | package org.apache.cloudstack.storage.command; | ||||||
| 
 | 
 | ||||||
| import com.cloud.agent.api.Answer; | import com.cloud.agent.api.Answer; | ||||||
|  | import com.cloud.agent.api.Command; | ||||||
| 
 | 
 | ||||||
| public class CreateVolumeAnswer extends Answer { | public class CreateVolumeAnswer extends Answer { | ||||||
|     private String volumeUuid; |     private String volumeUuid; | ||||||
| @ -27,7 +28,8 @@ public class CreateVolumeAnswer extends Answer { | |||||||
|         super(); |         super(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public CreateVolumeAnswer(String volumeUuid) { |     public CreateVolumeAnswer(Command cmd, String volumeUuid) { | ||||||
|  |         super(cmd); | ||||||
|         this.volumeUuid = volumeUuid; |         this.volumeUuid = volumeUuid; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ | |||||||
|  */ |  */ | ||||||
| package org.apache.cloudstack.storage.volume; | package org.apache.cloudstack.storage.volume; | ||||||
| 
 | 
 | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; | import org.apache.cloudstack.storage.datastore.PrimaryDataStore; | ||||||
| import org.apache.cloudstack.storage.image.TemplateInfo; | import org.apache.cloudstack.storage.image.TemplateInfo; | ||||||
| 
 | 
 | ||||||
| public interface TemplateOnPrimaryDataStoreInfo { | public interface TemplateOnPrimaryDataStoreInfo { | ||||||
| @ -26,7 +26,7 @@ public interface TemplateOnPrimaryDataStoreInfo { | |||||||
| 
 | 
 | ||||||
|     public void setPath(String path); |     public void setPath(String path); | ||||||
| 
 | 
 | ||||||
|     public PrimaryDataStoreInfo getPrimaryDataStore(); |     public PrimaryDataStore getPrimaryDataStore(); | ||||||
| 
 | 
 | ||||||
|     public TemplateInfo getTemplate(); |     public TemplateInfo getTemplate(); | ||||||
| } | } | ||||||
|  | |||||||
| @ -30,10 +30,14 @@ import org.apache.cloudstack.engine.datacenter.entity.api.StorageEntity; | |||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; | import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType; | import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType; | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType; | import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType; | ||||||
|  | import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; | ||||||
|  | import org.apache.cloudstack.framework.async.AsyncCallbackHandler; | ||||||
| import org.apache.cloudstack.storage.datastore.PrimaryDataStoreEntityImpl; | import org.apache.cloudstack.storage.datastore.PrimaryDataStoreEntityImpl; | ||||||
| import org.apache.cloudstack.storage.image.TemplateEntityImpl; | import org.apache.cloudstack.storage.image.TemplateEntityImpl; | ||||||
| import org.apache.cloudstack.storage.image.TemplateInfo; | import org.apache.cloudstack.storage.image.TemplateInfo; | ||||||
| 
 | 
 | ||||||
|  | import com.cloud.utils.exception.CloudRuntimeException; | ||||||
|  | 
 | ||||||
| public class VolumeEntityImpl implements VolumeEntity { | public class VolumeEntityImpl implements VolumeEntity { | ||||||
|     private VolumeInfo volumeInfo; |     private VolumeInfo volumeInfo; | ||||||
|     private final VolumeService vs; |     private final VolumeService vs; | ||||||
| @ -192,8 +196,25 @@ public class VolumeEntityImpl implements VolumeEntity { | |||||||
|     @Override |     @Override | ||||||
|     public boolean createVolumeFromTemplate(long dataStoreId, VolumeDiskType diskType, TemplateEntity template) { |     public boolean createVolumeFromTemplate(long dataStoreId, VolumeDiskType diskType, TemplateEntity template) { | ||||||
|         TemplateInfo ti = ((TemplateEntityImpl)template).getTemplateInfo(); |         TemplateInfo ti = ((TemplateEntityImpl)template).getTemplateInfo(); | ||||||
|         volumeInfo = vs.createVolumeFromTemplate(volumeInfo, dataStoreId, diskType, ti); |          | ||||||
|  |         AsyncCallbackDispatcher caller = new AsyncCallbackDispatcher(this) | ||||||
|  |             .setOperationName("volumeEntity.createVolumeFromTemplateAsyncCallback"); | ||||||
|  |         vs.createVolumeFromTemplateAsync(volumeInfo, dataStoreId, diskType, ti, caller); | ||||||
|  |         try { | ||||||
|  |             synchronized (volumeInfo) { | ||||||
|  |                 volumeInfo.wait(); | ||||||
|  |             } | ||||||
|  |         } catch (InterruptedException e) { | ||||||
|  |            throw new CloudRuntimeException("wait volume info failed", e); | ||||||
|  |         } | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     @AsyncCallbackHandler(operationName="volumeEntity.createVolumeFromTemplateAsyncCallback") | ||||||
|  |     public void createVolumeFromTemplateAsyncCallback(AsyncCallbackDispatcher callback) { | ||||||
|  |         synchronized (volumeInfo) { | ||||||
|  |             volumeInfo.notify(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -165,6 +165,7 @@ public class TemplatePrimaryDataStoreVO implements StateObject<TemplateOnPrimary | |||||||
|         this.poolId = poolId; |         this.poolId = poolId; | ||||||
|         this.templateId = templateId; |         this.templateId = templateId; | ||||||
|         this.downloadState = Status.NOT_DOWNLOADED; |         this.downloadState = Status.NOT_DOWNLOADED; | ||||||
|  |         this.state = TemplateOnPrimaryDataStoreStateMachine.State.Allocated; | ||||||
|         this.markedForGC = false; |         this.markedForGC = false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -5,16 +5,18 @@ import java.util.List; | |||||||
| 
 | 
 | ||||||
| import javax.inject.Inject; | import javax.inject.Inject; | ||||||
| 
 | 
 | ||||||
| import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity.State; |  | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; | import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle; | import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle; | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; | import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; | import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType; | import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType; | ||||||
|  | import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; | ||||||
|  | import org.apache.cloudstack.framework.async.AsyncCallbackHandler; | ||||||
|  | import org.apache.cloudstack.framework.async.AsyncCompletionCallback; | ||||||
| import org.apache.cloudstack.storage.EndPoint; | import org.apache.cloudstack.storage.EndPoint; | ||||||
| import org.apache.cloudstack.storage.HypervisorHostEndPoint; | import org.apache.cloudstack.storage.HypervisorHostEndPoint; | ||||||
|  | import org.apache.cloudstack.storage.command.CommandResult; | ||||||
| import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreVO; | import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreVO; | ||||||
| import org.apache.cloudstack.storage.datastore.driver.DefaultPrimaryDataStoreDriverImpl; |  | ||||||
| import org.apache.cloudstack.storage.datastore.driver.PrimaryDataStoreDriver; | import org.apache.cloudstack.storage.datastore.driver.PrimaryDataStoreDriver; | ||||||
| import org.apache.cloudstack.storage.image.TemplateInfo; | import org.apache.cloudstack.storage.image.TemplateInfo; | ||||||
| import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo; | import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo; | ||||||
| @ -28,6 +30,7 @@ import org.apache.log4j.Logger; | |||||||
| import com.cloud.host.HostVO; | import com.cloud.host.HostVO; | ||||||
| import com.cloud.host.dao.HostDao; | import com.cloud.host.dao.HostDao; | ||||||
| import com.cloud.hypervisor.Hypervisor.HypervisorType; | import com.cloud.hypervisor.Hypervisor.HypervisorType; | ||||||
|  | import com.cloud.storage.Volume; | ||||||
| import com.cloud.utils.component.ComponentInject; | import com.cloud.utils.component.ComponentInject; | ||||||
| import edu.emory.mathcs.backport.java.util.Collections; | import edu.emory.mathcs.backport.java.util.Collections; | ||||||
| 
 | 
 | ||||||
| @ -185,10 +188,27 @@ public class DefaultPrimaryDataStore implements PrimaryDataStore { | |||||||
|     public VolumeInfo createVoluemFromBaseImage(VolumeInfo volume, TemplateOnPrimaryDataStoreInfo template) { |     public VolumeInfo createVoluemFromBaseImage(VolumeInfo volume, TemplateOnPrimaryDataStoreInfo template) { | ||||||
|         VolumeObject vo = (VolumeObject) volume; |         VolumeObject vo = (VolumeObject) volume; | ||||||
|         vo.setVolumeDiskType(template.getTemplate().getDiskType()); |         vo.setVolumeDiskType(template.getTemplate().getDiskType()); | ||||||
|         this.driver.createVolumeFromBaseImage(vo, template); |         //this.driver.createVolumeFromBaseImage(vo, template); | ||||||
|         return volume; |         return volume; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     @Override | ||||||
|  |     public void createVoluemFromBaseImageAsync(VolumeInfo volume, TemplateOnPrimaryDataStoreInfo templateStore, AsyncCompletionCallback<CommandResult> callback) { | ||||||
|  |         VolumeObject vo = (VolumeObject) volume; | ||||||
|  |         vo.setVolumeDiskType(templateStore.getTemplate().getDiskType()); | ||||||
|  |         AsyncCallbackDispatcher caller = new AsyncCallbackDispatcher(this) | ||||||
|  |         .setParentCallback(callback) | ||||||
|  |         .setOperationName("primarydatastore.createvolumefrombaseImage"); | ||||||
|  |         this.driver.createVolumeFromBaseImageAsync(vo, templateStore, caller); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @AsyncCallbackHandler(operationName="primarydatastore.createvolumefrombaseImage") | ||||||
|  |     public void createVoluemFromBaseImageAsyncCallback(AsyncCallbackDispatcher callback) { | ||||||
|  |         AsyncCallbackDispatcher parent = callback.getParentCallback(); | ||||||
|  |         CommandResult result = callback.getResult(); | ||||||
|  |         parent.complete(result); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     @Override |     @Override | ||||||
|     public boolean installTemplate(TemplateOnPrimaryDataStoreInfo template) { |     public boolean installTemplate(TemplateOnPrimaryDataStoreInfo template) { | ||||||
|         // TODO Auto-generated method stub |         // TODO Auto-generated method stub | ||||||
| @ -202,7 +222,7 @@ public class DefaultPrimaryDataStore implements PrimaryDataStore { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public State getManagedState() { |     public Volume.State getManagedState() { | ||||||
|         // TODO Auto-generated method stub |         // TODO Auto-generated method stub | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
| @ -228,4 +248,6 @@ public class DefaultPrimaryDataStore implements PrimaryDataStore { | |||||||
|     public PrimaryDataStoreProvider getProvider() { |     public PrimaryDataStoreProvider getProvider() { | ||||||
|         return this.provider; |         return this.provider; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |      | ||||||
| } | } | ||||||
|  | |||||||
| @ -4,7 +4,11 @@ import java.util.List; | |||||||
| import java.util.Map; | import java.util.Map; | ||||||
| 
 | 
 | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; | import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; | ||||||
|  | import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; | ||||||
|  | import org.apache.cloudstack.framework.async.AsyncCallbackHandler; | ||||||
|  | import org.apache.cloudstack.framework.async.AsyncCompletionCallback; | ||||||
| import org.apache.cloudstack.storage.EndPoint; | import org.apache.cloudstack.storage.EndPoint; | ||||||
|  | import org.apache.cloudstack.storage.command.CommandResult; | ||||||
| import org.apache.cloudstack.storage.command.CreateVolumeAnswer; | import org.apache.cloudstack.storage.command.CreateVolumeAnswer; | ||||||
| import org.apache.cloudstack.storage.command.CreateVolumeCommand; | import org.apache.cloudstack.storage.command.CreateVolumeCommand; | ||||||
| import org.apache.cloudstack.storage.command.CreateVolumeFromBaseImageCommand; | import org.apache.cloudstack.storage.command.CreateVolumeFromBaseImageCommand; | ||||||
| @ -100,17 +104,38 @@ public class DefaultPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver | |||||||
|     } |     } | ||||||
|      |      | ||||||
|     @Override |     @Override | ||||||
|     public boolean createVolumeFromBaseImage(VolumeObject volume, TemplateOnPrimaryDataStoreInfo template) { |     public void createVolumeFromBaseImageAsync(VolumeObject volume, TemplateOnPrimaryDataStoreInfo template, AsyncCompletionCallback<CommandResult> callback) { | ||||||
|         VolumeTO vol = new VolumeTO(volume); |         VolumeTO vol = new VolumeTO(volume); | ||||||
|         ImageOnPrimayDataStoreTO image = new ImageOnPrimayDataStoreTO(template); |         ImageOnPrimayDataStoreTO image = new ImageOnPrimayDataStoreTO(template); | ||||||
|         CreateVolumeFromBaseImageCommand cmd = new CreateVolumeFromBaseImageCommand(vol, image); |         CreateVolumeFromBaseImageCommand cmd = new CreateVolumeFromBaseImageCommand(vol, image); | ||||||
|         List<EndPoint> endPoints = template.getPrimaryDataStore().getEndPoints(); |         List<EndPoint> endPoints = template.getPrimaryDataStore().getEndPoints(); | ||||||
|  |         EndPoint ep = endPoints.get(0); | ||||||
|          |          | ||||||
|         Answer answer = sendOutCommand(cmd, endPoints); |         AsyncCallbackDispatcher caller = new AsyncCallbackDispatcher(this) | ||||||
|  |         .setParentCallback(callback) | ||||||
|  |         .setOperationName("primarydatastoredriver.createvolumefrombaseImage") | ||||||
|  |         .setContextParam("volume", volume); | ||||||
|  |         ep.sendMessageAsync(cmd, caller); | ||||||
|          |          | ||||||
|         CreateVolumeAnswer volAnswer = (CreateVolumeAnswer) answer; |         | ||||||
|         volume.setPath(volAnswer.getVolumeUuid()); |     } | ||||||
|         return true; |      | ||||||
|  |     @AsyncCallbackHandler(operationName="primarydatastoredriver.createvolumefrombaseImage") | ||||||
|  |     public void createVolumeFromBaseImageAsyncCallback(AsyncCallbackDispatcher callback) { | ||||||
|  |         CreateVolumeAnswer answer = (CreateVolumeAnswer)callback.getResult(); | ||||||
|  |         CommandResult result = new CommandResult(); | ||||||
|  |         if (answer == null || answer.getDetails() != null) { | ||||||
|  |             result.setSucess(false); | ||||||
|  |             if (answer != null) { | ||||||
|  |                 result.setResult(answer.getDetails()); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             result.setSucess(true); | ||||||
|  |             VolumeObject volume = callback.getContextParam("volume"); | ||||||
|  |             volume.setPath(answer.getVolumeUuid()); | ||||||
|  |         } | ||||||
|  |         AsyncCallbackDispatcher parentCall = callback.getParentCallback(); | ||||||
|  |         parentCall.complete(result); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
| @ -142,4 +167,6 @@ public class DefaultPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver | |||||||
|         // TODO Auto-generated method stub |         // TODO Auto-generated method stub | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     | ||||||
| } | } | ||||||
|  | |||||||
| @ -2,7 +2,9 @@ package org.apache.cloudstack.storage.datastore.driver; | |||||||
| 
 | 
 | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| 
 | 
 | ||||||
|  | import org.apache.cloudstack.framework.async.AsyncCompletionCallback; | ||||||
| import org.apache.cloudstack.storage.EndPoint; | import org.apache.cloudstack.storage.EndPoint; | ||||||
|  | import org.apache.cloudstack.storage.command.CommandResult; | ||||||
| import org.apache.cloudstack.storage.datastore.PrimaryDataStore; | import org.apache.cloudstack.storage.datastore.PrimaryDataStore; | ||||||
| import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo; | import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo; | ||||||
| import org.apache.cloudstack.storage.volume.VolumeObject; | import org.apache.cloudstack.storage.volume.VolumeObject; | ||||||
| @ -10,7 +12,7 @@ import org.apache.cloudstack.storage.volume.VolumeObject; | |||||||
| public interface PrimaryDataStoreDriver { | public interface PrimaryDataStoreDriver { | ||||||
|     boolean createVolume(VolumeObject vol); |     boolean createVolume(VolumeObject vol); | ||||||
| 
 | 
 | ||||||
|     boolean createVolumeFromBaseImage(VolumeObject volume, TemplateOnPrimaryDataStoreInfo template); |     void createVolumeFromBaseImageAsync(VolumeObject volume, TemplateOnPrimaryDataStoreInfo template, AsyncCompletionCallback<CommandResult> callback); | ||||||
| 
 | 
 | ||||||
|     boolean deleteVolume(VolumeObject vo); |     boolean deleteVolume(VolumeObject vo); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -18,23 +18,14 @@ | |||||||
|  */ |  */ | ||||||
| package org.apache.cloudstack.storage.datastore.lifecycle; | package org.apache.cloudstack.storage.datastore.lifecycle; | ||||||
| 
 | 
 | ||||||
| import java.net.URI; |  | ||||||
| import java.net.URISyntaxException; |  | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| 
 | 
 | ||||||
| import javax.inject.Inject; | import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; | ||||||
| 
 |  | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; | import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle; | import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle; | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; |  | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.Scope; |  | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; |  | ||||||
| import org.apache.cloudstack.storage.datastore.DataStoreStatus; | import org.apache.cloudstack.storage.datastore.DataStoreStatus; | ||||||
| import org.apache.cloudstack.storage.datastore.PrimaryDataStore; |  | ||||||
| import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; | import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; | ||||||
| import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreProviderDao; |  | ||||||
| import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreVO; | import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreVO; | ||||||
| import org.springframework.stereotype.Component; |  | ||||||
| 
 | 
 | ||||||
| public class DefaultPrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLifeCycle { | public class DefaultPrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLifeCycle { | ||||||
|     protected PrimaryDataStoreInfo dataStore; |     protected PrimaryDataStoreInfo dataStore; | ||||||
| @ -58,8 +49,12 @@ public class DefaultPrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLif | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public boolean attach(Scope scope) { |     public boolean attachCluster(ClusterScope scope) { | ||||||
|         //if (scope.getScopeType() == ScopeType.CLUSTER)  |         PrimaryDataStoreVO dataStore = dataStoreDao.findById(this.dataStore.getId()); | ||||||
|  |         dataStore.setDataCenterId(scope.getZoneId()); | ||||||
|  |         dataStore.setPodId(scope.getPodId()); | ||||||
|  |         dataStore.setClusterId(scope.getScopeId()); | ||||||
|  |         dataStoreDao.update(this.dataStore.getId(), dataStore); | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ | |||||||
|  */ |  */ | ||||||
| package org.apache.cloudstack.storage.volume; | package org.apache.cloudstack.storage.volume; | ||||||
| 
 | 
 | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; | import org.apache.cloudstack.storage.datastore.PrimaryDataStore; | ||||||
| import org.apache.cloudstack.storage.image.TemplateInfo; | import org.apache.cloudstack.storage.image.TemplateInfo; | ||||||
| import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.Event; | import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.Event; | ||||||
| import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.State; | import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.State; | ||||||
| @ -31,14 +31,14 @@ import com.cloud.utils.fsm.NoTransitionException; | |||||||
| import com.cloud.utils.fsm.StateMachine2; | import com.cloud.utils.fsm.StateMachine2; | ||||||
| 
 | 
 | ||||||
| public class TemplateOnPrimaryDataStoreObject implements TemplateOnPrimaryDataStoreInfo { | public class TemplateOnPrimaryDataStoreObject implements TemplateOnPrimaryDataStoreInfo { | ||||||
|     protected PrimaryDataStoreInfo dataStore; |     protected PrimaryDataStore dataStore; | ||||||
|     protected TemplateInfo template; |     protected TemplateInfo template; | ||||||
|     protected TemplatePrimaryDataStoreVO vo; |     protected TemplatePrimaryDataStoreVO vo; | ||||||
|     protected TemplatePrimaryDataStoreDao templateStoreDao; |     protected TemplatePrimaryDataStoreDao templateStoreDao; | ||||||
|     protected TemplatePrimaryDataStoreManager mgr; |     protected TemplatePrimaryDataStoreManager mgr; | ||||||
|     protected StateMachine2<State, Event, TemplatePrimaryDataStoreVO> stateMachine; |     protected StateMachine2<State, Event, TemplatePrimaryDataStoreVO> stateMachine; | ||||||
| 
 | 
 | ||||||
|     public TemplateOnPrimaryDataStoreObject(PrimaryDataStoreInfo primaryDataStore, TemplateInfo template, TemplatePrimaryDataStoreVO vo, |     public TemplateOnPrimaryDataStoreObject(PrimaryDataStore primaryDataStore, TemplateInfo template, TemplatePrimaryDataStoreVO vo, | ||||||
|     		TemplatePrimaryDataStoreDao templateStoreDao, TemplatePrimaryDataStoreManager mgr) { |     		TemplatePrimaryDataStoreDao templateStoreDao, TemplatePrimaryDataStoreManager mgr) { | ||||||
|         this.dataStore = primaryDataStore; |         this.dataStore = primaryDataStore; | ||||||
|         this.template = template; |         this.template = template; | ||||||
| @ -59,7 +59,7 @@ public class TemplateOnPrimaryDataStoreObject implements TemplateOnPrimaryDataSt | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public PrimaryDataStoreInfo getPrimaryDataStore() { |     public PrimaryDataStore getPrimaryDataStore() { | ||||||
|         return this.dataStore; |         return this.dataStore; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -77,7 +77,7 @@ public class TemplateOnPrimaryDataStoreObject implements TemplateOnPrimaryDataSt | |||||||
|         try { |         try { | ||||||
|             this.stateMachine.transitTo(vo, event, null, templateStoreDao); |             this.stateMachine.transitTo(vo, event, null, templateStoreDao); | ||||||
|         } catch (NoTransitionException e) { |         } catch (NoTransitionException e) { | ||||||
|            throw new CloudRuntimeException(e.toString()); |            throw new CloudRuntimeException("Failed change state", e); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ | |||||||
|  */ |  */ | ||||||
| package org.apache.cloudstack.storage.volume; | package org.apache.cloudstack.storage.volume; | ||||||
| 
 | 
 | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; | import org.apache.cloudstack.storage.datastore.PrimaryDataStore; | ||||||
| import org.apache.cloudstack.storage.image.TemplateInfo; | import org.apache.cloudstack.storage.image.TemplateInfo; | ||||||
| import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.Event; | import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.Event; | ||||||
| import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.State; | import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.State; | ||||||
| @ -27,9 +27,9 @@ import org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreVO; | |||||||
| import com.cloud.utils.fsm.StateMachine2; | import com.cloud.utils.fsm.StateMachine2; | ||||||
| 
 | 
 | ||||||
| public interface TemplatePrimaryDataStoreManager { | public interface TemplatePrimaryDataStoreManager { | ||||||
|     public TemplateOnPrimaryDataStoreInfo createTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStoreInfo dataStore); |     public TemplateOnPrimaryDataStoreInfo createTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStore dataStore); | ||||||
| 
 | 
 | ||||||
|     public TemplateOnPrimaryDataStoreInfo findTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStoreInfo dataStore); |     public TemplateOnPrimaryDataStoreInfo findTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStore dataStore); | ||||||
|      |      | ||||||
|     public StateMachine2<State, Event, TemplatePrimaryDataStoreVO> getStateMachine(); |     public StateMachine2<State, Event, TemplatePrimaryDataStoreVO> getStateMachine(); | ||||||
| } | } | ||||||
|  | |||||||
| @ -21,6 +21,7 @@ package org.apache.cloudstack.storage.volume; | |||||||
| import javax.inject.Inject; | import javax.inject.Inject; | ||||||
| 
 | 
 | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; | import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; | ||||||
|  | import org.apache.cloudstack.storage.datastore.PrimaryDataStore; | ||||||
| import org.apache.cloudstack.storage.image.TemplateInfo; | import org.apache.cloudstack.storage.image.TemplateInfo; | ||||||
| import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.Event; | import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.Event; | ||||||
| import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.State; | import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.State; | ||||||
| @ -79,7 +80,7 @@ public class TemplatePrimaryDataStoreManagerImpl implements TemplatePrimaryDataS | |||||||
|         return templateStoreVO; |         return templateStoreVO; | ||||||
|     } |     } | ||||||
|     @Override |     @Override | ||||||
|     public TemplateOnPrimaryDataStoreObject createTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStoreInfo dataStore) { |     public TemplateOnPrimaryDataStoreObject createTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStore dataStore) { | ||||||
|         TemplatePrimaryDataStoreVO templateStoreVO = null; |         TemplatePrimaryDataStoreVO templateStoreVO = null; | ||||||
|         boolean freshNewTemplate = false; |         boolean freshNewTemplate = false; | ||||||
|         templateStoreVO = templateStoreDao.findByTemplateIdAndPoolId(template.getId(), dataStore.getId()); |         templateStoreVO = templateStoreDao.findByTemplateIdAndPoolId(template.getId(), dataStore.getId()); | ||||||
| @ -106,7 +107,7 @@ public class TemplatePrimaryDataStoreManagerImpl implements TemplatePrimaryDataS | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public TemplateOnPrimaryDataStoreObject findTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStoreInfo dataStore) { |     public TemplateOnPrimaryDataStoreObject findTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStore dataStore) { | ||||||
|         SearchCriteriaService<TemplatePrimaryDataStoreVO, TemplatePrimaryDataStoreVO> sc = SearchCriteria2.create(TemplatePrimaryDataStoreVO.class); |         SearchCriteriaService<TemplatePrimaryDataStoreVO, TemplatePrimaryDataStoreVO> sc = SearchCriteria2.create(TemplatePrimaryDataStoreVO.class); | ||||||
|         sc.addAnd(sc.getEntity().getTemplateId(), Op.EQ, template.getId()); |         sc.addAnd(sc.getEntity().getTemplateId(), Op.EQ, template.getId()); | ||||||
|         sc.addAnd(sc.getEntity().getPoolId(), Op.EQ, dataStore.getId()); |         sc.addAnd(sc.getEntity().getPoolId(), Op.EQ, dataStore.getId()); | ||||||
|  | |||||||
| @ -19,6 +19,7 @@ import org.apache.log4j.Logger; | |||||||
| import com.cloud.storage.Volume; | import com.cloud.storage.Volume; | ||||||
| import com.cloud.storage.Volume.State; | import com.cloud.storage.Volume.State; | ||||||
| import com.cloud.utils.component.ComponentInject; | import com.cloud.utils.component.ComponentInject; | ||||||
|  | import com.cloud.utils.db.DB; | ||||||
| import com.cloud.utils.exception.CloudRuntimeException; | import com.cloud.utils.exception.CloudRuntimeException; | ||||||
| import com.cloud.utils.fsm.NoTransitionException; | import com.cloud.utils.fsm.NoTransitionException; | ||||||
| import com.cloud.utils.fsm.StateMachine2; | import com.cloud.utils.fsm.StateMachine2; | ||||||
|  | |||||||
| @ -20,11 +20,9 @@ package org.apache.cloudstack.storage.volume; | |||||||
| 
 | 
 | ||||||
| import javax.inject.Inject; | import javax.inject.Inject; | ||||||
| 
 | 
 | ||||||
| import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity; |  | ||||||
| import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity; | import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity; | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; | import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType; | import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType; | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.type.BaseImage; |  | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType; | import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType; | ||||||
| import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; | import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; | ||||||
| import org.apache.cloudstack.framework.async.AsyncCallbackHandler; | import org.apache.cloudstack.framework.async.AsyncCallbackHandler; | ||||||
| @ -33,15 +31,12 @@ import org.apache.cloudstack.storage.EndPoint; | |||||||
| import org.apache.cloudstack.storage.command.CommandResult; | import org.apache.cloudstack.storage.command.CommandResult; | ||||||
| import org.apache.cloudstack.storage.datastore.PrimaryDataStore; | import org.apache.cloudstack.storage.datastore.PrimaryDataStore; | ||||||
| import org.apache.cloudstack.storage.datastore.manager.PrimaryDataStoreManager; | import org.apache.cloudstack.storage.datastore.manager.PrimaryDataStoreManager; | ||||||
| import org.apache.cloudstack.storage.image.TemplateEntityImpl; |  | ||||||
| import org.apache.cloudstack.storage.image.TemplateInfo; | import org.apache.cloudstack.storage.image.TemplateInfo; | ||||||
| import org.apache.cloudstack.storage.image.motion.ImageMotionService; | import org.apache.cloudstack.storage.image.motion.ImageMotionService; | ||||||
| import org.apache.cloudstack.storage.volume.db.VolumeDao; | import org.apache.cloudstack.storage.volume.db.VolumeDao; | ||||||
| import org.apache.cloudstack.storage.volume.db.VolumeVO; | import org.apache.cloudstack.storage.volume.db.VolumeVO; | ||||||
| 
 | 
 | ||||||
| import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||||
| import org.springframework.stereotype.Service; |  | ||||||
| 
 |  | ||||||
| import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; | import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; | ||||||
| import com.cloud.storage.Volume; | import com.cloud.storage.Volume; | ||||||
| import com.cloud.utils.db.DB; | import com.cloud.utils.db.DB; | ||||||
| @ -136,7 +131,8 @@ public class VolumeServiceImpl implements VolumeService { | |||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     protected void createBaseImageAsync(PrimaryDataStore dataStore, TemplateInfo template, AsyncCompletionCallback<TemplateOnPrimaryDataStoreObject> callback) { |     @DB | ||||||
|  |     protected void createBaseImageAsync(VolumeInfo volume, PrimaryDataStore dataStore, TemplateInfo template, AsyncCompletionCallback<VolumeInfo> callback) { | ||||||
|         TemplateOnPrimaryDataStoreObject templateOnPrimaryStoreObj = (TemplateOnPrimaryDataStoreObject) templatePrimaryStoreMgr.createTemplateOnPrimaryDataStore(template, dataStore); |         TemplateOnPrimaryDataStoreObject templateOnPrimaryStoreObj = (TemplateOnPrimaryDataStoreObject) templatePrimaryStoreMgr.createTemplateOnPrimaryDataStore(template, dataStore); | ||||||
|         templateOnPrimaryStoreObj.stateTransit(TemplateOnPrimaryDataStoreStateMachine.Event.CreateRequested); |         templateOnPrimaryStoreObj.stateTransit(TemplateOnPrimaryDataStoreStateMachine.Event.CreateRequested); | ||||||
|         templateOnPrimaryStoreObj.updateStatus(Status.CREATING); |         templateOnPrimaryStoreObj.updateStatus(Status.CREATING); | ||||||
| @ -154,11 +150,14 @@ public class VolumeServiceImpl implements VolumeService { | |||||||
|         AsyncCallbackDispatcher caller = new AsyncCallbackDispatcher(this) |         AsyncCallbackDispatcher caller = new AsyncCallbackDispatcher(this) | ||||||
|             .setParentCallback(callback) |             .setParentCallback(callback) | ||||||
|             .setOperationName("volumeservice.createbaseimage.callback") |             .setOperationName("volumeservice.createbaseimage.callback") | ||||||
|  |             .setContextParam("volume", volume) | ||||||
|  |             .setContextParam("primary", dataStore) | ||||||
|             .setContextParam("templateOnPrimary", templateOnPrimaryStoreObj); |             .setContextParam("templateOnPrimary", templateOnPrimaryStoreObj); | ||||||
| 
 | 
 | ||||||
|         imageMotion.copyTemplateAsync(templateOnPrimaryStoreObj, caller); |         imageMotion.copyTemplateAsync(templateOnPrimaryStoreObj, caller); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @DB | ||||||
|     @AsyncCallbackHandler(operationName="volumeservice.createbaseimage.callback") |     @AsyncCallbackHandler(operationName="volumeservice.createbaseimage.callback") | ||||||
|     public void createBaseImageCallback(AsyncCallbackDispatcher callback) { |     public void createBaseImageCallback(AsyncCallbackDispatcher callback) { | ||||||
|         CommandResult result = callback.getResult(); |         CommandResult result = callback.getResult(); | ||||||
| @ -172,8 +171,8 @@ public class VolumeServiceImpl implements VolumeService { | |||||||
|         } |         } | ||||||
|          |          | ||||||
|         AsyncCallbackDispatcher parentCaller = callback.getParentCallback(); |         AsyncCallbackDispatcher parentCaller = callback.getParentCallback(); | ||||||
|         VolumeInfo volume = parentCaller.getContextParam("volume"); |         VolumeInfo volume = callback.getContextParam("volume"); | ||||||
|         PrimaryDataStore pd = parentCaller.getContextParam("primary"); |         PrimaryDataStore pd = callback.getContextParam("primary"); | ||||||
|         AsyncCallbackDispatcher caller = new AsyncCallbackDispatcher(this) |         AsyncCallbackDispatcher caller = new AsyncCallbackDispatcher(this) | ||||||
|               .setParentCallback(parentCaller) |               .setParentCallback(parentCaller) | ||||||
|               .setOperationName("volumeservice.createvolumefrombaseimage.callback"); |               .setOperationName("volumeservice.createvolumefrombaseimage.callback"); | ||||||
| @ -181,6 +180,7 @@ public class VolumeServiceImpl implements VolumeService { | |||||||
|         createVolumeFromBaseImageAsync(volume, templateOnPrimaryStoreObj, pd, caller); |         createVolumeFromBaseImageAsync(volume, templateOnPrimaryStoreObj, pd, caller); | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     @DB | ||||||
|     protected void createVolumeFromBaseImageAsync(VolumeInfo volume, TemplateOnPrimaryDataStoreInfo templateOnPrimaryStore, PrimaryDataStore pd, AsyncCompletionCallback<VolumeObject> callback) { |     protected void createVolumeFromBaseImageAsync(VolumeInfo volume, TemplateOnPrimaryDataStoreInfo templateOnPrimaryStore, PrimaryDataStore pd, AsyncCompletionCallback<VolumeObject> callback) { | ||||||
|         VolumeObject vo = (VolumeObject) volume; |         VolumeObject vo = (VolumeObject) volume; | ||||||
|         try { |         try { | ||||||
| @ -198,6 +198,7 @@ public class VolumeServiceImpl implements VolumeService { | |||||||
|         pd.createVoluemFromBaseImageAsync(volume, templateOnPrimaryStore, caller); |         pd.createVoluemFromBaseImageAsync(volume, templateOnPrimaryStore, caller); | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     @DB | ||||||
|     @AsyncCallbackHandler(operationName="volumeservice.createVolumeFromBaseImageCallback") |     @AsyncCallbackHandler(operationName="volumeservice.createVolumeFromBaseImageCallback") | ||||||
|     public void createVolumeFromBaseImageCallback(AsyncCallbackDispatcher callback) { |     public void createVolumeFromBaseImageCallback(AsyncCallbackDispatcher callback) { | ||||||
|         VolumeObject vo = callback.getContextParam("volume"); |         VolumeObject vo = callback.getContextParam("volume"); | ||||||
| @ -212,6 +213,7 @@ public class VolumeServiceImpl implements VolumeService { | |||||||
|         parentCall.complete(vo); |         parentCall.complete(vo); | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     @DB | ||||||
|     @AsyncCallbackHandler(operationName="volumeservice.createvolumefrombaseimage.callback") |     @AsyncCallbackHandler(operationName="volumeservice.createvolumefrombaseimage.callback") | ||||||
|     public void createVolumeFromBaseImageAsyncCallback(AsyncCallbackDispatcher callback) { |     public void createVolumeFromBaseImageAsyncCallback(AsyncCallbackDispatcher callback) { | ||||||
|         AsyncCallbackDispatcher parentCall = callback.getParentCallback(); |         AsyncCallbackDispatcher parentCall = callback.getParentCallback(); | ||||||
| @ -219,16 +221,13 @@ public class VolumeServiceImpl implements VolumeService { | |||||||
|         parentCall.complete(vo); |         parentCall.complete(vo); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @DB | ||||||
|     @Override |     @Override | ||||||
|     public void createVolumeFromTemplateAsync(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType, TemplateInfo template, AsyncCompletionCallback<VolumeInfo> callback) { |     public void createVolumeFromTemplateAsync(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType, TemplateInfo template, AsyncCompletionCallback<VolumeInfo> callback) { | ||||||
|         PrimaryDataStore pd = dataStoreMgr.getPrimaryDataStore(dataStoreId); |         PrimaryDataStore pd = dataStoreMgr.getPrimaryDataStore(dataStoreId); | ||||||
|         TemplateOnPrimaryDataStoreInfo templateOnPrimaryStore = pd.getTemplate(template); |         TemplateOnPrimaryDataStoreInfo templateOnPrimaryStore = pd.getTemplate(template); | ||||||
|         if (templateOnPrimaryStore == null) { |         if (templateOnPrimaryStore == null) { | ||||||
|             AsyncCallbackDispatcher caller = new AsyncCallbackDispatcher(this).setParentCallback(callback) |             createBaseImageAsync(volume, pd, template, callback); | ||||||
|                     .setOperationName("volumeservice.createbaseimage.callback") |  | ||||||
|                     .setContextParam("volume", volume) |  | ||||||
|                     .setContextParam("primary", pd); |  | ||||||
|              createBaseImageAsync(pd, template, caller); |  | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -18,7 +18,9 @@ | |||||||
|  */ |  */ | ||||||
| package org.apache.cloudstack.storage.volume.test; | package org.apache.cloudstack.storage.volume.test; | ||||||
| 
 | 
 | ||||||
|  | import org.apache.cloudstack.storage.HostEndpointRpcServer; | ||||||
| import org.apache.cloudstack.storage.image.motion.ImageMotionService; | import org.apache.cloudstack.storage.image.motion.ImageMotionService; | ||||||
|  | import org.apache.cloudstack.storage.test.MockHypervsiorHostEndPointRpcServer; | ||||||
| import org.mockito.Mockito; | import org.mockito.Mockito; | ||||||
| import org.springframework.context.annotation.Bean; | import org.springframework.context.annotation.Bean; | ||||||
| import org.springframework.context.annotation.Configuration; | import org.springframework.context.annotation.Configuration; | ||||||
| @ -38,4 +40,9 @@ public class TestConfiguration { | |||||||
|     public ClusterDao clusterDao() { |     public ClusterDao clusterDao() { | ||||||
|         return Mockito.mock(ClusterDaoImpl.class); |         return Mockito.mock(ClusterDaoImpl.class); | ||||||
|     } |     } | ||||||
|  |      | ||||||
|  |     @Bean | ||||||
|  |     public HostEndpointRpcServer rpcServer() { | ||||||
|  |         return new MockHypervsiorHostEndPointRpcServer(); | ||||||
|  |     } | ||||||
| } | } | ||||||
| @ -104,7 +104,7 @@ public class AsyncCallbackDispatcher implements AsyncCompletionCallback { | |||||||
| 		} catch (IllegalAccessException e) { | 		} catch (IllegalAccessException e) { | ||||||
| 			throw new RuntimeException("IllegalAccessException when invoking RPC callback for command: " + callback.getOperationName()); | 			throw new RuntimeException("IllegalAccessException when invoking RPC callback for command: " + callback.getOperationName()); | ||||||
| 		} catch (InvocationTargetException e) { | 		} catch (InvocationTargetException e) { | ||||||
| 			throw new RuntimeException("InvocationTargetException when invoking RPC callback for command: " + callback.getOperationName()); | 			throw new RuntimeException("InvocationTargetException when invoking RPC callback for command: " + callback.getOperationName(), e); | ||||||
| 		} | 		} | ||||||
| 		 | 		 | ||||||
| 		return true; | 		return true; | ||||||
|  | |||||||
| @ -19,6 +19,8 @@ alter table vm_template add image_data_store_id bigint unsigned; | |||||||
| alter table storage_pool add storage_provider_id bigint unsigned;  | alter table storage_pool add storage_provider_id bigint unsigned;  | ||||||
| alter table storage_pool add configurator_key varchar(255);  | alter table storage_pool add configurator_key varchar(255);  | ||||||
| alter table storage_pool modify id bigint unsigned AUTO_INCREMENT UNIQUE NOT NULL; | alter table storage_pool modify id bigint unsigned AUTO_INCREMENT UNIQUE NOT NULL; | ||||||
|  | alter table template_spool_ref add state varchar(255); | ||||||
|  | alter table template_spool_ref add update_count bigint unsigned; | ||||||
| alter table volumes add disk_type varchar(255); | alter table volumes add disk_type varchar(255); | ||||||
| alter table volumes drop foreign key `fk_volumes__account_id`; | alter table volumes drop foreign key `fk_volumes__account_id`; | ||||||
| CREATE TABLE `cloud`.`primary_data_store_provider` ( | CREATE TABLE `cloud`.`primary_data_store_provider` ( | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user