mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	@DB works on spring
This commit is contained in:
		
							parent
							
								
									f92ce72639
								
							
						
					
					
						commit
						ad3e98c1eb
					
				| @ -1,23 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <projectDescription> | ||||
| 	<name>platform-storage</name> | ||||
| 	<comment></comment> | ||||
| 	<projects> | ||||
| 	</projects> | ||||
| 	<buildSpec> | ||||
| 		<buildCommand> | ||||
| 			<name>org.eclipse.jdt.core.javabuilder</name> | ||||
| 			<arguments> | ||||
| 			</arguments> | ||||
| 		</buildCommand> | ||||
| 		<buildCommand> | ||||
| 			<name>org.eclipse.m2e.core.maven2Builder</name> | ||||
| 			<arguments> | ||||
| 			</arguments> | ||||
| 		</buildCommand> | ||||
| 	</buildSpec> | ||||
| 	<natures> | ||||
| 		<nature>org.eclipse.m2e.core.maven2Nature</nature> | ||||
| 		<nature>org.eclipse.jdt.core.javanature</nature> | ||||
| 	</natures> | ||||
| </projectDescription> | ||||
| @ -1,21 +1,13 @@ | ||||
| <!-- | ||||
|   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. | ||||
| --> | ||||
| <!-- 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. --> | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
|   <modelVersion>4.0.0</modelVersion> | ||||
| @ -48,6 +40,37 @@ | ||||
|       <artifactId>cloud-platform-api</artifactId> | ||||
|       <version>${project.version}</version> | ||||
|     </dependency> | ||||
|     <dependency> | ||||
|       <groupId>org.apache.openjpa</groupId> | ||||
|       <artifactId>openjpa</artifactId> | ||||
|       <version>2.2.0</version> | ||||
|     </dependency> | ||||
|     <dependency> | ||||
|       <groupId>mysql</groupId> | ||||
|       <artifactId>mysql-connector-java</artifactId> | ||||
|       <version>${cs.mysql.version}</version> | ||||
|       <scope>provided</scope> | ||||
|     </dependency> | ||||
|     <dependency> | ||||
|       <groupId>org.mockito</groupId> | ||||
|       <artifactId>mockito-all</artifactId> | ||||
|       <version>1.9.5</version> | ||||
|     </dependency> | ||||
|     <dependency> | ||||
|     <groupId>org.aspectj</groupId> | ||||
|     <artifactId>aspectjrt</artifactId> | ||||
|     <version>1.7.1</version> | ||||
| </dependency> | ||||
| <dependency> | ||||
|     <groupId>org.aspectj</groupId> | ||||
|     <artifactId>aspectjweaver</artifactId> | ||||
|     <version>1.7.1</version> | ||||
| </dependency> | ||||
| <dependency> | ||||
|     <groupId>javax.inject</groupId> | ||||
|     <artifactId>javax.inject</artifactId> | ||||
|     <version>1</version> | ||||
| </dependency> | ||||
|   </dependencies> | ||||
|   <build> | ||||
|     <defaultGoal>install</defaultGoal> | ||||
|  | ||||
| @ -27,7 +27,6 @@ import org.apache.cloudstack.platform.subsystem.api.storage.StorageProvider; | ||||
| import org.apache.cloudstack.platform.subsystem.api.storage.TemplateProfile; | ||||
| import org.apache.cloudstack.platform.subsystem.api.storage.VolumeProfile; | ||||
| import org.apache.cloudstack.platform.subsystem.api.storage.VolumeStrategy; | ||||
| import org.apache.cloudstack.storage.db.VolumeHostVO; | ||||
| import org.apache.cloudstack.storage.image.ImageManager; | ||||
| import org.apache.cloudstack.storage.manager.BackupStorageManager; | ||||
| import org.apache.cloudstack.storage.manager.SecondaryStorageManager; | ||||
|  | ||||
| @ -1,328 +0,0 @@ | ||||
| // 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.db; | ||||
| 
 | ||||
| import java.util.Date; | ||||
| 
 | ||||
| import javax.persistence.Column; | ||||
| import javax.persistence.Entity; | ||||
| import javax.persistence.EnumType; | ||||
| import javax.persistence.Enumerated; | ||||
| import javax.persistence.GeneratedValue; | ||||
| import javax.persistence.GenerationType; | ||||
| import javax.persistence.Id; | ||||
| import javax.persistence.Table; | ||||
| import javax.persistence.Temporal; | ||||
| import javax.persistence.TemporalType; | ||||
| 
 | ||||
| import org.apache.cloudstack.platform.subsystem.api.storage.DataObjectBackupStorageOperationState; | ||||
| import org.apache.cloudstack.storage.VolumeBackupRef; | ||||
| 
 | ||||
| //import com.cloud.storage.VMVolumeStorageResourceAssoc.Status; | ||||
| import com.cloud.storage.Storage; | ||||
| import com.cloud.storage.VMTemplateStorageResourceAssoc; | ||||
| import com.cloud.storage.Storage.ImageFormat; | ||||
| import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; | ||||
| import com.cloud.utils.db.GenericDaoBase; | ||||
| 
 | ||||
