From a1719845b96765d71a317d9e32a824946b6630e8 Mon Sep 17 00:00:00 2001 From: GutoVeronezi Date: Mon, 19 Sep 2022 18:06:11 -0300 Subject: [PATCH 1/9] Refactor SnapshotDataStoreDaoImpl and add unit tests --- .../image/db/SnapshotDataStoreDaoImpl.java | 303 +++++++----------- .../db/SnapshotDataStoreDaoImplTest.java | 69 ++++ .../cloud/utils/db/GenericSearchBuilder.java | 38 +++ .../java/com/cloud/utils/db/SearchBase.java | 8 +- .../utils/db/GenericSearchBuilderTest.java | 54 ++++ 5 files changed, 292 insertions(+), 180 deletions(-) create mode 100644 framework/db/src/test/java/com/cloud/utils/db/GenericSearchBuilderTest.java 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 fa6c8d1f606b..5ff333b5387f 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 @@ -19,7 +19,6 @@ 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; @@ -27,12 +26,14 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.utils.Pair; 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; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; +import org.apache.commons.collections.CollectionUtils; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -45,7 +46,6 @@ 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; @@ -64,111 +64,94 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase volumeSearch; private SearchBuilder stateSearch; private SearchBuilder parentSnapshotSearch; - private SearchBuilder snapshotVOSearch; + protected SearchBuilder snapshotVOSearch; private SearchBuilder snapshotCreatedSearch; protected SearchBuilder snapshotSearch; - public static ArrayList hypervisorsSupportingSnapshotsChaining = new ArrayList(); + protected static final List HYPERVISORS_SUPPORTING_SNAPSHOTS_CHAINING = List.of(Hypervisor.HypervisorType.XenServer); @Inject - private SnapshotDao _snapshotDao; + protected SnapshotDao snapshotDao; - private final String findLatestSnapshot = "select store_id, store_role, snapshot_id from cloud.snapshot_store_ref where " + + private static final String FIND_OLDEST_OR_LATEST_SNAPSHOT = "select store_id, store_role, snapshot_id from cloud.snapshot_store_ref where " + " store_role = ? and volume_id = ? and state = 'Ready'" + - " order by created DESC " + - " limit 1"; - private final String findOldestSnapshot = "select store_id, store_role, snapshot_id from cloud.snapshot_store_ref where " + - " store_role = ? and volume_id = ? and state = 'Ready'" + - " order by created ASC " + + " order by created %s " + " limit 1"; @Override public boolean configure(String name, Map params) throws ConfigurationException { super.configure(name, params); - // Note that snapshot_store_ref stores snapshots on primary as well as - // those on secondary, so we need to - // use (store_id, store_role) to search + Pair storeIdEq = new Pair<>("store_id", SearchCriteria.Op.EQ); + Pair storeRoleEq = new Pair<>("store_role", SearchCriteria.Op.EQ); + Pair stateEq = new Pair<>("state", SearchCriteria.Op.EQ); + Pair stateNeq = new Pair<>("state", SearchCriteria.Op.NEQ); + Pair stateIn = new Pair<>("state", SearchCriteria.Op.IN); + Pair refCntNeq = new Pair<>("ref_cnt", SearchCriteria.Op.NEQ); + Pair idEq = new Pair<>("id", SearchCriteria.Op.EQ); + Pair updateCountEq = new Pair<>("updatedCount", SearchCriteria.Op.EQ); + Pair snapshotIdEq = new Pair<>("snapshot_id", SearchCriteria.Op.EQ); + Pair volumeIdEq = new Pair<>("volume_id", SearchCriteria.Op.EQ); + Pair createdBetween = new Pair<>("created", SearchCriteria.Op.BETWEEN); + storeSearch = createSearchBuilder(); - storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); - storeSearch.and("store_role", storeSearch.entity().getRole(), SearchCriteria.Op.EQ); - storeSearch.and("state", storeSearch.entity().getState(), SearchCriteria.Op.NEQ); + storeSearch.addAndConditions(storeIdEq, storeRoleEq, stateNeq); storeSearch.done(); storeStateSearch = createSearchBuilder(); - storeStateSearch.and("store_id", storeStateSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); - storeStateSearch.and("state", storeStateSearch.entity().getState(), SearchCriteria.Op.EQ); + storeStateSearch.addAndConditions(storeIdEq, stateEq); storeStateSearch.done(); destroyedSearch = createSearchBuilder(); - destroyedSearch.and("store_id", destroyedSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); - destroyedSearch.and("store_role", destroyedSearch.entity().getRole(), SearchCriteria.Op.EQ); - destroyedSearch.and("state", destroyedSearch.entity().getState(), SearchCriteria.Op.EQ); + destroyedSearch.addAndConditions(storeIdEq, storeRoleEq, stateEq); destroyedSearch.done(); cacheSearch = createSearchBuilder(); - cacheSearch.and("store_id", cacheSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); - cacheSearch.and("store_role", cacheSearch.entity().getRole(), SearchCriteria.Op.EQ); - cacheSearch.and("state", cacheSearch.entity().getState(), SearchCriteria.Op.NEQ); - cacheSearch.and("ref_cnt", cacheSearch.entity().getRefCnt(), SearchCriteria.Op.NEQ); + cacheSearch.addAndConditions(storeIdEq, storeRoleEq, stateNeq, refCntNeq); cacheSearch.done(); - updateStateSearch = this.createSearchBuilder(); - updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); - updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ); - updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), Op.EQ); + updateStateSearch = createSearchBuilder(); + updateStateSearch.addAndConditions(idEq, stateEq, updateCountEq); updateStateSearch.done(); snapshotSearch = createSearchBuilder(); - snapshotSearch.and("snapshot_id", snapshotSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ); - snapshotSearch.and("store_role", snapshotSearch.entity().getRole(), SearchCriteria.Op.EQ); - snapshotSearch.and("state", snapshotSearch.entity().getState(), SearchCriteria.Op.EQ); + snapshotSearch.addAndConditions(snapshotIdEq, storeRoleEq, stateEq); snapshotSearch.done(); storeSnapshotSearch = createSearchBuilder(); - storeSnapshotSearch.and("snapshot_id", storeSnapshotSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ); - storeSnapshotSearch.and("store_id", storeSnapshotSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); - storeSnapshotSearch.and("store_role", storeSnapshotSearch.entity().getRole(), SearchCriteria.Op.EQ); - storeSnapshotSearch.and("state", storeSnapshotSearch.entity().getState(), SearchCriteria.Op.EQ); + storeSnapshotSearch.addAndConditions(snapshotIdEq, storeIdEq, storeRoleEq, stateEq); storeSnapshotSearch.done(); snapshotIdSearch = createSearchBuilder(); - snapshotIdSearch.and("snapshot_id", snapshotIdSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ); + snapshotIdSearch.addAndConditions(snapshotIdEq); snapshotIdSearch.done(); volumeIdSearch = createSearchBuilder(); - volumeIdSearch.and("volume_id", volumeIdSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); + volumeIdSearch.addAndConditions(volumeIdEq); volumeIdSearch.done(); volumeSearch = createSearchBuilder(); - volumeSearch.and("volume_id", volumeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); - volumeSearch.and("store_role", volumeSearch.entity().getRole(), SearchCriteria.Op.EQ); - volumeSearch.and("snapshot_id", volumeSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ); + volumeSearch.addAndConditions(volumeIdEq, storeRoleEq, snapshotIdEq); volumeSearch.done(); volumeIdAndStateReadySearch = createSearchBuilder(); - volumeIdAndStateReadySearch.and("volume_id", volumeIdAndStateReadySearch.entity().getVolumeId(), SearchCriteria.Op.EQ); - volumeIdAndStateReadySearch.and("state", volumeIdAndStateReadySearch.entity().getState(), SearchCriteria.Op.EQ); + volumeIdAndStateReadySearch.addAndConditions(volumeIdEq, stateEq); volumeIdAndStateReadySearch.done(); stateSearch = createSearchBuilder(); - stateSearch.and("state", stateSearch.entity().getState(), SearchCriteria.Op.IN); + stateSearch.addAndConditions(stateIn); stateSearch.done(); parentSnapshotSearch = createSearchBuilder(); - parentSnapshotSearch.and("volume_id", parentSnapshotSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); - parentSnapshotSearch.and("store_id", parentSnapshotSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); - parentSnapshotSearch.and("store_role", parentSnapshotSearch.entity().getRole(), SearchCriteria.Op.EQ); - parentSnapshotSearch.and("state", parentSnapshotSearch.entity().getState(), SearchCriteria.Op.EQ); + parentSnapshotSearch.addAndConditions(volumeIdEq, storeIdEq, storeRoleEq, stateEq); parentSnapshotSearch.done(); - snapshotVOSearch = _snapshotDao.createSearchBuilder(); - snapshotVOSearch.and("volume_id", snapshotVOSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); + snapshotVOSearch = snapshotDao.createSearchBuilder(); + snapshotVOSearch.addAndConditions(volumeIdEq); snapshotVOSearch.done(); snapshotCreatedSearch = createSearchBuilder(); - snapshotCreatedSearch.and("store_id", snapshotCreatedSearch.entity().getDataStoreId(), Op.EQ); - snapshotCreatedSearch.and("created", snapshotCreatedSearch.entity().getCreated(), Op.BETWEEN); + snapshotCreatedSearch.addAndConditions(storeIdEq, createdBetween); snapshotCreatedSearch.done(); return true; @@ -191,44 +174,23 @@ public boolean updateState(State currentState, Event event, State nextState, Dat builder.set(dataObj, "state", nextState); builder.set(dataObj, "updated", new Date()); - int rows = update(dataObj, sc); - if (rows == 0 && s_logger.isDebugEnabled()) { - SnapshotDataStoreVO dbVol = findByIdIncludingRemoved(dataObj.getId()); - 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()); - 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()); - str.append(": stale Data={id=") - .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"); - } + if (update(dataObj, sc) > 0) { + return true; + } + + SnapshotDataStoreVO dbVol = findByIdIncludingRemoved(dataObj.getId()); + String message; + if (dbVol != null) { + message = String.format("Unable to update %s: DB Data={id=%s; state=%s; updatecount=%s;updatedTime=%s: New Data={id=%s; state=%s; event=%s; updatecount=%s; " + + "updatedTime=%s: stale Data={id=%s; state=%s; event=%s; updatecount=%s; updatedTime=%s", dataObj, dbVol.getId(), dbVol.getState(), + dbVol.getUpdatedCount(), dbVol.getUpdated(), dataObj.getId(), event, nextState, dataObj.getUpdatedCount(), dataObj.getUpdated(), dataObj.getId(), + currentState, event, oldUpdated, oldUpdatedTime); + } else { + message = String.format("Unable to update objectIndatastore: id=%s, as there is no such object exists in the database anymore", dataObj.getId()); } - return rows > 0; + + s_logger.debug(message); + return false; } @Override @@ -253,20 +215,14 @@ public void deletePrimaryRecordsForStore(long id, DataStoreRole role) { SearchCriteria sc = storeSearch.create(); sc.setParameters("store_id", id); sc.setParameters("store_role", role); - TransactionLegacy txn = TransactionLegacy.currentTxn(); - txn.start(); remove(sc); - txn.commit(); } @Override public void deleteSnapshotRecordsOnPrimary() { SearchCriteria sc = storeSearch.create(); sc.setParameters("store_role", DataStoreRole.Primary); - TransactionLegacy txn = TransactionLegacy.currentTxn(); - txn.start(); remove(sc); - txn.commit(); } @Override @@ -280,42 +236,32 @@ public SnapshotDataStoreVO findByStoreSnapshot(DataStoreRole role, long storeId, @Override public SnapshotDataStoreVO findLatestSnapshotForVolume(Long volumeId, DataStoreRole role) { - TransactionLegacy txn = TransactionLegacy.currentTxn(); - try ( - PreparedStatement pstmt = txn.prepareStatement(findLatestSnapshot); - ){ - pstmt.setString(1, role.toString()); - pstmt.setLong(2, volumeId); - try (ResultSet rs = pstmt.executeQuery();) { - while (rs.next()) { - long sid = rs.getLong(1); - long snid = rs.getLong(3); - return findByStoreSnapshot(role, sid, snid); - } - } - } catch (SQLException e) { - s_logger.debug("Failed to find latest snapshot for volume: " + volumeId + " due to: " + e.toString()); - } - return null; + return findOldestOrLatestSnapshotForVolume(volumeId, role, false); } @Override public SnapshotDataStoreVO findOldestSnapshotForVolume(Long volumeId, DataStoreRole role) { - TransactionLegacy txn = TransactionLegacy.currentTxn(); - try ( - PreparedStatement pstmt = txn.prepareStatement(findOldestSnapshot); - ){ - pstmt.setString(1, role.toString()); - pstmt.setLong(2, volumeId); - try (ResultSet rs = pstmt.executeQuery();) { - while (rs.next()) { - long sid = rs.getLong(1); - long snid = rs.getLong(3); - return findByStoreSnapshot(role, sid, snid); + return findOldestOrLatestSnapshotForVolume(volumeId, role, true); + } + + protected SnapshotDataStoreVO findOldestOrLatestSnapshotForVolume(long volumeId, DataStoreRole role, boolean oldest) { + String order = oldest ? "ASC" : "DESC"; + + try (TransactionLegacy transactionLegacy = TransactionLegacy.currentTxn()) { + try (PreparedStatement preparedStatement = transactionLegacy.prepareStatement(String.format(FIND_OLDEST_OR_LATEST_SNAPSHOT, order))) { + preparedStatement.setString(1, role.toString()); + preparedStatement.setLong(2, volumeId); + + try (ResultSet resultSet = preparedStatement.executeQuery()) { + if (resultSet.next()) { + long storeId = resultSet.getLong(1); + long snapshotId = resultSet.getLong(3); + return findByStoreSnapshot(role, storeId, snapshotId); + } } } } catch (SQLException e) { - s_logger.debug("Failed to find oldest snapshot for volume: " + volumeId + " due to: " + e.toString()); + s_logger.warn(String.format("Failed to find %s snapshot for volume [%s] in %s store due to [%s].", oldest ? "oldest" : "latest", volumeId, role, e.getMessage()), e); } return null; } @@ -323,17 +269,20 @@ public SnapshotDataStoreVO findOldestSnapshotForVolume(Long volumeId, DataStoreR @Override @DB public SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long volumeId) { - if(isSnapshotChainingRequired(volumeId)) { - SearchCriteria sc = parentSnapshotSearch.create(); - sc.setParameters("volume_id", volumeId); - sc.setParameters("store_role", role.toString()); - sc.setParameters("state", ObjectInDataStoreStateMachine.State.Ready.name()); - sc.setParameters("store_id", storeId); - - List snapshotList = listBy(sc, new Filter(SnapshotDataStoreVO.class, "created", false, null, null)); - if (snapshotList != null && snapshotList.size() != 0) { - return snapshotList.get(0); - } + if (!isSnapshotChainingRequired(volumeId)) { + s_logger.trace(String.format("Snapshot chaining is not required for snapshots of volume [%s]. Returning null as parent.", volumeId)); + return null; + } + + SearchCriteria sc = parentSnapshotSearch.create(); + sc.setParameters("volume_id", volumeId); + sc.setParameters("store_role", role.toString()); + sc.setParameters("state", ObjectInDataStoreStateMachine.State.Ready.name()); + sc.setParameters("store_id", storeId); + + List snapshotList = listBy(sc, new Filter(SnapshotDataStoreVO.class, "created", false, null, null)); + if (CollectionUtils.isNotEmpty(snapshotList)) { + return snapshotList.get(0); } return null; } @@ -403,40 +352,47 @@ public List listActiveOnCache(long id) { return listBy(sc); } + /** + * Creates an entry for each record, but with empty install path since the content is not on region-wide store yet. + */ @Override public void duplicateCacheRecordsOnRegionStore(long storeId) { - // find all records on image cache SearchCriteria sc = storeSnapshotSearch.create(); sc.setParameters("store_role", DataStoreRole.ImageCache); sc.setParameters("destroyed", false); List snapshots = listBy(sc); - // create an entry for each record, but with empty install path since the content is not yet on region-wide store yet - if (snapshots != null) { - s_logger.info("Duplicate " + snapshots.size() + " snapshot cache store records to region store"); - for (SnapshotDataStoreVO snap : snapshots) { - SnapshotDataStoreVO snapStore = findByStoreSnapshot(DataStoreRole.Image, storeId, snap.getSnapshotId()); - if (snapStore != null) { - s_logger.info("There is already entry for snapshot " + snap.getSnapshotId() + " on region store " + storeId); - continue; - } - s_logger.info("Persisting an entry for snapshot " + snap.getSnapshotId() + " on region store " + storeId); - SnapshotDataStoreVO ss = new SnapshotDataStoreVO(); - ss.setSnapshotId(snap.getSnapshotId()); - ss.setDataStoreId(storeId); - ss.setRole(DataStoreRole.Image); - ss.setVolumeId(snap.getVolumeId()); - ss.setParentSnapshotId(snap.getParentSnapshotId()); - ss.setState(snap.getState()); - ss.setSize(snap.getSize()); - ss.setPhysicalSize(snap.getPhysicalSize()); - ss.setRefCnt(snap.getRefCnt()); - persist(ss); - // increase ref_cnt so that this will not be recycled before the content is pushed to region-wide store - snap.incrRefCnt(); - update(snap.getId(), snap); - } + + if (snapshots == null) { + s_logger.debug(String.format("There are no snapshots on cache store to duplicate to region store [%s].", storeId)); + return; } + s_logger.info(String.format("Duplicating [%s] snapshot cache store records to region store [%s].", snapshots.size(), storeId)); + + for (SnapshotDataStoreVO snap : snapshots) { + SnapshotDataStoreVO snapStore = findByStoreSnapshot(DataStoreRole.Image, storeId, snap.getSnapshotId()); + + if (snapStore != null) { + s_logger.debug(String.format("There is already an entry for snapshot [%s] on region store [%s].", snap.getSnapshotId(), storeId)); + continue; + } + + s_logger.info(String.format("Persisting an entry for snapshot [%s] on region store [%s].", snap.getSnapshotId(), storeId)); + SnapshotDataStoreVO ss = new SnapshotDataStoreVO(); + ss.setSnapshotId(snap.getSnapshotId()); + ss.setDataStoreId(storeId); + ss.setRole(DataStoreRole.Image); + ss.setVolumeId(snap.getVolumeId()); + ss.setParentSnapshotId(snap.getParentSnapshotId()); + ss.setState(snap.getState()); + ss.setSize(snap.getSize()); + ss.setPhysicalSize(snap.getPhysicalSize()); + ss.setRefCnt(snap.getRefCnt()); + persist(ss); + + snap.incrRefCnt(); + update(snap.getId(), snap); + } } @Override @@ -463,8 +419,9 @@ public void updateStoreRoleToCache(long storeId) { sc.setParameters("destroyed", false); List snaps = listBy(sc); if (snaps != null) { - s_logger.info("Update to cache store role for " + snaps.size() + " entries in snapshot_store_ref"); + s_logger.info(String.format("Updating role to cache store for [%s] entries in snapshot_store_ref.", snaps.size())); for (SnapshotDataStoreVO snap : snaps) { + s_logger.debug(String.format("Updating role to cache store for entry [%s].", snap)); snap.setRole(DataStoreRole.ImageCache); update(snap.getId(), snap); } @@ -515,31 +472,19 @@ protected SearchCriteria createSearchCriteriaBySnapshotIdAn return sc; } - private boolean isSnapshotChainingRequired(long volumeId) { - - hypervisorsSupportingSnapshotsChaining.add(Hypervisor.HypervisorType.XenServer); - + protected boolean isSnapshotChainingRequired(long volumeId) { SearchCriteria sc = snapshotVOSearch.create(); sc.setParameters("volume_id", volumeId); - SnapshotVO volSnapshot = _snapshotDao.findOneBy(sc); - - if (volSnapshot != null && hypervisorsSupportingSnapshotsChaining.contains(volSnapshot.getHypervisorType())) { - return true; - } + SnapshotVO snapshot = snapshotDao.findOneBy(sc); - return false; + return snapshot != null && HYPERVISORS_SUPPORTING_SNAPSHOTS_CHAINING.contains(snapshot.getHypervisorType()); } @Override public boolean expungeReferenceBySnapshotIdAndDataStoreRole(long snapshotId, DataStoreRole dataStoreRole) { SnapshotDataStoreVO snapshotDataStoreVo = findOneBy(createSearchCriteriaBySnapshotIdAndStoreRole(snapshotId, dataStoreRole)); - - if (snapshotDataStoreVo == null) { - return true; - } - - return expunge(snapshotDataStoreVo.getId()); + return snapshotDataStoreVo == null || expunge(snapshotDataStoreVo.getId()); } @Override diff --git a/engine/storage/src/test/java/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImplTest.java b/engine/storage/src/test/java/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImplTest.java index b7be8e3e5269..f11632d059de 100644 --- a/engine/storage/src/test/java/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImplTest.java +++ b/engine/storage/src/test/java/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImplTest.java @@ -19,7 +19,10 @@ package org.apache.cloudstack.storage.image.db; +import com.cloud.hypervisor.Hypervisor; import com.cloud.storage.DataStoreRole; +import com.cloud.storage.SnapshotVO; +import com.cloud.storage.dao.SnapshotDao; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; @@ -45,9 +48,16 @@ public class SnapshotDataStoreDaoImplTest { @Mock SearchBuilder searchBuilderMock; + @Mock + SnapshotDao snapshotDaoMock; + + @Mock + SnapshotVO snapshotVoMock; + @Before public void init(){ snapshotDataStoreDaoImplSpy.snapshotSearch = searchBuilderMock; + snapshotDataStoreDaoImplSpy.snapshotDao = snapshotDaoMock; } @Test @@ -74,4 +84,63 @@ public void validateCreateSearchCriteriaBySnapshotIdAndStoreRole() { Mockito.verify(searchCriteriaMock).setParameters("snapshot_id", 0l); Mockito.verify(searchCriteriaMock).setParameters("store_role", DataStoreRole.Image); } + + @Test + public void isSnapshotChainingRequiredTestSnapshotIsNullReturnFalse() { + snapshotDataStoreDaoImplSpy.snapshotVOSearch = searchBuilderMock; + Mockito.doReturn(searchCriteriaMock).when(searchBuilderMock).create(); + Mockito.doReturn(null).when(snapshotDaoMock).findOneBy(Mockito.any()); + Assert.assertFalse(snapshotDataStoreDaoImplSpy.isSnapshotChainingRequired(2)); + } + + @Test + public void isSnapshotChainingRequiredTestSnapshotIsNotNullReturnAccordingHypervisorType() { + snapshotDataStoreDaoImplSpy.snapshotVOSearch = searchBuilderMock; + Mockito.doReturn(searchCriteriaMock).when(searchBuilderMock).create(); + Mockito.doReturn(snapshotVoMock).when(snapshotDaoMock).findOneBy(Mockito.any()); + + for (Hypervisor.HypervisorType hypervisorType : Hypervisor.HypervisorType.values()) { + Mockito.doReturn(hypervisorType).when(snapshotVoMock).getHypervisorType(); + boolean result = snapshotDataStoreDaoImplSpy.isSnapshotChainingRequired(2); + + if (SnapshotDataStoreDaoImpl.HYPERVISORS_SUPPORTING_SNAPSHOTS_CHAINING.contains(hypervisorType)) { + Assert.assertTrue(result); + } else { + Assert.assertFalse(result); + } + } + } + + @Test + public void expungeReferenceBySnapshotIdAndDataStoreRoleTestSnapshotDataStoreIsNullReturnTrue() { + Mockito.doReturn(searchCriteriaMock).when(snapshotDataStoreDaoImplSpy).createSearchCriteriaBySnapshotIdAndStoreRole(Mockito.anyLong(), Mockito.any()); + Mockito.doReturn(null).when(snapshotDataStoreDaoImplSpy).findOneBy(Mockito.any()); + + for (DataStoreRole value : DataStoreRole.values()) { + Assert.assertTrue(snapshotDataStoreDaoImplSpy.expungeReferenceBySnapshotIdAndDataStoreRole(1, value)); + } + } + + @Test + public void expungeReferenceBySnapshotIdAndDataStoreRoleTestSnapshotDataStoreIsNotNullAndExpungeIsTrueReturnTrue() { + Mockito.doReturn(searchCriteriaMock).when(snapshotDataStoreDaoImplSpy).createSearchCriteriaBySnapshotIdAndStoreRole(Mockito.anyLong(), Mockito.any()); + Mockito.doReturn(snapshotDataStoreVoMock).when(snapshotDataStoreDaoImplSpy).findOneBy(Mockito.any()); + Mockito.doReturn(true).when(snapshotDataStoreDaoImplSpy).expunge(Mockito.anyLong()); + + for (DataStoreRole value : DataStoreRole.values()) { + Assert.assertTrue(snapshotDataStoreDaoImplSpy.expungeReferenceBySnapshotIdAndDataStoreRole(1, value)); + } + } + + @Test + public void expungeReferenceBySnapshotIdAndDataStoreRoleTestSnapshotDataStoreIsNotNullAndExpungeIsFalseReturnTrue() { + Mockito.doReturn(searchCriteriaMock).when(snapshotDataStoreDaoImplSpy).createSearchCriteriaBySnapshotIdAndStoreRole(Mockito.anyLong(), Mockito.any()); + Mockito.doReturn(snapshotDataStoreVoMock).when(snapshotDataStoreDaoImplSpy).findOneBy(Mockito.any()); + Mockito.doReturn(false).when(snapshotDataStoreDaoImplSpy).expunge(Mockito.anyLong()); + + for (DataStoreRole value : DataStoreRole.values()) { + Assert.assertFalse(snapshotDataStoreDaoImplSpy.expungeReferenceBySnapshotIdAndDataStoreRole(1, value)); + } + } + } diff --git a/framework/db/src/main/java/com/cloud/utils/db/GenericSearchBuilder.java b/framework/db/src/main/java/com/cloud/utils/db/GenericSearchBuilder.java index df6f1f7602fd..52d7f7889da2 100644 --- a/framework/db/src/main/java/com/cloud/utils/db/GenericSearchBuilder.java +++ b/framework/db/src/main/java/com/cloud/utils/db/GenericSearchBuilder.java @@ -18,7 +18,9 @@ import java.util.UUID; +import com.cloud.utils.Pair; import com.cloud.utils.db.SearchCriteria.Op; +import org.apache.commons.lang3.ArrayUtils; /** * GenericSearchBuilder is used to build a search based on a VO object. It @@ -63,10 +65,46 @@ * @param Result object that should contain the results. */ public class GenericSearchBuilder extends SearchBase, T, K> { + protected GenericSearchBuilder(Class entityType, Class resultType) { super(entityType, resultType); } + /** + * Constructor used only for testing. + */ + protected GenericSearchBuilder() { + super(); + } + + /** + * Adds n AND conditions according to the pairs of string and operation passed as parameter. + */ + public GenericSearchBuilder addAndConditions(Pair... fieldsAndOperations) { + if (ArrayUtils.isNotEmpty(fieldsAndOperations)) { + for (Pair fieldsAndOperation : fieldsAndOperations) { + if (fieldsAndOperation == null) { + continue; + } + + this.and(fieldsAndOperation.first(), fieldsAndOperation.second()); + } + } + return this; + } + + /** + * Adds an AND condition to the SearchBuilder.

+ * Facade to {@link GenericSearchBuilder#and(String, Object, Op)} without passing the second parameter due to it is not used in the method. + * + * @param name param name you will use later to set the values in this search condition. + * @param op operation to apply to the field. + * @return this + */ + public GenericSearchBuilder and(String name, Op op) { + return and(name, null, op); + } + /** * Adds an AND condition to the SearchBuilder. * diff --git a/framework/db/src/main/java/com/cloud/utils/db/SearchBase.java b/framework/db/src/main/java/com/cloud/utils/db/SearchBase.java index 6861b844dbf2..40ef1b183e36 100644 --- a/framework/db/src/main/java/com/cloud/utils/db/SearchBase.java +++ b/framework/db/src/main/java/com/cloud/utils/db/SearchBase.java @@ -66,6 +66,12 @@ public abstract class SearchBase, T, K> { protected SelectType _selectType; T _entity; + /** + * Constructor used only for testing. + */ + protected SearchBase() { + } + SearchBase(final Class entityType, final Class resultType) { init(entityType, resultType); } @@ -503,4 +509,4 @@ public Object intercept(final Object object, final Method method, final Object[] } } -} \ No newline at end of file +} diff --git a/framework/db/src/test/java/com/cloud/utils/db/GenericSearchBuilderTest.java b/framework/db/src/test/java/com/cloud/utils/db/GenericSearchBuilderTest.java new file mode 100644 index 000000000000..4b2faf1799d1 --- /dev/null +++ b/framework/db/src/test/java/com/cloud/utils/db/GenericSearchBuilderTest.java @@ -0,0 +1,54 @@ +package com.cloud.utils.db; + +import com.cloud.utils.Pair; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; + +/* + * 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. + */ +public class GenericSearchBuilderTest { + + GenericSearchBuilder genericSearchBuilderSpy = Mockito.spy(new GenericSearchBuilder<>()); + + @Test + public void addAndConditionsTestNoParametersCallNothingAndReturnThis() { + GenericSearchBuilder result = genericSearchBuilderSpy.addAndConditions(); + Assert.assertEquals(genericSearchBuilderSpy, result); + Mockito.verify(genericSearchBuilderSpy, Mockito.never()).and(Mockito.anyString(), Mockito.any()); + } + + @Test + public void addAndConditionsTestArrayIsEmptyCallNothingAndReturnThis() { + Pair[] pairs = new Pair[]{}; + + GenericSearchBuilder result = genericSearchBuilderSpy.addAndConditions(pairs); + Assert.assertEquals(genericSearchBuilderSpy, result); + Mockito.verify(genericSearchBuilderSpy, Mockito.never()).and(Mockito.anyString(), Mockito.any()); + } + + @Test + public void addAndConditionsTestVarargsWithNullCallAndOnlyForNonNullValuesAndReturnThis() { + Mockito.doReturn(null).when(genericSearchBuilderSpy).and(Mockito.anyString(), Mockito.any()); + + GenericSearchBuilder result = genericSearchBuilderSpy.addAndConditions(null, new Pair<>("test", SearchCriteria.Op.EQ), null); + Assert.assertEquals(genericSearchBuilderSpy, result); + Mockito.verify(genericSearchBuilderSpy).and(Mockito.anyString(), Mockito.any()); + } +} From 2ff479245c3687bcb82a9b1e52fad72732250226 Mon Sep 17 00:00:00 2001 From: GutoVeronezi Date: Mon, 19 Sep 2022 22:24:11 -0300 Subject: [PATCH 2/9] Create constants for duplicated literals --- .../image/db/SnapshotDataStoreDaoImpl.java | 139 ++++++++++-------- 1 file changed, 74 insertions(+), 65 deletions(-) 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 5ff333b5387f..dfc614d50fea 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 @@ -52,6 +52,15 @@ @Component public class SnapshotDataStoreDaoImpl extends GenericDaoBase implements SnapshotDataStoreDao { private static final Logger s_logger = Logger.getLogger(SnapshotDataStoreDaoImpl.class); + private static final String STORE_ID = "store_id"; + private static final String STORE_ROLE = "store_role"; + private static final String STATE = "state"; + private static final String REF_CNT = "ref_cnt"; + private static final String ID = "id"; + private static final String UPDATED_COUNT = "updatedCount"; + private static final String SNAPSHOT_ID = "snapshot_id"; + private static final String VOLUME_ID = "volume_id"; + private static final String CREATED = "created"; private SearchBuilder updateStateSearch; private SearchBuilder storeSearch; private SearchBuilder storeStateSearch; @@ -82,17 +91,17 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase params) throws ConfigurationException { super.configure(name, params); - Pair storeIdEq = new Pair<>("store_id", SearchCriteria.Op.EQ); - Pair storeRoleEq = new Pair<>("store_role", SearchCriteria.Op.EQ); - Pair stateEq = new Pair<>("state", SearchCriteria.Op.EQ); - Pair stateNeq = new Pair<>("state", SearchCriteria.Op.NEQ); - Pair stateIn = new Pair<>("state", SearchCriteria.Op.IN); - Pair refCntNeq = new Pair<>("ref_cnt", SearchCriteria.Op.NEQ); - Pair idEq = new Pair<>("id", SearchCriteria.Op.EQ); - Pair updateCountEq = new Pair<>("updatedCount", SearchCriteria.Op.EQ); - Pair snapshotIdEq = new Pair<>("snapshot_id", SearchCriteria.Op.EQ); - Pair volumeIdEq = new Pair<>("volume_id", SearchCriteria.Op.EQ); - Pair createdBetween = new Pair<>("created", SearchCriteria.Op.BETWEEN); + Pair storeIdEq = new Pair<>(STORE_ID, SearchCriteria.Op.EQ); + Pair storeRoleEq = new Pair<>(STORE_ROLE, SearchCriteria.Op.EQ); + Pair stateEq = new Pair<>(STATE, SearchCriteria.Op.EQ); + Pair stateNeq = new Pair<>(STATE, SearchCriteria.Op.NEQ); + Pair stateIn = new Pair<>(STATE, SearchCriteria.Op.IN); + Pair refCntNeq = new Pair<>(REF_CNT, SearchCriteria.Op.NEQ); + Pair idEq = new Pair<>(ID, SearchCriteria.Op.EQ); + Pair updateCountEq = new Pair<>(UPDATED_COUNT, SearchCriteria.Op.EQ); + Pair snapshotIdEq = new Pair<>(SNAPSHOT_ID, SearchCriteria.Op.EQ); + Pair volumeIdEq = new Pair<>(VOLUME_ID, SearchCriteria.Op.EQ); + Pair createdBetween = new Pair<>(CREATED, SearchCriteria.Op.BETWEEN); storeSearch = createSearchBuilder(); storeSearch.addAndConditions(storeIdEq, storeRoleEq, stateNeq); @@ -164,14 +173,14 @@ public boolean updateState(State currentState, Event event, State nextState, Dat Date oldUpdatedTime = dataObj.getUpdated(); SearchCriteria sc = updateStateSearch.create(); - sc.setParameters("id", dataObj.getId()); - sc.setParameters("state", currentState); - sc.setParameters("updatedCount", dataObj.getUpdatedCount()); + sc.setParameters(ID, dataObj.getId()); + sc.setParameters(STATE, currentState); + sc.setParameters(UPDATED_COUNT, dataObj.getUpdatedCount()); dataObj.incrUpdatedCount(); UpdateBuilder builder = getUpdateBuilder(dataObj); - builder.set(dataObj, "state", nextState); + builder.set(dataObj, STATE, nextState); builder.set(dataObj, "updated", new Date()); if (update(dataObj, sc) > 0) { @@ -196,41 +205,41 @@ public boolean updateState(State currentState, Event event, State nextState, Dat @Override public List listByStoreId(long id, DataStoreRole role) { SearchCriteria sc = storeSearch.create(); - sc.setParameters("store_id", id); - sc.setParameters("store_role", role); - sc.setParameters("state", ObjectInDataStoreStateMachine.State.Destroyed); + sc.setParameters(STORE_ID, id); + sc.setParameters(STORE_ROLE, role); + sc.setParameters(STATE, ObjectInDataStoreStateMachine.State.Destroyed); return listBy(sc); } @Override public List listByStoreIdAndState(long id, ObjectInDataStoreStateMachine.State state) { SearchCriteria sc = storeStateSearch.create(); - sc.setParameters("store_id", id); - sc.setParameters("state", state); + sc.setParameters(STORE_ID, id); + sc.setParameters(STATE, state); return listBy(sc); } @Override public void deletePrimaryRecordsForStore(long id, DataStoreRole role) { SearchCriteria sc = storeSearch.create(); - sc.setParameters("store_id", id); - sc.setParameters("store_role", role); + sc.setParameters(STORE_ID, id); + sc.setParameters(STORE_ROLE, role); remove(sc); } @Override public void deleteSnapshotRecordsOnPrimary() { SearchCriteria sc = storeSearch.create(); - sc.setParameters("store_role", DataStoreRole.Primary); + sc.setParameters(STORE_ROLE, DataStoreRole.Primary); remove(sc); } @Override public SnapshotDataStoreVO findByStoreSnapshot(DataStoreRole role, long storeId, long snapshotId) { SearchCriteria sc = storeSnapshotSearch.create(); - sc.setParameters("store_id", storeId); - sc.setParameters("snapshot_id", snapshotId); - sc.setParameters("store_role", role); + sc.setParameters(STORE_ID, storeId); + sc.setParameters(SNAPSHOT_ID, snapshotId); + sc.setParameters(STORE_ROLE, role); return findOneBy(sc); } @@ -275,12 +284,12 @@ public SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long vol } SearchCriteria sc = parentSnapshotSearch.create(); - sc.setParameters("volume_id", volumeId); - sc.setParameters("store_role", role.toString()); - sc.setParameters("state", ObjectInDataStoreStateMachine.State.Ready.name()); - sc.setParameters("store_id", storeId); + sc.setParameters(VOLUME_ID, volumeId); + sc.setParameters(STORE_ROLE, role.toString()); + sc.setParameters(STATE, ObjectInDataStoreStateMachine.State.Ready.name()); + sc.setParameters(STORE_ID, storeId); - List snapshotList = listBy(sc, new Filter(SnapshotDataStoreVO.class, "created", false, null, null)); + List snapshotList = listBy(sc, new Filter(SnapshotDataStoreVO.class, CREATED, false, null, null)); if (CollectionUtils.isNotEmpty(snapshotList)) { return snapshotList.get(0); } @@ -290,65 +299,65 @@ public SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long vol @Override public SnapshotDataStoreVO findBySnapshot(long snapshotId, DataStoreRole role) { SearchCriteria sc = createSearchCriteriaBySnapshotIdAndStoreRole(snapshotId, role); - sc.setParameters("state", State.Ready); + sc.setParameters(STATE, State.Ready); return findOneBy(sc); } @Override public SnapshotDataStoreVO findBySourceSnapshot(long snapshotId, DataStoreRole role) { SearchCriteria sc = createSearchCriteriaBySnapshotIdAndStoreRole(snapshotId, role); - sc.setParameters("state", State.Migrating); + sc.setParameters(STATE, State.Migrating); return findOneBy(sc); } @Override public List listAllByVolumeAndDataStore(long volumeId, DataStoreRole role) { SearchCriteria sc = volumeSearch.create(); - sc.setParameters("volume_id", volumeId); - sc.setParameters("store_role", role); + sc.setParameters(VOLUME_ID, volumeId); + sc.setParameters(STORE_ROLE, role); return listBy(sc); } @Override public SnapshotDataStoreVO findByVolume(long volumeId, DataStoreRole role) { SearchCriteria sc = volumeSearch.create(); - sc.setParameters("volume_id", volumeId); - sc.setParameters("store_role", role); + sc.setParameters(VOLUME_ID, volumeId); + sc.setParameters(STORE_ROLE, role); return findOneBy(sc); } @Override public SnapshotDataStoreVO findByVolume(long snapshotId, long volumeId, DataStoreRole role) { SearchCriteria sc = volumeSearch.create(); - sc.setParameters("snapshot_id", snapshotId); - sc.setParameters("volume_id", volumeId); - sc.setParameters("store_role", role); + sc.setParameters(SNAPSHOT_ID, snapshotId); + sc.setParameters(VOLUME_ID, volumeId); + sc.setParameters(STORE_ROLE, role); return findOneBy(sc); } @Override public List findBySnapshotId(long snapshotId) { SearchCriteria sc = snapshotIdSearch.create(); - sc.setParameters("snapshot_id", snapshotId); + sc.setParameters(SNAPSHOT_ID, snapshotId); return listBy(sc); } @Override public List listDestroyed(long id) { SearchCriteria sc = destroyedSearch.create(); - sc.setParameters("store_id", id); - sc.setParameters("store_role", DataStoreRole.Image); - sc.setParameters("state", ObjectInDataStoreStateMachine.State.Destroyed); + sc.setParameters(STORE_ID, id); + sc.setParameters(STORE_ROLE, DataStoreRole.Image); + sc.setParameters(STATE, ObjectInDataStoreStateMachine.State.Destroyed); return listBy(sc); } @Override public List listActiveOnCache(long id) { SearchCriteria sc = cacheSearch.create(); - sc.setParameters("store_id", id); - sc.setParameters("store_role", DataStoreRole.ImageCache); - sc.setParameters("state", ObjectInDataStoreStateMachine.State.Destroyed); - sc.setParameters("ref_cnt", 0); + sc.setParameters(STORE_ID, id); + sc.setParameters(STORE_ROLE, DataStoreRole.ImageCache); + sc.setParameters(STATE, ObjectInDataStoreStateMachine.State.Destroyed); + sc.setParameters(REF_CNT, 0); return listBy(sc); } @@ -358,7 +367,7 @@ public List listActiveOnCache(long id) { @Override public void duplicateCacheRecordsOnRegionStore(long storeId) { SearchCriteria sc = storeSnapshotSearch.create(); - sc.setParameters("store_role", DataStoreRole.ImageCache); + sc.setParameters(STORE_ROLE, DataStoreRole.ImageCache); sc.setParameters("destroyed", false); List snapshots = listBy(sc); @@ -398,24 +407,24 @@ public void duplicateCacheRecordsOnRegionStore(long storeId) { @Override public SnapshotDataStoreVO findReadyOnCache(long snapshotId) { SearchCriteria sc = storeSnapshotSearch.create(); - sc.setParameters("snapshot_id", snapshotId); - sc.setParameters("store_role", DataStoreRole.ImageCache); - sc.setParameters("state", ObjectInDataStoreStateMachine.State.Ready); + sc.setParameters(SNAPSHOT_ID, snapshotId); + sc.setParameters(STORE_ROLE, DataStoreRole.ImageCache); + sc.setParameters(STATE, ObjectInDataStoreStateMachine.State.Ready); return findOneIncludingRemovedBy(sc); } @Override public List listOnCache(long snapshotId) { SearchCriteria sc = storeSnapshotSearch.create(); - sc.setParameters("snapshot_id", snapshotId); - sc.setParameters("store_role", DataStoreRole.ImageCache); + sc.setParameters(SNAPSHOT_ID, snapshotId); + sc.setParameters(STORE_ROLE, DataStoreRole.ImageCache); return search(sc, null); } @Override public void updateStoreRoleToCache(long storeId) { SearchCriteria sc = storeSearch.create(); - sc.setParameters("store_id", storeId); + sc.setParameters(STORE_ID, storeId); sc.setParameters("destroyed", false); List snaps = listBy(sc); if (snaps != null) { @@ -431,7 +440,7 @@ public void updateStoreRoleToCache(long storeId) { @Override public void updateVolumeIds(long oldVolId, long newVolId) { SearchCriteria sc = volumeIdSearch.create(); - sc.setParameters("volume_id", oldVolId); + sc.setParameters(VOLUME_ID, oldVolId); SnapshotDataStoreVO snapshot = createForUpdate(); snapshot.setVolumeId(newVolId); UpdateBuilder ub = getUpdateBuilder(snapshot); @@ -441,23 +450,23 @@ public void updateVolumeIds(long oldVolId, long newVolId) { @Override public List listByState(ObjectInDataStoreStateMachine.State... states) { SearchCriteria sc = stateSearch.create(); - sc.setParameters("state", (Object[])states); + sc.setParameters(STATE, (Object[])states); return listBy(sc, null); } @Override public List findSnapshots(Long storeId, Date start, Date end) { SearchCriteria sc = snapshotCreatedSearch.create(); - sc.setParameters("store_id", storeId); + sc.setParameters(STORE_ID, storeId); if (start != null && end != null) { - sc.setParameters("created", start, end); + sc.setParameters(CREATED, start, end); } return search(sc, null); } public SnapshotDataStoreVO findDestroyedReferenceBySnapshot(long snapshotId, DataStoreRole role) { SearchCriteria sc = createSearchCriteriaBySnapshotIdAndStoreRole(snapshotId, role); - sc.setParameters("state", State.Destroyed); + sc.setParameters(STATE, State.Destroyed); return findOneBy(sc); } @@ -467,14 +476,14 @@ public SnapshotDataStoreVO findDestroyedReferenceBySnapshot(long snapshotId, Dat */ protected SearchCriteria createSearchCriteriaBySnapshotIdAndStoreRole(long snapshotId, DataStoreRole role) { SearchCriteria sc = snapshotSearch.create(); - sc.setParameters("snapshot_id", snapshotId); - sc.setParameters("store_role", role); + sc.setParameters(SNAPSHOT_ID, snapshotId); + sc.setParameters(STORE_ROLE, role); return sc; } protected boolean isSnapshotChainingRequired(long volumeId) { SearchCriteria sc = snapshotVOSearch.create(); - sc.setParameters("volume_id", volumeId); + sc.setParameters(VOLUME_ID, volumeId); SnapshotVO snapshot = snapshotDao.findOneBy(sc); @@ -490,8 +499,8 @@ public boolean expungeReferenceBySnapshotIdAndDataStoreRole(long snapshotId, Dat @Override public List listReadyByVolumeId(long volumeId) { SearchCriteria sc = volumeIdAndStateReadySearch.create(); - sc.setParameters("volume_id", volumeId); - sc.setParameters("state", State.Ready); + sc.setParameters(VOLUME_ID, volumeId); + sc.setParameters(STATE, State.Ready); return listBy(sc); } } From ec1c413cb917e89c5356adb4891635155119bb0c Mon Sep 17 00:00:00 2001 From: Daniel Augusto Veronezi Salvador <38945620+GutoVeronezi@users.noreply.github.com> Date: Tue, 20 Sep 2022 12:57:52 -0300 Subject: [PATCH 3/9] Add missing license to file Co-authored-by: dahn --- .../cloud/utils/db/GenericSearchBuilderTest.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/framework/db/src/test/java/com/cloud/utils/db/GenericSearchBuilderTest.java b/framework/db/src/test/java/com/cloud/utils/db/GenericSearchBuilderTest.java index 4b2faf1799d1..e985b5c9dc12 100644 --- a/framework/db/src/test/java/com/cloud/utils/db/GenericSearchBuilderTest.java +++ b/framework/db/src/test/java/com/cloud/utils/db/GenericSearchBuilderTest.java @@ -1,3 +1,19 @@ +// 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 +// 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.utils.db; import com.cloud.utils.Pair; From acec30038448de24f44ef4c78be72d0cd5b8d8ac Mon Sep 17 00:00:00 2001 From: Daniel Augusto Veronezi Salvador <38945620+GutoVeronezi@users.noreply.github.com> Date: Tue, 20 Sep 2022 13:40:15 -0300 Subject: [PATCH 4/9] Remove duplicated license header --- .../utils/db/GenericSearchBuilderTest.java | 30 +++++-------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/framework/db/src/test/java/com/cloud/utils/db/GenericSearchBuilderTest.java b/framework/db/src/test/java/com/cloud/utils/db/GenericSearchBuilderTest.java index e985b5c9dc12..f29f230c4f42 100644 --- a/framework/db/src/test/java/com/cloud/utils/db/GenericSearchBuilderTest.java +++ b/framework/db/src/test/java/com/cloud/utils/db/GenericSearchBuilderTest.java @@ -1,26 +1,3 @@ -// 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 -// 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.utils.db; - -import com.cloud.utils.Pair; -import org.junit.Assert; -import org.junit.Test; -import org.mockito.Mockito; - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -39,6 +16,13 @@ * specific language governing permissions and limitations * under the License. */ +package com.cloud.utils.db; + +import com.cloud.utils.Pair; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; + public class GenericSearchBuilderTest { GenericSearchBuilder genericSearchBuilderSpy = Mockito.spy(new GenericSearchBuilder<>()); From e285a77a2eb6920f472459f683cbf100a128af8b Mon Sep 17 00:00:00 2001 From: GutoVeronezi Date: Fri, 30 Sep 2022 20:05:08 -0300 Subject: [PATCH 5/9] Undo unnecessary changes --- .../image/db/SnapshotDataStoreDaoImpl.java | 70 +++++++++++-------- .../cloud/utils/db/GenericSearchBuilder.java | 37 ---------- .../java/com/cloud/utils/db/SearchBase.java | 6 -- .../utils/db/GenericSearchBuilderTest.java | 54 -------------- 4 files changed, 41 insertions(+), 126 deletions(-) delete mode 100644 framework/db/src/test/java/com/cloud/utils/db/GenericSearchBuilderTest.java 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 dfc614d50fea..ebd325aa13d4 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 @@ -26,7 +26,6 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; -import com.cloud.utils.Pair; 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; @@ -91,76 +90,89 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase params) throws ConfigurationException { super.configure(name, params); - Pair storeIdEq = new Pair<>(STORE_ID, SearchCriteria.Op.EQ); - Pair storeRoleEq = new Pair<>(STORE_ROLE, SearchCriteria.Op.EQ); - Pair stateEq = new Pair<>(STATE, SearchCriteria.Op.EQ); - Pair stateNeq = new Pair<>(STATE, SearchCriteria.Op.NEQ); - Pair stateIn = new Pair<>(STATE, SearchCriteria.Op.IN); - Pair refCntNeq = new Pair<>(REF_CNT, SearchCriteria.Op.NEQ); - Pair idEq = new Pair<>(ID, SearchCriteria.Op.EQ); - Pair updateCountEq = new Pair<>(UPDATED_COUNT, SearchCriteria.Op.EQ); - Pair snapshotIdEq = new Pair<>(SNAPSHOT_ID, SearchCriteria.Op.EQ); - Pair volumeIdEq = new Pair<>(VOLUME_ID, SearchCriteria.Op.EQ); - Pair createdBetween = new Pair<>(CREATED, SearchCriteria.Op.BETWEEN); - + // Note that snapshot_store_ref stores snapshots on primary as well as + // those on secondary, so we need to + // use (store_id, store_role) to search storeSearch = createSearchBuilder(); - storeSearch.addAndConditions(storeIdEq, storeRoleEq, stateNeq); + storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + storeSearch.and("store_role", storeSearch.entity().getRole(), SearchCriteria.Op.EQ); + storeSearch.and("state", storeSearch.entity().getState(), SearchCriteria.Op.NEQ); storeSearch.done(); storeStateSearch = createSearchBuilder(); - storeStateSearch.addAndConditions(storeIdEq, stateEq); + storeStateSearch.and("store_id", storeStateSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + storeStateSearch.and("state", storeStateSearch.entity().getState(), SearchCriteria.Op.EQ); storeStateSearch.done(); destroyedSearch = createSearchBuilder(); - destroyedSearch.addAndConditions(storeIdEq, storeRoleEq, stateEq); + destroyedSearch.and("store_id", destroyedSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + destroyedSearch.and("store_role", destroyedSearch.entity().getRole(), SearchCriteria.Op.EQ); + destroyedSearch.and("state", destroyedSearch.entity().getState(), SearchCriteria.Op.EQ); destroyedSearch.done(); cacheSearch = createSearchBuilder(); - cacheSearch.addAndConditions(storeIdEq, storeRoleEq, stateNeq, refCntNeq); + cacheSearch.and("store_id", cacheSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + cacheSearch.and("store_role", cacheSearch.entity().getRole(), SearchCriteria.Op.EQ); + cacheSearch.and("state", cacheSearch.entity().getState(), SearchCriteria.Op.NEQ); + cacheSearch.and("ref_cnt", cacheSearch.entity().getRefCnt(), SearchCriteria.Op.NEQ); cacheSearch.done(); - updateStateSearch = createSearchBuilder(); - updateStateSearch.addAndConditions(idEq, stateEq, updateCountEq); + updateStateSearch = this.createSearchBuilder(); + updateStateSearch.and("id", updateStateSearch.entity().getId(), SearchCriteria.Op.EQ); + updateStateSearch.and("state", updateStateSearch.entity().getState(), SearchCriteria.Op.EQ); + updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), SearchCriteria.Op.EQ); updateStateSearch.done(); snapshotSearch = createSearchBuilder(); - snapshotSearch.addAndConditions(snapshotIdEq, storeRoleEq, stateEq); + snapshotSearch.and("snapshot_id", snapshotSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ); + snapshotSearch.and("store_role", snapshotSearch.entity().getRole(), SearchCriteria.Op.EQ); + snapshotSearch.and("state", snapshotSearch.entity().getState(), SearchCriteria.Op.EQ); snapshotSearch.done(); storeSnapshotSearch = createSearchBuilder(); - storeSnapshotSearch.addAndConditions(snapshotIdEq, storeIdEq, storeRoleEq, stateEq); + storeSnapshotSearch.and("snapshot_id", storeSnapshotSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ); + storeSnapshotSearch.and("store_id", storeSnapshotSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + storeSnapshotSearch.and("store_role", storeSnapshotSearch.entity().getRole(), SearchCriteria.Op.EQ); + storeSnapshotSearch.and("state", storeSnapshotSearch.entity().getState(), SearchCriteria.Op.EQ); storeSnapshotSearch.done(); snapshotIdSearch = createSearchBuilder(); - snapshotIdSearch.addAndConditions(snapshotIdEq); + snapshotIdSearch.and("snapshot_id", snapshotIdSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ); snapshotIdSearch.done(); volumeIdSearch = createSearchBuilder(); - volumeIdSearch.addAndConditions(volumeIdEq); + volumeIdSearch.and("volume_id", volumeIdSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); volumeIdSearch.done(); volumeSearch = createSearchBuilder(); - volumeSearch.addAndConditions(volumeIdEq, storeRoleEq, snapshotIdEq); + volumeSearch.and("volume_id", volumeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); + volumeSearch.and("store_role", volumeSearch.entity().getRole(), SearchCriteria.Op.EQ); + volumeSearch.and("snapshot_id", volumeSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ); volumeSearch.done(); volumeIdAndStateReadySearch = createSearchBuilder(); - volumeIdAndStateReadySearch.addAndConditions(volumeIdEq, stateEq); + volumeIdAndStateReadySearch.and("volume_id", volumeIdAndStateReadySearch.entity().getVolumeId(), SearchCriteria.Op.EQ); + volumeIdAndStateReadySearch.and("state", volumeIdAndStateReadySearch.entity().getState(), SearchCriteria.Op.EQ); volumeIdAndStateReadySearch.done(); stateSearch = createSearchBuilder(); - stateSearch.addAndConditions(stateIn); + stateSearch.and("state", stateSearch.entity().getState(), SearchCriteria.Op.IN); stateSearch.done(); parentSnapshotSearch = createSearchBuilder(); - parentSnapshotSearch.addAndConditions(volumeIdEq, storeIdEq, storeRoleEq, stateEq); + parentSnapshotSearch.and("volume_id", parentSnapshotSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); + parentSnapshotSearch.and("store_id", parentSnapshotSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + parentSnapshotSearch.and("store_role", parentSnapshotSearch.entity().getRole(), SearchCriteria.Op.EQ); + parentSnapshotSearch.and("state", parentSnapshotSearch.entity().getState(), SearchCriteria.Op.EQ); parentSnapshotSearch.done(); snapshotVOSearch = snapshotDao.createSearchBuilder(); - snapshotVOSearch.addAndConditions(volumeIdEq); + snapshotVOSearch.and("volume_id", snapshotVOSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); snapshotVOSearch.done(); snapshotCreatedSearch = createSearchBuilder(); - snapshotCreatedSearch.addAndConditions(storeIdEq, createdBetween); + snapshotCreatedSearch.and("store_id", snapshotCreatedSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + snapshotCreatedSearch.and("created", snapshotCreatedSearch.entity().getCreated(), SearchCriteria.Op.BETWEEN); snapshotCreatedSearch.done(); return true; diff --git a/framework/db/src/main/java/com/cloud/utils/db/GenericSearchBuilder.java b/framework/db/src/main/java/com/cloud/utils/db/GenericSearchBuilder.java index 52d7f7889da2..fa6120e1ffa8 100644 --- a/framework/db/src/main/java/com/cloud/utils/db/GenericSearchBuilder.java +++ b/framework/db/src/main/java/com/cloud/utils/db/GenericSearchBuilder.java @@ -18,9 +18,7 @@ import java.util.UUID; -import com.cloud.utils.Pair; import com.cloud.utils.db.SearchCriteria.Op; -import org.apache.commons.lang3.ArrayUtils; /** * GenericSearchBuilder is used to build a search based on a VO object. It @@ -70,41 +68,6 @@ protected GenericSearchBuilder(Class entityType, Class resultType) { super(entityType, resultType); } - /** - * Constructor used only for testing. - */ - protected GenericSearchBuilder() { - super(); - } - - /** - * Adds n AND conditions according to the pairs of string and operation passed as parameter. - */ - public GenericSearchBuilder addAndConditions(Pair... fieldsAndOperations) { - if (ArrayUtils.isNotEmpty(fieldsAndOperations)) { - for (Pair fieldsAndOperation : fieldsAndOperations) { - if (fieldsAndOperation == null) { - continue; - } - - this.and(fieldsAndOperation.first(), fieldsAndOperation.second()); - } - } - return this; - } - - /** - * Adds an AND condition to the SearchBuilder.

- * Facade to {@link GenericSearchBuilder#and(String, Object, Op)} without passing the second parameter due to it is not used in the method. - * - * @param name param name you will use later to set the values in this search condition. - * @param op operation to apply to the field. - * @return this - */ - public GenericSearchBuilder and(String name, Op op) { - return and(name, null, op); - } - /** * Adds an AND condition to the SearchBuilder. * diff --git a/framework/db/src/main/java/com/cloud/utils/db/SearchBase.java b/framework/db/src/main/java/com/cloud/utils/db/SearchBase.java index 40ef1b183e36..3d41a62b43ca 100644 --- a/framework/db/src/main/java/com/cloud/utils/db/SearchBase.java +++ b/framework/db/src/main/java/com/cloud/utils/db/SearchBase.java @@ -66,12 +66,6 @@ public abstract class SearchBase, T, K> { protected SelectType _selectType; T _entity; - /** - * Constructor used only for testing. - */ - protected SearchBase() { - } - SearchBase(final Class entityType, final Class resultType) { init(entityType, resultType); } diff --git a/framework/db/src/test/java/com/cloud/utils/db/GenericSearchBuilderTest.java b/framework/db/src/test/java/com/cloud/utils/db/GenericSearchBuilderTest.java deleted file mode 100644 index f29f230c4f42..000000000000 --- a/framework/db/src/test/java/com/cloud/utils/db/GenericSearchBuilderTest.java +++ /dev/null @@ -1,54 +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 com.cloud.utils.db; - -import com.cloud.utils.Pair; -import org.junit.Assert; -import org.junit.Test; -import org.mockito.Mockito; - -public class GenericSearchBuilderTest { - - GenericSearchBuilder genericSearchBuilderSpy = Mockito.spy(new GenericSearchBuilder<>()); - - @Test - public void addAndConditionsTestNoParametersCallNothingAndReturnThis() { - GenericSearchBuilder result = genericSearchBuilderSpy.addAndConditions(); - Assert.assertEquals(genericSearchBuilderSpy, result); - Mockito.verify(genericSearchBuilderSpy, Mockito.never()).and(Mockito.anyString(), Mockito.any()); - } - - @Test - public void addAndConditionsTestArrayIsEmptyCallNothingAndReturnThis() { - Pair[] pairs = new Pair[]{}; - - GenericSearchBuilder result = genericSearchBuilderSpy.addAndConditions(pairs); - Assert.assertEquals(genericSearchBuilderSpy, result); - Mockito.verify(genericSearchBuilderSpy, Mockito.never()).and(Mockito.anyString(), Mockito.any()); - } - - @Test - public void addAndConditionsTestVarargsWithNullCallAndOnlyForNonNullValuesAndReturnThis() { - Mockito.doReturn(null).when(genericSearchBuilderSpy).and(Mockito.anyString(), Mockito.any()); - - GenericSearchBuilder result = genericSearchBuilderSpy.addAndConditions(null, new Pair<>("test", SearchCriteria.Op.EQ), null); - Assert.assertEquals(genericSearchBuilderSpy, result); - Mockito.verify(genericSearchBuilderSpy).and(Mockito.anyString(), Mockito.any()); - } -} From 626addbd013653faaa123a2080f53e13df149015 Mon Sep 17 00:00:00 2001 From: GutoVeronezi Date: Fri, 30 Sep 2022 20:26:17 -0300 Subject: [PATCH 6/9] Refactor search builders --- .../image/db/SnapshotDataStoreDaoImpl.java | 164 ++++++------------ 1 file changed, 57 insertions(+), 107 deletions(-) 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 ebd325aa13d4..4f5e0ca135d8 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 @@ -60,21 +60,11 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase updateStateSearch; - private SearchBuilder storeSearch; - private SearchBuilder storeStateSearch; - private SearchBuilder destroyedSearch; - private SearchBuilder cacheSearch; - private SearchBuilder storeSnapshotSearch; - private SearchBuilder snapshotIdSearch; - private SearchBuilder volumeIdSearch; - private SearchBuilder volumeIdAndStateReadySearch; - private SearchBuilder volumeSearch; + private SearchBuilder searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq; + private SearchBuilder searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq; private SearchBuilder stateSearch; - private SearchBuilder parentSnapshotSearch; protected SearchBuilder snapshotVOSearch; private SearchBuilder snapshotCreatedSearch; - protected SearchBuilder snapshotSearch; protected static final List HYPERVISORS_SUPPORTING_SNAPSHOTS_CHAINING = List.of(Hypervisor.HypervisorType.XenServer); @@ -90,89 +80,49 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase params) throws ConfigurationException { super.configure(name, params); - // Note that snapshot_store_ref stores snapshots on primary as well as - // those on secondary, so we need to - // use (store_id, store_role) to search - storeSearch = createSearchBuilder(); - storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); - storeSearch.and("store_role", storeSearch.entity().getRole(), SearchCriteria.Op.EQ); - storeSearch.and("state", storeSearch.entity().getState(), SearchCriteria.Op.NEQ); - storeSearch.done(); - - storeStateSearch = createSearchBuilder(); - storeStateSearch.and("store_id", storeStateSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); - storeStateSearch.and("state", storeStateSearch.entity().getState(), SearchCriteria.Op.EQ); - storeStateSearch.done(); - - destroyedSearch = createSearchBuilder(); - destroyedSearch.and("store_id", destroyedSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); - destroyedSearch.and("store_role", destroyedSearch.entity().getRole(), SearchCriteria.Op.EQ); - destroyedSearch.and("state", destroyedSearch.entity().getState(), SearchCriteria.Op.EQ); - destroyedSearch.done(); - - cacheSearch = createSearchBuilder(); - cacheSearch.and("store_id", cacheSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); - cacheSearch.and("store_role", cacheSearch.entity().getRole(), SearchCriteria.Op.EQ); - cacheSearch.and("state", cacheSearch.entity().getState(), SearchCriteria.Op.NEQ); - cacheSearch.and("ref_cnt", cacheSearch.entity().getRefCnt(), SearchCriteria.Op.NEQ); - cacheSearch.done(); - - updateStateSearch = this.createSearchBuilder(); - updateStateSearch.and("id", updateStateSearch.entity().getId(), SearchCriteria.Op.EQ); - updateStateSearch.and("state", updateStateSearch.entity().getState(), SearchCriteria.Op.EQ); - updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), SearchCriteria.Op.EQ); - updateStateSearch.done(); - - snapshotSearch = createSearchBuilder(); - snapshotSearch.and("snapshot_id", snapshotSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ); - snapshotSearch.and("store_role", snapshotSearch.entity().getRole(), SearchCriteria.Op.EQ); - snapshotSearch.and("state", snapshotSearch.entity().getState(), SearchCriteria.Op.EQ); - snapshotSearch.done(); - - storeSnapshotSearch = createSearchBuilder(); - storeSnapshotSearch.and("snapshot_id", storeSnapshotSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ); - storeSnapshotSearch.and("store_id", storeSnapshotSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); - storeSnapshotSearch.and("store_role", storeSnapshotSearch.entity().getRole(), SearchCriteria.Op.EQ); - storeSnapshotSearch.and("state", storeSnapshotSearch.entity().getState(), SearchCriteria.Op.EQ); - storeSnapshotSearch.done(); - - snapshotIdSearch = createSearchBuilder(); - snapshotIdSearch.and("snapshot_id", snapshotIdSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ); - snapshotIdSearch.done(); - - volumeIdSearch = createSearchBuilder(); - volumeIdSearch.and("volume_id", volumeIdSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); - volumeIdSearch.done(); - - volumeSearch = createSearchBuilder(); - volumeSearch.and("volume_id", volumeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); - volumeSearch.and("store_role", volumeSearch.entity().getRole(), SearchCriteria.Op.EQ); - volumeSearch.and("snapshot_id", volumeSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ); - volumeSearch.done(); - - volumeIdAndStateReadySearch = createSearchBuilder(); - volumeIdAndStateReadySearch.and("volume_id", volumeIdAndStateReadySearch.entity().getVolumeId(), SearchCriteria.Op.EQ); - volumeIdAndStateReadySearch.and("state", volumeIdAndStateReadySearch.entity().getState(), SearchCriteria.Op.EQ); - volumeIdAndStateReadySearch.done(); + searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq = createSearchBuilder(); + searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.and(STORE_ID, searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.entity().getDataStoreId(), SearchCriteria.Op.EQ); + searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.and(STORE_ROLE, searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.entity().getRole(), SearchCriteria.Op.EQ); + searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.and(STATE, searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.entity().getState(), SearchCriteria.Op.NEQ); + searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.and(REF_CNT searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.entity().getRefCnt(), SearchCriteria.Op.NEQ); + searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.done(); + + searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq = createSearchBuilder(); + searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.and(STORE_ID, + searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.entity().getDataStoreId(), SearchCriteria.Op.EQ); + + searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.and(STATE, + searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.entity().getState(), SearchCriteria.Op.EQ); + + searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.and(STORE_ROLE, + searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.entity().getRole(), SearchCriteria.Op.EQ); + + searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.and(ID, + searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.entity().getId(), SearchCriteria.Op.EQ); + + searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.and(UPDATED_COUNT, + searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.entity().getUpdatedCount(), SearchCriteria.Op.EQ); + + searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.and(SNAPSHOT_ID, + searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.entity().getSnapshotId(), SearchCriteria.Op.EQ); + + searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.and(VOLUME_ID, + searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.entity().getVolumeId(), SearchCriteria.Op.EQ); + + searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.done(); + stateSearch = createSearchBuilder(); - stateSearch.and("state", stateSearch.entity().getState(), SearchCriteria.Op.IN); + stateSearch.and(STATE, stateSearch.entity().getState(), SearchCriteria.Op.IN); stateSearch.done(); - parentSnapshotSearch = createSearchBuilder(); - parentSnapshotSearch.and("volume_id", parentSnapshotSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); - parentSnapshotSearch.and("store_id", parentSnapshotSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); - parentSnapshotSearch.and("store_role", parentSnapshotSearch.entity().getRole(), SearchCriteria.Op.EQ); - parentSnapshotSearch.and("state", parentSnapshotSearch.entity().getState(), SearchCriteria.Op.EQ); - parentSnapshotSearch.done(); - snapshotVOSearch = snapshotDao.createSearchBuilder(); - snapshotVOSearch.and("volume_id", snapshotVOSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); + snapshotVOSearch.and(VOLUME_ID, snapshotVOSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); snapshotVOSearch.done(); snapshotCreatedSearch = createSearchBuilder(); - snapshotCreatedSearch.and("store_id", snapshotCreatedSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); - snapshotCreatedSearch.and("created", snapshotCreatedSearch.entity().getCreated(), SearchCriteria.Op.BETWEEN); + snapshotCreatedSearch.and(STORE_ID, snapshotCreatedSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + snapshotCreatedSearch.and(CREATED, snapshotCreatedSearch.entity().getCreated(), SearchCriteria.Op.BETWEEN); snapshotCreatedSearch.done(); return true; @@ -184,7 +134,7 @@ public boolean updateState(State currentState, Event event, State nextState, Dat Long oldUpdated = dataObj.getUpdatedCount(); Date oldUpdatedTime = dataObj.getUpdated(); - SearchCriteria sc = updateStateSearch.create(); + SearchCriteria sc = searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create(); sc.setParameters(ID, dataObj.getId()); sc.setParameters(STATE, currentState); sc.setParameters(UPDATED_COUNT, dataObj.getUpdatedCount()); @@ -216,7 +166,7 @@ public boolean updateState(State currentState, Event event, State nextState, Dat @Override public List listByStoreId(long id, DataStoreRole role) { - SearchCriteria sc = storeSearch.create(); + SearchCriteria sc = searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.create(); sc.setParameters(STORE_ID, id); sc.setParameters(STORE_ROLE, role); sc.setParameters(STATE, ObjectInDataStoreStateMachine.State.Destroyed); @@ -225,7 +175,7 @@ public List listByStoreId(long id, DataStoreRole role) { @Override public List listByStoreIdAndState(long id, ObjectInDataStoreStateMachine.State state) { - SearchCriteria sc = storeStateSearch.create(); + SearchCriteria sc = searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create(); sc.setParameters(STORE_ID, id); sc.setParameters(STATE, state); return listBy(sc); @@ -233,7 +183,7 @@ public List listByStoreIdAndState(long id, ObjectInDataStor @Override public void deletePrimaryRecordsForStore(long id, DataStoreRole role) { - SearchCriteria sc = storeSearch.create(); + SearchCriteria sc = searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.create(); sc.setParameters(STORE_ID, id); sc.setParameters(STORE_ROLE, role); remove(sc); @@ -241,14 +191,14 @@ public void deletePrimaryRecordsForStore(long id, DataStoreRole role) { @Override public void deleteSnapshotRecordsOnPrimary() { - SearchCriteria sc = storeSearch.create(); + SearchCriteria sc = searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.create(); sc.setParameters(STORE_ROLE, DataStoreRole.Primary); remove(sc); } @Override public SnapshotDataStoreVO findByStoreSnapshot(DataStoreRole role, long storeId, long snapshotId) { - SearchCriteria sc = storeSnapshotSearch.create(); + SearchCriteria sc = searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create(); sc.setParameters(STORE_ID, storeId); sc.setParameters(SNAPSHOT_ID, snapshotId); sc.setParameters(STORE_ROLE, role); @@ -295,7 +245,7 @@ public SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long vol return null; } - SearchCriteria sc = parentSnapshotSearch.create(); + SearchCriteria sc = searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create(); sc.setParameters(VOLUME_ID, volumeId); sc.setParameters(STORE_ROLE, role.toString()); sc.setParameters(STATE, ObjectInDataStoreStateMachine.State.Ready.name()); @@ -324,7 +274,7 @@ public SnapshotDataStoreVO findBySourceSnapshot(long snapshotId, DataStoreRole r @Override public List listAllByVolumeAndDataStore(long volumeId, DataStoreRole role) { - SearchCriteria sc = volumeSearch.create(); + SearchCriteria sc = searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create(); sc.setParameters(VOLUME_ID, volumeId); sc.setParameters(STORE_ROLE, role); return listBy(sc); @@ -332,7 +282,7 @@ public List listAllByVolumeAndDataStore(long volumeId, Data @Override public SnapshotDataStoreVO findByVolume(long volumeId, DataStoreRole role) { - SearchCriteria sc = volumeSearch.create(); + SearchCriteria sc = searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create(); sc.setParameters(VOLUME_ID, volumeId); sc.setParameters(STORE_ROLE, role); return findOneBy(sc); @@ -340,7 +290,7 @@ public SnapshotDataStoreVO findByVolume(long volumeId, DataStoreRole role) { @Override public SnapshotDataStoreVO findByVolume(long snapshotId, long volumeId, DataStoreRole role) { - SearchCriteria sc = volumeSearch.create(); + SearchCriteria sc = searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create(); sc.setParameters(SNAPSHOT_ID, snapshotId); sc.setParameters(VOLUME_ID, volumeId); sc.setParameters(STORE_ROLE, role); @@ -349,14 +299,14 @@ public SnapshotDataStoreVO findByVolume(long snapshotId, long volumeId, DataStor @Override public List findBySnapshotId(long snapshotId) { - SearchCriteria sc = snapshotIdSearch.create(); + SearchCriteria sc = searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create(); sc.setParameters(SNAPSHOT_ID, snapshotId); return listBy(sc); } @Override public List listDestroyed(long id) { - SearchCriteria sc = destroyedSearch.create(); + SearchCriteria sc = searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create(); sc.setParameters(STORE_ID, id); sc.setParameters(STORE_ROLE, DataStoreRole.Image); sc.setParameters(STATE, ObjectInDataStoreStateMachine.State.Destroyed); @@ -365,7 +315,7 @@ public List listDestroyed(long id) { @Override public List listActiveOnCache(long id) { - SearchCriteria sc = cacheSearch.create(); + SearchCriteria sc = searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.create(); sc.setParameters(STORE_ID, id); sc.setParameters(STORE_ROLE, DataStoreRole.ImageCache); sc.setParameters(STATE, ObjectInDataStoreStateMachine.State.Destroyed); @@ -378,7 +328,7 @@ public List listActiveOnCache(long id) { */ @Override public void duplicateCacheRecordsOnRegionStore(long storeId) { - SearchCriteria sc = storeSnapshotSearch.create(); + SearchCriteria sc = searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create(); sc.setParameters(STORE_ROLE, DataStoreRole.ImageCache); sc.setParameters("destroyed", false); List snapshots = listBy(sc); @@ -418,7 +368,7 @@ public void duplicateCacheRecordsOnRegionStore(long storeId) { @Override public SnapshotDataStoreVO findReadyOnCache(long snapshotId) { - SearchCriteria sc = storeSnapshotSearch.create(); + SearchCriteria sc = searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create(); sc.setParameters(SNAPSHOT_ID, snapshotId); sc.setParameters(STORE_ROLE, DataStoreRole.ImageCache); sc.setParameters(STATE, ObjectInDataStoreStateMachine.State.Ready); @@ -427,7 +377,7 @@ public SnapshotDataStoreVO findReadyOnCache(long snapshotId) { @Override public List listOnCache(long snapshotId) { - SearchCriteria sc = storeSnapshotSearch.create(); + SearchCriteria sc = searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create(); sc.setParameters(SNAPSHOT_ID, snapshotId); sc.setParameters(STORE_ROLE, DataStoreRole.ImageCache); return search(sc, null); @@ -435,7 +385,7 @@ public List listOnCache(long snapshotId) { @Override public void updateStoreRoleToCache(long storeId) { - SearchCriteria sc = storeSearch.create(); + SearchCriteria sc = searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.create(); sc.setParameters(STORE_ID, storeId); sc.setParameters("destroyed", false); List snaps = listBy(sc); @@ -451,7 +401,7 @@ public void updateStoreRoleToCache(long storeId) { @Override public void updateVolumeIds(long oldVolId, long newVolId) { - SearchCriteria sc = volumeIdSearch.create(); + SearchCriteria sc = searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create(); sc.setParameters(VOLUME_ID, oldVolId); SnapshotDataStoreVO snapshot = createForUpdate(); snapshot.setVolumeId(newVolId); @@ -487,7 +437,7 @@ public SnapshotDataStoreVO findDestroyedReferenceBySnapshot(long snapshotId, Dat * @return A SearchCriteria with snapshot id and data store role */ protected SearchCriteria createSearchCriteriaBySnapshotIdAndStoreRole(long snapshotId, DataStoreRole role) { - SearchCriteria sc = snapshotSearch.create(); + SearchCriteria sc = searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create(); sc.setParameters(SNAPSHOT_ID, snapshotId); sc.setParameters(STORE_ROLE, role); return sc; @@ -510,7 +460,7 @@ public boolean expungeReferenceBySnapshotIdAndDataStoreRole(long snapshotId, Dat @Override public List listReadyByVolumeId(long volumeId) { - SearchCriteria sc = volumeIdAndStateReadySearch.create(); + SearchCriteria sc = searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create(); sc.setParameters(VOLUME_ID, volumeId); sc.setParameters(STATE, State.Ready); return listBy(sc); From 7972f3f1f6a9374319097afb96c933a109df40cd Mon Sep 17 00:00:00 2001 From: GutoVeronezi Date: Fri, 30 Sep 2022 20:29:01 -0300 Subject: [PATCH 7/9] Undo some changes --- .../src/main/java/com/cloud/utils/db/GenericSearchBuilder.java | 1 - framework/db/src/main/java/com/cloud/utils/db/SearchBase.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/framework/db/src/main/java/com/cloud/utils/db/GenericSearchBuilder.java b/framework/db/src/main/java/com/cloud/utils/db/GenericSearchBuilder.java index fa6120e1ffa8..df6f1f7602fd 100644 --- a/framework/db/src/main/java/com/cloud/utils/db/GenericSearchBuilder.java +++ b/framework/db/src/main/java/com/cloud/utils/db/GenericSearchBuilder.java @@ -63,7 +63,6 @@ * @param Result object that should contain the results. */ public class GenericSearchBuilder extends SearchBase, T, K> { - protected GenericSearchBuilder(Class entityType, Class resultType) { super(entityType, resultType); } diff --git a/framework/db/src/main/java/com/cloud/utils/db/SearchBase.java b/framework/db/src/main/java/com/cloud/utils/db/SearchBase.java index 3d41a62b43ca..6861b844dbf2 100644 --- a/framework/db/src/main/java/com/cloud/utils/db/SearchBase.java +++ b/framework/db/src/main/java/com/cloud/utils/db/SearchBase.java @@ -503,4 +503,4 @@ public Object intercept(final Object object, final Method method, final Object[] } } -} +} \ No newline at end of file From be6378061f61f39ed242fc1fb4fb979f8f0dc5f1 Mon Sep 17 00:00:00 2001 From: GutoVeronezi Date: Mon, 3 Oct 2022 08:59:21 -0300 Subject: [PATCH 8/9] Add missing comma --- .../cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 4f5e0ca135d8..7e840b28584e 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 @@ -84,7 +84,7 @@ public boolean configure(String name, Map params) throws Configu searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.and(STORE_ID, searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.entity().getDataStoreId(), SearchCriteria.Op.EQ); searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.and(STORE_ROLE, searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.entity().getRole(), SearchCriteria.Op.EQ); searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.and(STATE, searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.entity().getState(), SearchCriteria.Op.NEQ); - searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.and(REF_CNT searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.entity().getRefCnt(), SearchCriteria.Op.NEQ); + searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.and(REF_CNT, searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.entity().getRefCnt(), SearchCriteria.Op.NEQ); searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.done(); searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq = createSearchBuilder(); From e9a76a849cc4395b4a2871e9cc452a09cc2fc512 Mon Sep 17 00:00:00 2001 From: GutoVeronezi Date: Mon, 3 Oct 2022 12:57:34 -0300 Subject: [PATCH 9/9] Fixes --- .../cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java | 2 +- .../storage/image/db/SnapshotDataStoreDaoImplTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 7e840b28584e..c3cfe89d491e 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 @@ -61,7 +61,7 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq; - private SearchBuilder searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq; + protected SearchBuilder searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq; private SearchBuilder stateSearch; protected SearchBuilder snapshotVOSearch; private SearchBuilder snapshotCreatedSearch; diff --git a/engine/storage/src/test/java/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImplTest.java b/engine/storage/src/test/java/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImplTest.java index f11632d059de..0a02721f67fb 100644 --- a/engine/storage/src/test/java/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImplTest.java +++ b/engine/storage/src/test/java/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImplTest.java @@ -56,7 +56,7 @@ public class SnapshotDataStoreDaoImplTest { @Before public void init(){ - snapshotDataStoreDaoImplSpy.snapshotSearch = searchBuilderMock; + snapshotDataStoreDaoImplSpy.searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq = searchBuilderMock; snapshotDataStoreDaoImplSpy.snapshotDao = snapshotDaoMock; }