Commit fb42cb14 authored by Matija Obreza's avatar Matija Obreza
Browse files

Limit DwCA filtered downloads to 100,000 entries

parent c1d772c6
......@@ -54,4 +54,6 @@ public interface GenesysLowlevelRepository {
void listAccessionsAlias(RowCallbackHandler rowCallbackHandler);
int countAccessions(ObjectNode filter);
}
......@@ -214,6 +214,19 @@ public class GenesysLowlevelRepositoryImpl implements GenesysLowlevelRepository
}
}
@Override
public int countAccessions(ObjectNode filter) {
final DirectMysqlQuery directQuery = new DirectMysqlQuery("accession", "a");
directQuery.jsonFilter(filter, new MethodResolver() {
@Override
public Method getMethod(long methodId) {
return methodRepository.findOne(methodId);
}
});
return jdbcTemplate.queryForObject(directQuery.getCountQuery("a.id"), directQuery.getParameters(), Integer.class);
}
@Override
public void listAccessions(final ObjectNode filter, RowCallbackHandler rowCallbackHandler) {
final DirectMysqlQuery directQuery = new DirectMysqlQuery("accession", "a");
......@@ -270,7 +283,7 @@ public class GenesysLowlevelRepositoryImpl implements GenesysLowlevelRepository
@Override
public void listAccessionsAlias(final ObjectNode filter, RowCallbackHandler rowCallbackHandler) {
//from n inner join accession a on a.id=n.accessionId
// from n inner join accession a on a.id=n.accessionId
final DirectMysqlQuery directQuery = new DirectMysqlQuery("accessionalias", "n");
directQuery.innerJoin("accession", "a", "a.id=n.accessionId");
directQuery.jsonFilter(filter, new MethodResolver() {
......@@ -279,12 +292,11 @@ public class GenesysLowlevelRepositoryImpl implements GenesysLowlevelRepository
return methodRepository.findOne(methodId);
}
});
jdbcTemplate.query(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
PreparedStatement stmt = con
.prepareStatement(directQuery.getQuery("a.id, n.instCode, n.name, n.aliasType, n.lang, n.version"));
PreparedStatement stmt = con.prepareStatement(directQuery.getQuery("a.id, n.instCode, n.name, n.aliasType, n.lang, n.version"));
ArgumentPreparedStatementSetter apss = new ArgumentPreparedStatementSetter(directQuery.getParameters());
apss.setValues(stmt);
......@@ -313,7 +325,8 @@ public class GenesysLowlevelRepositoryImpl implements GenesysLowlevelRepository
@Override
public void listAccessionsColl(final ObjectNode filter, RowCallbackHandler rowCallbackHandler) {
//from accessioncollect coll inner join accession a on a.id=coll.accessionId
// from accessioncollect coll inner join accession a on
// a.id=coll.accessionId
final DirectMysqlQuery directQuery = new DirectMysqlQuery("accessioncollect", "coll");
directQuery.innerJoin("accession", "a", "a.id=coll.accessionId");
directQuery.jsonFilter(filter, new MethodResolver() {
......@@ -322,16 +335,16 @@ public class GenesysLowlevelRepositoryImpl implements GenesysLowlevelRepository
return methodRepository.findOne(methodId);
}
});
jdbcTemplate.query(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
PreparedStatement stmt = con
.prepareStatement(directQuery.getQuery("a.id, coll.collMissId, coll.collNumb, coll.collDate, coll.collSrc, coll.collSite, coll.collCode, coll.collName, coll.collInstAddress, coll.version"));
PreparedStatement stmt = con.prepareStatement(directQuery
.getQuery("a.id, coll.collMissId, coll.collNumb, coll.collDate, coll.collSrc, coll.collSite, coll.collCode, coll.collName, coll.collInstAddress, coll.version"));
ArgumentPreparedStatementSetter apss = new ArgumentPreparedStatementSetter(directQuery.getParameters());
apss.setValues(stmt);
// Set mysql JConnector to stream results
stmt.setFetchSize(Integer.MIN_VALUE);
return stmt;
......
......@@ -178,4 +178,6 @@ public interface GenesysService {
Set<Long> listAccessions(FaoInstitute holdingInstitute, Set<Long> accessionIds);
int countAccessions(String jsonFilter);
}
......@@ -839,6 +839,16 @@ public class GenesysServiceImpl implements GenesysService, TraitService, Dataset
methodsWithValues.add(method.getId());
}
}
@Override
public int countAccessions(String jsonFilter) {
try {
ObjectNode filter = (ObjectNode) mapper.readTree(jsonFilter);
return genesysLowlevelRepository.countAccessions(filter);
} catch (IOException e) {
throw new RuntimeException("Could not parse jsonFilter", e);
}
}
@Override
public void writeAccessions(final FaoInstitute faoInstitute, OutputStream outputStream) throws IOException {
......
......@@ -339,7 +339,7 @@ public class ExplorerController extends BaseController {
@RequestMapping(value = "/explore/map", method = RequestMethod.GET)
public String map(ModelMap model, @RequestParam(value = "crop", required = false, defaultValue = "") String cropName,
@RequestParam(value = "filter", required = false, defaultValue="{}") String jsonFilter) {
@RequestParam(value = "filter", required = false, defaultValue = "{}") String jsonFilter) {
ObjectNode jsonTree = updateFilterWithCrop(cropName, jsonFilter);
......@@ -349,10 +349,16 @@ public class ExplorerController extends BaseController {
@RequestMapping(value = "/explore/dwca", method = RequestMethod.GET)
public void dwca(ModelMap model, @RequestParam(value = "crop", required = false, defaultValue = "") String cropName,
@RequestParam(value = "filter", required = false, defaultValue="{}") String jsonFilter, HttpServletResponse response) throws IOException {
@RequestParam(value = "filter", required = false, defaultValue = "{}") String jsonFilter, HttpServletResponse response) throws IOException {
ObjectNode jsonTree = updateFilterWithCrop(cropName, jsonFilter);
int countFiltered = genesysService.countAccessions(jsonTree.toString());
_logger.info("Attempting to download DwCA for " + countFiltered + " accessions");
if (countFiltered > 100000) {
throw new RuntimeException("Refusing to export more than 100,000 entries");
}
response.setContentType("application/zip");
response.addHeader("Content-Disposition", String.format("attachment; filename=\"genesys-accessions-filtered.zip\""));
......
......@@ -15,7 +15,10 @@
<div class="nav-header pull-left">
<div class="results"><spring:message code="accessions.number" arguments="${pagedData.totalElements}" />
<a href="<c:url value="/explore/map"><c:param name="crop" value="${crop.shortName}" /><c:param name="filter">${jsonFilter}</c:param></c:url>">Map</a>
<a href="<c:url value="/explore/dwca"><c:param name="crop" value="${crop.shortName}" /><c:param name="filter">${jsonFilter}</c:param></c:url>"><spring:message code="filter.download-dwca" /></a></div>
<c:if test="${pagedData.totalElements le 100000}">
<a href="<c:url value="/explore/dwca"><c:param name="crop" value="${crop.shortName}" /><c:param name="filter">${jsonFilter}</c:param></c:url>"><spring:message code="filter.download-dwca" /></a>
</c:if>
</div>
<div class="pagination">
<spring:message code="paged.pageOfPages" arguments="${pagedData.number+1},${pagedData.totalPages}" />
<a href="<spring:url value=""><spring:param name="page" value="${pagedData.number eq 0 ? 1 : pagedData.number}" /><spring:param name="filter" value="${jsonFilter}" /><spring:param name="pick" value="${jsonPick}" /></spring:url>"><spring:message code="pagination.previous-page" /></a>
......
Supports Markdown
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