| /** | ||||
|  * Join table for storage hosts and volumes | ||||
|  * | ||||
|  */ | ||||
| @Entity | ||||
| @Table(name="volume_host_ref") | ||||
| public class VolumeHostVO implements VolumeBackupRef { | ||||
| 	@Id | ||||
| 	@GeneratedValue(strategy=GenerationType.IDENTITY) | ||||
| 	Long id; | ||||
| 	 | ||||
| 	@Column(name="host_id") | ||||
| 	private long hostId; | ||||
| 	 | ||||
| 	@Column(name="volume_id") | ||||
| 	private long volumeId; | ||||
| 	 | ||||
| 	@Column(name="zone_id") | ||||
| 	private long zoneId; | ||||
| 	 | ||||
| 	@Column(name=GenericDaoBase.CREATED_COLUMN) | ||||
| 	private Date created = null; | ||||
| 	 | ||||
| 	@Column(name="last_updated") | ||||
| 	@Temporal(value=TemporalType.TIMESTAMP) | ||||
| 	private Date lastUpdated = null; | ||||
| 	 | ||||
| 	@Column (name="download_pct") | ||||
| 	private int downloadPercent; | ||||
| 	 | ||||
| 	@Column (name="size") | ||||
| 	private long size; | ||||
| 	 | ||||
| 	@Column (name="physical_size") | ||||
| 	private long physicalSize; | ||||
| 	 | ||||
| 	@Column (name="download_state") | ||||
| 	@Enumerated(EnumType.STRING) | ||||
| 	private Status downloadState; | ||||
| 	 | ||||
| 	@Column (name="opt_state") | ||||
| 	@Enumerated(EnumType.STRING) | ||||
| 	private DataObjectBackupStorageOperationState optState; | ||||
| 	 | ||||
|     @Column(name="checksum") | ||||
|     private String checksum; | ||||
| 	 | ||||
| 	@Column (name="local_path") | ||||
| 	private String localDownloadPath; | ||||
| 	 | ||||
| 	@Column (name="error_str") | ||||
| 	private String errorString; | ||||
| 	 | ||||
| 	@Column (name="job_id") | ||||
| 	private String jobId;	 | ||||
| 	 | ||||
| 	@Column (name="install_path") | ||||
|     private String installPath; | ||||
| 	 | ||||
| 	@Column (name="url") | ||||
| 	private String downloadUrl; | ||||
| 	 | ||||
| 	@Column(name="format") | ||||
|     private Storage.ImageFormat format; | ||||
|      | ||||
|     @Column(name="destroyed") | ||||
|     boolean destroyed = false; | ||||
|      | ||||
| 	 | ||||
|     public String getInstallPath() { | ||||
| 		return installPath; | ||||
| 	} | ||||
| 
 | ||||
| 	public long getHostId() { | ||||
| 		return hostId; | ||||
| 	} | ||||
| 
 | ||||
| 	public void setHostId(long hostId) { | ||||
| 		this.hostId = hostId; | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
|     public long getVolumeId() { | ||||
| 		return volumeId; | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
|     public void setVolumeId(long volumeId) { | ||||
| 		this.volumeId = volumeId; | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
|     public long getZoneId() { | ||||
| 		return zoneId; | ||||
| 	} | ||||
| 
 | ||||
| 	public void setZoneId(long zoneId) { | ||||
| 		this.zoneId = zoneId; | ||||
| 	} | ||||
| 
 | ||||
| 	public int getDownloadPercent() { | ||||
| 		return downloadPercent; | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
|     public void setDownloadPercent(int downloadPercent) { | ||||
| 		this.downloadPercent = downloadPercent; | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
|     public void setDownloadState(Status downloadState) { | ||||
| 		this.downloadState = downloadState; | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
| 
 | ||||
| 	public long getId() { | ||||
| 		return id; | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
|      | ||||
| 	public Date getCreated() { | ||||
| 		return created; | ||||
| 	} | ||||
| 
 | ||||
| 	public Date getLastUpdated() { | ||||
| 		return lastUpdated; | ||||
| 	} | ||||
| 	 | ||||
| 	 | ||||
|     public void setLastUpdated(Date date) { | ||||
| 	    lastUpdated = date; | ||||
| 	} | ||||
| 	 | ||||
| 	 | ||||
|     public void setInstallPath(String installPath) { | ||||
| 	    this.installPath = installPath; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	public Status getDownloadState() { | ||||
| 		return downloadState; | ||||
| 	} | ||||
| 
 | ||||
| 	public String getChecksum() { | ||||
| 		return checksum; | ||||
| 	} | ||||
| 
 | ||||
| 	public void setChecksum(String checksum) { | ||||
| 		this.checksum = checksum; | ||||
| 	} | ||||
| 
 | ||||
| 	public VolumeHostVO(long hostId, long volumeId) { | ||||
| 		super(); | ||||
| 		this.hostId = hostId; | ||||
| 		this.volumeId = volumeId; | ||||
| 	} | ||||
| 
 | ||||
| 	public VolumeHostVO(long hostId, long volumeId, long zoneId, Date lastUpdated, | ||||
| 			int downloadPercent, Status downloadState, | ||||
| 			String localDownloadPath, String errorString, String jobId, | ||||
| 			String installPath, String downloadUrl, String checksum, ImageFormat format) { | ||||
| 		//super(); | ||||
| 		this.hostId = hostId; | ||||
| 		this.volumeId = volumeId; | ||||
| 		this.zoneId = zoneId; | ||||
| 		this.lastUpdated = lastUpdated; | ||||
| 		this.downloadPercent = downloadPercent; | ||||
| 		this.downloadState = downloadState; | ||||
| 		this.localDownloadPath = localDownloadPath; | ||||
| 		this.errorString = errorString; | ||||
| 		this.jobId = jobId; | ||||
| 		this.installPath = installPath; | ||||
| 		this.setDownloadUrl(downloadUrl); | ||||
| 		this.checksum = checksum; | ||||
| 		this.format = format; | ||||
| 	} | ||||
| 
 | ||||
| 	protected VolumeHostVO() { | ||||
| 		 | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
|     public void setLocalDownloadPath(String localPath) { | ||||
| 		this.localDownloadPath = localPath; | ||||
| 	} | ||||
| 
 | ||||
| 	public String getLocalDownloadPath() { | ||||
| 		return localDownloadPath; | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
|     public void setErrorString(String errorString) { | ||||
| 		this.errorString = errorString; | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
|     public String getErrorString() { | ||||
| 		return errorString; | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
|     public void setJobId(String jobId) { | ||||
| 		this.jobId = jobId; | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
|     public String getJobId() { | ||||
| 		return jobId; | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
| 	public boolean equals(Object obj) { | ||||
| 		if (obj instanceof VolumeHostVO) { | ||||
| 			VolumeBackupRef other = (VolumeBackupRef)obj; | ||||
| 			return (this.volumeId==other.getVolumeId() && this.hostId==other.getHostId());		    | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
| 	public int hashCode() { | ||||
| 		Long tid = new Long(volumeId); | ||||
| 		Long hid = new Long(hostId); | ||||
| 		return tid.hashCode()+hid.hashCode(); | ||||
| 	} | ||||
| 
 | ||||
|     public void setSize(long size) { | ||||
|         this.size = size; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 	public long getSize() { | ||||
|         return size; | ||||
|     } | ||||
| 	 | ||||
|      | ||||
|     public void setPhysicalSize(long physicalSize) { | ||||
|         this.physicalSize = physicalSize; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 	public long getPhysicalSize() { | ||||
|         return physicalSize; | ||||
|     } | ||||
| 
 | ||||
|     public void setDestroyed(boolean destroyed) { | ||||
|     	this.destroyed = destroyed; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 	public boolean getDestroyed() { | ||||
|     	return destroyed; | ||||
|     } | ||||
| 
 | ||||
| 	public void setDownloadUrl(String downloadUrl) { | ||||
| 		this.downloadUrl = downloadUrl; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	public String getDownloadUrl() { | ||||
| 		return downloadUrl; | ||||
| 	}	 | ||||
| 	 | ||||
| 	public Storage.ImageFormat getFormat() { | ||||
| 		return format; | ||||
| 	} | ||||
| 
 | ||||
| 	public void setFormat(Storage.ImageFormat format) { | ||||
| 		this.format = format; | ||||
| 	} | ||||
| 	 | ||||
|     public String toString() { | ||||
| 	    return new StringBuilder("VolumeHost[").append(id).append("-").append(volumeId).append("-").append(hostId).append(installPath).append("]").toString(); | ||||
| 	} | ||||
| 
 | ||||
| 	public DataObjectBackupStorageOperationState getOperationState() { | ||||
| 		return optState; | ||||
| 	} | ||||
| 
 | ||||
| 	public long getVolumeSize() { | ||||
| 		// TODO Auto-generated method stub | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,17 @@ | ||||
| package org.apache.cloudstack.storage.volume; | ||||
| 
 | ||||
| import org.apache.cloudstack.storage.volume.db.VolumeVO; | ||||
| 
 | ||||
| import com.cloud.utils.fsm.StateObject; | ||||
| 
 | ||||
| public class Volume implements StateObject<VolumeState>{ | ||||
| 	private VolumeVO volumeVO; | ||||
| 	@Override | ||||
| 	public VolumeState getState() { | ||||
| 		// TODO Auto-generated method stub | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,34 @@ | ||||
| /* | ||||
|  * Licensed to the Apache Software Foundation (ASF) under one | ||||
|  * or more contributor license agreements.  See the NOTICE file | ||||
|  * distributed with this work for additional information | ||||
|  * regarding copyright ownership.  The ASF licenses this file | ||||
|  * to you under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance | ||||
|  * with the License.  You may obtain a copy of the License at | ||||
|  * | ||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, | ||||
|  * software distributed under the License is distributed on an | ||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||||
|  * KIND, either express or implied.  See the License for the | ||||
|  * specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  */ | ||||
| package org.apache.cloudstack.storage.volume; | ||||
| 
 | ||||
| public enum VolumeEvent { | ||||
| 	CreateRequested, | ||||
| 	CopyRequested, | ||||
| 	CopySucceeded, | ||||
| 	CopyFailed, | ||||
| 	OperationFailed, | ||||
| 	OperationSucceeded, | ||||
| 	OperationRetry, | ||||
| 	UploadRequested, | ||||
| 	MigrationRequested, | ||||
| 	SnapshotRequested, | ||||
| 	DestroyRequested, | ||||
| 	ExpungingRequested; | ||||
| } | ||||
| @ -40,13 +40,13 @@ public class VolumeManagerImpl implements VolumeManager { | ||||
| 		newVol.setInstanceId(oldVol.getInstanceId()); | ||||
| 		newVol.setRecreatable(oldVol.isRecreatable()); | ||||
| 		newVol.setReservationId(oldVol.getReservationId()); | ||||
| 		 | ||||
| 		return _volumeDao.persist(newVol); | ||||
| 		return null; | ||||
| 		//return _volumeDao.persist(newVol); | ||||
| 	} | ||||
| 	 | ||||
| 
 | ||||
| 	public VolumeVO processEvent(Volume vol, Volume.Event event) throws NoTransitionException { | ||||
| 		_volStateMachine.transitTo(vol, event, null, _volumeDao); | ||||
| 		//_volStateMachine.transitTo(vol, event, null, _volumeDao); | ||||
| 		return _volumeDao.findById(vol.getId()); | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -18,24 +18,34 @@ | ||||
|  */ | ||||
| package org.apache.cloudstack.storage.volume; | ||||
| 
 | ||||
| import org.apache.cloudstack.storage.volume.db.VolumeDao; | ||||
| import org.apache.cloudstack.storage.volume.db.VolumeVO; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.stereotype.Component; | ||||
| 
 | ||||
| import com.cloud.api.commands.CreateVolumeCmd; | ||||
| import com.cloud.storage.SnapshotVO; | ||||
| import com.cloud.storage.Volume; | ||||
| import com.cloud.storage.dao.SnapshotDao; | ||||
| import com.cloud.upgrade.dao.VersionDao; | ||||
| import com.cloud.upgrade.dao.VersionVO; | ||||
| import com.cloud.utils.db.DB; | ||||
| 
 | ||||
| @Component | ||||
| public class VolumeServiceImpl implements VolumeService { | ||||
| 
 | ||||
| 	@Autowired | ||||
| 	VolumeDao _volumeDao; | ||||
| 	@Override | ||||
| 	public Volume createVolume(long volumeId) { | ||||
| 		// TODO Auto-generated method stub | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
| 	@DB | ||||
| 	@Override | ||||
| 	public boolean deleteVolume(long volumeId) { | ||||
| 		// TODO Auto-generated method stub | ||||
| 		return false; | ||||
| 		VolumeVO vol = new VolumeVO(VolumeType.ROOT, "root", 1, 1,1 ,1,1); | ||||
| 		_volumeDao.persist(vol); | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| @ -61,5 +71,4 @@ public class VolumeServiceImpl implements VolumeService { | ||||
| 		// TODO Auto-generated method stub | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,71 @@ | ||||
| /* | ||||
|  * Licensed to the Apache Software Foundation (ASF) under one | ||||
|  * or more contributor license agreements.  See the NOTICE file | ||||
|  * distributed with this work for additional information | ||||
|  * regarding copyright ownership.  The ASF licenses this file | ||||
|  * to you under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance | ||||
|  * with the License.  You may obtain a copy of the License at | ||||
|  * | ||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, | ||||
|  * software distributed under the License is distributed on an | ||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||||
|  * KIND, either express or implied.  See the License for the | ||||
|  * specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  */ | ||||
| package org.apache.cloudstack.storage.volume; | ||||
| 
 | ||||
| import com.cloud.utils.fsm.StateMachine2; | ||||
| 
 | ||||
| public enum VolumeState { | ||||
| 	Allocated("The volume is allocated but has not been created yet."), | ||||
|     Creating("The volume is being created.  getPoolId() should reflect the pool where it is being created."), | ||||
|     Ready("The volume is ready to be used."), | ||||
|     Migrating("The volume is migrating to other storage pool"), | ||||
|     Snapshotting("There is a snapshot created on this volume, not backed up to secondary storage yet"), | ||||
|     Expunging("The volume is being expunging"), | ||||
|     Destroy("The volume is destroyed, and can't be recovered."),         | ||||
|     UploadOp ("The volume upload operation is in progress or in short the volume is on secondary storage");             | ||||
| 
 | ||||
|     String _description; | ||||
| 
 | ||||
|     private VolumeState(String description) { | ||||
|         _description = description; | ||||
|     } | ||||
| 
 | ||||
|     public static StateMachine2<VolumeState, VolumeEvent, Volume> getStateMachine() { | ||||
|         return s_fsm; | ||||
|     } | ||||
| 
 | ||||
|     public String getDescription() { | ||||
|         return _description; | ||||
|     } | ||||
| 
 | ||||
|     private final static StateMachine2<VolumeState, VolumeEvent, Volume> s_fsm = new StateMachine2<VolumeState, VolumeEvent, Volume>(); | ||||
|     static { | ||||
|         s_fsm.addTransition(Allocated, VolumeEvent.CreateRequested, Creating); | ||||
|         s_fsm.addTransition(Allocated, VolumeEvent.DestroyRequested, Destroy); | ||||
|         s_fsm.addTransition(Creating, VolumeEvent.OperationRetry, Creating); | ||||
|         s_fsm.addTransition(Creating, VolumeEvent.OperationFailed, Allocated); | ||||
|         s_fsm.addTransition(Creating, VolumeEvent.OperationSucceeded, Ready); | ||||
|         s_fsm.addTransition(Creating, VolumeEvent.DestroyRequested, Destroy); | ||||
|         s_fsm.addTransition(Creating, VolumeEvent.CreateRequested, Creating);             | ||||
|         s_fsm.addTransition(Allocated, VolumeEvent.UploadRequested, UploadOp); | ||||
|         s_fsm.addTransition(UploadOp, VolumeEvent.CopyRequested, Creating);// CopyRequested for volume from sec to primary storage             | ||||
|         s_fsm.addTransition(Creating, VolumeEvent.CopySucceeded, Ready); | ||||
|         s_fsm.addTransition(Creating, VolumeEvent.CopyFailed, UploadOp);// Copying volume from sec to primary failed.   | ||||
|         s_fsm.addTransition(UploadOp, VolumeEvent.DestroyRequested, Destroy); | ||||
|         s_fsm.addTransition(Ready, VolumeEvent.DestroyRequested, Destroy); | ||||
|         s_fsm.addTransition(Destroy, VolumeEvent.ExpungingRequested, Expunging); | ||||
|         s_fsm.addTransition(Ready, VolumeEvent.SnapshotRequested, Snapshotting); | ||||
|         s_fsm.addTransition(Snapshotting, VolumeEvent.OperationSucceeded, Ready); | ||||
|         s_fsm.addTransition(Snapshotting, VolumeEvent.OperationFailed, Ready); | ||||
|         s_fsm.addTransition(Ready, VolumeEvent.MigrationRequested, Migrating); | ||||
|         s_fsm.addTransition(Migrating, VolumeEvent.OperationSucceeded, Ready); | ||||
|         s_fsm.addTransition(Migrating, VolumeEvent.OperationFailed, Ready); | ||||
|         s_fsm.addTransition(Destroy, VolumeEvent.OperationSucceeded, Destroy); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,27 @@ | ||||
| /* | ||||
|  * Licensed to the Apache Software Foundation (ASF) under one | ||||
|  * or more contributor license agreements.  See the NOTICE file | ||||
|  * distributed with this work for additional information | ||||
|  * regarding copyright ownership.  The ASF licenses this file | ||||
|  * to you under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance | ||||
|  * with the License.  You may obtain a copy of the License at | ||||
|  * | ||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, | ||||
|  * software distributed under the License is distributed on an | ||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||||
|  * KIND, either express or implied.  See the License for the | ||||
|  * specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  */ | ||||
| package org.apache.cloudstack.storage.volume; | ||||
| 
 | ||||
| public enum VolumeType { | ||||
| 	UNKNOWN,  | ||||
| 	ROOT,  | ||||
| 	SWAP,  | ||||
| 	DATADISK,  | ||||
| 	ISO | ||||
| } | ||||
| @ -0,0 +1,79 @@ | ||||
| // Licensed to the Apache Software Foundation (ASF) under one | ||||
| // or more contributor license agreements.  See the NOTICE file | ||||
| // distributed with this work for additional information | ||||
| // regarding copyright ownership.  The ASF licenses this file | ||||
| // to you under the Apache License, Version 2.0 (the | ||||
| // "License"); you may not use this file except in compliance | ||||
| // with the License.  You may obtain a copy of the License at | ||||
| // | ||||
| //   http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, | ||||
| // software distributed under the License is distributed on an | ||||
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||||
| // KIND, either express or implied.  See the License for the | ||||
| // specific language governing permissions and limitations | ||||
| // under the License. | ||||
| package org.apache.cloudstack.storage.volume.db; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| import org.apache.cloudstack.storage.volume.Volume; | ||||
| import org.apache.cloudstack.storage.volume.VolumeEvent; | ||||
| import org.apache.cloudstack.storage.volume.VolumeState; | ||||
| import org.apache.cloudstack.storage.volume.VolumeType; | ||||
| 
 | ||||
| import com.cloud.hypervisor.Hypervisor.HypervisorType; | ||||
| import com.cloud.storage.Storage.ImageFormat; | ||||
| import com.cloud.utils.Pair; | ||||
| import com.cloud.utils.db.GenericDao; | ||||
| import com.cloud.utils.fsm.StateDao; | ||||
| 
 | ||||
| public interface VolumeDao extends GenericDao<VolumeVO, Long>, StateDao<VolumeState, VolumeEvent, VolumeVO> { | ||||
|      | ||||
| 	List<VolumeVO> findDetachedByAccount(long accountId); | ||||
| 	 | ||||
|     List<VolumeVO> findByAccount(long accountId); | ||||
|      | ||||
|     Pair<Long, Long> getCountAndTotalByPool(long poolId); | ||||
|      | ||||
|     Pair<Long, Long> getNonDestroyedCountAndTotalByPool(long poolId); | ||||
|      | ||||
|     List<VolumeVO> findByInstance(long id); | ||||
|      | ||||
|     List<VolumeVO> findByInstanceAndType(long id, VolumeType vType); | ||||
|      | ||||
|     List<VolumeVO> findByInstanceIdDestroyed(long vmId); | ||||
|      | ||||
|     List<VolumeVO> findByAccountAndPod(long accountId, long podId); | ||||
|      | ||||
|     List<VolumeVO> findByTemplateAndZone(long templateId, long zoneId); | ||||
|      | ||||
|     void deleteVolumesByInstance(long instanceId); | ||||
|      | ||||
|     void attachVolume(long volumeId, long vmId, long deviceId); | ||||
|      | ||||
|     void detachVolume(long volumeId); | ||||
|      | ||||
|     boolean isAnyVolumeActivelyUsingTemplateOnPool(long templateId, long poolId); | ||||
|      | ||||
|     List<VolumeVO> findCreatedByInstance(long id); | ||||
|      | ||||
|     List<VolumeVO> findByPoolId(long poolId); | ||||
|      | ||||
| 	List<VolumeVO> findByInstanceAndDeviceId(long instanceId, long deviceId); | ||||
| 	 | ||||
|     List<VolumeVO> findUsableVolumesForInstance(long instanceId); | ||||
|      | ||||
|     Long countAllocatedVolumesForAccount(long accountId);  | ||||
|     | ||||
|     HypervisorType getHypervisorType(long volumeId); | ||||
|      | ||||
|     List<VolumeVO> listVolumesToBeDestroyed(); | ||||
|      | ||||
|     ImageFormat getImageFormat(Long volumeId); | ||||
|      | ||||
|     List<VolumeVO> findReadyRootVolumesByInstance(long instanceId); | ||||
|      | ||||
|     List<Long> listPoolIdsByVolumeCount(long dcId, Long podId, Long clusterId, long accountId); | ||||
| } | ||||
| @ -0,0 +1,416 @@ | ||||
| // Licensed to the Apache Software Foundation (ASF) under one | ||||
| // or more contributor license agreements.  See the NOTICE file | ||||
| // distributed with this work for additional information | ||||
| // regarding copyright ownership.  The ASF licenses this file | ||||
| // to you under the Apache License, Version 2.0 (the | ||||
| // "License"); you may not use this file except in compliance | ||||
| // with the License.  You may obtain a copy of the License at | ||||
| // | ||||
| //   http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, | ||||
| // software distributed under the License is distributed on an | ||||
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||||
| // KIND, either express or implied.  See the License for the | ||||
| // specific language governing permissions and limitations | ||||
| // under the License. | ||||
| package org.apache.cloudstack.storage.volume.db; | ||||
| 
 | ||||
| import java.sql.PreparedStatement; | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Date; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import javax.ejb.Local; | ||||
| 
 | ||||
| import org.apache.cloudstack.storage.volume.VolumeEvent; | ||||
| import org.apache.cloudstack.storage.volume.VolumeState; | ||||
| import org.apache.cloudstack.storage.volume.VolumeType; | ||||
| import org.apache.log4j.Logger; | ||||
| import org.springframework.stereotype.Component; | ||||
| 
 | ||||
| import com.cloud.hypervisor.Hypervisor.HypervisorType; | ||||
| import com.cloud.server.ResourceTag.TaggedResourceType; | ||||
| import com.cloud.storage.Storage.ImageFormat; | ||||
| import com.cloud.tags.dao.ResourceTagsDaoImpl; | ||||
| import com.cloud.utils.Pair; | ||||
| import com.cloud.utils.component.ComponentLocator; | ||||
| import com.cloud.utils.db.DB; | ||||
| import com.cloud.utils.db.GenericDaoBase; | ||||
| import com.cloud.utils.db.GenericSearchBuilder; | ||||
| import com.cloud.utils.db.SearchBuilder; | ||||
| import com.cloud.utils.db.SearchCriteria; | ||||
| import com.cloud.utils.db.SearchCriteria.Func; | ||||
| import com.cloud.utils.db.SearchCriteria.Op; | ||||
| import com.cloud.utils.db.Transaction; | ||||
| import com.cloud.utils.db.UpdateBuilder; | ||||
| import com.cloud.utils.exception.CloudRuntimeException; | ||||
| 
 | ||||
| @Local(value=VolumeDao.class) | ||||
| @Component | ||||
| public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements VolumeDao { | ||||
|     private static final Logger s_logger = Logger.getLogger(VolumeDaoImpl.class); | ||||
|     protected final SearchBuilder<VolumeVO> DetachedAccountIdSearch; | ||||
|     protected final SearchBuilder<VolumeVO> TemplateZoneSearch; | ||||
|     protected final GenericSearchBuilder<VolumeVO, SumCount> TotalSizeByPoolSearch; | ||||
|     protected final GenericSearchBuilder<VolumeVO, Long> ActiveTemplateSearch; | ||||
|     protected final SearchBuilder<VolumeVO> InstanceStatesSearch; | ||||
|     protected final SearchBuilder<VolumeVO> AllFieldsSearch; | ||||
|     protected GenericSearchBuilder<VolumeVO, Long> CountByAccount; | ||||
|     ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class); | ||||
|      | ||||
|     protected static final String SELECT_VM_SQL = "SELECT DISTINCT instance_id from volumes v where v.host_id = ? and v.mirror_state = ?"; | ||||
|     protected static final String SELECT_HYPERTYPE_FROM_VOLUME = "SELECT c.hypervisor_type from volumes v, storage_pool s, cluster c where v.pool_id = s.id and s.cluster_id = c.id and v.id = ?"; | ||||
| 
 | ||||
|     private static final String ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT = "SELECT pool.id, SUM(IF(vol.state='Ready' AND vol.account_id = ?, 1, 0)) FROM `cloud`.`storage_pool` pool LEFT JOIN `cloud`.`volumes` vol ON pool.id = vol.pool_id WHERE pool.data_center_id = ? " + | ||||
|                                                                         " AND pool.pod_id = ? AND pool.cluster_id = ? " + | ||||
|                                                                         " GROUP BY pool.id ORDER BY 2 ASC "; | ||||
|      | ||||
|     @Override | ||||
|     public List<VolumeVO> findDetachedByAccount(long accountId) { | ||||
|     	SearchCriteria<VolumeVO> sc = DetachedAccountIdSearch.create(); | ||||
|     	sc.setParameters("accountId", accountId); | ||||
|     	sc.setParameters("destroyed", VolumeState.Destroy); | ||||
|     	return listBy(sc); | ||||
|     } | ||||
|      | ||||
|     @Override | ||||
|     public List<VolumeVO> findByAccount(long accountId) { | ||||
|         SearchCriteria<VolumeVO> sc = AllFieldsSearch.create(); | ||||
|         sc.setParameters("accountId", accountId); | ||||
|         sc.setParameters("state", VolumeState.Ready); | ||||
|         return listBy(sc); | ||||
|     } | ||||
|      | ||||
|     @Override | ||||
|     public List<VolumeVO> findByInstance(long id) { | ||||
|         SearchCriteria<VolumeVO> sc = AllFieldsSearch.create(); | ||||
|         sc.setParameters("instanceId", id); | ||||
| 	    return listBy(sc); | ||||
| 	} | ||||
|     | ||||
|     @Override | ||||
|     public List<VolumeVO> findByInstanceAndDeviceId(long instanceId, long deviceId){ | ||||
|     	SearchCriteria<VolumeVO> sc = AllFieldsSearch.create(); | ||||
|     	sc.setParameters("instanceId", instanceId); | ||||
|     	sc.setParameters("deviceId", deviceId); | ||||
|     	return listBy(sc); | ||||
|     } | ||||
|      | ||||
|     @Override | ||||
|     public List<VolumeVO> findByPoolId(long poolId) { | ||||
|         SearchCriteria<VolumeVO> sc = AllFieldsSearch.create(); | ||||
|         sc.setParameters("poolId", poolId); | ||||
|         sc.setParameters("notDestroyed", VolumeState.Destroy); | ||||
|         sc.setParameters("vType", VolumeType.ROOT.toString()); | ||||
| 	    return listBy(sc); | ||||
| 	} | ||||
|      | ||||
|     @Override  | ||||
|     public List<VolumeVO> findCreatedByInstance(long id) { | ||||
|         SearchCriteria<VolumeVO> sc = AllFieldsSearch.create(); | ||||
|         sc.setParameters("instanceId", id); | ||||
|         sc.setParameters("state", VolumeState.Ready); | ||||
|         return listBy(sc); | ||||
|     } | ||||
|      | ||||
|     @Override | ||||
|     public List<VolumeVO> findUsableVolumesForInstance(long instanceId) { | ||||
|         SearchCriteria<VolumeVO> sc = InstanceStatesSearch.create(); | ||||
|         sc.setParameters("instance", instanceId); | ||||
|         sc.setParameters("states", VolumeState.Creating, VolumeState.Ready, VolumeState.Allocated); | ||||
|          | ||||
|         return listBy(sc); | ||||
|     } | ||||
|      | ||||
| 	@Override | ||||
| 	public List<VolumeVO> findByInstanceAndType(long id, VolumeType vType) { | ||||
|         SearchCriteria<VolumeVO> sc = AllFieldsSearch.create(); | ||||
|         sc.setParameters("instanceId", id); | ||||
|         sc.setParameters("vType", vType.toString()); | ||||
| 	    return listBy(sc); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public List<VolumeVO> findByInstanceIdDestroyed(long vmId) { | ||||
| 		SearchCriteria<VolumeVO> sc = AllFieldsSearch.create(); | ||||
| 		sc.setParameters("instanceId", vmId); | ||||
| 		sc.setParameters("destroyed", VolumeState.Destroy); | ||||
| 		return listBy(sc); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public List<VolumeVO> findReadyRootVolumesByInstance(long instanceId) { | ||||
| 		SearchCriteria<VolumeVO> sc = AllFieldsSearch.create(); | ||||
| 		sc.setParameters("instanceId", instanceId); | ||||
| 		sc.setParameters("state", VolumeState.Ready); | ||||
| 		sc.setParameters("vType", VolumeType.ROOT);		 | ||||
| 		return listBy(sc); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public List<VolumeVO> findByAccountAndPod(long accountId, long podId) { | ||||
| 		SearchCriteria<VolumeVO> sc = AllFieldsSearch.create(); | ||||
|         sc.setParameters("accountId", accountId); | ||||
|         sc.setParameters("pod", podId); | ||||
|         sc.setParameters("state", VolumeState.Ready); | ||||
|          | ||||
|         return listIncludingRemovedBy(sc); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public List<VolumeVO> findByTemplateAndZone(long templateId, long zoneId) { | ||||
| 		SearchCriteria<VolumeVO> sc = TemplateZoneSearch.create(); | ||||
| 		sc.setParameters("template", templateId); | ||||
| 		sc.setParameters("zone", zoneId); | ||||
| 		 | ||||
| 		return listIncludingRemovedBy(sc); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public boolean isAnyVolumeActivelyUsingTemplateOnPool(long templateId, long poolId) { | ||||
| 	    SearchCriteria<Long> sc = ActiveTemplateSearch.create(); | ||||
| 	    sc.setParameters("template", templateId); | ||||
| 	    sc.setParameters("pool", poolId); | ||||
| 	     | ||||
| 	    List<Long> results = customSearchIncludingRemoved(sc, null); | ||||
| 	    assert results.size() > 0 : "How can this return a size of " + results.size(); | ||||
| 	     | ||||
| 	    return results.get(0) > 0; | ||||
| 	} | ||||
| 	 | ||||
|     @Override | ||||
|     public void deleteVolumesByInstance(long instanceId) { | ||||
|         SearchCriteria<VolumeVO> sc = AllFieldsSearch.create(); | ||||
|         sc.setParameters("instanceId", instanceId); | ||||
|         expunge(sc); | ||||
|     } | ||||
|      | ||||
|     @Override | ||||
|     public void attachVolume(long volumeId, long vmId, long deviceId) { | ||||
|     	VolumeVO volume = createForUpdate(volumeId); | ||||
|     	volume.setInstanceId(vmId); | ||||
|     	volume.setDeviceId(deviceId); | ||||
|     	volume.setUpdated(new Date()); | ||||
|     	volume.setAttached(new Date()); | ||||
|     	update(volumeId, volume); | ||||
|     } | ||||
|      | ||||
|     @Override | ||||
|     public void detachVolume(long volumeId) { | ||||
|     	VolumeVO volume = createForUpdate(volumeId); | ||||
|     	volume.setInstanceId(null); | ||||
|         volume.setDeviceId(null); | ||||
|     	volume.setUpdated(new Date()); | ||||
|     	volume.setAttached(null); | ||||
|     	update(volumeId, volume); | ||||
|     } | ||||
|      | ||||
|     @Override | ||||
|     @DB | ||||
| 	public HypervisorType getHypervisorType(long volumeId) { | ||||
| 		/*lookup from cluster of pool*/ | ||||
|     	 Transaction txn = Transaction.currentTxn(); | ||||
|          PreparedStatement pstmt = null; | ||||
| 
 | ||||
|          try { | ||||
|              String sql = SELECT_HYPERTYPE_FROM_VOLUME; | ||||
|              pstmt = txn.prepareAutoCloseStatement(sql); | ||||
|              pstmt.setLong(1, volumeId); | ||||
|              ResultSet rs = pstmt.executeQuery(); | ||||
|              if (rs.next()) { | ||||
|                 return HypervisorType.getType(rs.getString(1)); | ||||
|             } | ||||
|              return HypervisorType.None; | ||||
|          } catch (SQLException e) { | ||||
|              throw new CloudRuntimeException("DB Exception on: " + SELECT_HYPERTYPE_FROM_VOLUME, e); | ||||
|          } catch (Throwable e) { | ||||
|              throw new CloudRuntimeException("Caught: " + SELECT_HYPERTYPE_FROM_VOLUME, e); | ||||
|          } | ||||
| 	} | ||||
|      | ||||
|     @Override | ||||
|     public ImageFormat getImageFormat(Long volumeId) { | ||||
|         HypervisorType type = getHypervisorType(volumeId); | ||||
|         if ( type.equals(HypervisorType.KVM)) { | ||||
|             return ImageFormat.QCOW2; | ||||
|         } else if ( type.equals(HypervisorType.XenServer)) { | ||||
|             return ImageFormat.VHD; | ||||
|         } else if ( type.equals(HypervisorType.VMware)) { | ||||
|             return ImageFormat.OVA; | ||||
|         } else { | ||||
|             s_logger.warn("Do not support hypervisor " + type.toString()); | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
|      | ||||
| 	protected VolumeDaoImpl() { | ||||
| 	    AllFieldsSearch = createSearchBuilder(); | ||||
| 	    AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ); | ||||
|         AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getAccountId(), Op.EQ); | ||||
|         AllFieldsSearch.and("pod", AllFieldsSearch.entity().getPodId(), Op.EQ); | ||||
|         AllFieldsSearch.and("instanceId", AllFieldsSearch.entity().getInstanceId(), Op.EQ); | ||||
|         AllFieldsSearch.and("deviceId", AllFieldsSearch.entity().getDeviceId(), Op.EQ); | ||||
|         AllFieldsSearch.and("poolId", AllFieldsSearch.entity().getPoolId(), Op.EQ); | ||||
|         AllFieldsSearch.and("vType", AllFieldsSearch.entity().getVolumeType(), Op.EQ); | ||||
|         AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ); | ||||
|         AllFieldsSearch.and("destroyed", AllFieldsSearch.entity().getState(), Op.EQ); | ||||
|         AllFieldsSearch.and("notDestroyed", AllFieldsSearch.entity().getState(), Op.NEQ); | ||||
|         AllFieldsSearch.and("updatedCount", AllFieldsSearch.entity().getUpdatedCount(), Op.EQ); | ||||
|         AllFieldsSearch.done(); | ||||
|          | ||||
|         DetachedAccountIdSearch = createSearchBuilder(); | ||||
|         DetachedAccountIdSearch.and("accountId", DetachedAccountIdSearch.entity().getAccountId(), Op.EQ); | ||||
|         DetachedAccountIdSearch.and("destroyed", DetachedAccountIdSearch.entity().getState(), Op.NEQ); | ||||
|         DetachedAccountIdSearch.and("instanceId", DetachedAccountIdSearch.entity().getInstanceId(), Op.NULL); | ||||
|         DetachedAccountIdSearch.done(); | ||||
|          | ||||
|         TemplateZoneSearch = createSearchBuilder(); | ||||
|         TemplateZoneSearch.and("template", TemplateZoneSearch.entity().getTemplateId(), Op.EQ); | ||||
|         TemplateZoneSearch.and("zone", TemplateZoneSearch.entity().getDataCenterId(), Op.EQ); | ||||
|         TemplateZoneSearch.done(); | ||||
|          | ||||
|         TotalSizeByPoolSearch = createSearchBuilder(SumCount.class); | ||||
|         TotalSizeByPoolSearch.select("sum", Func.SUM, TotalSizeByPoolSearch.entity().getSize()); | ||||
|         TotalSizeByPoolSearch.select("count", Func.COUNT, (Object[])null); | ||||
|         TotalSizeByPoolSearch.and("poolId", TotalSizeByPoolSearch.entity().getPoolId(), Op.EQ); | ||||
|         TotalSizeByPoolSearch.and("removed", TotalSizeByPoolSearch.entity().getRemoved(), Op.NULL); | ||||
|         TotalSizeByPoolSearch.and("state", TotalSizeByPoolSearch.entity().getState(), Op.NEQ); | ||||
|         TotalSizeByPoolSearch.done(); | ||||
|        | ||||
|         ActiveTemplateSearch = createSearchBuilder(Long.class); | ||||
|         ActiveTemplateSearch.and("pool", ActiveTemplateSearch.entity().getPoolId(), Op.EQ); | ||||
|         ActiveTemplateSearch.and("template", ActiveTemplateSearch.entity().getTemplateId(), Op.EQ); | ||||
|         ActiveTemplateSearch.and("removed", ActiveTemplateSearch.entity().getRemoved(), Op.NULL); | ||||
|         ActiveTemplateSearch.select(null, Func.COUNT, null); | ||||
|         ActiveTemplateSearch.done(); | ||||
|          | ||||
|         InstanceStatesSearch = createSearchBuilder(); | ||||
|         InstanceStatesSearch.and("instance", InstanceStatesSearch.entity().getInstanceId(), Op.EQ); | ||||
|         InstanceStatesSearch.and("states", InstanceStatesSearch.entity().getState(), Op.IN); | ||||
|         InstanceStatesSearch.done(); | ||||
| 
 | ||||
|         CountByAccount = createSearchBuilder(Long.class); | ||||
|         CountByAccount.select(null, Func.COUNT, null); | ||||
|         CountByAccount.and("account", CountByAccount.entity().getAccountId(), SearchCriteria.Op.EQ); | ||||
|         CountByAccount.and("state", CountByAccount.entity().getState(), SearchCriteria.Op.NIN);         | ||||
|         CountByAccount.done(); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override @DB(txn=false) | ||||
| 	public Pair<Long, Long> getCountAndTotalByPool(long poolId) { | ||||
|         SearchCriteria<SumCount> sc = TotalSizeByPoolSearch.create(); | ||||
|         sc.setParameters("poolId", poolId); | ||||
|         List<SumCount> results = customSearch(sc, null); | ||||
|         SumCount sumCount = results.get(0); | ||||
|         return new Pair<Long, Long>(sumCount.count, sumCount.sum); | ||||
| 	} | ||||
| 
 | ||||
|     @Override | ||||
| 	public Long countAllocatedVolumesForAccount(long accountId) { | ||||
| 	  	SearchCriteria<Long> sc = CountByAccount.create(); | ||||
|         sc.setParameters("account", accountId); | ||||
| 		sc.setParameters("state", VolumeState.Destroy); | ||||
|         return customSearch(sc, null).get(0);		 | ||||
| 	} | ||||
| 
 | ||||
| 	public static class SumCount { | ||||
| 	    public long sum; | ||||
| 	    public long count; | ||||
| 	    public SumCount() { | ||||
| 	    } | ||||
| 	} | ||||
| 
 | ||||
|     @Override | ||||
|     public List<VolumeVO> listVolumesToBeDestroyed() { | ||||
|         SearchCriteria<VolumeVO> sc = AllFieldsSearch.create(); | ||||
|         sc.setParameters("state", VolumeState.Destroy); | ||||
|          | ||||
|         return listBy(sc); | ||||
|     } | ||||
| 
 | ||||
| 	@Override | ||||
| 	public boolean updateState(VolumeState currentState, | ||||
| 			VolumeEvent event, VolumeState nextState, VolumeVO vo, | ||||
| 			Object data) { | ||||
| 		 | ||||
| 	        Long oldUpdated = vo.getUpdatedCount(); | ||||
| 	        Date oldUpdatedTime = vo.getUpdated(); | ||||
| 	         | ||||
| 	        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create(); | ||||
| 	        sc.setParameters("id", vo.getId()); | ||||
| 	        sc.setParameters("state", currentState); | ||||
| 	        sc.setParameters("updatedCount", vo.getUpdatedCount()); | ||||
| 	         | ||||
| 	        vo.incrUpdatedCount(); | ||||
| 	         | ||||
| 	        UpdateBuilder builder = getUpdateBuilder(vo); | ||||
| 	        builder.set(vo, "state", nextState); | ||||
| 	        builder.set(vo, "updated", new Date()); | ||||
| 	         | ||||
| 	        int rows = update((VolumeVO)vo, sc); | ||||
| 	        if (rows == 0 && s_logger.isDebugEnabled()) { | ||||
| 	            VolumeVO dbVol = findByIdIncludingRemoved(vo.getId());  | ||||
| 	            if (dbVol != null) { | ||||
| 	            	StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString()); | ||||
| 	            	str.append(": DB Data={id=").append(dbVol.getId()).append("; state=").append(dbVol.getState()).append("; updatecount=").append(dbVol.getUpdatedCount()).append(";updatedTime=").append(dbVol.getUpdated()); | ||||
| 	            	str.append(": New Data={id=").append(vo.getId()).append("; state=").append(nextState).append("; event=").append(event).append("; updatecount=").append(vo.getUpdatedCount()).append("; updatedTime=").append(vo.getUpdated()); | ||||
| 	            	str.append(": stale Data={id=").append(vo.getId()).append("; state=").append(currentState).append("; event=").append(event).append("; updatecount=").append(oldUpdated).append("; updatedTime=").append(oldUpdatedTime); | ||||
| 	            } else { | ||||
| 	            	s_logger.debug("Unable to update volume: id=" + vo.getId() + ", as there is no such volume exists in the database anymore"); | ||||
| 	            } | ||||
| 	        } | ||||
| 	        return rows > 0; | ||||
| 	} | ||||
| 
 | ||||
|     @Override | ||||
|     public List<Long> listPoolIdsByVolumeCount(long dcId, Long podId, Long clusterId, long accountId) { | ||||
|         Transaction txn = Transaction.currentTxn(); | ||||
|         PreparedStatement pstmt = null; | ||||
|         List<Long> result = new ArrayList<Long>(); | ||||
|         try { | ||||
|             String sql = ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT; | ||||
|             pstmt = txn.prepareAutoCloseStatement(sql); | ||||
|             pstmt.setLong(1, accountId); | ||||
|             pstmt.setLong(2, dcId); | ||||
|             pstmt.setLong(3, podId); | ||||
|             pstmt.setLong(4, clusterId); | ||||
|              | ||||
|             ResultSet rs = pstmt.executeQuery(); | ||||
|             while (rs.next()) { | ||||
|                 result.add(rs.getLong(1)); | ||||
|             } | ||||
|             return result; | ||||
|         } catch (SQLException e) { | ||||
|             throw new CloudRuntimeException("DB Exception on: " + ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT, e); | ||||
|         } catch (Throwable e) { | ||||
|             throw new CloudRuntimeException("Caught: " + ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT, e); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     @Override @DB(txn=false) | ||||
|     public Pair<Long, Long> getNonDestroyedCountAndTotalByPool(long poolId) { | ||||
|         SearchCriteria<SumCount> sc = TotalSizeByPoolSearch.create(); | ||||
|         sc.setParameters("poolId", poolId); | ||||
|         sc.setParameters("state", VolumeState.Destroy); | ||||
|         List<SumCount> results = customSearch(sc, null); | ||||
|         SumCount sumCount = results.get(0); | ||||
|         return new Pair<Long, Long>(sumCount.count, sumCount.sum); | ||||
|     } | ||||
|      | ||||
|     @Override | ||||
|     @DB | ||||
|     public boolean remove(Long id) { | ||||
|         Transaction txn = Transaction.currentTxn(); | ||||
|         txn.start(); | ||||
|         VolumeVO entry = findById(id); | ||||
|         if (entry != null) { | ||||
|             _tagsDao.removeByIdAndType(id, TaggedResourceType.Volume); | ||||
|         } | ||||
|         boolean result = super.remove(id); | ||||
|         txn.commit(); | ||||
|         return result; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,434 @@ | ||||
| //Licensed to the Apache Software Foundation (ASF) under one | ||||
| //or more contributor license agreements.  See the NOTICE file | ||||
| //distributed with this work for additional information | ||||
| //regarding copyright ownership.  The ASF licenses this file | ||||
| //to you under the Apache License, Version 2.0 (the | ||||
| //"License"); you may not use this file except in compliance | ||||
| //with the License.  You may obtain a copy of the License at | ||||
| // | ||||
| //http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| //Unless required by applicable law or agreed to in writing, | ||||
| //software distributed under the License is distributed on an | ||||
| //"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||||
| //KIND, either express or implied.  See the License for the | ||||
| //specific language governing permissions and limitations | ||||
| //under the License. | ||||
| 
 | ||||
| package org.apache.cloudstack.storage.volume.db; | ||||
| import java.util.Date; | ||||
| import java.util.UUID; | ||||
| 
 | ||||
| import javax.persistence.Column; | ||||
| import javax.persistence.Entity; | ||||
| import javax.persistence.EnumType; | ||||
| import javax.persistence.Enumerated; | ||||
| import javax.persistence.GeneratedValue; | ||||
| import javax.persistence.GenerationType; | ||||
| import javax.persistence.Id; | ||||
| import javax.persistence.Table; | ||||
| import javax.persistence.TableGenerator; | ||||
| import javax.persistence.Temporal; | ||||
| import javax.persistence.TemporalType; | ||||
| 
 | ||||
| import org.apache.cloudstack.storage.volume.VolumeState; | ||||
| import org.apache.cloudstack.storage.volume.VolumeType; | ||||
| 
 | ||||
| import com.cloud.api.Identity; | ||||
| import com.cloud.storage.Storage.StoragePoolType; | ||||
| import com.cloud.utils.NumbersUtil; | ||||
| import com.cloud.utils.db.GenericDao; | ||||
| 
 | ||||
| @Entity | ||||
| @Table(name = "volumes") | ||||
| public class VolumeVO implements Identity { | ||||
|  @Id | ||||
|  @TableGenerator(name = "volume_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "volume_seq", allocationSize = 1) | ||||
|  @GeneratedValue(strategy = GenerationType.TABLE) | ||||
|  @Column(name = "id") | ||||
|  long id; | ||||
| 
 | ||||
|  @Column(name = "name") | ||||
|  String name; | ||||
| 
 | ||||
|  @Column(name = "pool_id") | ||||
|  Long poolId; | ||||
|   | ||||
|  @Column(name = "last_pool_id") | ||||
|  Long lastPoolId; | ||||
|   | ||||
|  @Column(name = "account_id") | ||||
|  long accountId; | ||||
| 
 | ||||
|  @Column(name = "domain_id") | ||||
|  long domainId; | ||||
| 
 | ||||
|  @Column(name = "instance_id") | ||||
|  Long instanceId = null; | ||||
| 
 | ||||
|  @Column(name = "device_id") | ||||
|  Long deviceId = null; | ||||
| 
 | ||||
|  @Column(name = "size") | ||||
|  long size; | ||||
| 
 | ||||
|  @Column(name = "folder") | ||||
|  String folder; | ||||
| 
 | ||||
|  @Column(name = "path") | ||||
|  String path; | ||||
| 
 | ||||
|  @Column(name = "pod_id") | ||||
|  Long podId; | ||||
| 
 | ||||
|  @Column(name = "created") | ||||
|  Date created; | ||||
| 
 | ||||
|  @Column(name = "attached") | ||||
|  @Temporal(value = TemporalType.TIMESTAMP) | ||||
|  Date attached; | ||||
| 
 | ||||
|  @Column(name = "data_center_id") | ||||
|  long dataCenterId; | ||||
| 
 | ||||
|  @Column(name = "host_ip") | ||||
|  String hostip; | ||||
| 
 | ||||
|  @Column(name = "disk_offering_id") | ||||
|  long diskOfferingId; | ||||
| 
 | ||||
|  @Column(name = "template_id") | ||||
|  Long templateId; | ||||
| 
 | ||||
|  @Column(name = "first_snapshot_backup_uuid") | ||||
|  String firstSnapshotBackupUuid; | ||||
| 
 | ||||
|  @Column(name = "volume_type") | ||||
|  @Enumerated(EnumType.STRING) | ||||
|  VolumeType volumeType = VolumeType.UNKNOWN; | ||||
| 
 | ||||
|  @Column(name = "pool_type") | ||||
|  @Enumerated(EnumType.STRING) | ||||
|  StoragePoolType poolType; | ||||
| 
 | ||||
|  @Column(name = GenericDao.REMOVED_COLUMN) | ||||
|  Date removed; | ||||
| 
 | ||||
|  @Column(name = "updated") | ||||
|  @Temporal(value = TemporalType.TIMESTAMP) | ||||
|  Date updated; | ||||
|   | ||||
|  @Column(name="update_count", updatable = true, nullable=false) | ||||
|  protected long updatedCount;	// This field should be updated everytime the state is updated.  There's no set method in the vo object because it is done with in the dao code. | ||||
| 
 | ||||
|  @Column(name = "recreatable") | ||||
|  boolean recreatable; | ||||
| 
 | ||||
|  @Column(name = "state") | ||||
|  @Enumerated(value = EnumType.STRING) | ||||
|  private VolumeState state; | ||||
| 
 | ||||
|  @Column(name = "chain_info") | ||||
|  String chainInfo; | ||||
| 
 | ||||
|  @Column(name = "uuid") | ||||
|  String uuid; | ||||
|   | ||||
|  @Column(name="reservation") | ||||
|  String reservationId; | ||||
|   | ||||
|  // Real Constructor | ||||
|  public VolumeVO(VolumeType type, String name, long dcId, long domainId, long accountId, long diskOfferingId, long size) { | ||||
|      this.volumeType = type; | ||||
|      this.name = name; | ||||
|      this.dataCenterId = dcId; | ||||
|      this.accountId = accountId; | ||||
|      this.domainId = domainId; | ||||
|      this.size = size; | ||||
|      this.diskOfferingId = diskOfferingId; | ||||
|      this.state = VolumeState.Allocated; | ||||
|      this.uuid = UUID.randomUUID().toString(); | ||||
|  } | ||||
| 
 | ||||
|  public VolumeVO(String name, long dcId, long podId, long accountId, long domainId, Long instanceId, String folder, String path, long size, VolumeType vType) { | ||||
|      this.name = name; | ||||
|      this.accountId = accountId; | ||||
|      this.domainId = domainId; | ||||
|      this.instanceId = instanceId; | ||||
|      this.folder = folder; | ||||
|      this.path = path; | ||||
|      this.size = size; | ||||
|      this.podId = podId; | ||||
|      this.dataCenterId = dcId; | ||||
|      this.volumeType = vType; | ||||
|      this.state = VolumeState.Allocated; | ||||
|      this.recreatable = false; | ||||
|      this.uuid = UUID.randomUUID().toString(); | ||||
|  } | ||||
| 
 | ||||
|  // Copy Constructor | ||||
|  public VolumeVO(VolumeVO that) { | ||||
|      this(that.getName(), that.getDataCenterId(), that.getPodId(), that.getAccountId(), that.getDomainId(), that.getInstanceId(), that.getFolder(), that.getPath(), that.getSize(), that | ||||
|              .getVolumeType()); | ||||
|      this.recreatable = that.isRecreatable(); | ||||
|      this.state = that.getState(); | ||||
|      this.size = that.getSize(); | ||||
|      this.diskOfferingId = that.getDiskOfferingId(); | ||||
|      this.poolId = that.getPoolId(); | ||||
|      this.attached = that.getAttached(); | ||||
|      this.chainInfo = that.getChainInfo(); | ||||
|      this.templateId = that.getTemplateId(); | ||||
|      this.deviceId = that.getDeviceId(); | ||||
|      this.uuid = UUID.randomUUID().toString(); | ||||
|  } | ||||
| 
 | ||||
|  public long getUpdatedCount() { | ||||
|  	return this.updatedCount; | ||||
|  } | ||||
|   | ||||
|  public void incrUpdatedCount() { | ||||
|  	this.updatedCount++; | ||||
|  } | ||||
|   | ||||
|  public void decrUpdatedCount() { | ||||
|  	this.updatedCount--; | ||||
|  } | ||||
|   | ||||
|  public boolean isRecreatable() { | ||||
|      return recreatable; | ||||
|  } | ||||
| 
 | ||||
|  public void setRecreatable(boolean recreatable) { | ||||
|      this.recreatable = recreatable; | ||||
|  } | ||||
| 
 | ||||
|  public long getId() { | ||||
|      return id; | ||||
|  } | ||||
| 
 | ||||
| 
 | ||||
|  public Long getPodId() { | ||||
|      return podId; | ||||
|  } | ||||
| 
 | ||||
| 
 | ||||
|  public long getDataCenterId() { | ||||
|      return dataCenterId; | ||||
|  } | ||||
| 
 | ||||
|  public String getName() { | ||||
|      return name; | ||||
|  } | ||||
| 
 | ||||
|  public long getAccountId() { | ||||
|      return accountId; | ||||
|  } | ||||
| 
 | ||||
|  public void setPoolType(StoragePoolType poolType) { | ||||
|      this.poolType = poolType; | ||||
|  } | ||||
| 
 | ||||
|  public StoragePoolType getPoolType() { | ||||
|      return poolType; | ||||
|  } | ||||
| 
 | ||||
|  public long getDomainId() { | ||||
|      return domainId; | ||||
|  } | ||||
| 
 | ||||
|  public String getFolder() { | ||||
|      return folder; | ||||
|  } | ||||
| 
 | ||||
|  public String getPath() { | ||||
|      return path; | ||||
|  } | ||||
| 
 | ||||
|  protected VolumeVO() { | ||||
|  } | ||||
| 
 | ||||
|  public long getSize() { | ||||
|      return size; | ||||
|  } | ||||
| 
 | ||||
|  public void setSize(long size) { | ||||
|      this.size = size; | ||||
|  } | ||||
| 
 | ||||
|  public Long getInstanceId() { | ||||
|      return instanceId; | ||||
|  } | ||||
| 
 | ||||
|  public Long getDeviceId() { | ||||
|      return deviceId; | ||||
|  } | ||||
| 
 | ||||
|  public void setDeviceId(Long deviceId) { | ||||
|      this.deviceId = deviceId; | ||||
|  } | ||||
| 
 | ||||
|  public VolumeType getVolumeType() { | ||||
|      return volumeType; | ||||
|  } | ||||
| 
 | ||||
|  public void setName(String name) { | ||||
|      this.name = name; | ||||
|  } | ||||
| 
 | ||||
|  public void setFolder(String folder) { | ||||
|      this.folder = folder; | ||||
|  } | ||||
| 
 | ||||
|  public void setAccountId(long accountId) { | ||||
|      this.accountId = accountId; | ||||
|  } | ||||
| 
 | ||||
|  public void setDomainId(long domainId) { | ||||
|      this.domainId = domainId; | ||||
|  } | ||||
| 
 | ||||
|  public void setInstanceId(Long instanceId) { | ||||
|      this.instanceId = instanceId; | ||||
|  } | ||||
| 
 | ||||
|  public void setPath(String path) { | ||||
|      this.path = path; | ||||
|  } | ||||
| 
 | ||||
|  public String getHostIp() { | ||||
|      return hostip; | ||||
|  } | ||||
| 
 | ||||
|  public void setHostIp(String hostip) { | ||||
|      this.hostip = hostip; | ||||
|  } | ||||
| 
 | ||||
|  public void setPodId(Long podId) { | ||||
|      this.podId = podId; | ||||
|  } | ||||
| 
 | ||||
|  public void setDataCenterId(long dataCenterId) { | ||||
|      this.dataCenterId = dataCenterId; | ||||
|  } | ||||
| 
 | ||||
|  public void setVolumeType(VolumeType type) { | ||||
|      volumeType = type; | ||||
|  } | ||||
| 
 | ||||
|  public Date getCreated() { | ||||
|      return created; | ||||
|  } | ||||
| 
 | ||||
|  public Date getRemoved() { | ||||
|      return removed; | ||||
|  } | ||||
| 
 | ||||
|  public void setRemoved(Date removed) { | ||||
|      this.removed = removed; | ||||
|  } | ||||
| 
 | ||||
|  public long getDiskOfferingId() { | ||||
|      return diskOfferingId; | ||||
|  } | ||||
| 
 | ||||
|  public void setDiskOfferingId(long diskOfferingId) { | ||||
|      this.diskOfferingId = diskOfferingId; | ||||
|  } | ||||
| 
 | ||||
|  public Long getTemplateId() { | ||||
|      return templateId; | ||||
|  } | ||||
| 
 | ||||
|  public void setTemplateId(Long templateId) { | ||||
|      this.templateId = templateId; | ||||
|  } | ||||
| 
 | ||||
|  public String getFirstSnapshotBackupUuid() { | ||||
|      return firstSnapshotBackupUuid; | ||||
|  } | ||||
| 
 | ||||
|  public void setFirstSnapshotBackupUuid(String firstSnapshotBackupUuid) { | ||||
|      this.firstSnapshotBackupUuid = firstSnapshotBackupUuid; | ||||
|  } | ||||
| 
 | ||||
|  public Long getPoolId() { | ||||
|      return poolId; | ||||
|  } | ||||
| 
 | ||||
|  public void setPoolId(Long poolId) { | ||||
|      this.poolId = poolId; | ||||
|  } | ||||
| 
 | ||||
|  public Date getUpdated() { | ||||
|      return updated; | ||||
|  } | ||||
| 
 | ||||
|  public VolumeState getState() { | ||||
|      return state; | ||||
|  } | ||||
| 
 | ||||
|  public void setUpdated(Date updated) { | ||||
|      this.updated = updated; | ||||
|  } | ||||
| 
 | ||||
|  @Override | ||||
|  public String toString() { | ||||
|      return new StringBuilder("Vol[").append(id).append("|vm=").append(instanceId).append("|").append(volumeType).append("]").toString(); | ||||
|  } | ||||
| 
 | ||||
|  public Date getAttached() { | ||||
|      return this.attached; | ||||
|  } | ||||
| 
 | ||||
|  public void setAttached(Date attached) { | ||||
|      this.attached = attached; | ||||
|  } | ||||
|   | ||||
|  public String getChainInfo() { | ||||
|      return this.chainInfo; | ||||
|  } | ||||
| 
 | ||||
|  public void setChainInfo(String chainInfo) { | ||||
|      this.chainInfo = chainInfo; | ||||
|  } | ||||
|   | ||||
|  public Long getLastPoolId() { | ||||
|  	return this.lastPoolId; | ||||
|  } | ||||
|   | ||||
|  public void setLastPoolId(Long poolId) { | ||||
|  	this.lastPoolId = poolId; | ||||
|  } | ||||
| 
 | ||||
|  @Override | ||||
|  public int hashCode() { | ||||
|      return NumbersUtil.hash(id); | ||||
|  } | ||||
| 
 | ||||
|  @Override | ||||
|  public boolean equals(Object obj) { | ||||
|      if (obj instanceof VolumeVO) { | ||||
|          return id == ((VolumeVO) obj).id; | ||||
|      } else { | ||||
|          return false; | ||||
|      } | ||||
|  } | ||||
|   | ||||
|  public String getReservationId() { | ||||
|  	return this.reservationId; | ||||
|  } | ||||
| 
 | ||||
|  public void setReservationId(String reserv) { | ||||
|  	this.reservationId = reserv; | ||||
|  } | ||||
|   | ||||
|  @Override | ||||
|  public String getUuid() { | ||||
|  	return this.uuid; | ||||
|  } | ||||
|   | ||||
|  public void setUuid(String uuid) { | ||||
|  	this.uuid = uuid; | ||||
|  } | ||||
| } | ||||
| 
 | ||||
| @ -0,0 +1,14 @@ | ||||
| package org.apache.cloudstack.storage.test; | ||||
| 
 | ||||
| import static java.lang.annotation.ElementType.METHOD; | ||||
| import static java.lang.annotation.ElementType.TYPE; | ||||
| import static java.lang.annotation.RetentionPolicy.RUNTIME; | ||||
| 
 | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.Target; | ||||
| 
 | ||||
| @Target({TYPE, METHOD}) | ||||
| @Retention(RUNTIME) | ||||
| public @interface AopTest { | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,20 @@ | ||||
| package org.apache.cloudstack.storage.test; | ||||
| 
 | ||||
| import org.aspectj.lang.ProceedingJoinPoint; | ||||
| 
 | ||||
| import com.cloud.utils.db.Transaction; | ||||
| 
 | ||||
| public class AopTestAdvice { | ||||
| 	public Object AopTestMethod(ProceedingJoinPoint call) throws Throwable { | ||||
| 		Transaction txn = Transaction.open(call.getSignature().getName()); | ||||
| 		System.out.println(call.getSignature().getName()); | ||||
| 		Object ret = null; | ||||
| 		try { | ||||
| 			 ret = call.proceed(); | ||||
| 		} finally { | ||||
| 			txn.close(); | ||||
| 		} | ||||
| 		System.out.println("end"); | ||||
| 		return ret; | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,42 @@ | ||||
| package org.apache.cloudstack.storage.test; | ||||
| 
 | ||||
| 
 | ||||
| import org.mockito.Mockito; | ||||
| import org.springframework.beans.factory.FactoryBean; | ||||
| 
 | ||||
| /** | ||||
|  * A {@link FactoryBean} for creating mocked beans based on Mockito so that they  | ||||
|  * can be {@link @Autowired} into Spring test configurations. | ||||
|  * | ||||
|  * @author Mattias Severson, Jayway | ||||
|  * | ||||
|  * @see FactoryBean | ||||
|  * @see org.mockito.Mockito | ||||
|  */ | ||||
| public class StorageFactoryBean<T> implements FactoryBean<T> { | ||||
| 
 | ||||
|     private Class<T> classToBeMocked; | ||||
| 
 | ||||
|     /** | ||||
|      * Creates a Mockito mock instance of the provided class. | ||||
|      * @param classToBeMocked The class to be mocked. | ||||
|      */ | ||||
|     public StorageFactoryBean(Class<T> classToBeMocked) { | ||||
|         this.classToBeMocked = classToBeMocked; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public T getObject() throws Exception { | ||||
|         return Mockito.mock(classToBeMocked); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public Class<?> getObjectType() { | ||||
|         return classToBeMocked; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean isSingleton() { | ||||
|         return true; | ||||
|     } | ||||
| } | ||||
| @ -1,11 +1,66 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <beans xmlns="http://www.springframework.org/schema/beans" | ||||
|   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" | ||||
|   xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" | ||||
|   xsi:schemaLocation="http://www.springframework.org/schema/beans | ||||
|                         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd | ||||
|                          http://www.springframework.org/schema/tx  | ||||
|        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd | ||||
|        http://www.springframework.org/schema/aop | ||||
|        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd | ||||
|                                  http://www.springframework.org/schema/context | ||||
|                                           http://www.springframework.org/schema/context/spring-context-3.0.xsd"> | ||||
|   <context:annotation-config />           | ||||
|   <context:annotation-config /> | ||||
|   <context:component-scan base-package="org.apache.cloudstack.storage" /> | ||||
|   <context:component-scan base-package="com.cloud.utils.db" /> | ||||
|   <context:component-scan base-package="com.cloud.storage.dao" /> | ||||
|   | ||||
|    <context:component-scan base-package=" com.cloud.upgrade.dao" /> | ||||
|   <tx:annotation-driven transaction-manager="transactionManager" /> | ||||
|   <bean id="aopTestBean" class="org.apache.cloudstack.storage.test.AopTestAdvice"/> | ||||
|   <aop:config proxy-target-class="true" > | ||||
|     <aop:aspect id="AopTestAdvice" ref="aopTestBean"> | ||||
|     <aop:pointcut id="aoptest" | ||||
|       expression="@annotation(com.cloud.utils.db.DB)" /> | ||||
|       <aop:around pointcut-ref="aoptest" method="AopTestMethod"/>  | ||||
|     </aop:aspect> | ||||
|      | ||||
| 
 | ||||
|   </aop:config> | ||||
|   <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> | ||||
|     <property name="entityManagerFactory" ref="entityManagerFactory" /> | ||||
|   </bean> | ||||
| 
 | ||||
|   <bean id="dataSource" | ||||
|     class="org.springframework.jdbc.datasource.DriverManagerDataSource"> | ||||
|     <property name="driverClassName" value="com.mysql.jdbc.Driver" /> | ||||
|     <property name="url" value="jdbc:mysql://localhost:3306/cloud" /> | ||||
|     <property name="username" value="root" /> | ||||
|     <property name="password" value="" /> | ||||
|   </bean> | ||||
| 
 | ||||
|   <bean id="openJpaVendorAdapter" | ||||
|     class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter"> | ||||
|     <property name="showSql" value="true" /> | ||||
|     <property name="databasePlatform" | ||||
|       value="org.apache.openjpa.jdbc.sql.MySQLDictionary" /> | ||||
|   </bean> | ||||
| 
 | ||||
|   <bean id="entityManagerFactory" | ||||
|     class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> | ||||
|     <property name="dataSource" ref="dataSource" /> | ||||
|     <property name="jpaVendorAdapter" ref="openJpaVendorAdapter" /> | ||||
|     <property name="packagesToScan" value="org.apache.cloudstack.storage" /> | ||||
|   </bean> | ||||
| 
 | ||||
|   <bean id="sharedEntityManager" | ||||
|     class="org.springframework.orm.jpa.support.SharedEntityManagerBean"> | ||||
|     <property name="entityManagerFactory" ref="entityManagerFactory" /> | ||||
|   </bean> | ||||
| 
 | ||||
|   <bean id="someDependencyMock" class="org.apache.cloudstack.storage.test.StorageFactoryBean"> | ||||
|     <constructor-arg name="classToBeMocked" | ||||
|       value="org.apache.cloudstack.storage.volume.VolumeMotionService" /> | ||||
|   </bean> | ||||
| 
 | ||||
| </beans> | ||||
|  | ||||
| @ -20,21 +20,61 @@ package org.apache.cloudstack.storage.test; | ||||
| 
 | ||||
| import static org.junit.Assert.*; | ||||
| 
 | ||||
| import java.awt.List; | ||||
| import java.util.LinkedList; | ||||
| 
 | ||||
| import javax.inject.Inject; | ||||
| 
 | ||||
| import org.apache.cloudstack.storage.volume.VolumeMotionService; | ||||
| import org.apache.cloudstack.storage.volume.VolumeService; | ||||
| import org.apache.cloudstack.storage.volume.db.VolumeDao; | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.mockito.Mock; | ||||
| import org.mockito.Mockito; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.test.context.ContextConfiguration; | ||||
| import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; | ||||
| import org.mockito.Mockito.*; | ||||
| 
 | ||||
| 
 | ||||
| import com.cloud.utils.db.DB; | ||||
| 
 | ||||
| 
 | ||||
| @RunWith(SpringJUnit4ClassRunner.class) | ||||
| @ContextConfiguration(locations="storageContext.xml") | ||||
| public class volumeServiceTest { | ||||
| 	@Autowired | ||||
| 	protected VolumeService volService; | ||||
| 	@Inject | ||||
| 	protected VolumeDao volumeDao; | ||||
| 	@Autowired | ||||
| 	protected VolumeMotionService vmotion; | ||||
|   | ||||
| 	@Before | ||||
| 	public void setUp() { | ||||
| 		Mockito.when(vmotion.copyVolume(null, null)).thenReturn(false); | ||||
| 	} | ||||
| 	 | ||||
| 	@Test | ||||
| 	@DB | ||||
| 	public void test() { | ||||
| 		assertTrue(volService.deleteVolume(1) == false); | ||||
| 		assertTrue(volService.deleteVolume(1) != false); | ||||
| 		assertNotNull(volumeDao); | ||||
| 		//VolumeVO vol = new VolumeVO(Volume.Type.DATADISK, "test", 1, 2, 2, 1, 1); | ||||
| 		//volumeDao.persist(vol); | ||||
| 		/* | ||||
| 		VolumeVO volume = new VolumeVO(); | ||||
| 		String name = "test"; | ||||
| 		long size = 100; | ||||
| 		volume.setName(name); | ||||
| 		volume.setSize(size); | ||||
| 		volumeDao.persist(volume); | ||||
| 		VolumeVO newVol = volumeDao.getVolumeByName(name); | ||||
| 		assertTrue(newVol.getSize() == volume.getSize()); | ||||
| 		*/ | ||||
| 
 | ||||
| 		fail("Not yet implemented"); | ||||
| 	} | ||||
| } | ||||
|  | ||||
							
								
								
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							| @ -79,7 +79,7 @@ | ||||
|     <cs.servlet.version>2.4</cs.servlet.version> | ||||
|     <cs.jstl.version>1.2</cs.jstl.version> | ||||
|     <cs.selenium.server.version>1.0-20081010.060147</cs.selenium.server.version> | ||||
|     <org.springframework.version>3.0.5.RELEASE</org.springframework.version> | ||||
|     <org.springframework.version>3.1.2.RELEASE</org.springframework.version> | ||||
|     <skipTests>true</skipTests> | ||||
| 
 | ||||
|   </properties> | ||||
|  | ||||
| @ -1500,6 +1500,7 @@ CREATE TABLE  `cloud`.`storage_pool` ( | ||||
|   `created` datetime COMMENT 'date the pool created', | ||||
|   `removed` datetime COMMENT 'date removed if not null', | ||||
|   `update_time` DATETIME, | ||||
|   `storage_provider` varchar(255) NOT NULL, | ||||
|   `status` varchar(32), | ||||
|   PRIMARY KEY  (`id`), | ||||
|   CONSTRAINT `fk_storage_pool__pod_id` FOREIGN KEY `fk_storage_pool__pod_id` (`pod_id`) REFERENCES `host_pod_ref` (`id`) ON DELETE CASCADE, | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user