From 4d76d3bb5835412f62a81ab7390f9010c9cb17ec Mon Sep 17 00:00:00 2001 From: Gobi Selvaraj Date: Fri, 26 Feb 2021 11:24:20 -0500 Subject: [PATCH] Allow double underscore in the field name for filtering --- .../hubspot/httpql/impl/UriParamParser.java | 31 +++++++++++++--- .../httpql/impl/UriParamParserTest.java | 36 +++++++++++++++++++ 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/httpql/src/main/java/com/hubspot/httpql/impl/UriParamParser.java b/httpql/src/main/java/com/hubspot/httpql/impl/UriParamParser.java index 1f44f30..5b362cb 100644 --- a/httpql/src/main/java/com/hubspot/httpql/impl/UriParamParser.java +++ b/httpql/src/main/java/com/hubspot/httpql/impl/UriParamParser.java @@ -14,6 +14,7 @@ import org.apache.commons.lang.math.NumberUtils; import org.jooq.impl.DSL; +import com.google.common.base.Joiner; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Multimap; @@ -28,7 +29,9 @@ public class UriParamParser { public static final Map BY_NAME = new HashMap<>(); private static final ServiceLoader LOADER = ServiceLoader.load(Filter.class); - private static final Splitter FILTER_PARAM_SPLITTER = Splitter.on("__").trimResults(); + private static final String FILTER_PARAM_DELIMITER = "__"; + private static final Splitter FILTER_PARAM_SPLITTER = Splitter.on(FILTER_PARAM_DELIMITER).trimResults(); + private static final Joiner FILTER_PARAM_JOINER = Joiner.on(FILTER_PARAM_DELIMITER); private static final Splitter MULTIVALUE_PARAM_SPLITTER = Splitter.on(",").omitEmptyStrings().trimResults(); static { @@ -59,8 +62,12 @@ public ParsedUriParams parseUriParams(Multimap uriParams) { return parseUriParams(multimapToMultivaluedMap(uriParams)); } - @SuppressWarnings("rawtypes") public ParsedUriParams parseUriParams(Map> uriParams) { + return parseUriParams(uriParams, false); + } + + @SuppressWarnings("rawtypes") + public ParsedUriParams parseUriParams(Map> uriParams, boolean allowDoubleUnderscoreInFieldName) { final ParsedUriParams result = new ParsedUriParams(); @@ -94,11 +101,11 @@ public ParsedUriParams parseUriParams(Map> uriParams) { for (Map.Entry> entry : params.entrySet()) { List parts = FILTER_PARAM_SPLITTER.splitToList(entry.getKey().trim()); - if (parts.size() > 2) { + if (parts.size() > 2 && !allowDoubleUnderscoreInFieldName) { continue; } - final String fieldName = parts.get(0); + final String fieldName = fieldNameFromParts(parts, allowDoubleUnderscoreInFieldName); final String filterName = filterNameFromParts(parts); final Filter filter = BY_NAME.get(filterName); @@ -123,8 +130,22 @@ private static String filterNameFromParts(List parts) { if (parts.size() == 1) { return (new Equal()).names()[0]; } else { - return parts.get(1); + return parts.get(parts.size() - 1); + } + } + + private static String fieldNameFromParts(List parts, boolean allowDoubleUnderscoreInFieldName) { + if (!allowDoubleUnderscoreInFieldName) { + return parts.get(0); } + + if (BY_NAME.keySet().contains(parts.get(parts.size() - 1))) { + List partsCopy = new ArrayList<>(parts); + partsCopy.remove(parts.size() - 1); + return FILTER_PARAM_JOINER.join(partsCopy); + } + + return FILTER_PARAM_JOINER.join(parts); } public static Builder newBuilder() { diff --git a/httpql/src/test/java/com/hubspot/httpql/impl/UriParamParserTest.java b/httpql/src/test/java/com/hubspot/httpql/impl/UriParamParserTest.java index 92f7d8d..6d7d347 100644 --- a/httpql/src/test/java/com/hubspot/httpql/impl/UriParamParserTest.java +++ b/httpql/src/test/java/com/hubspot/httpql/impl/UriParamParserTest.java @@ -1,6 +1,7 @@ package com.hubspot.httpql.impl; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.util.Collections; import java.util.HashMap; @@ -11,6 +12,8 @@ import org.junit.Before; import org.junit.Test; +import com.hubspot.httpql.error.FilterViolation; + public class UriParamParserTest { UriParamParser uriParamParser; @@ -42,4 +45,37 @@ public void itPreservesCommasInEqValues() { assertThat(parsedUriParams.getFieldFilters().get(0).getValue()).isEqualTo("1,2,3"); } + @Test + public void itAllowsDoubleUnderscoresInFieldNames() { + Map> query = new HashMap<>(); + query.put("foo1__bar1__eq", Lists.newArrayList("1")); + query.put("foo2__bar2__contains", Lists.newArrayList("1")); + query.put("foo3__eq", Lists.newArrayList("1")); + query.put("foo4", Lists.newArrayList("1")); + + final ParsedUriParams parsedUriParams = uriParamParser.parseUriParams(query, true); + + assertThat(parsedUriParams.getFieldFilters().get(0).getField()).isEqualTo("foo2__bar2"); + assertThat(parsedUriParams.getFieldFilters().get(0).getFilterName()).isEqualTo("contains"); + + assertThat(parsedUriParams.getFieldFilters().get(1).getField()).isEqualTo("foo3"); + assertThat(parsedUriParams.getFieldFilters().get(1).getFilterName()).isEqualTo("eq"); + + assertThat(parsedUriParams.getFieldFilters().get(2).getField()).isEqualTo("foo1__bar1"); + assertThat(parsedUriParams.getFieldFilters().get(2).getFilterName()).isEqualTo("eq"); + + assertThat(parsedUriParams.getFieldFilters().get(3).getField()).isEqualTo("foo4"); + assertThat(parsedUriParams.getFieldFilters().get(3).getFilterName()).isEqualTo("eq"); + } + + @Test + public void itRequiresExplicitEqualFilterWithDoubleUnderscoreInFieldNames() { + Map> query = new HashMap<>(); + query.put("foo2__bar2", Lists.newArrayList("1")); + + assertThatThrownBy( + () -> uriParamParser.parseUriParams(query, true) + ) + .isInstanceOf(FilterViolation.class); + } }