You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ed...@apache.org on 2012/10/25 19:27:31 UTC
git commit: @DB works on spring
Updated Branches:
refs/heads/javelin f92ce7263 -> ad3e98c1e
@DB works on spring
Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/ad3e98c1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/ad3e98c1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/ad3e98c1
Branch: refs/heads/javelin
Commit: ad3e98c1eba439a265b3aa56dc5982439ae54266
Parents: f92ce72
Author: Edison Su <ed...@citrix.com>
Authored: Thu Oct 25 10:26:49 2012 -0700
Committer: Edison Su <ed...@citrix.com>
Committed: Thu Oct 25 10:27:22 2012 -0700
----------------------------------------------------------------------
platform/storage/.project | 23 -
platform/storage/pom.xml | 59 ++-
.../storage/StorageOrchestratorImpl.java | 1 -
.../apache/cloudstack/storage/db/VolumeHostVO.java | 328 -----------
.../apache/cloudstack/storage/volume/Volume.java | 17 +
.../cloudstack/storage/volume/VolumeEvent.java | 34 ++
.../storage/volume/VolumeManagerImpl.java | 6 +-
.../storage/volume/VolumeServiceImpl.java | 19 +-
.../cloudstack/storage/volume/VolumeState.java | 71 +++
.../cloudstack/storage/volume/VolumeType.java | 27 +
.../cloudstack/storage/volume/db/VolumeDao.java | 79 +++
.../storage/volume/db/VolumeDaoImpl.java | 416 ++++++++++++++
.../cloudstack/storage/volume/db/VolumeVO.java | 434 +++++++++++++++
.../apache/cloudstack/storage/test/AopTest.java | 14 +
.../cloudstack/storage/test/AopTestAdvice.java | 20 +
.../storage/test/StorageFactoryBean.java | 42 ++
.../cloudstack/storage/test/storageContext.xml | 57 ++-
.../cloudstack/storage/test/volumeServiceTest.java | 42 ++-
pom.xml | 2 +-
setup/db/create-schema.sql | 1 +
20 files changed, 1311 insertions(+), 381 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ad3e98c1/platform/storage/.project
----------------------------------------------------------------------
diff --git a/platform/storage/.project b/platform/storage/.project
deleted file mode 100755
index ae8a72b..0000000
--- a/platform/storage/.project
+++ /dev/null
@@ -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>
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ad3e98c1/platform/storage/pom.xml
----------------------------------------------------------------------
diff --git a/platform/storage/pom.xml b/platform/storage/pom.xml
index f222a97..614fccb 100644
--- a/platform/storage/pom.xml
+++ b/platform/storage/pom.xml
@@ -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>
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ad3e98c1/platform/storage/src/org/apache/cloudstack/storage/StorageOrchestratorImpl.java
----------------------------------------------------------------------
diff --git a/platform/storage/src/org/apache/cloudstack/storage/StorageOrchestratorImpl.java b/platform/storage/src/org/apache/cloudstack/storage/StorageOrchestratorImpl.java
index 00e6eae..7c88cae 100644
--- a/platform/storage/src/org/apache/cloudstack/storage/StorageOrchestratorImpl.java
+++ b/platform/storage/src/org/apache/cloudstack/storage/StorageOrchestratorImpl.java
@@ -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;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ad3e98c1/platform/storage/src/org/apache/cloudstack/storage/db/VolumeHostVO.java
----------------------------------------------------------------------
diff --git a/platform/storage/src/org/apache/cloudstack/storage/db/VolumeHostVO.java b/platform/storage/src/org/apache/cloudstack/storage/db/VolumeHostVO.java
deleted file mode 100755
index bb41864..0000000
--- a/platform/storage/src/org/apache/cloudstack/storage/db/VolumeHostVO.java
+++ /dev/null
@@ -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;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ad3e98c1/platform/storage/src/org/apache/cloudstack/storage/volume/Volume.java
----------------------------------------------------------------------
diff --git a/platform/storage/src/org/apache/cloudstack/storage/volume/Volume.java b/platform/storage/src/org/apache/cloudstack/storage/volume/Volume.java
new file mode 100644
index 0000000..15ab86b
--- /dev/null
+++ b/platform/storage/src/org/apache/cloudstack/storage/volume/Volume.java
@@ -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;
+ }
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ad3e98c1/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeEvent.java
----------------------------------------------------------------------
diff --git a/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeEvent.java b/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeEvent.java
new file mode 100644
index 0000000..33d1261
--- /dev/null
+++ b/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeEvent.java
@@ -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;
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ad3e98c1/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeManagerImpl.java
----------------------------------------------------------------------
diff --git a/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeManagerImpl.java b/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeManagerImpl.java
index 6d9bde8..19e61a8 100644
--- a/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeManagerImpl.java
+++ b/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeManagerImpl.java
@@ -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());
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ad3e98c1/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
----------------------------------------------------------------------
diff --git a/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
index 4bf6f99..57e5a68 100644
--- a/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
+++ b/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
@@ -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;
}
-
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ad3e98c1/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeState.java
----------------------------------------------------------------------
diff --git a/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeState.java b/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeState.java
new file mode 100644
index 0000000..6b81f00
--- /dev/null
+++ b/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeState.java
@@ -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);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ad3e98c1/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeType.java
----------------------------------------------------------------------
diff --git a/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeType.java b/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeType.java
new file mode 100644
index 0000000..ca9bfed
--- /dev/null
+++ b/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeType.java
@@ -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
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ad3e98c1/platform/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDao.java
----------------------------------------------------------------------
diff --git a/platform/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDao.java b/platform/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDao.java
new file mode 100644
index 0000000..0ac26f9
--- /dev/null
+++ b/platform/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDao.java
@@ -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);
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ad3e98c1/platform/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDaoImpl.java
----------------------------------------------------------------------
diff --git a/platform/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDaoImpl.java b/platform/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDaoImpl.java
new file mode 100644
index 0000000..6557e8a
--- /dev/null
+++ b/platform/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDaoImpl.java
@@ -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;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ad3e98c1/platform/storage/src/org/apache/cloudstack/storage/volume/db/VolumeVO.java
----------------------------------------------------------------------
diff --git a/platform/storage/src/org/apache/cloudstack/storage/volume/db/VolumeVO.java b/platform/storage/src/org/apache/cloudstack/storage/volume/db/VolumeVO.java
new file mode 100644
index 0000000..7dca42e
--- /dev/null
+++ b/platform/storage/src/org/apache/cloudstack/storage/volume/db/VolumeVO.java
@@ -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;
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ad3e98c1/platform/storage/test/org/apache/cloudstack/storage/test/AopTest.java
----------------------------------------------------------------------
diff --git a/platform/storage/test/org/apache/cloudstack/storage/test/AopTest.java b/platform/storage/test/org/apache/cloudstack/storage/test/AopTest.java
new file mode 100644
index 0000000..0c2a2ad
--- /dev/null
+++ b/platform/storage/test/org/apache/cloudstack/storage/test/AopTest.java
@@ -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 {
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ad3e98c1/platform/storage/test/org/apache/cloudstack/storage/test/AopTestAdvice.java
----------------------------------------------------------------------
diff --git a/platform/storage/test/org/apache/cloudstack/storage/test/AopTestAdvice.java b/platform/storage/test/org/apache/cloudstack/storage/test/AopTestAdvice.java
new file mode 100644
index 0000000..9bdec74
--- /dev/null
+++ b/platform/storage/test/org/apache/cloudstack/storage/test/AopTestAdvice.java
@@ -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;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ad3e98c1/platform/storage/test/org/apache/cloudstack/storage/test/StorageFactoryBean.java
----------------------------------------------------------------------
diff --git a/platform/storage/test/org/apache/cloudstack/storage/test/StorageFactoryBean.java b/platform/storage/test/org/apache/cloudstack/storage/test/StorageFactoryBean.java
new file mode 100644
index 0000000..68952b1
--- /dev/null
+++ b/platform/storage/test/org/apache/cloudstack/storage/test/StorageFactoryBean.java
@@ -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;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ad3e98c1/platform/storage/test/org/apache/cloudstack/storage/test/storageContext.xml
----------------------------------------------------------------------
diff --git a/platform/storage/test/org/apache/cloudstack/storage/test/storageContext.xml b/platform/storage/test/org/apache/cloudstack/storage/test/storageContext.xml
index 35d18a6..508848a 100644
--- a/platform/storage/test/org/apache/cloudstack/storage/test/storageContext.xml
+++ b/platform/storage/test/org/apache/cloudstack/storage/test/storageContext.xml
@@ -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>
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ad3e98c1/platform/storage/test/org/apache/cloudstack/storage/test/volumeServiceTest.java
----------------------------------------------------------------------
diff --git a/platform/storage/test/org/apache/cloudstack/storage/test/volumeServiceTest.java b/platform/storage/test/org/apache/cloudstack/storage/test/volumeServiceTest.java
index 39df0c5..8734d53 100644
--- a/platform/storage/test/org/apache/cloudstack/storage/test/volumeServiceTest.java
+++ b/platform/storage/test/org/apache/cloudstack/storage/test/volumeServiceTest.java
@@ -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");
}
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ad3e98c1/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index ff4b9ee..9a633a1 100644
--- a/pom.xml
+++ b/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>
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ad3e98c1/setup/db/create-schema.sql
----------------------------------------------------------------------
diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql
index aa8aeb8..aa5867f 100755
--- a/setup/db/create-schema.sql
+++ b/setup/db/create-schema.sql
@@ -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,