Skip to content

Commit

Permalink
fix error message when changeset filter is used in snapshot query (#294)
Browse files Browse the repository at this point in the history
* fix error message when changeset filter is used in snapshot query

closes #289

* add test
  • Loading branch information
tyrasd committed Mar 9, 2023
1 parent a8a1518 commit 1dee8f9
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ Changelog

## 1.9.0-SNAPSHOT (current master)

### Bug Fixes
* Show proper error message when a `changeset` filter is used on a snapshot based endpoint ([#289])

[#289] https://github.com/GIScience/ohsome-api/issues/289


## 1.8.1

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ public class ExceptionMessages {
+ "when you set the filter parameter.";
public static final String FILTER_SYNTAX = "Invalid filter syntax. Please look at the additional "
+ "info and examples about the filter parameter at https://docs.ohsome.org/ohsome-api.";
public static final String FILTER_INVALID_CHANGESET = "Invalid filter: The changeset filters can "
+ "only be used in contribution based API endpoints. Please look at the additional "
+ "info and examples about the filter parameter at https://docs.ohsome.org/ohsome-api.";
public static final String GROUP_BY_KEY_PARAM =
"You need to give one groupByKey parameter, if you want to use groupBy/tag.";
public static final String GROUP_BY_KEYS_PARAM =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,10 @@ public static Response aggregateRatio(RequestResource requestResource,
FilterParser fp = new FilterParser(DbConnData.tagTranslator);
FilterExpression filterExpr1 = inputProcessor.getUtils().parseFilter(fp, filter1);
FilterExpression filterExpr2 = inputProcessor.getUtils().parseFilter(fp, filter2);
if (!(InputProcessingUtils.filterSuitableForSnapshots(filterExpr1)
&& InputProcessingUtils.filterSuitableForSnapshots(filterExpr2))) {
throw new BadRequestException(ExceptionMessages.FILTER_INVALID_CHANGESET);
}
RequestParameters requestParamsCombined = new RequestParameters(servletRequest.getMethod(),
isSnapshot, isDensity, servletRequest.getParameter("bboxes"),
servletRequest.getParameter("bcircles"), servletRequest.getParameter("bpolys"),
Expand Down Expand Up @@ -985,6 +989,10 @@ public static <P extends Geometry & Polygonal> Response aggregateRatioGroupByBou
final FilterParser fp = new FilterParser(DbConnData.tagTranslator);
final FilterExpression filterExpr1 = inputProcessor.getUtils().parseFilter(fp, filter1);
final FilterExpression filterExpr2 = inputProcessor.getUtils().parseFilter(fp, filter2);
if (!(InputProcessingUtils.filterSuitableForSnapshots(filterExpr1)
&& InputProcessingUtils.filterSuitableForSnapshots(filterExpr2))) {
throw new BadRequestException(ExceptionMessages.FILTER_INVALID_CHANGESET);
}
RequestParameters requestParamsCombined = new RequestParameters(servletRequest.getMethod(),
isSnapshot, isDensity, servletRequest.getParameter("bboxes"),
servletRequest.getParameter("bcircles"), servletRequest.getParameter("bpolys"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
Expand All @@ -16,6 +17,9 @@
import org.heigit.ohsome.ohsomeapi.utils.TimestampFormatter;
import org.heigit.ohsome.oshdb.OSHDBTag;
import org.heigit.ohsome.oshdb.api.mapreducer.MapReducer;
import org.heigit.ohsome.oshdb.filter.ChangesetIdFilterEquals;
import org.heigit.ohsome.oshdb.filter.ChangesetIdFilterEqualsAnyOf;
import org.heigit.ohsome.oshdb.filter.ChangesetIdFilterRange;
import org.heigit.ohsome.oshdb.filter.Filter;
import org.heigit.ohsome.oshdb.filter.FilterExpression;
import org.heigit.ohsome.oshdb.filter.FilterParser;
Expand Down Expand Up @@ -396,6 +400,19 @@ public FilterExpression parseFilter(FilterParser fp, String filter) {
}
}

/**
* Returns whether a given filter is suitable for snapshots based endpoints.
*
* <p>For example, `changeset:*` filter can only be used on contribution based endpoints,
* see also <a href="https://github.com/GIScience/ohsome-api/issues/289">#289</a>.</p>
*/
public static boolean filterSuitableForSnapshots(FilterExpression filter) {
return filter.normalize().stream().flatMap(Collection::stream)
.noneMatch(f -> f instanceof ChangesetIdFilterEquals
|| f instanceof ChangesetIdFilterRange
|| f instanceof ChangesetIdFilterEqualsAnyOf);
}

/**
* Checks the provided time info on its temporal extent.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,9 @@ public <T extends OSHDBMapReducible> MapReducer<T> processParameters(ComputeMode
// call translator and add filters to mapRed
FilterParser fp = new FilterParser(DbConnData.tagTranslator);
FilterExpression filterExpr = utils.parseFilter(fp, filter);
if (isSnapshot && !InputProcessingUtils.filterSuitableForSnapshots(filterExpr)) {
throw new BadRequestException(ExceptionMessages.FILTER_INVALID_CHANGESET);
}
processingData.setFilterExpression(filterExpr);
if (!(processingData.isRatio()
|| processingData.isGroupByBoundary()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package org.heigit.ohsome.ohsomeapi.inputprocessing;

import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.heigit.ohsome.oshdb.OSHDBRole;
import org.heigit.ohsome.oshdb.OSHDBTag;
import org.heigit.ohsome.oshdb.util.OSHDBTagKey;
import org.heigit.ohsome.oshdb.util.tagtranslator.OSMRole;
import org.heigit.ohsome.oshdb.util.tagtranslator.OSMTag;
import org.heigit.ohsome.oshdb.util.tagtranslator.OSMTagKey;
import org.heigit.ohsome.oshdb.util.tagtranslator.TagTranslator;

public class DummyTagTranslator implements TagTranslator {

@Override
public Optional<OSHDBTagKey> getOSHDBTagKeyOf(OSMTagKey osmTagKey) {
return Optional.empty();
}

@Override
public Optional<OSHDBTag> getOSHDBTagOf(OSMTag osmTag) {
return Optional.empty();
}

@Override
public Map<OSMTag, OSHDBTag> getOSHDBTagOf(Collection<OSMTag> collection) {
return null;
}

@Override
public Optional<OSHDBRole> getOSHDBRoleOf(OSMRole osmRole) {
return Optional.empty();
}

@Override
public Map<OSMRole, OSHDBRole> getOSHDBRoleOf(Collection<OSMRole> collection) {
return null;
}

@Override
public OSMTag lookupTag(OSHDBTag oshdbTag) {
return null;
}

@Override
public Map<OSHDBTag, OSMTag> lookupTag(Set<? extends OSHDBTag> set) {
return null;
}

@Override
public OSMRole lookupRole(OSHDBRole oshdbRole) {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package org.heigit.ohsome.ohsomeapi.inputprocessing;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeTrue;

import org.heigit.ohsome.ohsomeapi.controller.TestProperties;
import org.heigit.ohsome.ohsomeapi.exception.BadRequestException;
import org.heigit.ohsome.ohsomeapi.oshdb.ExtractMetadata;
import org.heigit.ohsome.oshdb.filter.FilterParser;
import org.heigit.ohsome.oshdb.util.tagtranslator.TagTranslator;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -111,4 +114,14 @@ public void provideIsoConformTimeParameter() throws Exception {
assertTrue(timeVals[1].equals("2017-01-01T00:00:00Z"));
assertTrue(timeVals[2].equals("P1Y"));
}

@SuppressWarnings("DataFlowIssue")
@Test void filterSuitableForSnapshots() {
TagTranslator dummyTagTranslator = new DummyTagTranslator();
FilterParser filterParser = new FilterParser(dummyTagTranslator);
assertTrue(InputProcessingUtils.filterSuitableForSnapshots(inProUtils.parseFilter(filterParser,
"type:node and id:42")));
assertFalse(InputProcessingUtils.filterSuitableForSnapshots(inProUtils.parseFilter(filterParser,
"type:node and changeset:42")));
}
}

0 comments on commit 1dee8f9

Please sign in to comment.