Commit 5ae52dc6 authored by Maxym Borodenko's avatar Maxym Borodenko

Number of subsets and datasets

parent 7450ce3b
......@@ -17,9 +17,11 @@ package org.genesys.catalog.persistence.dataset;
import java.util.List;
import com.google.common.collect.Lists;
import org.genesys.catalog.model.dataset.Dataset;
import org.genesys.catalog.model.dataset.DatasetAccessionRef;
import org.genesys.catalog.model.dataset.QDatasetAccessionRef;
import org.genesys2.server.model.genesys.AccessionId;
import org.genesys2.server.persistence.AccessionRefRepositoryCustomImpl;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
......@@ -47,4 +49,12 @@ public class DatasetAccessionRefRepositoryCustomImpl extends AccessionRefReposit
return new PageImpl<>(l, page, total);
}
@Override
public List<AccessionId> findAccessionIdsByList(Dataset list) {
JPAQuery<AccessionId> q = jpaQueryFactory.select(QDatasetAccessionRef.datasetAccessionRef.accession.accessionId)
.from(QDatasetAccessionRef.datasetAccessionRef)
.where(QDatasetAccessionRef.datasetAccessionRef.list.eq(list));
return Lists.newArrayList(q.fetch());
}
}
/*
* Copyright 2020 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.genesys2.server.component.aspect;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.genesys.catalog.model.dataset.Dataset;
import org.genesys.catalog.persistence.dataset.DatasetAccessionRefRepository;
import org.genesys2.server.component.elastic.ElasticReindex;
import org.genesys2.server.model.PublishState;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.AccessionId;
import org.genesys2.server.model.impl.Subset;
import org.genesys2.server.persistence.AccessionIdRepository;
import org.genesys2.server.persistence.SubsetAccessionRefRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
/**
* This aspect updates {@link AccessionId#datasetCount} and {@link AccessionId#subsetCount}.
* - when associated subset/dataset is published, the count is increased by 1;
* - when associated subset/dataset is unpublished, the count is decreased by 1.
*
* @author Maxym Borodenko
*/
@Aspect
@Component
public class DatasetAndSubsetCountAspect {
/** The Constant LOG. */
private final static Logger LOG = LoggerFactory.getLogger(DatasetAndSubsetCountAspect.class);
@Autowired
private AccessionIdRepository accessionIdRepository;
@Autowired
private DatasetAccessionRefRepository datasetAccessionRefRepository;
@Autowired
private SubsetAccessionRefRepository subsetAccessionRefRepository;
@Autowired
private ThreadPoolTaskExecutor taskExecutor;
@Resource
private BlockingQueue<ElasticReindex> elasticReindexQueue;
@AfterReturning(value = "execution(* org.genesys.catalog.service.*.approveDataset(..)) || execution(* org.genesys.catalog.service.*.rejectDataset(..))", returning = "result")
public void afterDatasetPersist(final Dataset result) {
if (result == null || result.getAccessionCount() == 0) {
return;
}
List<AccessionId> accessionIds = datasetAccessionRefRepository.findAccessionIdsByList(result);
Lists.partition(accessionIds, 1000).parallelStream().forEach(batch -> {
try {
if (result.getState().equals(PublishState.PUBLISHED)) {
accessionIdRepository.increaseDatasetCount(batch);
} else {
accessionIdRepository.decreaseDatasetCount(batch);
}
scheduleReindexing(batch);
} catch (Throwable ex) {
LOG.warn("Error updating datasetCount of accessions, error is {}", ex.getMessage());
}
});
}
@AfterReturning(value = "execution(* org.genesys2.server.service.*.approveSubset(..)) || execution(* org.genesys2.server.service.*.rejectSubset(..))", returning = "result")
public void afterSubsetPersist(final Subset result) {
if (result == null || result.getAccessionCount() == 0) {
return;
}
List<AccessionId> accessionIds = subsetAccessionRefRepository.findAccessionIdsByList(result);
Lists.partition(accessionIds, 1000).parallelStream().forEach(batch -> {
try {
if (result.getState().equals(PublishState.PUBLISHED)) {
accessionIdRepository.increaseSubsetCount(batch);
} else {
accessionIdRepository.decreaseSubsetCount(batch);
}
scheduleReindexing(batch);
} catch (Throwable ex) {
LOG.warn("Error updating datasetCount of accessions, error is {}", ex.getMessage());
}
});
}
private void scheduleReindexing(List<AccessionId> toReindex) {
if (CollectionUtils.isEmpty(toReindex)) {
return;
}
taskExecutor.execute(() -> toReindex.forEach(accessionId -> {
LOG.trace("Scheduling reindexing of {} {}", Accession.class.getName(), accessionId.getId());
elasticReindexQueue.add(new ElasticReindex(Accession.class.getName(), accessionId.getId()));
}));
}
}
......@@ -162,6 +162,12 @@ public class AccessionId extends AuditedVersionedModel implements IdUUID {
@ColumnDefault("0")
private int imageCount;
/** Number of associated published subsets. */
private long subsetCount = 0;
/** Number of associated published datasets. */
private long datasetCount = 0;
@OneToOne(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }, optional = true, orphanRemoval = true)
@JoinColumn(name = "folderId", unique = true)
@JsonIgnore
......@@ -315,6 +321,22 @@ public class AccessionId extends AuditedVersionedModel implements IdUUID {
this.imageCount = imageCount;
}
public long getSubsetCount() {
return subsetCount;
}
public void setSubsetCount(long subsetCount) {
this.subsetCount = subsetCount;
}
public long getDatasetCount() {
return datasetCount;
}
public void setDatasetCount(long datasetCount) {
this.datasetCount = datasetCount;
}
public RepositoryFolder getRepositoryFolder() {
return repositoryFolder;
}
......
/*
* Copyright 2018 Global Crop Diversity Trust
* Copyright 2020 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -58,6 +58,7 @@ import org.genesys2.server.persistence.FaoInstituteRepository;
import org.genesys2.server.persistence.PDCIRepository;
import org.genesys2.server.persistence.SubsetRepository;
import org.genesys2.server.persistence.kpi.ExecutionRepository;
import org.genesys2.server.service.AccessionService;
import org.genesys2.server.service.ContentService;
import org.genesys2.server.service.CountryNamesUpdater;
import org.genesys2.server.service.CropService;
......@@ -192,6 +193,9 @@ public class AdminController {
@Autowired
private ScheduledGLISUpdater scheduledGLISUpdater;
@Autowired
private AccessionService accessionService;
@RequestMapping("/")
public String root(Model model) {
return "/admin/index";
......@@ -235,6 +239,24 @@ public class AdminController {
return "redirect:/admin/";
}
@RequestMapping(method = RequestMethod.POST, value = "/scanForSubsets")
public String scanForSubsets() {
accessionService.scanForPublishedSubsets();
return "redirect:/admin/";
}
@RequestMapping(method = RequestMethod.POST, value = "/scanForDatasets")
public String scanForDatasets() {
accessionService.scanForPublishedDatasets();
return "redirect:/admin/";
}
@RequestMapping(method = RequestMethod.POST, value = "/resetCounters")
public String resetCounters() {
accessionService.resetSubsetAndDatasetCounters();
return "redirect:/admin/";
}
@RequestMapping(method = RequestMethod.POST, value = "/relinkDatasetAccessions")
public String rematchDatasetAccessions() {
datasetService.rematchDatasetAccessions();
......
/**
* Copyright 2014 Global Crop Diversity Trust
/*
* Copyright 2020 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -12,7 +12,7 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
*/
package org.genesys2.server.persistence;
......@@ -23,8 +23,9 @@ import org.genesys2.server.model.genesys.AccessionId;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
public interface AccessionIdRepository extends JpaRepository<AccessionId, Long> {
public interface AccessionIdRepository extends JpaRepository<AccessionId, Long>, AccessionIdRepositoryCustom, QuerydslPredicateExecutor<AccessionId> {
@Query("select aid from AccessionId aid where aid.uuid is null")
List<AccessionId> findMissingUuid(Pageable pageable);
......
/*
* Copyright 2020 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.genesys2.server.persistence;
import org.genesys2.server.model.genesys.AccessionId;
import java.util.List;
/**
* Custom {@link AccessionId} repository methods.
*
* @author Maxym Borodenko
*/
public interface AccessionIdRepositoryCustom {
void increaseDatasetCount(List<AccessionId> accessionIds);
void decreaseDatasetCount(List<AccessionId> accessionIds);
void increaseSubsetCount(List<AccessionId> accessionIds);
void decreaseSubsetCount(List<AccessionId> accessionIds);
void resetSubsetAndDatasetCounters();
}
/*
* Copyright 2020 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.genesys2.server.persistence;
import java.util.List;
import com.querydsl.core.types.dsl.NumberPath;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.genesys2.server.model.genesys.AccessionId;
import org.genesys2.server.model.genesys.QAccessionId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
/**
* @author Maxym Borodenko
*/
@Repository
public class AccessionIdRepositoryCustomImpl implements AccessionIdRepositoryCustom {
@Autowired
private JPAQueryFactory jpaQueryFactory;
@Override
@Transactional
public void increaseDatasetCount(List<AccessionId> accessionIds) {
increaseCount(accessionIds, QAccessionId.accessionId.datasetCount);
}
@Override
@Transactional
public void decreaseDatasetCount(List<AccessionId> accessionIds) {
decreaseCount(accessionIds, QAccessionId.accessionId.datasetCount);
}
@Override
@Transactional
public void increaseSubsetCount(List<AccessionId> accessionIds) {
increaseCount(accessionIds, QAccessionId.accessionId.subsetCount);
}
@Override
@Transactional
public void decreaseSubsetCount(List<AccessionId> accessionIds) {
decreaseCount(accessionIds, QAccessionId.accessionId.subsetCount);
}
@Override
public void resetSubsetAndDatasetCounters() {
NumberPath<Long> subsetCount = QAccessionId.accessionId.subsetCount;
NumberPath<Long> datasetCount = QAccessionId.accessionId.datasetCount;
jpaQueryFactory.update(QAccessionId.accessionId)
.where(datasetCount.gt(0).or(subsetCount.gt(0)))
.set(datasetCount, 0L).set(subsetCount, 0L)
.execute();
}
private void decreaseCount(List<AccessionId> accessionIds, NumberPath<Long> path) {
jpaQueryFactory.update(QAccessionId.accessionId)
.where(QAccessionId.accessionId.in(accessionIds).and(path.gt(0)))
.set(path, path.subtract(1))
.execute();
}
private void increaseCount(List<AccessionId> accessionIds, NumberPath<Long> path) {
jpaQueryFactory.update(QAccessionId.accessionId)
.where(QAccessionId.accessionId.in(accessionIds))
.set(path, path.add(1))
.execute();
}
}
......@@ -17,6 +17,7 @@ package org.genesys2.server.persistence;
import java.util.List;
import org.genesys2.server.model.genesys.AccessionId;
import org.genesys2.server.model.genesys.AccessionRef;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
......@@ -32,4 +33,6 @@ public interface AccessionRefCustomRepository<X, T extends AccessionRef<X>> {
Page<T> findByList(X list, Pageable page);
List<AccessionId> findAccessionIdsByList(X list);
}
......@@ -17,6 +17,8 @@ package org.genesys2.server.persistence;
import java.util.List;
import com.google.common.collect.Lists;
import org.genesys2.server.model.genesys.AccessionId;
import org.genesys2.server.model.impl.QSubsetAccessionRef;
import org.genesys2.server.model.impl.Subset;
import org.genesys2.server.model.impl.SubsetAccessionRef;
......@@ -45,4 +47,13 @@ public class SubsetAccessionRefRepositoryCustomImpl extends AccessionRefReposito
List<SubsetAccessionRef> l = q.orderBy(QSubsetAccessionRef.subsetAccessionRef.accession.seqNo.asc(), QSubsetAccessionRef.subsetAccessionRef.acceNumb.asc()).leftJoin(QSubsetAccessionRef.subsetAccessionRef.accession).fetchJoin().offset(page.getOffset()).limit(page.getPageSize()).fetch();
return new PageImpl<>(l, page, total);
}
@Override
public List<AccessionId> findAccessionIdsByList(Subset list) {
JPAQuery<AccessionId> q = jpaQueryFactory.select(QSubsetAccessionRef.subsetAccessionRef.accession.accessionId)
.from(QSubsetAccessionRef.subsetAccessionRef)
.where(QSubsetAccessionRef.subsetAccessionRef.list.eq(list));
return Lists.newArrayList(q.fetch());
}
}
......@@ -186,7 +186,22 @@ public interface AccessionService {
* @return the accession
*/
Accession findMatchingAccession(RepositoryFolder repositoryFolder);
/**
* Scan for published datasets and increase the counts. Admin - only
*/
void scanForPublishedDatasets();
/**
* Scan for published subsets and increase the counts. Admin - only
*/
void scanForPublishedSubsets();
/**
* Reset subset/dataset counters to 0. Admin - only
*/
void resetSubsetAndDatasetCounters();
/**
* Executes the action on a list of accession in a
* Spring transaction. Spring security context not supported.
......
......@@ -28,14 +28,19 @@ import java.util.UUID;
import java.util.regex.Matcher;
import java.util.stream.Collectors;
import com.querydsl.core.types.dsl.BooleanExpression;
import org.apache.commons.collections.CollectionUtils;
import org.genesys.blocks.auditlog.service.AuditTrailService;
import org.genesys.catalog.model.dataset.Dataset;
import org.genesys.catalog.model.dataset.QDataset;
import org.genesys.catalog.persistence.dataset.DatasetRepository;
import org.genesys.catalog.service.DatasetService;
import org.genesys.filerepository.model.ImageGallery;
import org.genesys.filerepository.model.RepositoryFolder;
import org.genesys.filerepository.service.ImageGalleryService;
import org.genesys2.server.component.aspect.DatasetAndSubsetCountAspect;
import org.genesys2.server.exception.NotFoundElement;
import org.genesys2.server.model.PublishState;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.AccessionData;
import org.genesys2.server.model.genesys.AccessionId;
......@@ -43,8 +48,11 @@ import org.genesys2.server.model.genesys.QAccession;
import org.genesys2.server.model.impl.AccessionIdentifier3;
import org.genesys2.server.model.impl.Country;
import org.genesys2.server.model.impl.FaoInstitute;
import org.genesys2.server.model.impl.QSubset;
import org.genesys2.server.model.impl.Subset;
import org.genesys2.server.persistence.AccessionIdRepository;
import org.genesys2.server.persistence.AccessionRepository;
import org.genesys2.server.persistence.SubsetRepository;
import org.genesys2.server.service.AccessionService;
import org.genesys2.server.service.ElasticsearchService;
import org.genesys2.server.service.FilterConstants;
......@@ -116,6 +124,18 @@ public class AccessionServiceImpl implements AccessionService {
@Autowired
private GeoService geoService;
@Autowired
private DatasetRepository datasetRepository;
@Autowired
private SubsetRepository subsetRepository;
@Autowired
private AccessionIdRepository accessionIdRepository;
@Autowired
private DatasetAndSubsetCountAspect datasetAndSubsetCountAspect;
private static final int LOAD_CHUNK_SIZE = 200;
private <T extends AccessionData> T lazyLoad(T accession) {
......@@ -590,4 +610,27 @@ public class AccessionServiceImpl implements AccessionService {
}
return accession;
}
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR')")
public void scanForPublishedDatasets() {
BooleanExpression expression = QDataset.dataset.state.eq(PublishState.PUBLISHED);
datasetRepository.findAll(expression).forEach(dataset -> datasetAndSubsetCountAspect.afterDatasetPersist(dataset));
}
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR')")
public void scanForPublishedSubsets() {
BooleanExpression expression = QSubset.subset.state.eq(PublishState.PUBLISHED);
subsetRepository.findAll(expression).forEach(subset -> datasetAndSubsetCountAspect.afterSubsetPersist(subset));
}
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR')")
public void resetSubsetAndDatasetCounters() {
accessionIdRepository.resetSubsetAndDatasetCounters();
}
}
......@@ -6403,3 +6403,23 @@ databaseChangeLog:
tableName: ds2descriptor
- dropTable:
tableName: ds2
- changeSet:
id: 1590748834285-1
author: mborodenko
changes:
- addColumn:
columns:
- column:
constraints:
nullable: false
defaultValueNumeric: 0
name: subsetCount
type: bigint
- column:
constraints:
nullable: false
defaultValueNumeric: 0
name: datasetCount
type: bigint
tableName: acce
......@@ -113,6 +113,21 @@
<!-- CSRF protection -->
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
<form method="post" action="<c:url value="/admin/scanForSubsets" />">
<input type="submit" class="btn btn-default" value="Scan for subsets and increase the counts" />
<!-- CSRF protection -->
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
<form method="post" action="<c:url value="/admin/scanForDatasets" />">
<input type="submit" class="btn btn-default" value="Scan for datasets and increase the counts" />
<!-- CSRF protection -->
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
<form method="post" action="<c:url value="/admin/resetCounters" />">
<input type="submit" class="btn btn-default" value="Reset subset/dataset counters" />
<!-- CSRF protection -->
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
<h3>Dataset</h3>
<form method="post" action="<c:url value="/admin/relinkDatasetAccessions" />">
......
......@@ -184,6 +184,47 @@ public class DatasetServiceTest extends AbstractDatasetServiceTest {
assertThat(accessionRes.getUuid(), is(accession.getAccessionId().getUuid()));
}
/**
* Test updating of AccessionId#datasetCount after approving
* and rejecting a dataset with associated accession
*/
@Test
public void testUpdateDatasetCountInAccessionId() throws InterruptedException {
final Accession accession = upsertAccession(TEST_INSTCODE, "TestAccNum", "TestGen");
assertNotNull(accession);
final Long acceId = accession.getId();
assertTrue(acceId > 0);
Dataset dataset = buildDataset(DATASET_TITLE_1, DATASET_DESCRIPTION_1, partner, PublishState.DRAFT);
dataset = datasetService.createDataset(dataset);
final Set<DatasetAccessionRef> datasetAccessionRefs = Sets.newHashSet(makeAccessionIdentifier(TEST_INSTCODE, "TestAccNum", "TestGen", null));
dataset = datasetService.setAccessionRefs(dataset, datasetAccessionRefs);
dataset = datasetService.rematchDatasetAccessions(dataset);
assertThat(dataset, not(nullValue()));
assertThat(dataset.getAccessionCount(), is(1));
datasetService.rematchDatasetAccessions(dataset);
Thread.sleep(500);
dataset = datasetService.reviewDataset(dataset);
assertEquals(PublishState.REVIEWING, dataset.getState());
assertEquals(0L, accessionIdRepository.findById(acceId).get().getDatasetCount());
dataset = datasetService.approveDataset(dataset);
assertEquals(PublishState.PUBLISHED, dataset.getState());
// expecting increased dataset count after approving
assertEquals(1L, accessionIdRepository.findById(acceId).get().getDatasetCount());
dataset = datasetService.rejectDataset(dataset);
assertEquals(PublishState.DRAFT, dataset.getState());
// expecting decreased dataset count after approving
assertEquals(0L, accessionIdRepository.findById(acceId).get().getDatasetCount());
}
@Test
public void testCreateAndUpdateAccessionsInDataset() throws InterruptedException {
final Accession accession1 = upsertAccession(TEST_INSTCODE, TEST_ACCNUM, TEST_GEN);
......
......@@ -11,6 +11,7 @@ import java.util.UUID;
import javax.validation.ConstraintViolationException;
import org.genesys2.server.model.PublishState;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.impl.FaoInstitute;
import org.genesys2.server.model.impl.Subset;
......@@ -222,6 +223,42 @@ public class SubsetServiceTest extends CatalogServiceTest {
assertThat(subsetService.listByAccession(accession2), hasSize(0));
}
/**
* Test updating of AccessionId#subsetCount after approving
* and rejecting a subset with associated accession
*/
@Test
public void testUpdateSubsetCountInAccessionId() {
final Accession accession = upsertAccession("XXX0001", "acceNumb1", "genus1");
assertNotNull(accession);
final Long acceId = accession.getId();
assertTrue(acceId > 0);
Set<SubsetAccessionRef> accessionRefs = Sets.newHashSet(new SubsetAccessionRef(accession));
// add accessions to the Subset
subset = subsetService.addAccessionRefs(subset, accessionRefs);
subset = subsetService.rematchSubsetAccessions(subset);
assertThat(subset.getAccessionCount(), is(accessionRefs.size()));
subset = subsetService.reviewSubset(subset);
assertEquals(PublishState.REVIEWING, subset.getState());
assertEquals(0L, accessionIdRepository.findById(acceId).get().getSubsetCount());
subset = subsetService.approveSubset(subset);
assertEquals(PublishState.PUBLISHED, subset.getState());
// expecting increased subset count after approving
assertEquals(1L, accessionIdRepository.findById(acceId).get().getSubsetCount());
subset = subsetService.rejectSubset(subset);
assertEquals(PublishState.DRAFT, subset.getState());
// expecting decreased subset count after approving
assertEquals(0L, accessionIdRepository.findById(acceId).get().getSubsetCount());