Commit 58fcf762 authored by Matija Obreza's avatar Matija Obreza
Browse files

Merge branch '541-extend-taxonomy2-list-results' into 'master'

Resolve "Extend Taxonomy2 /list results"

Closes #541

See merge request genesys-pgr/genesys-server!572
parents d0401c8e 279904c4
......@@ -77,14 +77,14 @@ public class TaxonomyController extends ApiBaseController {
}
/**
* List taxonomies.
* List of Taxonomy2 entities with included count of accessions.
*
* @param page the page
* @param filter the taxonomy2 filter
* @return the page
*/
@PostMapping(value = "/list", produces = { MediaType.APPLICATION_JSON_VALUE })
public FilteredPage<Taxonomy2> listTaxonomies(final Pagination page, @RequestBody final TaxonomyFilter filter) {
public FilteredPage<TaxonomyService.Taxonomy2Info> listTaxonomies(final Pagination page, @RequestBody final TaxonomyFilter filter) {
return new FilteredPage<>(filter, taxonomyService.list(filter, page.toPageRequest(100, Sort.Direction.ASC, "genus", "species", "id")));
}
}
......@@ -76,14 +76,14 @@ public class TaxonomyController extends ApiBaseController {
}
/**
* List taxonomies.
* List of Taxonomy2 entities with included count of accessions.
*
* @param page the page
* @param filter the taxonomy2 filter
* @return the page
*/
@PostMapping(value = "/list", produces = { MediaType.APPLICATION_JSON_VALUE })
public FilteredPage<Taxonomy2> listTaxonomies(final Pagination page, @RequestBody final TaxonomyFilter filter) {
public FilteredPage<TaxonomyService.Taxonomy2Info> listTaxonomies(final Pagination page, @RequestBody final TaxonomyFilter filter) {
return new FilteredPage<>(filter, taxonomyService.list(filter, page.toPageRequest(100, Sort.Direction.ASC, "genus", "species", "id")));
}
}
......@@ -17,6 +17,7 @@
package org.genesys2.server.model.genesys;
import java.text.MessageFormat;
import java.util.List;
import javax.persistence.Cacheable;
import javax.persistence.Column;
......@@ -25,6 +26,7 @@ import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.PrePersist;
import javax.persistence.Table;
import javax.persistence.Transient;
......@@ -39,6 +41,7 @@ import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
......@@ -102,6 +105,9 @@ public class Taxonomy2 extends GlobalVersionedAuditedModel {
@Field(type = FieldType.Object)
private TaxonomySpecies currentTaxonomySpecies;
@OneToMany(cascade = {}, fetch = FetchType.LAZY, mappedBy = "taxonomy")
@JsonIgnore
private List<Accession> accessions;
public Taxonomy2() {
}
......
......@@ -168,4 +168,6 @@ public interface AccessionRepository extends JpaRepository<Accession, Long>, Acc
@Query("select count(a.id) - count(distinct a.accessionNumber) from Accession a where a.institute.id = ?1")
public long countNonuniqueAccessionNumbers(long instituteId);
public Long countByTaxonomy(Taxonomy2 taxonomy2);
}
......@@ -16,8 +16,10 @@
package org.genesys2.server.service;
import java.io.Serializable;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import org.genesys2.server.model.genesys.Taxonomy2;
import org.genesys2.server.service.filter.TaxonomyFilter;
import org.springframework.data.domain.Page;
......@@ -45,7 +47,7 @@ public interface TaxonomyService {
List<Taxonomy2> list(TaxonomyFilter filter);
Page<Taxonomy2> list(TaxonomyFilter filter, Pageable page);
Page<Taxonomy2Info> list(TaxonomyFilter filter, Pageable page);
List<String> getAllGenera();
......@@ -65,4 +67,19 @@ public interface TaxonomyService {
List<Long> findGrinGenusId(List<String> genera);
List<Long> findGrinSpeciesId(List<String> speciesNames);
public static class Taxonomy2Info implements Serializable {
private static final long serialVersionUID = 2114693656081783236L;
@JsonUnwrapped
public Taxonomy2 taxonomy;
public Long accessionCount;
public static Taxonomy2Info from(Taxonomy2 taxonomy, Long accessionCount) {
Taxonomy2Info taxonomy2Info = new Taxonomy2Info();
taxonomy2Info.taxonomy = taxonomy;
taxonomy2Info.accessionCount = accessionCount;
return taxonomy2Info;
}
}
}
......@@ -29,7 +29,6 @@ import org.genesys2.server.service.TaxonomyService;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.JPQLQuery;
/**
* The Class TaxonomyFilter.
......@@ -134,73 +133,4 @@ public class TaxonomyFilter extends AuditedVersionedModelFilter<TaxonomyFilter,
public StringFilter subtaxa() {
return this.subtaxa == null ? this.subtaxa = new StringFilter() : this.subtaxa;
}
//
// /**
// * This is mostly a copy of {@link #collectPredicates()} above, with inner joins where possible.
// *
// * @param taxonomy
// * @return the list of where clauses
// */
// public List<Predicate> buildJpaQuery(JPQLQuery<?> query, QTaxonomy2 taxonomy) {
// final List<Predicate> predicates = super.collectPredicates(taxonomy, taxonomy._super._super);
// final TaxonomyService taxonomyService = CurrentApplicationContext.getContext().getBean(TaxonomyService.class);
//
// if (CollectionUtils.isNotEmpty(genus) && taxonomyService != null) {
// // We need to look up the taxonomy2.id for provided names so that ES queries
// // also work out of the box
// List<Long> taxGenus = taxonomyService.findTaxonomy2GenusId(new ArrayList<>(genus));
// List<Long> grinGenus = taxonomyService.findGrinGenusId(new ArrayList<>(genus));
//
// BooleanBuilder builder = new BooleanBuilder(taxonomy.taxGenus.in(taxGenus));
// if (!grinGenus.isEmpty()) {
// builder.or(taxonomy.grinTaxonomySpecies.taxonomyGenus.id.in(grinGenus));
// if (synonyms == null || synonyms) {
// builder.or(taxonomy.currentTaxonomySpecies.taxonomyGenus.id.in(grinGenus));
// }
// }
// predicates.add(builder);
// }
// if (species != null && !species.isEmpty()) {
// BooleanBuilder builder = new BooleanBuilder(taxonomy.species.in(species));
// builder.or(taxonomy.grinTaxonomySpecies.speciesName.in(species));
// if (synonyms == null || synonyms) {
// builder.or(taxonomy.currentTaxonomySpecies.speciesName.in(species));
// }
// predicates.add(builder);
// }
// if (subtaxa != null) {
// BooleanBuilder builder = new BooleanBuilder(subtaxa.buildQuery(taxonomy.subtaxa));
// builder.or(subtaxa.buildQuery(taxonomy.grinTaxonomySpecies.subtaxa));
// if (synonyms == null || synonyms) {
// builder.or(subtaxa.buildQuery(taxonomy.currentTaxonomySpecies.subtaxa));
// }
// predicates.add(builder);
// }
// if (taxonName != null) {
// BooleanBuilder builder = new BooleanBuilder(taxonName.buildQuery(taxonomy.taxonName));
// builder.or(taxonName.buildQuery(taxonomy.grinTaxonomySpecies.name));
// if (synonyms == null || synonyms) {
// builder.or(taxonName.buildQuery(taxonomy.currentTaxonomySpecies.name));
// }
// predicates.add(builder);
// }
// if (CollectionUtils.isNotEmpty(genusSpecies) && taxonomyService != null) {
// // We need to look up the taxonomy2.id for provided names so that ES queries
// // also work out of the box
// List<Long> taxSpecies = taxonomyService.findTaxonomy2SpeciesId(new ArrayList<>(genusSpecies));
// List<Long> grinSpecies = taxonomyService.findGrinSpeciesId(new ArrayList<>(genusSpecies));
//
// BooleanBuilder builder = new BooleanBuilder(taxonomy.taxSpecies.in(taxSpecies));
// if (!grinSpecies.isEmpty()) {
// builder.or(taxonomy.grinTaxonomySpecies.id.in(grinSpecies));
// if (synonyms == null || synonyms) {
// builder.or(taxonomy.currentTaxonomySpecies.id.in(grinSpecies));
// }
// }
// predicates.add(builder);
// }
//
// return predicates;
// }
}
......@@ -19,10 +19,12 @@ package org.genesys2.server.service.impl;
import java.math.BigInteger;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.genesys2.server.model.genesys.QTaxonomy2;
import org.genesys2.server.model.genesys.Taxonomy2;
import org.genesys2.server.persistence.AccessionRepository;
import org.genesys2.server.persistence.Taxonomy2Repository;
import org.genesys2.server.persistence.grin.TaxonomyGenusRepository;
import org.genesys2.server.persistence.grin.TaxonomySpeciesRepository;
......@@ -36,6 +38,7 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
......@@ -43,6 +46,7 @@ import org.springframework.transaction.annotation.Transactional;
import com.google.api.client.util.Lists;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQueryFactory;
@Service
@Transactional(readOnly = true)
......@@ -58,6 +62,12 @@ public class TaxonomyServiceImpl implements TaxonomyService {
@Autowired
private TaxonomyGenusRepository grinGenusRepository;
@Autowired
private AccessionRepository accessionRepository;
@Autowired
private JPAQueryFactory jpaQueryFactory;
@Override
public Taxonomy2 get(Long id) {
return taxonomy2Repository.findById(id).orElse(null);
......@@ -213,13 +223,23 @@ public class TaxonomyServiceImpl implements TaxonomyService {
}
@Override
public Page<Taxonomy2> list(TaxonomyFilter filter, Pageable page) {
@PreAuthorize("hasRole('ADMINISTRATOR')")
public Page<Taxonomy2Info> list(TaxonomyFilter filter, Pageable page) {
final BooleanBuilder predicate = new BooleanBuilder();
if (filter != null) {
predicate.and(filter.buildPredicate());
}
Page<Taxonomy2> res = taxonomy2Repository.findAll(predicate, page);
return new PageImpl<>(res.getContent(), page, res.getTotalElements());
List<Taxonomy2> matches = jpaQueryFactory.selectFrom(QTaxonomy2.taxonomy2).where(predicate).offset(page.getOffset()).limit(page.getPageSize()).orderBy(
QTaxonomy2.taxonomy2.accessions.size().desc()).fetch();
final Page<Taxonomy2> res = taxonomy2Repository.findAll(predicate, page);
final List<Taxonomy2Info> content = matches.stream().map(taxonomy2 -> {
Long accessionCount = accessionRepository.countByTaxonomy(taxonomy2);
return Taxonomy2Info.from(taxonomy2, accessionCount);
}).collect(Collectors.toList());
return new PageImpl<>(content, page, res.getTotalElements());
}
@Override
......
......@@ -58,6 +58,7 @@ import org.genesys2.server.model.impl.Subset;
import org.genesys2.server.model.impl.SubsetCreator;
import org.genesys2.server.persistence.AccessionRepository;
import org.genesys2.server.persistence.FaoInstituteRepository;
import org.genesys2.server.service.InstituteService;
import org.genesys2.server.service.TaxonomyService;
import org.junit.After;
import org.junit.Before;
......@@ -122,6 +123,8 @@ public abstract class AbstractApiTest extends AbstractTest {
protected TaxonomyService taxonomyService;
@Autowired
protected AccessionRepository accessionRepository;
@Autowired
protected InstituteService instituteService;
private AtomicInteger acceNumb = new AtomicInteger(1);
......@@ -241,6 +244,14 @@ public abstract class AbstractApiTest extends AbstractTest {
return partnerRepository.save(partner);
}
protected FaoInstitute setUpInstitute() {
FaoInstitute institute = new FaoInstitute();
institute.setCode("INS001");
institute.setFullName("An institute");
instituteService.update(Lists.newArrayList(institute));
return instituteService.getInstitute("INS001");
}
protected Descriptor setUpDescriptor() {
final Descriptor descriptor = new Descriptor();
......
......@@ -24,7 +24,6 @@ import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import com.google.common.collect.Lists;
import org.genesys.catalog.model.dataset.DatasetAccessionRef;
import org.genesys.test.base.AbstractApiTest;
import org.genesys2.server.model.genesys.Accession;
......@@ -32,7 +31,6 @@ import org.genesys2.server.model.genesys.AccessionData;
import org.genesys2.server.model.genesys.AccessionRef;
import org.genesys2.server.model.impl.FaoInstitute;
import org.genesys2.server.persistence.AccessionRepository;
import org.genesys2.server.service.InstituteService;
import org.junit.After;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
......@@ -44,8 +42,6 @@ public abstract class AbstractDatasetControllerTest extends AbstractApiTest {
@Autowired
protected AccessionRepository accessionRepository;
@Autowired
protected InstituteService instituteService;
@Override
public void beforeTest() throws Exception {
......@@ -71,14 +67,6 @@ public abstract class AbstractDatasetControllerTest extends AbstractApiTest {
return accessionRefs;
}
protected FaoInstitute setUpInstitute() {
FaoInstitute institute = new FaoInstitute();
institute.setCode("INS001");
institute.setFullName("An institute");
instituteService.update(Lists.newArrayList(institute));
return instituteService.getInstitute("INS001");
}
protected Set<DatasetAccessionRef> setUpAccessions(FaoInstitute institute) {
final List<Accession> accessions = new ArrayList<>(2);
accessions.add(setUpAccession(institute));
......
......@@ -16,6 +16,9 @@
package org.genesys.test.server.api;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.genesys.test.base.AbstractApiTest;
import org.genesys2.server.model.genesys.Taxonomy2;
import org.genesys2.server.persistence.Taxonomy2Repository;
......@@ -25,9 +28,6 @@ import org.junit.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* @author Maxym Borodenko
*/
......@@ -55,6 +55,8 @@ public abstract class AbstractTaxonomyControllerTest extends AbstractApiTest {
@Override
@Transactional
public void cleanup() throws Exception {
accessionRepository.deleteAll();
accessionIdRepository.deleteAll();
super.cleanup();
taxonomyRepository.deleteAll();
}
......
......@@ -27,6 +27,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import com.google.common.collect.Sets;
import org.genesys.test.server.api.AbstractTaxonomyControllerTest;
import org.genesys2.server.api.v1.TaxonomyController;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.Taxonomy2;
import org.genesys2.server.service.filter.TaxonomyFilter;
import org.junit.Test;
......@@ -64,9 +65,11 @@ public class TaxonomyControllerTest extends AbstractTaxonomyControllerTest {
@Test
public void listByFilterTest() throws Exception {
assertThat(taxonomyRepository.count(), is(2L));
Accession accession = accessionRepository.save(setUpAccession(setUpInstitute()));
assertThat(accessionRepository.count(), is(1L));
TaxonomyFilter filter = new TaxonomyFilter();
filter.genus = Sets.newHashSet(GENUS_1);
filter.genus = Sets.newHashSet(accession.getTaxonomy().getGenus());
/*@formatter:off*/
mockMvc
......@@ -82,9 +85,11 @@ public class TaxonomyControllerTest extends AbstractTaxonomyControllerTest {
.andExpect(jsonPath("$.sort[0].direction", is("ASC")))
.andExpect(jsonPath("$.totalElements", is(1)))
.andExpect(jsonPath("$.totalPages", is(1)))
.andExpect(jsonPath("$.content[0].genus", is(GENUS_1)))
.andExpect(jsonPath("$.content[0].genus", is(accession.getTaxonomy().getGenus())))
.andExpect(jsonPath("$.content[0].grinTaxonomySpecies").hasJsonPath())
.andExpect(jsonPath("$.content[0].currentTaxonomySpecies").hasJsonPath())
.andExpect(jsonPath("$.content[0].accessionCount").hasJsonPath())
.andExpect(jsonPath("$.content[0].accessionCount", is(1)))
;
/*@formatter:on*/
}
......
......@@ -27,6 +27,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import com.google.common.collect.Sets;
import org.genesys.test.server.api.AbstractTaxonomyControllerTest;
import org.genesys2.server.api.v1.TaxonomyController;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.Taxonomy2;
import org.genesys2.server.service.filter.TaxonomyFilter;
import org.junit.Test;
......@@ -64,9 +65,11 @@ public class TaxonomyControllerTest extends AbstractTaxonomyControllerTest {
@Test
public void listByFilterTest() throws Exception {
assertThat(taxonomyRepository.count(), is(2L));
Accession accession = accessionRepository.save(setUpAccession(setUpInstitute()));
assertThat(accessionRepository.count(), is(1L));
TaxonomyFilter filter = new TaxonomyFilter();
filter.genus = Sets.newHashSet(GENUS_1);
filter.genus = Sets.newHashSet(accession.getTaxonomy().getGenus());
/*@formatter:off*/
mockMvc
......@@ -82,9 +85,11 @@ public class TaxonomyControllerTest extends AbstractTaxonomyControllerTest {
.andExpect(jsonPath("$.sort[0].direction", is("ASC")))
.andExpect(jsonPath("$.totalElements", is(1)))
.andExpect(jsonPath("$.totalPages", is(1)))
.andExpect(jsonPath("$.content[0].genus", is(GENUS_1)))
.andExpect(jsonPath("$.content[0].genus", is(accession.getTaxonomy().getGenus())))
.andExpect(jsonPath("$.content[0].grinTaxonomySpecies").hasJsonPath())
.andExpect(jsonPath("$.content[0].currentTaxonomySpecies").hasJsonPath())
.andExpect(jsonPath("$.content[0].accessionCount").hasJsonPath())
.andExpect(jsonPath("$.content[0].accessionCount", is(1)))
;
/*@formatter:on*/
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment