Commit 1d87d61b authored by Matija Obreza's avatar Matija Obreza

API: Added listSpecies of filtered accessions at /acn/species

parent 1d0ffd4c
......@@ -44,6 +44,7 @@ import org.genesys2.server.exception.InvalidApiUsageException;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.AccessionGeo;
import org.genesys2.server.model.genesys.QAccession;
import org.genesys2.server.model.genesys.Taxonomy2;
import org.genesys2.server.model.impl.AccessionIdentifier3;
import org.genesys2.server.service.AccessionService;
import org.genesys2.server.service.AccessionService.AccessionMapInfo;
......@@ -197,6 +198,23 @@ public class AccessionController {
FilterInfo<AccessionFilter> filterInfo = shortFilterService.processFilter(filterCode, filter, AccessionFilter.class);
return new FilteredPage<>(filterInfo.filterCode, filterInfo.filter, accessionService.list(filterInfo.filter, page.toPageRequest(500, Sort.Direction.ASC, "seqNo")));
}
/**
* List distinct taxonomic data for filtered accessions
*
* @param filter the accession filter
* @throws IOException
*/
@PostMapping(value = "/species", produces = { MediaType.APPLICATION_JSON_VALUE, CSVMessageConverter.TEXT_CSV_VALUE })
@JsonView({ JsonViews.Public.class })
public List<Taxonomy2> listSpecies(@RequestBody(required = false) AccessionFilter filter) throws IOException, SearchException {
return accessionService.listSpecies(filter);
}
/**
* List accessions by filterCode or filter
*
......
/*
* Copyright 2018 Global Crop Diversity Trust
* Copyright 2019 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.
......@@ -22,6 +22,7 @@ import java.util.UUID;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.AccessionData;
import org.genesys2.server.model.genesys.Taxonomy2;
import org.genesys2.server.model.impl.AccessionIdentifier3;
import org.genesys2.server.model.impl.FaoInstitute;
import org.genesys2.server.service.filter.AccessionFilter;
......@@ -86,4 +87,13 @@ public interface AccessionRepositoryCustom {
* @return the long
*/
long count(AccessionFilter filter);
/**
* List species.
*
* @param filter the filter
* @return the list
*/
public List<Taxonomy2> listSpecies(AccessionFilter filter);
}
......@@ -39,6 +39,8 @@ import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.AccessionData;
import org.genesys2.server.model.genesys.AccessionHistoric;
import org.genesys2.server.model.genesys.QAccession;
import org.genesys2.server.model.genesys.QTaxonomy2;
import org.genesys2.server.model.genesys.Taxonomy2;
import org.genesys2.server.model.impl.AccessionIdentifier3;
import org.genesys2.server.model.impl.FaoInstitute;
import org.genesys2.server.service.filter.AccessionFilter;
......@@ -52,8 +54,10 @@ import org.springframework.data.jpa.repository.support.Querydsl;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.PathBuilder;
import com.querydsl.core.types.dsl.PathBuilderFactory;
import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.JPQLQuery;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
......@@ -252,4 +256,16 @@ public class AccessionRepositoryCustomImpl implements AccessionRepositoryCustom,
return query.select(qAccession).fetch();
}
@Override
public List<Taxonomy2> listSpecies(AccessionFilter filter) {
JPQLQuery<Taxonomy2> subquery = JPAExpressions.select(QAccession.accession.taxonomy).from(QAccession.accession).distinct();
if (filter != null) {
filter.buildJpaQuery(subquery, QAccession.accession);
}
return jpaQueryFactory.selectFrom(QTaxonomy2.taxonomy2).where(QTaxonomy2.taxonomy2.in(subquery))
// order
.orderBy(QTaxonomy2.taxonomy2.genus.asc(), QTaxonomy2.taxonomy2.species.asc(), QTaxonomy2.taxonomy2.subtaxa.asc()).fetch();
}
}
......@@ -30,6 +30,7 @@ import org.genesys.filerepository.model.RepositoryFolder;
import org.genesys2.server.api.FilteredPage;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.PDCI;
import org.genesys2.server.model.genesys.Taxonomy2;
import org.genesys2.server.model.impl.AccessionIdentifier3;
import org.genesys2.server.model.impl.Subset;
import org.genesys2.server.service.filter.AccessionFilter;
......@@ -282,4 +283,12 @@ public interface AccessionService {
}
}
/**
* List taxonomic records for filtered accession.
*
* @param filter the filter
* @return the list
*/
List<Taxonomy2> listSpecies(AccessionFilter filter);
}
......@@ -28,7 +28,6 @@ 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;
......@@ -45,6 +44,7 @@ import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.AccessionData;
import org.genesys2.server.model.genesys.AccessionId;
import org.genesys2.server.model.genesys.QAccession;
import org.genesys2.server.model.genesys.Taxonomy2;
import org.genesys2.server.model.impl.AccessionIdentifier3;
import org.genesys2.server.model.impl.Country;
import org.genesys2.server.model.impl.FaoInstitute;
......@@ -80,6 +80,7 @@ import org.springframework.transaction.annotation.Transactional;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
......@@ -646,4 +647,9 @@ public class AccessionServiceImpl implements AccessionService {
public void resetSubsetAndDatasetCounters() {
accessionIdRepository.resetSubsetAndDatasetCounters();
}
@Override
public List<Taxonomy2> listSpecies(AccessionFilter filter) {
return accessionRepository.listSpecies(filter);
}
}
......@@ -127,15 +127,23 @@ public abstract class AbstractAccessionControllerTest extends AbstractApiTest {
protected List<Accession> setUpAccessions(int amount) {
return setUpAccessions(amount, null);
}
protected List<Accession> setUpAccessions(int amount, Taxonomy2 taxonomy) {
final List<Accession> accessions = new ArrayList<>(amount);
for (int i = 0; i < amount; i++) {
accessions.add(addAccessionInDB(false));
accessions.add(addAccessionInDB(false, taxonomy));
}
return accessionRepository.saveAll(accessions);
}
protected Accession addAccessionInDB(Boolean aegis) {
return addAccessionInDB(aegis, null);
}
protected Accession addAccessionInDB(Boolean aegis, Taxonomy2 taxonomy) {
Accession a = new Accession();
a.setAegis(aegis);
a.setAccessionId(new AccessionId());
......@@ -149,9 +157,11 @@ public abstract class AbstractAccessionControllerTest extends AbstractApiTest {
a.getAccessionId().getStorage().add(10 * i);
}
a.setAccessionNumber("ACC" + System.currentTimeMillis() + "-" + acceNumb.incrementAndGet());
Taxonomy2 taxon = new Taxonomy2();
taxon.setGenus("Hordeum");
a.setTaxonomy(taxonomyService.ensureTaxonomy(taxon));
if (taxonomy == null) {
a.setTaxonomy(addTaxonomy("Hordeum", null, null));
} else {
a.setTaxonomy(taxonomy);
}
a.getAccessionId().setBreederCode(new HashSet<>());
for (int i = RandomUtils.nextInt(0, 3 + 1); i > 0; i--) {
......@@ -170,6 +180,14 @@ public abstract class AbstractAccessionControllerTest extends AbstractApiTest {
return a;
}
protected Taxonomy2 addTaxonomy(String genus, String species, String subtaxa) {
Taxonomy2 taxon = new Taxonomy2();
taxon.setGenus(genus);
taxon.setSpecies(species);
taxon.setSubtaxa(subtaxa);
return taxonomyService.ensureTaxonomy(taxon);
}
protected ObjectNode setUpAccession() {
ObjectNode accession = objectMapper.createObjectNode();
accession.put("instituteCode", institute.getCode());
......
......@@ -565,9 +565,9 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
@Test
public void historicFilterTest() throws Exception {
Accession accession1 = addAccessionInDB(null);
Accession accession2 = addAccessionInDB(null);
Accession accessionH = addAccessionInDB(null);
Accession accession1 = addAccessionInDB(null, null);
Accession accession2 = addAccessionInDB(null, null);
Accession accessionH = addAccessionInDB(null, null);
accessionH.setHistoric(true);
accessionRepository.save(accession1);
accessionRepository.save(accession2);
......@@ -622,9 +622,9 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
@Test
public void historicNullFilterTest() throws Exception {
Accession accession1 = addAccessionInDB(null);
Accession accession2 = addAccessionInDB(null);
Accession accessionH = addAccessionInDB(null);
Accession accession1 = addAccessionInDB(null, null);
Accession accession2 = addAccessionInDB(null, null);
Accession accessionH = addAccessionInDB(null, null);
accessionH.setHistoric(true);
accessionRepository.save(accession1);
accessionRepository.save(accession2);
......@@ -649,9 +649,9 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
@Test
public void historicFilterIsNullTest() throws Exception {
Accession accession1 = addAccessionInDB(null);
Accession accession2 = addAccessionInDB(null);
Accession accessionH = addAccessionInDB(null);
Accession accession1 = addAccessionInDB(null, null);
Accession accession2 = addAccessionInDB(null, null);
Accession accessionH = addAccessionInDB(null, null);
accessionH.setHistoric(true);
accessionRepository.save(accession1);
accessionRepository.save(accession2);
......@@ -681,9 +681,9 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
@Test
public void aegisFilterTest() throws Exception {
Accession withAegis = addAccessionInDB(true);
Accession withoutAegis = addAccessionInDB(false);
Accession nullAegis = addAccessionInDB(null);
Accession withAegis = addAccessionInDB(true, null);
Accession withoutAegis = addAccessionInDB(false, null);
Accession nullAegis = addAccessionInDB(null, null);
accessionRepository.save(withAegis);
accessionRepository.save(withoutAegis);
accessionRepository.save(nullAegis);
......@@ -734,7 +734,7 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
@Test
public void accessionsAsCSVTest() throws Exception {
List<Accession> accessions = setUpAccessions(30);
List<Accession> accessions = setUpAccessions(30, null);
assertThat(accessionRepository.count(), is((long) accessions.size()));
AccessionFilter filter = new AccessionFilter();
......@@ -760,7 +760,7 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
@Test
public void accessionsAsCSVwithSelector() throws Exception {
List<Accession> accessions = setUpAccessions(30);
List<Accession> accessions = setUpAccessions(30, null);
assertThat(accessionRepository.count(), is((long) accessions.size()));
AccessionFilter filter = new AccessionFilter();
......@@ -785,7 +785,7 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
final int pageSize = 5;
final int accessionCount = 52;
List<Accession> accessions = setUpAccessions(accessionCount);
List<Accession> accessions = setUpAccessions(accessionCount, null);
assertThat(accessionRepository.count(), is((long) accessions.size()));
AccessionFilter filter = new AccessionFilter();
......@@ -819,7 +819,7 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
// Also works with 2000, 5000, 10000, 15000
int amounts[] = { 10, 99, 100, 101, 1000 };
List<Accession> accessions = setUpAccessions(2000);
List<Accession> accessions = setUpAccessions(2000, null);
assertThat(accessionRepository.count(), is(2000L));
for (int amount: amounts) {
......@@ -1032,7 +1032,7 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
public void testGeoJson() throws Exception {
final int accAmount = 5;
List<Accession> accessions = setUpAccessions(accAmount);
List<Accession> accessions = setUpAccessions(accAmount, null);
assertThat(accessionRepository.count(), is((long)accAmount));
ObjectNode filter = objectMapper.createObjectNode();
......@@ -1204,7 +1204,7 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
@Test
public void getAccessionsByUUIDTestCSV() throws Exception {
List<Accession> accessions = setUpAccessions(100);
List<Accession> accessions = setUpAccessions(100, null);
assertThat(accessionRepository.count(), is(100L));
List<UUID> uuids = accessions.stream().filter(a -> RandomUtils.nextBoolean()).map(Accession::getAccessionId).map(AccessionId::getUuid).collect(Collectors.toList());
......@@ -1470,6 +1470,55 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
;
/*@formatter:on*/
}
@Test
public void taxonomyAsCSV() throws Exception {
setUpAccessions(10, addTaxonomy("Musa", "banksii", null));
setUpAccessions(10, addTaxonomy("Hordeum", "vulgare", null));
setUpAccessions(10, addTaxonomy("Manihot", "esculenta", null));
assertThat(accessionRepository.count(), is(30L));
/*@formatter:off*/
String csvText = mockMvc
.perform(post(AccessionController.CONTROLLER_URL + "/species")
.accept(CSVMessageConverter.TEXT_CSV_VALUE))
.andDo(org.springframework.test.web.servlet.result.MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andExpect(content().contentType("text/csv"))
.andReturn().getResponse().getContentAsString()
;
/*@formatter:on*/
// test read
CSVReader csvReader = new CSVReader(new StringReader(csvText), '\t');
assertThat(csvReader.readNext().length, is(14));
assertThat(csvReader.readAll().size(), is(3));
AccessionFilter filter = new AccessionFilter();
filter.taxonomy = filter.taxa();
filter.taxonomy.genusSpecies = Sets.newHashSet("Hordeum vulgare");
/*@formatter:off*/
csvText = mockMvc
.perform(post(AccessionController.CONTROLLER_URL + "/species")
.contentType(MediaType.APPLICATION_JSON)
.characterEncoding("UTF8")
.content(verboseMapper.writeValueAsString(filter))
.accept(CSVMessageConverter.TEXT_CSV_VALUE))
.andDo(org.springframework.test.web.servlet.result.MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andExpect(content().contentType("text/csv"))
.andReturn().getResponse().getContentAsString()
;
/*@formatter:on*/
// test read
csvReader = new CSVReader(new StringReader(csvText), '\t');
assertThat(csvReader.readNext().length, is(14));
assertThat(csvReader.readAll().size(), is(1));
}
private JsonNode accessionGeo(Double latitude, Double longitude, Double elevation) {
ObjectNode geo = objectMapper.createObjectNode();
......
......@@ -487,9 +487,9 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
@Test
public void historicFilterTest() throws Exception {
Accession accession1 = addAccessionInDB(null);
Accession accession2 = addAccessionInDB(null);
Accession accessionH = addAccessionInDB(null);
Accession accession1 = addAccessionInDB(null, null);
Accession accession2 = addAccessionInDB(null, null);
Accession accessionH = addAccessionInDB(null, null);
accessionH.setHistoric(true);
accessionRepository.save(accession1);
accessionRepository.save(accession2);
......@@ -543,9 +543,9 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
@Test
public void historicNullFilterTest() throws Exception {
Accession accession1 = addAccessionInDB(null);
Accession accession2 = addAccessionInDB(null);
Accession accessionH = addAccessionInDB(null);
Accession accession1 = addAccessionInDB(null, null);
Accession accession2 = addAccessionInDB(null, null);
Accession accessionH = addAccessionInDB(null, null);
accessionH.setHistoric(true);
accessionRepository.save(accession1);
accessionRepository.save(accession2);
......@@ -570,9 +570,9 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
@Test
public void historicFilterIsNullTest() throws Exception {
Accession accession1 = addAccessionInDB(null);
Accession accession2 = addAccessionInDB(null);
Accession accessionH = addAccessionInDB(null);
Accession accession1 = addAccessionInDB(null, null);
Accession accession2 = addAccessionInDB(null, null);
Accession accessionH = addAccessionInDB(null, null);
accessionH.setHistoric(true);
accessionRepository.save(accession1);
accessionRepository.save(accession2);
......@@ -602,9 +602,9 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
@Test
public void aegisFilterTest() throws Exception {
Accession withAegis = addAccessionInDB(true);
Accession withoutAegis = addAccessionInDB(false);
Accession nullAegis = addAccessionInDB(null);
Accession withAegis = addAccessionInDB(true, null);
Accession withoutAegis = addAccessionInDB(false, null);
Accession nullAegis = addAccessionInDB(null, null);
accessionRepository.save(withAegis);
accessionRepository.save(withoutAegis);
accessionRepository.save(nullAegis);
......@@ -655,7 +655,7 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
@Test
public void accessionsAsCSVTest() throws Exception {
List<Accession> accessions = setUpAccessions(30);
List<Accession> accessions = setUpAccessions(30, null);
assertThat(accessionRepository.count(), is((long) accessions.size()));
AccessionFilter filter = new AccessionFilter();
......@@ -681,7 +681,7 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
@Test
public void accessionsAsCSVwithSelector() throws Exception {
List<Accession> accessions = setUpAccessions(30);
List<Accession> accessions = setUpAccessions(30, null);
assertThat(accessionRepository.count(), is((long) accessions.size()));
AccessionFilter filter = new AccessionFilter();
......@@ -706,7 +706,7 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
final int pageSize = 5;
final int accessionCount = 52;
List<Accession> accessions = setUpAccessions(accessionCount);
List<Accession> accessions = setUpAccessions(accessionCount, null);
assertThat(accessionRepository.count(), is((long) accessions.size()));
AccessionFilter filter = new AccessionFilter();
......@@ -740,7 +740,7 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
// Also works with 2000, 5000, 10000, 15000
int amounts[] = { 10, 99, 100, 101, 1000 };
List<Accession> accessions = setUpAccessions(2000);
List<Accession> accessions = setUpAccessions(2000, null);
assertThat(accessionRepository.count(), is(2000L));
for (int amount: amounts) {
......@@ -913,7 +913,7 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
public void testGeoJson() throws Exception {
final int accAmount = 5;
List<Accession> accessions = setUpAccessions(accAmount);
List<Accession> accessions = setUpAccessions(accAmount, null);
assertThat(accessionRepository.count(), is((long)accAmount));
ObjectNode filter = objectMapper.createObjectNode();
......@@ -1083,7 +1083,7 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
@Test
public void getAccessionsByUUIDTestCSV() throws Exception {
List<Accession> accessions = setUpAccessions(100);
List<Accession> accessions = setUpAccessions(100, null);
assertThat(accessionRepository.count(), is(100L));
List<UUID> uuids = accessions.stream().filter(a -> RandomUtils.nextBoolean()).map(Accession::getAccessionId).map(AccessionId::getUuid).collect(Collectors.toList());
......
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