Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 26 additions & 5 deletions httpql/src/main/java/com/hubspot/httpql/impl/UriParamParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -28,7 +29,9 @@ public class UriParamParser {
public static final Map<String, Filter> BY_NAME = new HashMap<>();
private static final ServiceLoader<Filter> 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 {
Expand Down Expand Up @@ -59,8 +62,12 @@ public ParsedUriParams parseUriParams(Multimap<String, String> uriParams) {
return parseUriParams(multimapToMultivaluedMap(uriParams));
}

@SuppressWarnings("rawtypes")
public ParsedUriParams parseUriParams(Map<String, List<String>> uriParams) {
return parseUriParams(uriParams, false);
}

@SuppressWarnings("rawtypes")
public ParsedUriParams parseUriParams(Map<String, List<String>> uriParams, boolean allowDoubleUnderscoreInFieldName) {

final ParsedUriParams result = new ParsedUriParams();

Expand Down Expand Up @@ -94,11 +101,11 @@ public ParsedUriParams parseUriParams(Map<String, List<String>> uriParams) {

for (Map.Entry<String, List<String>> entry : params.entrySet()) {
List<String> 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);

Expand All @@ -123,8 +130,22 @@ private static String filterNameFromParts(List<String> 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<String> parts, boolean allowDoubleUnderscoreInFieldName) {
if (!allowDoubleUnderscoreInFieldName) {
return parts.get(0);
}

if (BY_NAME.keySet().contains(parts.get(parts.size() - 1))) {
List<String> 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() {
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -11,6 +12,8 @@
import org.junit.Before;
import org.junit.Test;

import com.hubspot.httpql.error.FilterViolation;

public class UriParamParserTest {
UriParamParser uriParamParser;

Expand Down Expand Up @@ -42,4 +45,37 @@ public void itPreservesCommasInEqValues() {
assertThat(parsedUriParams.getFieldFilters().get(0).getValue()).isEqualTo("1,2,3");
}

@Test
public void itAllowsDoubleUnderscoresInFieldNames() {
Map<String, List<String>> 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<String, List<String>> query = new HashMap<>();
query.put("foo2__bar2", Lists.newArrayList("1"));

assertThatThrownBy(
() -> uriParamParser.parseUriParams(query, true)
)
.isInstanceOf(FilterViolation.class);
}
}