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
|
||||||
Licensed to the Apache Software Foundation (ASF) under one
|
license agreements. See the NOTICE file distributed with this work for additional
|
||||||
or more contributor license agreements. See the NOTICE file
|
information regarding copyright ownership. The ASF licenses this file to
|
||||||
distributed with this work for additional information
|
you under the Apache License, Version 2.0 (the "License"); you may not use
|
||||||
regarding copyright ownership. The ASF licenses this file
|
this file except in compliance with the License. You may obtain a copy of
|
||||||
to you under the Apache License, Version 2.0 (the
|
the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
|
||||||
"License"); you may not use this file except in compliance
|
by applicable law or agreed to in writing, software distributed under the
|
||||||
with the License. You may obtain a copy of the License at
|
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
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
language governing permissions and limitations under the License. -->
|
||||||
|
|
||||||
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"
|
<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">
|
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
@ -48,6 +40,37 @@
|
|||||||
<artifactId>cloud-platform-api</artifactId>
|
<artifactId>cloud-platform-api</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</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>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
<defaultGoal>install</defaultGoal>
|
<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.TemplateProfile;
|
||||||
import org.apache.cloudstack.platform.subsystem.api.storage.VolumeProfile;
|
import org.apache.cloudstack.platform.subsystem.api.storage.VolumeProfile;
|
||||||
import org.apache.cloudstack.platform.subsystem.api.storage.VolumeStrategy;
|
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.image.ImageManager;
|
||||||
import org.apache.cloudstack.storage.manager.BackupStorageManager;
|
import org.apache.cloudstack.storage.manager.BackupStorageManager;
|
||||||
import org.apache.cloudstack.storage.manager.SecondaryStorageManager;
|
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.setInstanceId(oldVol.getInstanceId());
|
||||||
newVol.setRecreatable(oldVol.isRecreatable());
|
newVol.setRecreatable(oldVol.isRecreatable());
|
||||||
newVol.setReservationId(oldVol.getReservationId());
|
newVol.setReservationId(oldVol.getReservationId());
|
||||||
|
return null;
|
||||||
return _volumeDao.persist(newVol);
|
//return _volumeDao.persist(newVol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public VolumeVO processEvent(Volume vol, Volume.Event event) throws NoTransitionException {
|
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());
|
return _volumeDao.findById(vol.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,24 +18,34 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cloudstack.storage.volume;
|
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 org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.cloud.api.commands.CreateVolumeCmd;
|
import com.cloud.storage.SnapshotVO;
|
||||||
import com.cloud.storage.Volume;
|
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
|
@Component
|
||||||
public class VolumeServiceImpl implements VolumeService {
|
public class VolumeServiceImpl implements VolumeService {
|
||||||
|
@Autowired
|
||||||
|
VolumeDao _volumeDao;
|
||||||
@Override
|
@Override
|
||||||
public Volume createVolume(long volumeId) {
|
public Volume createVolume(long volumeId) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DB
|
||||||
@Override
|
@Override
|
||||||
public boolean deleteVolume(long volumeId) {
|
public boolean deleteVolume(long volumeId) {
|
||||||
// TODO Auto-generated method stub
|
VolumeVO vol = new VolumeVO(VolumeType.ROOT, "root", 1, 1,1 ,1,1);
|
||||||
return false;
|
_volumeDao.persist(vol);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -61,5 +71,4 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return false;
|
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"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
<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: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
|
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||||
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
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
|
||||||
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
|
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="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>
|
</beans>
|
||||||
|
|||||||
@ -20,21 +20,61 @@ package org.apache.cloudstack.storage.test;
|
|||||||
|
|
||||||
import static org.junit.Assert.*;
|
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.VolumeService;
|
||||||
|
import org.apache.cloudstack.storage.volume.db.VolumeDao;
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
|
||||||
|
import com.cloud.utils.db.DB;
|
||||||
|
|
||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@ContextConfiguration(locations="storageContext.xml")
|
@ContextConfiguration(locations="storageContext.xml")
|
||||||
public class volumeServiceTest {
|
public class volumeServiceTest {
|
||||||
@Autowired
|
@Autowired
|
||||||
protected VolumeService volService;
|
protected VolumeService volService;
|
||||||
|
@Inject
|
||||||
|
protected VolumeDao volumeDao;
|
||||||
|
@Autowired
|
||||||
|
protected VolumeMotionService vmotion;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
Mockito.when(vmotion.copyVolume(null, null)).thenReturn(false);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@DB
|
||||||
public void test() {
|
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");
|
fail("Not yet implemented");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@ -79,7 +79,7 @@
|
|||||||
<cs.servlet.version>2.4</cs.servlet.version>
|
<cs.servlet.version>2.4</cs.servlet.version>
|
||||||
<cs.jstl.version>1.2</cs.jstl.version>
|
<cs.jstl.version>1.2</cs.jstl.version>
|
||||||
<cs.selenium.server.version>1.0-20081010.060147</cs.selenium.server.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>
|
<skipTests>true</skipTests>
|
||||||
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|||||||
@ -1500,6 +1500,7 @@ CREATE TABLE `cloud`.`storage_pool` (
|
|||||||
`created` datetime COMMENT 'date the pool created',
|
`created` datetime COMMENT 'date the pool created',
|
||||||
`removed` datetime COMMENT 'date removed if not null',
|
`removed` datetime COMMENT 'date removed if not null',
|
||||||
`update_time` DATETIME,
|
`update_time` DATETIME,
|
||||||
|
`storage_provider` varchar(255) NOT NULL,
|
||||||
`status` varchar(32),
|
`status` varchar(32),
|
||||||
PRIMARY KEY (`id`),
|
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,
|
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