rafaelweingartner closed pull request #2808: Fix the problem at #1740 when it 
loads all snapshots in the primary storage
URL: https://github.com/apache/cloudstack/pull/2808
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git 
a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
 
b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
index 20cff5671b7..50f311a4eaa 100644
--- 
a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
+++ 
b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
@@ -26,7 +26,7 @@
 import com.cloud.utils.fsm.StateDao;
 
 public interface SnapshotDataStoreDao extends GenericDao<SnapshotDataStoreVO, 
Long>,
-        StateDao<ObjectInDataStoreStateMachine.State, 
ObjectInDataStoreStateMachine.Event, DataObjectInStore> {
+StateDao<ObjectInDataStoreStateMachine.State, 
ObjectInDataStoreStateMachine.Event, DataObjectInStore> {
 
     List<SnapshotDataStoreVO> listByStoreId(long id, DataStoreRole role);
 
@@ -63,5 +63,10 @@
 
     SnapshotDataStoreVO findByVolume(long volumeId, DataStoreRole role);
 
+    /**
+     * List all snapshots in 'snapshot_store_ref' by volume and data store 
role. Therefore, it is possible to list all snapshots that are in the primary 
storage or in the secondary storage.
+     */
+    List<SnapshotDataStoreVO> listAllByVolumeAndDataStore(long volumeId, 
DataStoreRole role);
+
     List<SnapshotDataStoreVO> 
listByState(ObjectInDataStoreStateMachine.State... states);
 }
diff --git 
a/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java
 
b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java
index ad58f42a97a..11d61df3d7f 100644
--- 
a/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java
+++ 
b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java
@@ -28,9 +28,9 @@
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 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.VolumeDataFactory;
 import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
+import org.apache.commons.collections.CollectionUtils;
 
 import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.SnapshotVO;
@@ -38,14 +38,13 @@
 import com.cloud.utils.exception.CloudRuntimeException;
 
 public class SnapshotDataFactoryImpl implements SnapshotDataFactory {
+
     @Inject
-    SnapshotDao snapshotDao;
-    @Inject
-    SnapshotDataStoreDao snapshotStoreDao;
+    private SnapshotDao snapshotDao;
     @Inject
-    DataStoreManager storeMgr;
+    private SnapshotDataStoreDao snapshotStoreDao;
     @Inject
-    VolumeDataFactory volumeFactory;
+    private DataStoreManager storeMgr;
 
     @Override
     public SnapshotInfo getSnapshot(long snapshotId, DataStore store) {
@@ -66,16 +65,16 @@ public SnapshotInfo getSnapshot(DataObject obj, DataStore 
store) {
 
     @Override
     public List<SnapshotInfo> getSnapshots(long volumeId, DataStoreRole role) {
-
-        SnapshotDataStoreVO snapshotStore = 
snapshotStoreDao.findByVolume(volumeId, role);
-        if (snapshotStore == null) {
+        List<SnapshotDataStoreVO> allSnapshotsFromVolumeAndDataStore = 
snapshotStoreDao.listAllByVolumeAndDataStore(volumeId, role);
+        if (CollectionUtils.isEmpty(allSnapshotsFromVolumeAndDataStore)) {
             return new ArrayList<>();
         }
-        DataStore store = 
storeMgr.getDataStore(snapshotStore.getDataStoreId(), role);
-        List<SnapshotVO> volSnapShots = snapshotDao.listByVolumeId(volumeId);
         List<SnapshotInfo> infos = new ArrayList<>();
-        for(SnapshotVO snapshot: volSnapShots) {
+        for (SnapshotDataStoreVO snapshotDataStoreVO : 
allSnapshotsFromVolumeAndDataStore) {
+            DataStore store = 
storeMgr.getDataStore(snapshotDataStoreVO.getDataStoreId(), role);
+            SnapshotVO snapshot = 
snapshotDao.findById(snapshotDataStoreVO.getSnapshotId());
             SnapshotObject info = SnapshotObject.getSnapshotObject(snapshot, 
store);
+
             infos.add(info);
         }
         return infos;
diff --git 
a/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImplTest.java
 
b/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImplTest.java
new file mode 100644
index 00000000000..aad339bb8ff
--- /dev/null
+++ 
b/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImplTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.snapshot;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.SnapshotInfo;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.utils.component.ComponentContext;
+
+@RunWith(PowerMockRunner.class)
+public class SnapshotDataFactoryImplTest {
+
+    @Spy
+    @InjectMocks
+    private SnapshotDataFactoryImpl snapshotDataFactoryImpl = new 
SnapshotDataFactoryImpl();
+
+    @Mock
+    private SnapshotDataStoreDao snapshotStoreDaoMock;
+    @Mock
+    private DataStoreManager dataStoreManagerMock;
+    @Mock
+    private SnapshotDao snapshotDaoMock;
+
+    private long volumeMockId = 1;
+
+    @Test
+    public void 
getSnapshotsByVolumeAndDataStoreTestNoSnapshotDataStoreVOFound() {
+        Mockito.doReturn(new 
ArrayList<>()).when(snapshotStoreDaoMock).listAllByVolumeAndDataStore(volumeMockId,
 DataStoreRole.Primary);
+
+        List<SnapshotInfo> snapshots = 
snapshotDataFactoryImpl.getSnapshots(volumeMockId, DataStoreRole.Primary);
+
+        Assert.assertTrue(snapshots.isEmpty());
+    }
+
+    @Test
+    @PrepareForTest({ComponentContext.class})
+    public void getSnapshotsByVolumeAndDataStoreTest() {
+        PowerMockito.mockStatic(ComponentContext.class);
+        
PowerMockito.when(ComponentContext.inject(SnapshotObject.class)).thenReturn(new 
SnapshotObject());
+
+        SnapshotDataStoreVO snapshotDataStoreVoMock = 
Mockito.mock(SnapshotDataStoreVO.class);
+        
Mockito.doReturn(volumeMockId).when(snapshotDataStoreVoMock).getVolumeId();
+
+        long snapshotId = 1223;
+        long dataStoreId = 34567;
+        
Mockito.doReturn(snapshotId).when(snapshotDataStoreVoMock).getSnapshotId();
+        
Mockito.doReturn(dataStoreId).when(snapshotDataStoreVoMock).getDataStoreId();
+
+        SnapshotVO snapshotVoMock  = Mockito.mock(SnapshotVO.class);
+        Mockito.doReturn(snapshotId).when(snapshotVoMock).getId();
+
+        DataStoreRole dataStoreRole = DataStoreRole.Primary;
+        DataStore dataStoreMock = Mockito.mock(DataStore.class);
+        Mockito.doReturn(dataStoreId).when(dataStoreMock).getId();
+        Mockito.doReturn(dataStoreRole).when(dataStoreMock).getRole();
+
+        List<SnapshotDataStoreVO> snapshotDataStoreVOs = new ArrayList<>();
+        snapshotDataStoreVOs.add(snapshotDataStoreVoMock);
+
+        
Mockito.doReturn(snapshotDataStoreVOs).when(snapshotStoreDaoMock).listAllByVolumeAndDataStore(volumeMockId,
 dataStoreRole);
+        
Mockito.doReturn(dataStoreMock).when(dataStoreManagerMock).getDataStore(dataStoreId,
 dataStoreRole);
+        
Mockito.doReturn(snapshotVoMock).when(snapshotDaoMock).findById(snapshotId);
+
+        List<SnapshotInfo> snapshots = 
snapshotDataFactoryImpl.getSnapshots(volumeMockId, dataStoreRole);
+
+        Assert.assertEquals(1, snapshots.size());
+
+        SnapshotInfo snapshotInfo = snapshots.get(0);
+        Assert.assertEquals(dataStoreMock, snapshotInfo.getDataStore());
+        Assert.assertEquals(snapshotVoMock, 
((SnapshotObject)snapshotInfo).getSnapshotVO());
+
+        PowerMockito.verifyStatic();
+        ComponentContext.inject(SnapshotObject.class);
+    }
+}
diff --git 
a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java
 
b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java
index c3e48b9b2f3..6ca6b239b6f 100644
--- 
a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java
+++ 
b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java
@@ -16,14 +16,17 @@
 // under the License.
 package org.apache.cloudstack.storage.image.db;
 
-import com.cloud.storage.DataStoreRole;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.db.UpdateBuilder;
+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 java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import 
org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
 import 
org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
@@ -33,19 +36,18 @@
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.SnapshotVO;
 import com.cloud.storage.dao.SnapshotDao;
-import javax.inject.Inject;
-import com.cloud.hypervisor.Hypervisor;
-import java.util.ArrayList;
+import com.cloud.utils.db.DB;
 import com.cloud.utils.db.Filter;
-import javax.naming.ConfigurationException;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.db.UpdateBuilder;
 
 @Component
 public class SnapshotDataStoreDaoImpl extends 
GenericDaoBase<SnapshotDataStoreVO, Long> implements SnapshotDataStoreDao {
@@ -176,33 +178,33 @@ public boolean updateState(State currentState, Event 
event, State nextState, Dat
             if (dbVol != null) {
                 StringBuilder str = new StringBuilder("Unable to update 
").append(dataObj.toString());
                 str.append(": DB Data={id=")
-                    .append(dbVol.getId())
-                    .append("; state=")
-                    .append(dbVol.getState())
-                    .append("; updatecount=")
-                    .append(dbVol.getUpdatedCount())
-                    .append(";updatedTime=")
-                    .append(dbVol.getUpdated());
+                .append(dbVol.getId())
+                .append("; state=")
+                .append(dbVol.getState())
+                .append("; updatecount=")
+                .append(dbVol.getUpdatedCount())
+                .append(";updatedTime=")
+                .append(dbVol.getUpdated());
                 str.append(": New Data={id=")
-                    .append(dataObj.getId())
-                    .append("; state=")
-                    .append(nextState)
-                    .append("; event=")
-                    .append(event)
-                    .append("; updatecount=")
-                    .append(dataObj.getUpdatedCount())
-                    .append("; updatedTime=")
-                    .append(dataObj.getUpdated());
+                .append(dataObj.getId())
+                .append("; state=")
+                .append(nextState)
+                .append("; event=")
+                .append(event)
+                .append("; updatecount=")
+                .append(dataObj.getUpdatedCount())
+                .append("; updatedTime=")
+                .append(dataObj.getUpdated());
                 str.append(": stale Data={id=")
-                    .append(dataObj.getId())
-                    .append("; state=")
-                    .append(currentState)
-                    .append("; event=")
-                    .append(event)
-                    .append("; updatecount=")
-                    .append(oldUpdated)
-                    .append("; updatedTime=")
-                    .append(oldUpdatedTime);
+                .append(dataObj.getId())
+                .append("; state=")
+                .append(currentState)
+                .append("; event=")
+                .append(event)
+                .append("; updatecount=")
+                .append(oldUpdated)
+                .append("; updatedTime=")
+                .append(oldUpdatedTime);
             } else {
                 s_logger.debug("Unable to update objectIndatastore: id=" + 
dataObj.getId() + ", as there is no such object exists in the database 
anymore");
             }
@@ -254,7 +256,7 @@ public SnapshotDataStoreVO findLatestSnapshotForVolume(Long 
volumeId, DataStoreR
         TransactionLegacy txn = TransactionLegacy.currentTxn();
         try (
                 PreparedStatement pstmt = 
txn.prepareStatement(findLatestSnapshot);
-            ){
+                ){
             pstmt.setString(1, role.toString());
             pstmt.setLong(2, volumeId);
             try (ResultSet rs = pstmt.executeQuery();) {
@@ -275,7 +277,7 @@ public SnapshotDataStoreVO findOldestSnapshotForVolume(Long 
volumeId, DataStoreR
         TransactionLegacy txn = TransactionLegacy.currentTxn();
         try (
                 PreparedStatement pstmt = 
txn.prepareStatement(findOldestSnapshot);
-            ){
+                ){
             pstmt.setString(1, role.toString());
             pstmt.setLong(2, volumeId);
             try (ResultSet rs = pstmt.executeQuery();) {
@@ -318,6 +320,14 @@ public SnapshotDataStoreVO findBySnapshot(long snapshotId, 
DataStoreRole role) {
         return findOneBy(sc);
     }
 
+    @Override
+    public List<SnapshotDataStoreVO> listAllByVolumeAndDataStore(long 
volumeId, DataStoreRole role) {
+        SearchCriteria<SnapshotDataStoreVO> sc = volumeSearch.create();
+        sc.setParameters("volume_id", volumeId);
+        sc.setParameters("store_role", role);
+        return listBy(sc);
+    }
+
     @Override
     public SnapshotDataStoreVO findByVolume(long volumeId, DataStoreRole role) 
{
         SearchCriteria<SnapshotDataStoreVO> sc = volumeSearch.create();


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to