This is an automated email from the ASF dual-hosted git repository.
dahn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/main by this push:
new f7b29856d17 Refactor SnapshotDataStoreDaoImpl (#6751)
f7b29856d17 is described below
commit f7b29856d17dd2826ba87427425340558d732398
Author: Daniel Augusto Veronezi Salvador
<[email protected]>
AuthorDate: Tue Oct 11 08:53:02 2022 -0300
Refactor SnapshotDataStoreDaoImpl (#6751)
* Refactor SnapshotDataStoreDaoImpl and add unit tests
* Create constants for duplicated literals
* Refactor search builders
Co-authored-by: GutoVeronezi <[email protected]>
Co-authored-by: dahn <[email protected]>
---
.../storage/image/db/SnapshotDataStoreDaoImpl.java | 502 +++++++++------------
.../image/db/SnapshotDataStoreDaoImplTest.java | 71 ++-
2 files changed, 279 insertions(+), 294 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 fa6c8d1f606..c3cfe89d491 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 @@ package org.apache.cloudstack.storage.image.db;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
-import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -33,6 +32,7 @@ import
org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreState
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,130 +45,84 @@ import com.cloud.utils.db.Filter;
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 {
private static final Logger s_logger =
Logger.getLogger(SnapshotDataStoreDaoImpl.class);
- private SearchBuilder<SnapshotDataStoreVO> updateStateSearch;
- private SearchBuilder<SnapshotDataStoreVO> storeSearch;
- private SearchBuilder<SnapshotDataStoreVO> storeStateSearch;
- private SearchBuilder<SnapshotDataStoreVO> destroyedSearch;
- private SearchBuilder<SnapshotDataStoreVO> cacheSearch;
- private SearchBuilder<SnapshotDataStoreVO> storeSnapshotSearch;
- private SearchBuilder<SnapshotDataStoreVO> snapshotIdSearch;
- private SearchBuilder<SnapshotDataStoreVO> volumeIdSearch;
- private SearchBuilder<SnapshotDataStoreVO> volumeIdAndStateReadySearch;
- private SearchBuilder<SnapshotDataStoreVO> volumeSearch;
+ 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<SnapshotDataStoreVO>
searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq;
+ protected SearchBuilder<SnapshotDataStoreVO>
searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq;
private SearchBuilder<SnapshotDataStoreVO> stateSearch;
- private SearchBuilder<SnapshotDataStoreVO> parentSnapshotSearch;
- private SearchBuilder<SnapshotVO> snapshotVOSearch;
+ protected SearchBuilder<SnapshotVO> snapshotVOSearch;
private SearchBuilder<SnapshotDataStoreVO> snapshotCreatedSearch;
- protected SearchBuilder<SnapshotDataStoreVO> snapshotSearch;
- public static ArrayList<Hypervisor.HypervisorType>
hypervisorsSupportingSnapshotsChaining = new
ArrayList<Hypervisor.HypervisorType>();
+ protected static final List<Hypervisor.HypervisorType>
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<String, Object> 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(), Op.EQ);
- updateStateSearch.and("state", updateStateSearch.entity().getState(),
Op.EQ);
- updateStateSearch.and("updatedCount",
updateStateSearch.entity().getUpdatedCount(), 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 = snapshotDao.createSearchBuilder();
+ snapshotVOSearch.and(VOLUME_ID,
snapshotVOSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
snapshotVOSearch.done();
snapshotCreatedSearch = createSearchBuilder();
- snapshotCreatedSearch.and("store_id",
snapshotCreatedSearch.entity().getDataStoreId(), Op.EQ);
- snapshotCreatedSearch.and("created",
snapshotCreatedSearch.entity().getCreated(), 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;
@@ -180,142 +134,105 @@ public class SnapshotDataStoreDaoImpl extends
GenericDaoBase<SnapshotDataStoreVO
Long oldUpdated = dataObj.getUpdatedCount();
Date oldUpdatedTime = dataObj.getUpdated();
- SearchCriteria<SnapshotDataStoreVO> sc = updateStateSearch.create();
- sc.setParameters("id", dataObj.getId());
- sc.setParameters("state", currentState);
- sc.setParameters("updatedCount", dataObj.getUpdatedCount());
+ SearchCriteria<SnapshotDataStoreVO> sc =
searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create();
+ 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());
- 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
public List<SnapshotDataStoreVO> listByStoreId(long id, DataStoreRole
role) {
- SearchCriteria<SnapshotDataStoreVO> sc = storeSearch.create();
- sc.setParameters("store_id", id);
- sc.setParameters("store_role", role);
- sc.setParameters("state",
ObjectInDataStoreStateMachine.State.Destroyed);
+ SearchCriteria<SnapshotDataStoreVO> sc =
searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.create();
+ sc.setParameters(STORE_ID, id);
+ sc.setParameters(STORE_ROLE, role);
+ sc.setParameters(STATE, ObjectInDataStoreStateMachine.State.Destroyed);
return listBy(sc);
}
@Override
public List<SnapshotDataStoreVO> listByStoreIdAndState(long id,
ObjectInDataStoreStateMachine.State state) {
- SearchCriteria<SnapshotDataStoreVO> sc = storeStateSearch.create();
- sc.setParameters("store_id", id);
- sc.setParameters("state", state);
+ SearchCriteria<SnapshotDataStoreVO> sc =
searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create();
+ sc.setParameters(STORE_ID, id);
+ sc.setParameters(STATE, state);
return listBy(sc);
}
@Override
public void deletePrimaryRecordsForStore(long id, DataStoreRole role) {
- SearchCriteria<SnapshotDataStoreVO> sc = storeSearch.create();
- sc.setParameters("store_id", id);
- sc.setParameters("store_role", role);
- TransactionLegacy txn = TransactionLegacy.currentTxn();
- txn.start();
+ SearchCriteria<SnapshotDataStoreVO> sc =
searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.create();
+ sc.setParameters(STORE_ID, id);
+ sc.setParameters(STORE_ROLE, role);
remove(sc);
- txn.commit();
}
@Override
public void deleteSnapshotRecordsOnPrimary() {
- SearchCriteria<SnapshotDataStoreVO> sc = storeSearch.create();
- sc.setParameters("store_role", DataStoreRole.Primary);
- TransactionLegacy txn = TransactionLegacy.currentTxn();
- txn.start();
+ SearchCriteria<SnapshotDataStoreVO> sc =
searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.create();
+ sc.setParameters(STORE_ROLE, DataStoreRole.Primary);
remove(sc);
- txn.commit();
}
@Override
public SnapshotDataStoreVO findByStoreSnapshot(DataStoreRole role, long
storeId, long snapshotId) {
- SearchCriteria<SnapshotDataStoreVO> sc = storeSnapshotSearch.create();
- sc.setParameters("store_id", storeId);
- sc.setParameters("snapshot_id", snapshotId);
- sc.setParameters("store_role", role);
+ SearchCriteria<SnapshotDataStoreVO> sc =
searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create();
+ sc.setParameters(STORE_ID, storeId);
+ sc.setParameters(SNAPSHOT_ID, snapshotId);
+ sc.setParameters(STORE_ROLE, role);
return findOneBy(sc);
}
@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 +240,20 @@ public class SnapshotDataStoreDaoImpl extends
GenericDaoBase<SnapshotDataStoreVO
@Override
@DB
public SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId,
Long volumeId) {
- if(isSnapshotChainingRequired(volumeId)) {
- SearchCriteria<SnapshotDataStoreVO> 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<SnapshotDataStoreVO> 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<SnapshotDataStoreVO> sc =
searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.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<SnapshotDataStoreVO> snapshotList = listBy(sc, new
Filter(SnapshotDataStoreVO.class, CREATED, false, null, null));
+ if (CollectionUtils.isNotEmpty(snapshotList)) {
+ return snapshotList.get(0);
}
return null;
}
@@ -341,130 +261,138 @@ public class SnapshotDataStoreDaoImpl extends
GenericDaoBase<SnapshotDataStoreVO
@Override
public SnapshotDataStoreVO findBySnapshot(long snapshotId, DataStoreRole
role) {
SearchCriteria<SnapshotDataStoreVO> 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<SnapshotDataStoreVO> sc =
createSearchCriteriaBySnapshotIdAndStoreRole(snapshotId, role);
- sc.setParameters("state", State.Migrating);
+ sc.setParameters(STATE, State.Migrating);
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);
+ SearchCriteria<SnapshotDataStoreVO> sc =
searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.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();
- sc.setParameters("volume_id", volumeId);
- sc.setParameters("store_role", role);
+ SearchCriteria<SnapshotDataStoreVO> sc =
searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create();
+ sc.setParameters(VOLUME_ID, volumeId);
+ sc.setParameters(STORE_ROLE, role);
return findOneBy(sc);
}
@Override
public SnapshotDataStoreVO findByVolume(long snapshotId, long volumeId,
DataStoreRole role) {
- SearchCriteria<SnapshotDataStoreVO> sc = volumeSearch.create();
- sc.setParameters("snapshot_id", snapshotId);
- sc.setParameters("volume_id", volumeId);
- sc.setParameters("store_role", role);
+ SearchCriteria<SnapshotDataStoreVO> sc =
searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create();
+ sc.setParameters(SNAPSHOT_ID, snapshotId);
+ sc.setParameters(VOLUME_ID, volumeId);
+ sc.setParameters(STORE_ROLE, role);
return findOneBy(sc);
}
@Override
public List<SnapshotDataStoreVO> findBySnapshotId(long snapshotId) {
- SearchCriteria<SnapshotDataStoreVO> sc = snapshotIdSearch.create();
- sc.setParameters("snapshot_id", snapshotId);
+ SearchCriteria<SnapshotDataStoreVO> sc =
searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create();
+ sc.setParameters(SNAPSHOT_ID, snapshotId);
return listBy(sc);
}
@Override
public List<SnapshotDataStoreVO> listDestroyed(long id) {
- SearchCriteria<SnapshotDataStoreVO> sc = destroyedSearch.create();
- sc.setParameters("store_id", id);
- sc.setParameters("store_role", DataStoreRole.Image);
- sc.setParameters("state",
ObjectInDataStoreStateMachine.State.Destroyed);
+ SearchCriteria<SnapshotDataStoreVO> sc =
searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create();
+ sc.setParameters(STORE_ID, id);
+ sc.setParameters(STORE_ROLE, DataStoreRole.Image);
+ sc.setParameters(STATE, ObjectInDataStoreStateMachine.State.Destroyed);
return listBy(sc);
}
@Override
public List<SnapshotDataStoreVO> listActiveOnCache(long id) {
- SearchCriteria<SnapshotDataStoreVO> 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);
+ SearchCriteria<SnapshotDataStoreVO> sc =
searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.create();
+ 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);
}
+ /**
+ * 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<SnapshotDataStoreVO> sc = storeSnapshotSearch.create();
- sc.setParameters("store_role", DataStoreRole.ImageCache);
+ SearchCriteria<SnapshotDataStoreVO> sc =
searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create();
+ sc.setParameters(STORE_ROLE, DataStoreRole.ImageCache);
sc.setParameters("destroyed", false);
List<SnapshotDataStoreVO> 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
public SnapshotDataStoreVO findReadyOnCache(long snapshotId) {
- SearchCriteria<SnapshotDataStoreVO> sc = storeSnapshotSearch.create();
- sc.setParameters("snapshot_id", snapshotId);
- sc.setParameters("store_role", DataStoreRole.ImageCache);
- sc.setParameters("state", ObjectInDataStoreStateMachine.State.Ready);
+ SearchCriteria<SnapshotDataStoreVO> sc =
searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create();
+ sc.setParameters(SNAPSHOT_ID, snapshotId);
+ sc.setParameters(STORE_ROLE, DataStoreRole.ImageCache);
+ sc.setParameters(STATE, ObjectInDataStoreStateMachine.State.Ready);
return findOneIncludingRemovedBy(sc);
}
@Override
public List<SnapshotDataStoreVO> listOnCache(long snapshotId) {
- SearchCriteria<SnapshotDataStoreVO> sc = storeSnapshotSearch.create();
- sc.setParameters("snapshot_id", snapshotId);
- sc.setParameters("store_role", DataStoreRole.ImageCache);
+ SearchCriteria<SnapshotDataStoreVO> sc =
searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create();
+ sc.setParameters(SNAPSHOT_ID, snapshotId);
+ sc.setParameters(STORE_ROLE, DataStoreRole.ImageCache);
return search(sc, null);
}
@Override
public void updateStoreRoleToCache(long storeId) {
- SearchCriteria<SnapshotDataStoreVO> sc = storeSearch.create();
- sc.setParameters("store_id", storeId);
+ SearchCriteria<SnapshotDataStoreVO> sc =
searchFilteringStoreIdEqStoreRoleEqStateNeqRefCntNeq.create();
+ sc.setParameters(STORE_ID, storeId);
sc.setParameters("destroyed", false);
List<SnapshotDataStoreVO> 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);
}
@@ -473,8 +401,8 @@ public class SnapshotDataStoreDaoImpl extends
GenericDaoBase<SnapshotDataStoreVO
@Override
public void updateVolumeIds(long oldVolId, long newVolId) {
- SearchCriteria<SnapshotDataStoreVO> sc = volumeIdSearch.create();
- sc.setParameters("volume_id", oldVolId);
+ SearchCriteria<SnapshotDataStoreVO> sc =
searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create();
+ sc.setParameters(VOLUME_ID, oldVolId);
SnapshotDataStoreVO snapshot = createForUpdate();
snapshot.setVolumeId(newVolId);
UpdateBuilder ub = getUpdateBuilder(snapshot);
@@ -484,23 +412,23 @@ public class SnapshotDataStoreDaoImpl extends
GenericDaoBase<SnapshotDataStoreVO
@Override
public List<SnapshotDataStoreVO>
listByState(ObjectInDataStoreStateMachine.State... states) {
SearchCriteria<SnapshotDataStoreVO> sc = stateSearch.create();
- sc.setParameters("state", (Object[])states);
+ sc.setParameters(STATE, (Object[])states);
return listBy(sc, null);
}
@Override
public List<SnapshotDataStoreVO> findSnapshots(Long storeId, Date start,
Date end) {
SearchCriteria<SnapshotDataStoreVO> 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<SnapshotDataStoreVO> sc =
createSearchCriteriaBySnapshotIdAndStoreRole(snapshotId, role);
- sc.setParameters("state", State.Destroyed);
+ sc.setParameters(STATE, State.Destroyed);
return findOneBy(sc);
}
@@ -509,44 +437,32 @@ public class SnapshotDataStoreDaoImpl extends
GenericDaoBase<SnapshotDataStoreVO
* @return A SearchCriteria with snapshot id and data store role
*/
protected SearchCriteria<SnapshotDataStoreVO>
createSearchCriteriaBySnapshotIdAndStoreRole(long snapshotId, DataStoreRole
role) {
- SearchCriteria<SnapshotDataStoreVO> sc = snapshotSearch.create();
- sc.setParameters("snapshot_id", snapshotId);
- sc.setParameters("store_role", role);
+ SearchCriteria<SnapshotDataStoreVO> sc =
searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create();
+ sc.setParameters(SNAPSHOT_ID, snapshotId);
+ sc.setParameters(STORE_ROLE, role);
return sc;
}
- private boolean isSnapshotChainingRequired(long volumeId) {
-
-
hypervisorsSupportingSnapshotsChaining.add(Hypervisor.HypervisorType.XenServer);
-
+ protected boolean isSnapshotChainingRequired(long volumeId) {
SearchCriteria<SnapshotVO> sc = snapshotVOSearch.create();
- sc.setParameters("volume_id", volumeId);
+ sc.setParameters(VOLUME_ID, volumeId);
- SnapshotVO volSnapshot = _snapshotDao.findOneBy(sc);
+ SnapshotVO snapshot = snapshotDao.findOneBy(sc);
- if (volSnapshot != null &&
hypervisorsSupportingSnapshotsChaining.contains(volSnapshot.getHypervisorType()))
{
- return true;
- }
-
- 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
public List<SnapshotDataStoreVO> listReadyByVolumeId(long volumeId) {
- SearchCriteria<SnapshotDataStoreVO> sc =
volumeIdAndStateReadySearch.create();
- sc.setParameters("volume_id", volumeId);
- sc.setParameters("state", State.Ready);
+ SearchCriteria<SnapshotDataStoreVO> sc =
searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq.create();
+ sc.setParameters(VOLUME_ID, volumeId);
+ sc.setParameters(STATE, State.Ready);
return listBy(sc);
}
}
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 b7be8e3e526..0a02721f67f 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.searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq
= searchBuilderMock;
+ snapshotDataStoreDaoImplSpy.snapshotDao = snapshotDaoMock;
}
@Test
@@ -74,4 +84,63 @@ public class SnapshotDataStoreDaoImplTest {
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));
+ }
+ }
+
}