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 2013/10/26 03:24:56 UTC
[2/5] git commit: updated refs/heads/master to 465c9ec
move a lot of code into vmsnapshot strategy
fix compile
fix compile
add vm_snapshot_details table in db
add vmsnapshot test cases
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/a6ce66e5
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/a6ce66e5
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/a6ce66e5
Branch: refs/heads/master
Commit: a6ce66e55a65eb0fbae9ead92de6ceac7a87c531
Parents: 5c5326f
Author: Edison Su <su...@gmail.com>
Authored: Thu Oct 10 18:00:21 2013 -0700
Committer: Edison Su <su...@gmail.com>
Committed: Fri Oct 25 15:09:04 2013 -0700
----------------------------------------------------------------------
client/tomcatconf/applicationContext.xml.in | 12 +-
.../cloud/agent/api/CreateVMSnapshotAnswer.java | 12 +-
.../agent/api/CreateVMSnapshotCommand.java | 4 +-
.../cloud/agent/api/DeleteVMSnapshotAnswer.java | 12 +-
.../agent/api/DeleteVMSnapshotCommand.java | 3 +-
.../agent/api/RevertToVMSnapshotAnswer.java | 14 +-
.../agent/api/RevertToVMSnapshotCommand.java | 3 +-
.../cloud/agent/api/VMSnapshotBaseCommand.java | 10 +-
.../cloudstack/storage/to/VolumeObjectTO.java | 12 +
.../api/storage/VMSnapshotStrategy.java | 28 ++
.../cloud/vm/snapshot/VMSnapshotDetailsVO.java | 87 ++++
.../src/com/cloud/vm/snapshot/VMSnapshotVO.java | 2 +-
.../vm/snapshot/dao/VMSnapshotDetailsDao.java | 28 ++
.../snapshot/dao/VMSnapshotDetailsDaoImpl.java | 52 ++
.../motion/AncientDataMotionStrategy.java | 26 -
.../vm/snapshot/dao/VmSnapshotDaoTest.java | 46 ++
.../storage/test/ChildTestConfiguration.java | 47 +-
.../cloudstack/storage/test/SnapshotTest.java | 100 ++--
.../test/resources/storageContext.xml | 2 +
engine/storage/snapshot/pom.xml | 32 ++
.../storage/snapshot/SnapshotServiceImpl.java | 44 +-
.../snapshot/XenserverSnapshotStrategy.java | 27 +-
.../vmsnapshot/DefaultVMSnapshotStrategy.java | 369 ++++++++++++++
.../storage/vmsnapshot/VMSnapshotHelper.java | 38 ++
.../vmsnapshot/VMSnapshotHelperImpl.java | 148 ++++++
.../test/src/VMSnapshotStrategyTest.java | 256 ++++++++++
.../storage/volume/VolumeServiceImpl.java | 85 ++--
.../manager/VmwareStorageManagerImpl.java | 87 ++--
.../xen/resource/CitrixResourceBase.java | 28 +-
.../storage/snapshot/SnapshotManagerImpl.java | 97 ----
.../vm/snapshot/VMSnapshotManagerImpl.java | 484 +++----------------
.../vm/snapshot/VMSnapshotManagerTest.java | 7 -
setup/db/db/schema-421to430.sql | 9 +
33 files changed, 1398 insertions(+), 813 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/client/tomcatconf/applicationContext.xml.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in
index 2a3520b..13ab71e 100644
--- a/client/tomcatconf/applicationContext.xml.in
+++ b/client/tomcatconf/applicationContext.xml.in
@@ -365,6 +365,7 @@
<bean id="vMReservationDaoImpl" class="org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMReservationDaoImpl" />
<bean id="vMRootDiskTagDaoImpl" class="org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMRootDiskTagDaoImpl" />
<bean id="vMSnapshotDaoImpl" class="com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl" />
+ <bean id="vMSnapshotDetailsDaoImpl" class="com.cloud.vm.snapshot.dao.VMSnapshotDetailsDaoImpl" />
<bean id="vMTemplateDetailsDaoImpl" class="com.cloud.storage.dao.VMTemplateDetailsDaoImpl" />
<bean id="vMTemplateHostDaoImpl" class="com.cloud.storage.dao.VMTemplateHostDaoImpl" />
<bean id="vMTemplatePoolDaoImpl" class="com.cloud.storage.dao.VMTemplatePoolDaoImpl" />
@@ -882,8 +883,17 @@
<bean id="ApplicationLoadBalancerService" class="org.apache.cloudstack.network.lb.ApplicationLoadBalancerManagerImpl" />
<bean id="InternalLoadBalancerVMManager" class="org.apache.cloudstack.network.lb.InternalLoadBalancerVMManagerImpl" />
- <bean id="vMSnapshotManagerImpl" class="com.cloud.vm.snapshot.VMSnapshotManagerImpl" />
+ <!--VM snapshot Strategies-->
+ <bean id='vmSnapshotHelper' class="org.apache.cloudstack.storage.vmsnapshot.VMSnapshotHelperImpl" />
+ <bean id='defaultVMSnapshotStrategy' class="org.apache.cloudstack.storage.vmsnapshot.DefaultVMSnapshotStrategy"/>
+ <bean id="vMSnapshotManagerImpl" class="com.cloud.vm.snapshot.VMSnapshotManagerImpl">
+ <property name="vmSnapshotStrategies">
+ <list>
+ <ref local="defaultVMSnapshotStrategy"/>
+ </list>
+ </property>
+ </bean>
<!--=======================================================================================================-->
<!-- -->
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/core/src/com/cloud/agent/api/CreateVMSnapshotAnswer.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/CreateVMSnapshotAnswer.java b/core/src/com/cloud/agent/api/CreateVMSnapshotAnswer.java
index f9fb164..8b8e69e 100644
--- a/core/src/com/cloud/agent/api/CreateVMSnapshotAnswer.java
+++ b/core/src/com/cloud/agent/api/CreateVMSnapshotAnswer.java
@@ -17,21 +17,21 @@
package com.cloud.agent.api;
-import java.util.List;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
-import com.cloud.agent.api.to.VolumeTO;
+import java.util.List;
public class CreateVMSnapshotAnswer extends Answer {
- private List<VolumeTO> volumeTOs;
+ private List<VolumeObjectTO> volumeTOs;
private VMSnapshotTO vmSnapshotTo;
- public List<VolumeTO> getVolumeTOs() {
+ public List<VolumeObjectTO> getVolumeTOs() {
return volumeTOs;
}
- public void setVolumeTOs(List<VolumeTO> volumeTOs) {
+ public void setVolumeTOs(List<VolumeObjectTO> volumeTOs) {
this.volumeTOs = volumeTOs;
}
@@ -53,7 +53,7 @@ public class CreateVMSnapshotAnswer extends Answer {
}
public CreateVMSnapshotAnswer(CreateVMSnapshotCommand cmd,
- VMSnapshotTO vmSnapshotTo, List<VolumeTO> volumeTOs) {
+ VMSnapshotTO vmSnapshotTo, List<VolumeObjectTO> volumeTOs) {
super(cmd, true, "");
this.vmSnapshotTo = vmSnapshotTo;
this.volumeTOs = volumeTOs;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/core/src/com/cloud/agent/api/CreateVMSnapshotCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/CreateVMSnapshotCommand.java b/core/src/com/cloud/agent/api/CreateVMSnapshotCommand.java
index 478987d..bfbc21d 100644
--- a/core/src/com/cloud/agent/api/CreateVMSnapshotCommand.java
+++ b/core/src/com/cloud/agent/api/CreateVMSnapshotCommand.java
@@ -18,12 +18,14 @@ package com.cloud.agent.api;
import java.util.List;
+import com.cloud.agent.api.to.DataTO;
import com.cloud.agent.api.to.VolumeTO;
import com.cloud.vm.VirtualMachine;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
public class CreateVMSnapshotCommand extends VMSnapshotBaseCommand {
- public CreateVMSnapshotCommand(String vmName, VMSnapshotTO snapshot, List<VolumeTO> volumeTOs, String guestOSType, VirtualMachine.State vmState) {
+ public CreateVMSnapshotCommand(String vmName, VMSnapshotTO snapshot, List<VolumeObjectTO> volumeTOs, String guestOSType, VirtualMachine.State vmState) {
super(vmName, snapshot, volumeTOs, guestOSType);
this.vmState = vmState;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/core/src/com/cloud/agent/api/DeleteVMSnapshotAnswer.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/DeleteVMSnapshotAnswer.java b/core/src/com/cloud/agent/api/DeleteVMSnapshotAnswer.java
index 8f4ecad..d6ae95c 100644
--- a/core/src/com/cloud/agent/api/DeleteVMSnapshotAnswer.java
+++ b/core/src/com/cloud/agent/api/DeleteVMSnapshotAnswer.java
@@ -16,12 +16,12 @@
// under the License.
package com.cloud.agent.api;
-import java.util.List;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
-import com.cloud.agent.api.to.VolumeTO;
+import java.util.List;
public class DeleteVMSnapshotAnswer extends Answer {
- private List<VolumeTO> volumeTOs;
+ private List<VolumeObjectTO> volumeTOs;
public DeleteVMSnapshotAnswer() {
}
@@ -32,16 +32,16 @@ public class DeleteVMSnapshotAnswer extends Answer {
}
public DeleteVMSnapshotAnswer(DeleteVMSnapshotCommand cmd,
- List<VolumeTO> volumeTOs) {
+ List<VolumeObjectTO> volumeTOs) {
super(cmd, true, "");
this.volumeTOs = volumeTOs;
}
- public List<VolumeTO> getVolumeTOs() {
+ public List<VolumeObjectTO> getVolumeTOs() {
return volumeTOs;
}
- public void setVolumeTOs(List<VolumeTO> volumeTOs) {
+ public void setVolumeTOs(List<VolumeObjectTO> volumeTOs) {
this.volumeTOs = volumeTOs;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/core/src/com/cloud/agent/api/DeleteVMSnapshotCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/DeleteVMSnapshotCommand.java b/core/src/com/cloud/agent/api/DeleteVMSnapshotCommand.java
index c213448..1c64a2b 100644
--- a/core/src/com/cloud/agent/api/DeleteVMSnapshotCommand.java
+++ b/core/src/com/cloud/agent/api/DeleteVMSnapshotCommand.java
@@ -19,10 +19,11 @@ package com.cloud.agent.api;
import java.util.List;
import com.cloud.agent.api.to.VolumeTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
public class DeleteVMSnapshotCommand extends VMSnapshotBaseCommand {
- public DeleteVMSnapshotCommand(String vmName, VMSnapshotTO snapshot, List<VolumeTO> volumeTOs, String guestOSType) {
+ public DeleteVMSnapshotCommand(String vmName, VMSnapshotTO snapshot, List<VolumeObjectTO> volumeTOs, String guestOSType) {
super( vmName, snapshot, volumeTOs, guestOSType);
}
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/core/src/com/cloud/agent/api/RevertToVMSnapshotAnswer.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/RevertToVMSnapshotAnswer.java b/core/src/com/cloud/agent/api/RevertToVMSnapshotAnswer.java
index 848ffc0..6170864 100644
--- a/core/src/com/cloud/agent/api/RevertToVMSnapshotAnswer.java
+++ b/core/src/com/cloud/agent/api/RevertToVMSnapshotAnswer.java
@@ -17,14 +17,14 @@
package com.cloud.agent.api;
-import java.util.List;
-
-import com.cloud.agent.api.to.VolumeTO;
import com.cloud.vm.VirtualMachine;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+
+import java.util.List;
public class RevertToVMSnapshotAnswer extends Answer {
- private List<VolumeTO> volumeTOs;
+ private List<VolumeObjectTO> volumeTOs;
private VirtualMachine.State vmState;
public RevertToVMSnapshotAnswer(RevertToVMSnapshotCommand cmd, boolean result,
@@ -37,7 +37,7 @@ public class RevertToVMSnapshotAnswer extends Answer {
}
public RevertToVMSnapshotAnswer(RevertToVMSnapshotCommand cmd,
- List<VolumeTO> volumeTOs,
+ List<VolumeObjectTO> volumeTOs,
VirtualMachine.State vmState) {
super(cmd, true, "");
this.volumeTOs = volumeTOs;
@@ -48,11 +48,11 @@ public class RevertToVMSnapshotAnswer extends Answer {
return vmState;
}
- public List<VolumeTO> getVolumeTOs() {
+ public List<VolumeObjectTO> getVolumeTOs() {
return volumeTOs;
}
- public void setVolumeTOs(List<VolumeTO> volumeTOs) {
+ public void setVolumeTOs(List<VolumeObjectTO> volumeTOs) {
this.volumeTOs = volumeTOs;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/core/src/com/cloud/agent/api/RevertToVMSnapshotCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/RevertToVMSnapshotCommand.java b/core/src/com/cloud/agent/api/RevertToVMSnapshotCommand.java
index 429a186..1e5fd6c 100644
--- a/core/src/com/cloud/agent/api/RevertToVMSnapshotCommand.java
+++ b/core/src/com/cloud/agent/api/RevertToVMSnapshotCommand.java
@@ -19,10 +19,11 @@ package com.cloud.agent.api;
import java.util.List;
import com.cloud.agent.api.to.VolumeTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
public class RevertToVMSnapshotCommand extends VMSnapshotBaseCommand {
- public RevertToVMSnapshotCommand(String vmName, VMSnapshotTO snapshot, List<VolumeTO> volumeTOs, String guestOSType) {
+ public RevertToVMSnapshotCommand(String vmName, VMSnapshotTO snapshot, List<VolumeObjectTO> volumeTOs, String guestOSType) {
super(vmName, snapshot, volumeTOs, guestOSType);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java b/core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java
index 2120f2f..b2c5241 100644
--- a/core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java
+++ b/core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java
@@ -19,27 +19,29 @@ package com.cloud.agent.api;
import java.util.List;
+import com.cloud.agent.api.to.DataTO;
import com.cloud.agent.api.to.VolumeTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
public class VMSnapshotBaseCommand extends Command{
- protected List<VolumeTO> volumeTOs;
+ protected List<VolumeObjectTO> volumeTOs;
protected VMSnapshotTO target;
protected String vmName;
protected String guestOSType;
- public VMSnapshotBaseCommand(String vmName, VMSnapshotTO snapshot, List<VolumeTO> volumeTOs, String guestOSType) {
+ public VMSnapshotBaseCommand(String vmName, VMSnapshotTO snapshot, List<VolumeObjectTO> volumeTOs, String guestOSType) {
this.vmName = vmName;
this.target = snapshot;
this.volumeTOs = volumeTOs;
this.guestOSType = guestOSType;
}
- public List<VolumeTO> getVolumeTOs() {
+ public List<VolumeObjectTO> getVolumeTOs() {
return volumeTOs;
}
- public void setVolumeTOs(List<VolumeTO> volumeTOs) {
+ public void setVolumeTOs(List<VolumeObjectTO> volumeTOs) {
this.volumeTOs = volumeTOs;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/core/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java
----------------------------------------------------------------------
diff --git a/core/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/core/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java
index 5685fad..46659a3 100644
--- a/core/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java
+++ b/core/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java
@@ -38,6 +38,8 @@ public class VolumeObjectTO implements DataTO {
private String chainInfo;
private Storage.ImageFormat format;
private long id;
+
+ private Long deviceId;
private Long bytesReadRate;
private Long bytesWriteRate;
private Long iopsReadRate;
@@ -70,6 +72,7 @@ public class VolumeObjectTO implements DataTO {
this.iopsReadRate = volume.getIopsReadRate();
this.iopsWriteRate = volume.getIopsWriteRate();
this.hypervisorType = volume.getHypervisorType();
+ setDeviceId(volume.getDeviceId());
}
public String getUuid() {
@@ -220,4 +223,13 @@ public class VolumeObjectTO implements DataTO {
return iopsWriteRate;
}
+ public Long getDeviceId() {
+ return deviceId;
+ }
+
+ public void setDeviceId(Long deviceId) {
+ this.deviceId = deviceId;
+ }
+
+
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VMSnapshotStrategy.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VMSnapshotStrategy.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VMSnapshotStrategy.java
new file mode 100644
index 0000000..8dd6eca
--- /dev/null
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VMSnapshotStrategy.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.engine.subsystem.api.storage;
+
+import com.cloud.vm.snapshot.VMSnapshot;
+
+public interface VMSnapshotStrategy {
+ VMSnapshot takeVMSnapshot(VMSnapshot vmSnapshot);
+ boolean deleteVMSnapshot(VMSnapshot vmSnapshot);
+ boolean revertVMSnapshot(VMSnapshot vmSnapshot);
+ boolean canHandle(VMSnapshot vmSnapshot);
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/engine/schema/src/com/cloud/vm/snapshot/VMSnapshotDetailsVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/vm/snapshot/VMSnapshotDetailsVO.java b/engine/schema/src/com/cloud/vm/snapshot/VMSnapshotDetailsVO.java
new file mode 100644
index 0000000..934dd92
--- /dev/null
+++ b/engine/schema/src/com/cloud/vm/snapshot/VMSnapshotDetailsVO.java
@@ -0,0 +1,87 @@
+/*
+ * 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 com.cloud.vm.snapshot;
+
+import org.apache.cloudstack.api.InternalIdentity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.TableGenerator;
+
+@Entity
+@Table(name = "vm_snapshot_details")
+public class VMSnapshotDetailsVO implements InternalIdentity {
+ @Id
+ @TableGenerator(name = "vm_snapshot_details_seq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "vm_snapshot_details_seq", allocationSize = 1)
+ @GeneratedValue(strategy = GenerationType.TABLE)
+ @Column(name = "id")
+ private long id;
+
+ @Column(name = "vm_snapshot_id")
+ Long vmSnapshotId;
+
+ @Column(name = "name")
+ String name;
+
+ @Column(name = "value")
+ String value;
+
+ public VMSnapshotDetailsVO() {
+
+ }
+
+ public VMSnapshotDetailsVO(Long vmSnapshotId, String name, String value) {
+ this.vmSnapshotId = vmSnapshotId;
+ this.name = name;
+ this.value = value;
+ }
+
+ public Long getVmSnapshotId() {
+ return this.vmSnapshotId;
+ }
+
+ public void setVmSnapshotId(Long vmSnapshotId) {
+ this.vmSnapshotId = vmSnapshotId;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getValue() {
+ return this.value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public long getId() {
+ return id;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/engine/schema/src/com/cloud/vm/snapshot/VMSnapshotVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/vm/snapshot/VMSnapshotVO.java b/engine/schema/src/com/cloud/vm/snapshot/VMSnapshotVO.java
index 03d4945..477148c 100644
--- a/engine/schema/src/com/cloud/vm/snapshot/VMSnapshotVO.java
+++ b/engine/schema/src/com/cloud/vm/snapshot/VMSnapshotVO.java
@@ -41,7 +41,7 @@ public class VMSnapshotVO implements VMSnapshot {
@TableGenerator(name = "vm_snapshots_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "vm_snapshots_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name = "id")
- long id;
+ Long id;
@Column(name = "uuid")
String uuid = UUID.randomUUID().toString();
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/engine/schema/src/com/cloud/vm/snapshot/dao/VMSnapshotDetailsDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/vm/snapshot/dao/VMSnapshotDetailsDao.java b/engine/schema/src/com/cloud/vm/snapshot/dao/VMSnapshotDetailsDao.java
new file mode 100644
index 0000000..e84178c
--- /dev/null
+++ b/engine/schema/src/com/cloud/vm/snapshot/dao/VMSnapshotDetailsDao.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.cloud.vm.snapshot.dao;
+
+import com.cloud.utils.db.GenericDao;
+import com.cloud.vm.snapshot.VMSnapshotDetailsVO;
+
+import java.util.Map;
+
+public interface VMSnapshotDetailsDao extends GenericDao<VMSnapshotDetailsVO, Long> {
+ Map<String, String> getDetails(Long vmSnapshotId);
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/engine/schema/src/com/cloud/vm/snapshot/dao/VMSnapshotDetailsDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/vm/snapshot/dao/VMSnapshotDetailsDaoImpl.java b/engine/schema/src/com/cloud/vm/snapshot/dao/VMSnapshotDetailsDaoImpl.java
new file mode 100644
index 0000000..b528b39
--- /dev/null
+++ b/engine/schema/src/com/cloud/vm/snapshot/dao/VMSnapshotDetailsDaoImpl.java
@@ -0,0 +1,52 @@
+/*
+ * 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 com.cloud.vm.snapshot.dao;
+
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.vm.snapshot.VMSnapshotDetailsVO;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class VMSnapshotDetailsDaoImpl extends GenericDaoBase<VMSnapshotDetailsVO, Long> implements VMSnapshotDetailsDao {
+ protected final SearchBuilder<VMSnapshotDetailsVO> searchDetails;
+
+ protected VMSnapshotDetailsDaoImpl() {
+ super();
+ searchDetails = createSearchBuilder();
+ searchDetails.and("vmsnapshotId", searchDetails.entity().getVmSnapshotId(), SearchCriteria.Op.EQ);
+ searchDetails.done();
+ }
+ @Override
+ public Map<String, String> getDetails(Long vmSnapshotId) {
+ SearchCriteria<VMSnapshotDetailsVO> sc = searchDetails.create();
+ sc.setParameters("vmsnapshotId", vmSnapshotId);
+
+ List<VMSnapshotDetailsVO> details = listBy(sc);
+ Map<String, String> detailsMap = new HashMap<String, String>();
+ for (VMSnapshotDetailsVO detail : details) {
+ detailsMap.put(detail.getName(), detail.getValue());
+ }
+
+ return detailsMap;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
----------------------------------------------------------------------
diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
index 5f5f01e..7b5b7fc 100644
--- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
+++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
@@ -87,38 +87,12 @@ AncientDataMotionStrategy implements DataMotionStrategy {
@Inject
EndPointSelector selector;
@Inject
- TemplateManager templateMgr;
- @Inject
- VolumeDataStoreDao volumeStoreDao;
- @Inject
- HostDao hostDao;
- @Inject
ConfigurationDao configDao;
@Inject
- StorageManager storageMgr;
- @Inject
VolumeDao volDao;
@Inject
- VMTemplateDao templateDao;
- @Inject
- SnapshotManager snapshotMgr;
- @Inject
- SnapshotDao snapshotDao;
- @Inject
- SnapshotDataStoreDao _snapshotStoreDao;
- @Inject
- PrimaryDataStoreDao primaryDataStoreDao;
- @Inject
DataStoreManager dataStoreMgr;
@Inject
- TemplateDataStoreDao templateStoreDao;
- @Inject
- DiskOfferingDao diskOfferingDao;
- @Inject
- VMTemplatePoolDao templatePoolDao;
- @Inject
- VolumeOrchestrationService volumeMgr;
- @Inject
StorageCacheManager cacheMgr;
@Inject
ManagementService _mgmtServer;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/engine/storage/integration-test/test/com/cloud/vm/snapshot/dao/VmSnapshotDaoTest.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/com/cloud/vm/snapshot/dao/VmSnapshotDaoTest.java b/engine/storage/integration-test/test/com/cloud/vm/snapshot/dao/VmSnapshotDaoTest.java
new file mode 100644
index 0000000..fc52f89
--- /dev/null
+++ b/engine/storage/integration-test/test/com/cloud/vm/snapshot/dao/VmSnapshotDaoTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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 com.cloud.vm.snapshot.dao;
+
+import com.cloud.vm.snapshot.VMSnapshotDetailsVO;
+import junit.framework.Assert;
+import org.apache.cloudstack.storage.test.CloudStackTestNGBase;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import javax.inject.Inject;
+import java.util.Map;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = "classpath:/storageContext.xml")
+public class VmSnapshotDaoTest extends CloudStackTestNGBase {
+ @Inject
+ VMSnapshotDetailsDao vmsnapshotDetailsDao;
+
+ @Test
+ public void testVmSnapshotDetails() {
+ VMSnapshotDetailsVO detailsVO = new VMSnapshotDetailsVO(1L, "test", "foo");
+ vmsnapshotDetailsDao.persist(detailsVO);
+ Map<String, String> details = vmsnapshotDetailsDao.getDetails(1L);
+ Assert.assertTrue(details.containsKey("test"));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
index d5eea85..228b957 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
@@ -16,30 +16,6 @@
// under the License.
package org.apache.cloudstack.storage.test;
-import java.io.IOException;
-
-import com.cloud.event.ActionEventUtils;
-import com.cloud.event.dao.EventDaoImpl;
-import org.apache.cloudstack.acl.APIChecker;
-import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
-import org.apache.cloudstack.engine.service.api.OrchestrationService;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDaoImpl;
-import org.apache.cloudstack.framework.rpc.RpcProvider;
-import org.apache.cloudstack.storage.cache.manager.StorageCacheManagerImpl;
-import org.apache.cloudstack.storage.test.ChildTestConfiguration.Library;
-import org.apache.cloudstack.test.utils.SpringUtils;
-
-import org.mockito.Mockito;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.ComponentScan.Filter;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.FilterType;
-import org.springframework.core.type.classreading.MetadataReader;
-import org.springframework.core.type.classreading.MetadataReaderFactory;
-import org.springframework.core.type.filter.TypeFilter;
-
import com.cloud.agent.AgentManager;
import com.cloud.alert.AlertManager;
import com.cloud.capacity.dao.CapacityDaoImpl;
@@ -55,6 +31,8 @@ import com.cloud.dc.dao.DcDetailsDaoImpl;
import com.cloud.dc.dao.HostPodDaoImpl;
import com.cloud.dc.dao.PodVlanDaoImpl;
import com.cloud.domain.dao.DomainDaoImpl;
+import com.cloud.event.ActionEventUtils;
+import com.cloud.event.dao.EventDaoImpl;
import com.cloud.host.dao.HostDao;
import com.cloud.host.dao.HostDaoImpl;
import com.cloud.host.dao.HostDetailsDaoImpl;
@@ -80,7 +58,6 @@ import com.cloud.storage.dao.VolumeDaoImpl;
import com.cloud.storage.dao.VolumeHostDaoImpl;
import com.cloud.storage.download.DownloadMonitorImpl;
import com.cloud.storage.secondary.SecondaryStorageVmManager;
-import com.cloud.storage.snapshot.SnapshotManager;
import com.cloud.tags.dao.ResourceTagsDaoImpl;
import com.cloud.template.TemplateManager;
import com.cloud.user.AccountManager;
@@ -96,6 +73,26 @@ import com.cloud.vm.dao.UserVmDaoImpl;
import com.cloud.vm.dao.UserVmDetailsDaoImpl;
import com.cloud.vm.dao.VMInstanceDaoImpl;
import com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl;
+import org.apache.cloudstack.acl.APIChecker;
+import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
+import org.apache.cloudstack.engine.service.api.OrchestrationService;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDaoImpl;
+import org.apache.cloudstack.framework.rpc.RpcProvider;
+import org.apache.cloudstack.storage.cache.manager.StorageCacheManagerImpl;
+import org.apache.cloudstack.storage.test.ChildTestConfiguration.Library;
+import org.apache.cloudstack.test.utils.SpringUtils;
+import org.mockito.Mockito;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.ComponentScan.Filter;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.FilterType;
+import org.springframework.core.type.classreading.MetadataReader;
+import org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.core.type.filter.TypeFilter;
+
+import java.io.IOException;
@Configuration
@ComponentScan(basePackageClasses = { NicDaoImpl.class, VMInstanceDaoImpl.class, VMTemplateHostDaoImpl.class,
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
index 81f77d6..36bc912 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
@@ -18,16 +18,42 @@
*/
package org.apache.cloudstack.storage.test;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-import java.util.concurrent.ExecutionException;
-
-import javax.inject.Inject;
-
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Command;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.HypervisorGuruManager;
+import com.cloud.org.Cluster.ClusterType;
+import com.cloud.org.Managed.ManagedState;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceState;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.Storage.TemplateType;
+import com.cloud.storage.StoragePoolStatus;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.utils.component.ComponentContext;
import junit.framework.Assert;
-
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
@@ -39,13 +65,14 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy;
+import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
import org.apache.cloudstack.framework.async.AsyncCallFuture;
import org.apache.cloudstack.storage.LocalHostEndpoint;
@@ -64,41 +91,12 @@ import org.springframework.test.context.ContextConfiguration;
import org.testng.AssertJUnit;
import org.testng.annotations.Test;
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Command;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.host.Host;
-import com.cloud.host.Host.Type;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.HypervisorGuruManager;
-import com.cloud.org.Cluster.ClusterType;
-import com.cloud.org.Managed.ManagedState;
-import com.cloud.resource.ResourceManager;
-import com.cloud.resource.ResourceState;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.Storage.TemplateType;
-import com.cloud.storage.StoragePoolStatus;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.utils.component.ComponentContext;
+import javax.inject.Inject;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
@ContextConfiguration(locations = { "classpath:/storageContext.xml" })
public class SnapshotTest extends CloudStackTestNGBase {
@@ -404,7 +402,7 @@ public class SnapshotTest extends CloudStackTestNGBase {
StrategyPriority.sortStrategies(snapshotStrategies, snapshot);
for (SnapshotStrategy strategy : this.snapshotStrategies) {
- if (strategy.canHandle(snapshot) != Priority.CANT_HANDLE) {
+ if (strategy.canHandle(snapshot) != StrategyPriority.Priority.CANT_HANDLE) {
snapshot = strategy.takeSnapshot(snapshot);
result = true;
}
@@ -429,7 +427,7 @@ public class SnapshotTest extends CloudStackTestNGBase {
StrategyPriority.sortStrategies(snapshotStrategies, newSnapshot);
for (SnapshotStrategy strategy : this.snapshotStrategies) {
- if (strategy.canHandle(snapshot) != Priority.CANT_HANDLE) {
+ if (strategy.canHandle(snapshot) != StrategyPriority.Priority.CANT_HANDLE) {
newSnapshot = strategy.takeSnapshot(snapshot);
}
}
@@ -437,7 +435,7 @@ public class SnapshotTest extends CloudStackTestNGBase {
// create another snapshot
for (SnapshotStrategy strategy : this.snapshotStrategies) {
- if (strategy.canHandle(snapshot) != Priority.CANT_HANDLE) {
+ if (strategy.canHandle(snapshot) != StrategyPriority.Priority.CANT_HANDLE) {
strategy.deleteSnapshot(newSnapshot.getId());
}
}
@@ -454,7 +452,7 @@ public class SnapshotTest extends CloudStackTestNGBase {
StrategyPriority.sortStrategies(snapshotStrategies, snapshot);
for (SnapshotStrategy strategy : this.snapshotStrategies) {
- if (strategy.canHandle(snapshot) != Priority.CANT_HANDLE) {
+ if (strategy.canHandle(snapshot) != StrategyPriority.Priority.CANT_HANDLE) {
snapshot = strategy.takeSnapshot(snapshot);
result = true;
}
@@ -487,7 +485,7 @@ public class SnapshotTest extends CloudStackTestNGBase {
StrategyPriority.sortStrategies(snapshotStrategies, newSnapshot);
for (SnapshotStrategy strategy : this.snapshotStrategies) {
- if (strategy.canHandle(snapshot) != Priority.CANT_HANDLE) {
+ if (strategy.canHandle(snapshot) != StrategyPriority.Priority.CANT_HANDLE) {
newSnapshot = strategy.takeSnapshot(snapshot);
}
}
@@ -499,7 +497,7 @@ public class SnapshotTest extends CloudStackTestNGBase {
try {
for (SnapshotStrategy strategy : this.snapshotStrategies) {
- if (strategy.canHandle(snapshot) != Priority.CANT_HANDLE) {
+ if (strategy.canHandle(snapshot) != StrategyPriority.Priority.CANT_HANDLE) {
boolean res = strategy.deleteSnapshot(newSnapshot.getId());
Assert.assertTrue(res);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/engine/storage/integration-test/test/resources/storageContext.xml
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/resources/storageContext.xml b/engine/storage/integration-test/test/resources/storageContext.xml
index 664f1e3..884e813 100644
--- a/engine/storage/integration-test/test/resources/storageContext.xml
+++ b/engine/storage/integration-test/test/resources/storageContext.xml
@@ -85,4 +85,6 @@
<bean id="AccountGuestVlanMapDaoImpl" class="com.cloud.network.dao.AccountGuestVlanMapDaoImpl" />
<bean id="StorageCacheReplacementAlgorithm" class="org.apache.cloudstack.storage.cache.manager.StorageCacheReplacementAlgorithmLRU" />
<bean id="ServiceOfferingDetailsDao" class="com.cloud.service.dao.ServiceOfferingDetailsDaoImpl" />
+ <bean id="vmsnapshotDetailsDao" class="com.cloud.vm.snapshot.dao.VMSnapshotDetailsDaoImpl" />
+ <bean id="snapshotManager" class="com.cloud.storage.snapshot.SnapshotManagerImpl" />
</beans>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/engine/storage/snapshot/pom.xml
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/pom.xml b/engine/storage/snapshot/pom.xml
index 8a84704..808d0c2 100644
--- a/engine/storage/snapshot/pom.xml
+++ b/engine/storage/snapshot/pom.xml
@@ -30,5 +30,37 @@
<artifactId>cloud-engine-api</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-api</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
</dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>testCompile</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>integration-test</phase>
+ <goals>
+ <goal>test</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
</project>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
index a4014b0..0799721 100644
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
@@ -17,11 +17,10 @@
package org.apache.cloudstack.storage.snapshot;
-import java.util.concurrent.ExecutionException;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.Snapshot;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService;
@@ -41,57 +40,26 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.framework.async.AsyncRpcContext;
import org.apache.cloudstack.storage.command.CommandResult;
import org.apache.cloudstack.storage.command.CopyCmdAnswer;
-import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.snapshot.SnapshotManager;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.snapshot.dao.VMSnapshotDao;
+import javax.inject.Inject;
+import java.util.concurrent.ExecutionException;
@Component
public class SnapshotServiceImpl implements SnapshotService {
private static final Logger s_logger = Logger.getLogger(SnapshotServiceImpl.class);
@Inject
- protected VolumeDao _volsDao;
- @Inject
- protected UserVmDao _vmDao;
- @Inject
- protected PrimaryDataStoreDao _storagePoolDao;
- @Inject
- protected ClusterDao _clusterDao;
- @Inject
- protected SnapshotDao _snapshotDao;
- @Inject
protected SnapshotDataStoreDao _snapshotStoreDao;
-
- @Inject
- protected SnapshotManager snapshotMgr;
- @Inject
- protected VolumeOrchestrationService volumeMgr;
- @Inject
- protected SnapshotStateMachineManager stateMachineManager;
@Inject
SnapshotDataFactory snapshotfactory;
@Inject
DataStoreManager dataStoreMgr;
@Inject
DataMotionService motionSrv;
- @Inject
- ObjectInDataStoreManager objInStoreMgr;
- @Inject
- VMSnapshotDao _vmSnapshotDao;
static private class CreateSnapshotContext<T> extends AsyncRpcContext<T> {
final SnapshotInfo snapshot;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
index 6a874d6..403f113 100644
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
@@ -16,8 +16,17 @@
// under the License.
package org.apache.cloudstack.storage.snapshot;
-import javax.inject.Inject;
-
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.snapshot.SnapshotManager;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
@@ -36,25 +45,13 @@ import org.apache.cloudstack.storage.to.SnapshotObjectTO;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.Volume;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.snapshot.SnapshotManager;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.NoTransitionException;
+import javax.inject.Inject;
@Component
public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
private static final Logger s_logger = Logger.getLogger(XenserverSnapshotStrategy.class);
@Inject
- SnapshotManager snapshotMgr;
- @Inject
SnapshotService snapshotSvr;
@Inject
DataStoreManager dataStoreMgr;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java
new file mode 100644
index 0000000..6b5e5fb
--- /dev/null
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java
@@ -0,0 +1,369 @@
+/*
+ * 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.vmsnapshot;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.VMSnapshotStrategy;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CreateVMSnapshotAnswer;
+import com.cloud.agent.api.CreateVMSnapshotCommand;
+import com.cloud.agent.api.DeleteVMSnapshotAnswer;
+import com.cloud.agent.api.DeleteVMSnapshotCommand;
+import com.cloud.agent.api.RevertToVMSnapshotAnswer;
+import com.cloud.agent.api.RevertToVMSnapshotCommand;
+import com.cloud.agent.api.VMSnapshotTO;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.GuestOSVO;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.snapshot.VMSnapshot;
+import com.cloud.vm.snapshot.VMSnapshotVO;
+import com.cloud.vm.snapshot.dao.VMSnapshotDao;
+
+public class DefaultVMSnapshotStrategy extends ManagerBase implements VMSnapshotStrategy {
+ private static final Logger s_logger = Logger.getLogger(DefaultVMSnapshotStrategy.class);
+ @Inject
+ VMSnapshotHelper vmSnapshotHelper;
+ @Inject
+ GuestOSDao guestOSDao;
+ @Inject
+ UserVmDao userVmDao;
+ @Inject
+ VMSnapshotDao vmSnapshotDao;
+ int _wait;
+ @Inject
+ ConfigurationDao configurationDao;
+ @Inject
+ AgentManager agentMgr;
+ @Inject
+ VolumeDao volumeDao;
+ @Inject
+ DiskOfferingDao diskOfferingDao;
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ String value = configurationDao.getValue("vmsnapshot.create.wait");
+ _wait = NumbersUtil.parseInt(value, 1800);
+ return true;
+ }
+
+ public VMSnapshot takeVMSnapshot(VMSnapshot vmSnapshot) {
+ Long hostId = vmSnapshotHelper.pickRunningHost(vmSnapshot.getVmId());
+ UserVm userVm = userVmDao.findById(vmSnapshot.getVmId());
+ VMSnapshotVO vmSnapshotVO = (VMSnapshotVO)vmSnapshot;
+ try {
+ vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshotVO, VMSnapshot.Event.CreateRequested);
+ } catch (NoTransitionException e) {
+ throw new CloudRuntimeException(e.getMessage());
+ }
+
+ CreateVMSnapshotAnswer answer = null;
+ boolean result = false;
+ try {
+ GuestOSVO guestOS = guestOSDao.findById(userVm.getGuestOSId());
+
+ List<VolumeObjectTO> volumeTOs = vmSnapshotHelper.getVolumeTOList(userVm.getId());
+
+ VMSnapshotTO current = null;
+ VMSnapshotVO currentSnapshot = vmSnapshotDao.findCurrentSnapshotByVmId(userVm.getId());
+ if (currentSnapshot != null)
+ current = vmSnapshotHelper.getSnapshotWithParents(currentSnapshot);
+ VMSnapshotTO target = new VMSnapshotTO(vmSnapshot.getId(), vmSnapshot.getName(), vmSnapshot.getType(), null, vmSnapshot.getDescription(), false,
+ current);
+ if (current == null)
+ vmSnapshotVO.setParent(null);
+ else
+ vmSnapshotVO.setParent(current.getId());
+
+ CreateVMSnapshotCommand ccmd = new CreateVMSnapshotCommand(userVm.getInstanceName(),target ,volumeTOs, guestOS.getDisplayName(),userVm.getState());
+ ccmd.setWait(_wait);
+
+ answer = (CreateVMSnapshotAnswer)agentMgr.send(hostId, ccmd);
+ if (answer != null && answer.getResult()) {
+ processAnswer(vmSnapshotVO, userVm, answer, hostId);
+ s_logger.debug("Create vm snapshot " + vmSnapshot.getName() + " succeeded for vm: " + userVm.getInstanceName());
+ result = true;
+
+ for (VolumeObjectTO volumeTo : answer.getVolumeTOs()){
+ publishUsageEvent(EventTypes.EVENT_VM_SNAPSHOT_CREATE,vmSnapshot,userVm,volumeTo);
+ }
+ return vmSnapshot;
+ } else {
+ String errMsg = "Creating VM snapshot: " + vmSnapshot.getName() + " failed";
+ if(answer != null && answer.getDetails() != null)
+ errMsg = errMsg + " due to " + answer.getDetails();
+ s_logger.error(errMsg);
+ throw new CloudRuntimeException(errMsg);
+ }
+ } catch (OperationTimedoutException e) {
+ s_logger.debug("Creating VM snapshot: " + vmSnapshot.getName() + " failed: " + e.toString());
+ throw new CloudRuntimeException("Creating VM snapshot: " + vmSnapshot.getName() + " failed: " + e.toString());
+ } catch (AgentUnavailableException e) {
+ s_logger.debug("Creating VM snapshot: " + vmSnapshot.getName() + " failed", e);
+ throw new CloudRuntimeException("Creating VM snapshot: " + vmSnapshot.getName() + " failed: " + e.toString());
+ } finally{
+ if (!result) {
+ try {
+ vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationFailed);
+ } catch (NoTransitionException e1) {
+ s_logger.error("Cannot set vm snapshot state due to: " + e1.getMessage());
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean deleteVMSnapshot(VMSnapshot vmSnapshot) {
+ UserVmVO userVm = userVmDao.findById(vmSnapshot.getVmId());
+ VMSnapshotVO vmSnapshotVO = (VMSnapshotVO)vmSnapshot;
+ try {
+ vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshot,VMSnapshot.Event.ExpungeRequested);
+ } catch (NoTransitionException e) {
+ s_logger.debug("Failed to change vm snapshot state with event ExpungeRequested");
+ throw new CloudRuntimeException("Failed to change vm snapshot state with event ExpungeRequested: " + e.getMessage());
+ }
+
+ try {
+ Long hostId = vmSnapshotHelper.pickRunningHost(vmSnapshot.getVmId());
+
+ List<VolumeObjectTO> volumeTOs = vmSnapshotHelper.getVolumeTOList(vmSnapshot.getVmId());
+
+ String vmInstanceName = userVm.getInstanceName();
+ VMSnapshotTO parent = vmSnapshotHelper.getSnapshotWithParents(vmSnapshotVO).getParent();
+ VMSnapshotTO vmSnapshotTO = new VMSnapshotTO(vmSnapshot.getId(), vmSnapshot.getName(), vmSnapshot.getType(),
+ vmSnapshot.getCreated().getTime(), vmSnapshot.getDescription(), vmSnapshot.getCurrent(), parent);
+ GuestOSVO guestOS = guestOSDao.findById(userVm.getGuestOSId());
+ DeleteVMSnapshotCommand deleteSnapshotCommand = new DeleteVMSnapshotCommand(vmInstanceName, vmSnapshotTO, volumeTOs,guestOS.getDisplayName());
+
+ Answer answer = agentMgr.send(hostId, deleteSnapshotCommand);
+
+ if (answer != null && answer.getResult()) {
+ DeleteVMSnapshotAnswer deleteVMSnapshotAnswer = (DeleteVMSnapshotAnswer)answer;
+ processAnswer(vmSnapshotVO, userVm, answer, hostId);
+ for (VolumeObjectTO volumeTo : deleteVMSnapshotAnswer.getVolumeTOs()){
+ publishUsageEvent(EventTypes.EVENT_VM_SNAPSHOT_DELETE,vmSnapshot,userVm,volumeTo);
+ }
+ return true;
+ } else {
+ String errMsg = (answer == null) ? null : answer.getDetails();
+ s_logger.error("Delete vm snapshot " + vmSnapshot.getName() + " of vm " + userVm.getInstanceName() + " failed due to " + errMsg);
+ throw new CloudRuntimeException("Delete vm snapshot " + vmSnapshot.getName() + " of vm " + userVm.getInstanceName() + " failed due to " + errMsg);
+ }
+ } catch (OperationTimedoutException e) {
+ throw new CloudRuntimeException("Delete vm snapshot " + vmSnapshot.getName() + " of vm " + userVm.getInstanceName() + " failed due to " + e.getMessage());
+ } catch (AgentUnavailableException e) {
+ throw new CloudRuntimeException("Delete vm snapshot " + vmSnapshot.getName() + " of vm " + userVm.getInstanceName() + " failed due to " + e.getMessage());
+ }
+ }
+
+ @DB
+ protected void processAnswer(VMSnapshotVO vmSnapshot, UserVm userVm, Answer as, Long hostId) {
+ final Transaction txn = Transaction.currentTxn();
+ try {
+ txn.start();
+ if (as instanceof CreateVMSnapshotAnswer) {
+ CreateVMSnapshotAnswer answer = (CreateVMSnapshotAnswer) as;
+ finalizeCreate(vmSnapshot, answer.getVolumeTOs());
+ vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded);
+ } else if (as instanceof RevertToVMSnapshotAnswer) {
+ RevertToVMSnapshotAnswer answer = (RevertToVMSnapshotAnswer) as;
+ finalizeRevert(vmSnapshot, answer.getVolumeTOs());
+ vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded);
+ } else if (as instanceof DeleteVMSnapshotAnswer) {
+ DeleteVMSnapshotAnswer answer = (DeleteVMSnapshotAnswer) as;
+ finalizeDelete(vmSnapshot, answer.getVolumeTOs());
+ vmSnapshotDao.remove(vmSnapshot.getId());
+ }
+ txn.commit();
+ } catch (Exception e) {
+ String errMsg = "Error while process answer: " + as.getClass() + " due to " + e.getMessage();
+ s_logger.error(errMsg, e);
+ txn.rollback();
+ throw new CloudRuntimeException(errMsg);
+ } finally {
+ txn.close();
+ }
+ }
+
+ protected void finalizeDelete(VMSnapshotVO vmSnapshot, List<VolumeObjectTO> VolumeTOs) {
+ // update volumes path
+ updateVolumePath(VolumeTOs);
+
+ // update children's parent snapshots
+ List<VMSnapshotVO> children= vmSnapshotDao.listByParent(vmSnapshot.getId());
+ for (VMSnapshotVO child : children) {
+ child.setParent(vmSnapshot.getParent());
+ vmSnapshotDao.persist(child);
+ }
+
+ // update current snapshot
+ VMSnapshotVO current = vmSnapshotDao.findCurrentSnapshotByVmId(vmSnapshot.getVmId());
+ if(current != null && current.getId() == vmSnapshot.getId() && vmSnapshot.getParent() != null){
+ VMSnapshotVO parent = vmSnapshotDao.findById(vmSnapshot.getParent());
+ parent.setCurrent(true);
+ vmSnapshotDao.persist(parent);
+ }
+ vmSnapshot.setCurrent(false);
+ vmSnapshotDao.persist(vmSnapshot);
+ }
+
+ protected void finalizeCreate(VMSnapshotVO vmSnapshot, List<VolumeObjectTO> VolumeTOs) {
+ // update volumes path
+ updateVolumePath(VolumeTOs);
+
+ vmSnapshot.setCurrent(true);
+
+ // change current snapshot
+ if (vmSnapshot.getParent() != null) {
+ VMSnapshotVO previousCurrent = vmSnapshotDao.findById(vmSnapshot.getParent());
+ previousCurrent.setCurrent(false);
+ vmSnapshotDao.persist(previousCurrent);
+ }
+ vmSnapshotDao.persist(vmSnapshot);
+ }
+
+ protected void finalizeRevert(VMSnapshotVO vmSnapshot, List<VolumeObjectTO> volumeToList) {
+ // update volumes path
+ updateVolumePath(volumeToList);
+
+ // update current snapshot, current snapshot is the one reverted to
+ VMSnapshotVO previousCurrent = vmSnapshotDao.findCurrentSnapshotByVmId(vmSnapshot.getVmId());
+ if(previousCurrent != null){
+ previousCurrent.setCurrent(false);
+ vmSnapshotDao.persist(previousCurrent);
+ }
+ vmSnapshot.setCurrent(true);
+ vmSnapshotDao.persist(vmSnapshot);
+ }
+
+ private void updateVolumePath(List<VolumeObjectTO> volumeTOs) {
+ for (VolumeObjectTO volume : volumeTOs) {
+ if (volume.getPath() != null) {
+ VolumeVO volumeVO = volumeDao.findById(volume.getId());
+ volumeVO.setPath(volume.getPath());
+ volumeVO.setVmSnapshotChainSize(volume.getSize());
+ volumeDao.persist(volumeVO);
+ }
+ }
+ }
+
+ private void publishUsageEvent(String type, VMSnapshot vmSnapshot, UserVm userVm, VolumeObjectTO volumeTo){
+ VolumeVO volume = volumeDao.findById(volumeTo.getId());
+ Long diskOfferingId = volume.getDiskOfferingId();
+ Long offeringId = null;
+ if (diskOfferingId != null) {
+ DiskOfferingVO offering = diskOfferingDao.findById(diskOfferingId);
+ if (offering != null
+ && (offering.getType() == DiskOfferingVO.Type.Disk)) {
+ offeringId = offering.getId();
+ }
+ }
+ UsageEventUtils.publishUsageEvent(
+ type,
+ vmSnapshot.getAccountId(),
+ userVm.getDataCenterId(),
+ userVm.getId(),
+ vmSnapshot.getName(),
+ offeringId,
+ volume.getId(), // save volume's id into templateId field
+ volumeTo.getSize(),
+ VMSnapshot.class.getName(), vmSnapshot.getUuid());
+ }
+
+ @Override
+ public boolean revertVMSnapshot(VMSnapshot vmSnapshot) {
+ VMSnapshotVO vmSnapshotVO = (VMSnapshotVO)vmSnapshot;
+ UserVmVO userVm = userVmDao.findById(vmSnapshot.getVmId());
+ try {
+ vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshotVO, VMSnapshot.Event.RevertRequested);
+ } catch (NoTransitionException e) {
+ throw new CloudRuntimeException(e.getMessage());
+ }
+
+ boolean result = false;
+ try {
+ VMSnapshotVO snapshot = vmSnapshotDao.findById(vmSnapshotVO.getId());
+ List<VolumeObjectTO> volumeTOs = vmSnapshotHelper.getVolumeTOList(userVm.getId());
+ String vmInstanceName = userVm.getInstanceName();
+ VMSnapshotTO parent = vmSnapshotHelper.getSnapshotWithParents(snapshot).getParent();
+
+ VMSnapshotTO vmSnapshotTO = new VMSnapshotTO(snapshot.getId(), snapshot.getName(), snapshot.getType(),
+ snapshot.getCreated().getTime(), snapshot.getDescription(), snapshot.getCurrent(), parent);
+ Long hostId = vmSnapshotHelper.pickRunningHost(vmSnapshot.getVmId());
+ GuestOSVO guestOS = guestOSDao.findById(userVm.getGuestOSId());
+ RevertToVMSnapshotCommand revertToSnapshotCommand = new RevertToVMSnapshotCommand(vmInstanceName, vmSnapshotTO, volumeTOs, guestOS.getDisplayName());
+
+ RevertToVMSnapshotAnswer answer = (RevertToVMSnapshotAnswer) agentMgr.send(hostId, revertToSnapshotCommand);
+ if (answer != null && answer.getResult()) {
+ processAnswer(vmSnapshotVO, userVm, answer, hostId);
+ result = true;
+ } else {
+ String errMsg = "Revert VM: " + userVm.getInstanceName() + " to snapshot: "+ vmSnapshotVO.getName() + " failed";
+ if(answer != null && answer.getDetails() != null)
+ errMsg = errMsg + " due to " + answer.getDetails();
+ s_logger.error(errMsg);
+ throw new CloudRuntimeException(errMsg);
+ }
+ } catch (OperationTimedoutException e) {
+ s_logger.debug("Failed to revert vm snapshot", e);
+ throw new CloudRuntimeException(e.getMessage());
+ } catch (AgentUnavailableException e) {
+ s_logger.debug("Failed to revert vm snapshot", e);
+ throw new CloudRuntimeException(e.getMessage());
+ } finally {
+ if (!result) {
+ try {
+ vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationFailed);
+ } catch (NoTransitionException e1) {
+ s_logger.error("Cannot set vm snapshot state due to: " + e1.getMessage());
+ }
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public boolean canHandle(VMSnapshot vmSnapshot) {
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelper.java
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelper.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelper.java
new file mode 100644
index 0000000..1437f80
--- /dev/null
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelper.java
@@ -0,0 +1,38 @@
+/*
+ * 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.vmsnapshot;
+
+import com.cloud.agent.api.VMSnapshotTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.vm.snapshot.VMSnapshot;
+import com.cloud.vm.snapshot.VMSnapshotVO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+
+import java.util.List;
+
+public interface VMSnapshotHelper {
+ boolean vmSnapshotStateTransitTo(VMSnapshot vsnp, VMSnapshot.Event event) throws NoTransitionException;
+
+ Long pickRunningHost(Long vmId);
+
+ List<VolumeObjectTO> getVolumeTOList(Long vmId);
+
+ VMSnapshotTO getSnapshotWithParents(VMSnapshotVO snapshot);
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a6ce66e5/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelperImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelperImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelperImpl.java
new file mode 100644
index 0000000..320a59c
--- /dev/null
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelperImpl.java
@@ -0,0 +1,148 @@
+/*
+ * 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.vmsnapshot;
+
+import com.cloud.agent.api.VMSnapshotTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.VolumeTO;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.fsm.StateMachine2;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.snapshot.VMSnapshot;
+import com.cloud.vm.snapshot.VMSnapshotVO;
+import com.cloud.vm.snapshot.dao.VMSnapshotDao;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+
+import javax.inject.Inject;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class VMSnapshotHelperImpl implements VMSnapshotHelper {
+ @Inject
+ VMSnapshotDao _vmSnapshotDao;
+ @Inject
+ UserVmDao userVmDao;
+ @Inject
+ HostDao hostDao;
+ @Inject
+ VolumeDao volumeDao;
+ @Inject
+ PrimaryDataStoreDao primaryDataStoreDao;
+ @Inject
+ VolumeDataFactory volumeDataFactory;
+
+ StateMachine2<VMSnapshot.State, VMSnapshot.Event, VMSnapshot> _vmSnapshottateMachine ;
+ public VMSnapshotHelperImpl() {
+ _vmSnapshottateMachine = VMSnapshot.State.getStateMachine();
+ }
+ @Override
+ public boolean vmSnapshotStateTransitTo(VMSnapshot vsnp, VMSnapshot.Event event) throws NoTransitionException {
+ return _vmSnapshottateMachine.transitTo(vsnp, event, null, _vmSnapshotDao);
+ }
+
+ @Override
+ public Long pickRunningHost(Long vmId) {
+ UserVmVO vm = userVmDao.findById(vmId);
+ // use VM's host if VM is running
+ if(vm.getState() == VirtualMachine.State.Running)
+ return vm.getHostId();
+
+ // check if lastHostId is available
+ if(vm.getLastHostId() != null){
+ HostVO lastHost = hostDao.findById(vm.getLastHostId());
+ if(lastHost.getStatus() == com.cloud.host.Status.Up && !lastHost.isInMaintenanceStates())
+ return lastHost.getId();
+ }
+
+ List<VolumeVO> listVolumes = volumeDao.findByInstance(vmId);
+ if (listVolumes == null || listVolumes.size() == 0) {
+ throw new InvalidParameterValueException("vmInstance has no volumes");
+ }
+ VolumeVO volume = listVolumes.get(0);
+ Long poolId = volume.getPoolId();
+ if (poolId == null) {
+ throw new InvalidParameterValueException("pool id is not found");
+ }
+ StoragePoolVO storagePool = primaryDataStoreDao.findById(poolId);
+ if (storagePool == null) {
+ throw new InvalidParameterValueException("storage pool is not found");
+ }
+ List<HostVO> listHost = hostDao.listAllUpAndEnabledNonHAHosts(Host.Type.Routing, storagePool.getClusterId(), storagePool.getPodId(),
+ storagePool.getDataCenterId(), null);
+ if (listHost == null || listHost.size() == 0) {
+ throw new InvalidParameterValueException("no host in up state is found");
+ }
+ return listHost.get(0).getId();
+ }
+
+ @Override
+ public List<VolumeObjectTO> getVolumeTOList(Long vmId) {
+ List<VolumeObjectTO> volumeTOs = new ArrayList<VolumeObjectTO>();
+ List<VolumeVO> volumeVos = volumeDao.findByInstance(vmId);
+ VolumeInfo volumeInfo = null;
+ for (VolumeVO volume : volumeVos) {
+ volumeInfo = volumeDataFactory.getVolume(volume.getId());
+
+ volumeTOs.add((VolumeObjectTO)volumeInfo.getTO());
+ }
+ return volumeTOs;
+ }
+
+
+ private VMSnapshotTO convert2VMSnapshotTO(VMSnapshotVO vo) {
+ return new VMSnapshotTO(vo.getId(), vo.getName(), vo.getType(), vo.getCreated().getTime(), vo.getDescription(),
+ vo.getCurrent(), null);
+ }
+
+ @Override
+ public VMSnapshotTO getSnapshotWithParents(VMSnapshotVO snapshot) {
+ Map<Long, VMSnapshotVO> snapshotMap = new HashMap<Long, VMSnapshotVO>();
+ List<VMSnapshotVO> allSnapshots = _vmSnapshotDao.findByVm(snapshot.getVmId());
+ for (VMSnapshotVO vmSnapshotVO : allSnapshots) {
+ snapshotMap.put(vmSnapshotVO.getId(), vmSnapshotVO);
+ }
+
+ VMSnapshotTO currentTO = convert2VMSnapshotTO(snapshot);
+ VMSnapshotTO result = currentTO;
+ VMSnapshotVO current = snapshot;
+ while (current.getParent() != null) {
+ VMSnapshotVO parent = snapshotMap.get(current.getParent());
+ currentTO.setParent(convert2VMSnapshotTO(parent));
+ current = snapshotMap.get(current.getParent());
+ currentTO = currentTO.getParent();
+ }
+ return result;
+ }
+
+}