Skip to content

Commit

Permalink
Index name expressions should not be broken up
Browse files Browse the repository at this point in the history
Closes #13665
  • Loading branch information
martijnvg committed Sep 25, 2015
1 parent 51a9df7 commit f3fe3bb
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 21 deletions.
1 change: 0 additions & 1 deletion core/src/main/java/org/elasticsearch/common/Strings.java
Expand Up @@ -569,7 +569,6 @@ public static Set<String> splitStringToSet(final String s, final char c) {
count++;
}
}
// TODO (MvG): No push: hppc or jcf?
final Set<String> result = new HashSet<>(count);
final int len = chars.length;
int start = 0; // starting index in chars of the current substring.
Expand Down
52 changes: 50 additions & 2 deletions core/src/main/java/org/elasticsearch/common/path/PathTrie.java
Expand Up @@ -22,6 +22,8 @@
import com.google.common.collect.ImmutableMap;
import org.elasticsearch.common.Strings;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static org.elasticsearch.common.collect.MapBuilder.newMapBuilder;
Expand Down Expand Up @@ -195,7 +197,7 @@ public T retrieve(String[] path, int index, Map<String, String> params) {

private void put(Map<String, String> params, TrieNode<T> node, String value) {
if (params != null && node.isNamedWildcard()) {
params.put(node.namedWildcard(), decoder.decode(value));
params.put(node.namedWildcard(), value);
}
}
}
Expand All @@ -222,7 +224,7 @@ public T retrieve(String path, Map<String, String> params) {
if (path.length() == 0) {
return rootValue;
}
String[] strings = Strings.splitStringToArray(path, separator);
String[] strings = splitPath(decoder.decode(path));
if (strings.length == 0) {
return rootValue;
}
Expand All @@ -233,4 +235,50 @@ public T retrieve(String path, Map<String, String> params) {
}
return root.retrieve(strings, index, params);
}

/*
Splits up the url path up by '/' and is aware of
index name expressions that appear between '<' and '>'.
*/
String[] splitPath(final String path) {
if (path == null || path.length() == 0) {
return Strings.EMPTY_ARRAY;
}
int count = 1;
boolean splitAllowed = true;
for (int i = 0; i < path.length(); i++) {
final char currentC = path.charAt(i);
if ('<' == currentC) {
splitAllowed = false;
} else if (currentC == '>') {
splitAllowed = true;
} else if (splitAllowed && currentC == separator) {
count++;
}
}

final List<String> result = new ArrayList<>(count);
final StringBuilder builder = new StringBuilder();

splitAllowed = true;
for (int i = 0; i < path.length(); i++) {
final char currentC = path.charAt(i);
if ('<' == currentC) {
splitAllowed = false;
} else if (currentC == '>') {
splitAllowed = true;
} else if (splitAllowed && currentC == separator) {
if (builder.length() > 0) {
result.add(builder.toString());
builder.setLength(0);
}
continue;
}
builder.append(currentC);
}
if (builder.length() > 0) {
result.add(builder.toString());
}
return result.toArray(new String[result.size()]);
}
}
51 changes: 33 additions & 18 deletions core/src/test/java/org/elasticsearch/common/path/PathTrieTests.java
Expand Up @@ -22,9 +22,10 @@
import org.elasticsearch.test.ESTestCase;
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

import static com.google.common.collect.Maps.newHashMap;
import static org.hamcrest.Matchers.arrayContaining;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.nullValue;

Expand All @@ -33,7 +34,6 @@
*/
public class PathTrieTests extends ESTestCase {

@Test
public void testPath() {
PathTrie<String> trie = new PathTrie<>();
trie.insert("/a/b/c", "walla");
Expand All @@ -54,27 +54,25 @@ public void testPath() {
assertThat(trie.retrieve("a/b/c/d"), nullValue());
assertThat(trie.retrieve("g/t/x"), equalTo("three"));

Map<String, String> params = newHashMap();
Map<String, String> params = new HashMap<>();
assertThat(trie.retrieve("index1/insert/12", params), equalTo("bingo"));
assertThat(params.size(), equalTo(2));
assertThat(params.get("index"), equalTo("index1"));
assertThat(params.get("docId"), equalTo("12"));
}

@Test
public void testEmptyPath() {
PathTrie<String> trie = new PathTrie<>();
trie.insert("/", "walla");
assertThat(trie.retrieve(""), equalTo("walla"));
}

@Test
public void testDifferentNamesOnDifferentPath() {
PathTrie<String> trie = new PathTrie<>();
trie.insert("/a/{type}", "test1");
trie.insert("/b/{name}", "test2");

Map<String, String> params = newHashMap();
Map<String, String> params = new HashMap<>();
assertThat(trie.retrieve("/a/test", params), equalTo("test1"));
assertThat(params.get("type"), equalTo("test"));

Expand All @@ -83,13 +81,12 @@ public void testDifferentNamesOnDifferentPath() {
assertThat(params.get("name"), equalTo("testX"));
}

@Test
public void testSameNameOnDifferentPath() {
PathTrie<String> trie = new PathTrie<>();
trie.insert("/a/c/{name}", "test1");
trie.insert("/b/{name}", "test2");

Map<String, String> params = newHashMap();
Map<String, String> params = new HashMap<>();
assertThat(trie.retrieve("/a/c/test", params), equalTo("test1"));
assertThat(params.get("name"), equalTo("test"));

Expand All @@ -98,7 +95,6 @@ public void testSameNameOnDifferentPath() {
assertThat(params.get("name"), equalTo("testX"));
}

@Test
public void testPreferNonWildcardExecution() {
PathTrie<String> trie = new PathTrie<>();
trie.insert("{test}", "test1");
Expand All @@ -108,20 +104,19 @@ public void testPreferNonWildcardExecution() {
trie.insert("{test}/{testB}", "test5");
trie.insert("{test}/x/{testC}", "test6");

Map<String, String> params = newHashMap();
Map<String, String> params = new HashMap<>();
assertThat(trie.retrieve("/b", params), equalTo("test2"));
assertThat(trie.retrieve("/b/a", params), equalTo("test4"));
assertThat(trie.retrieve("/v/x", params), equalTo("test5"));
assertThat(trie.retrieve("/v/x/c", params), equalTo("test6"));
}

@Test
public void testSamePathConcreteResolution() {
PathTrie<String> trie = new PathTrie<>();
trie.insert("{x}/{y}/{z}", "test1");
trie.insert("{x}/_y/{k}", "test2");

Map<String, String> params = newHashMap();
Map<String, String> params = new HashMap<>();
assertThat(trie.retrieve("/a/b/c", params), equalTo("test1"));
assertThat(params.get("x"), equalTo("a"));
assertThat(params.get("y"), equalTo("b"));
Expand All @@ -132,7 +127,6 @@ public void testSamePathConcreteResolution() {
assertThat(params.get("k"), equalTo("c"));
}

@Test
public void testNamedWildcardAndLookupWithWildcard() {
PathTrie<String> trie = new PathTrie<>();
trie.insert("x/{test}", "test1");
Expand All @@ -141,24 +135,45 @@ public void testNamedWildcardAndLookupWithWildcard() {
trie.insert("/{test}/_endpoint", "test4");
trie.insert("/*/{test}/_endpoint", "test5");

Map<String, String> params = newHashMap();
Map<String, String> params = new HashMap<>();
assertThat(trie.retrieve("/x/*", params), equalTo("test1"));
assertThat(params.get("test"), equalTo("*"));

params = newHashMap();
params = new HashMap<>();
assertThat(trie.retrieve("/b/a", params), equalTo("test2"));
assertThat(params.get("test"), equalTo("b"));

params = newHashMap();
params = new HashMap<>();
assertThat(trie.retrieve("/*", params), equalTo("test3"));
assertThat(params.get("test"), equalTo("*"));

params = newHashMap();
params = new HashMap<>();
assertThat(trie.retrieve("/*/_endpoint", params), equalTo("test4"));
assertThat(params.get("test"), equalTo("*"));

params = newHashMap();
params = new HashMap<>();
assertThat(trie.retrieve("a/*/_endpoint", params), equalTo("test5"));
assertThat(params.get("test"), equalTo("*"));
}

public void testSplitPath() {
PathTrie<String> trie = new PathTrie<>();
assertThat(trie.splitPath("/a/"), arrayContaining("a"));
assertThat(trie.splitPath("/a/b"),arrayContaining("a", "b"));
assertThat(trie.splitPath("/a/b/c"), arrayContaining("a", "b", "c"));
assertThat(trie.splitPath("/a/b/<c/d>"), arrayContaining("a", "b", "<c/d>"));
assertThat(trie.splitPath("/a/b/<c/d>/d"), arrayContaining("a", "b", "<c/d>", "d"));

assertThat(trie.splitPath("/<logstash-{now}>/_search"), arrayContaining("<logstash-{now}>", "_search"));
assertThat(trie.splitPath("/<logstash-{now/d}>/_search"), arrayContaining("<logstash-{now/d}>", "_search"));
assertThat(trie.splitPath("/<logstash-{now/M{YYYY.MM}}>/_search"), arrayContaining("<logstash-{now/M{YYYY.MM}}>", "_search"));
assertThat(trie.splitPath("/<logstash-{now/M{YYYY.MM}}>/_search"), arrayContaining("<logstash-{now/M{YYYY.MM}}>", "_search"));
assertThat(trie.splitPath("/<logstash-{now/M{YYYY.MM|UTC}}>/log/_search"), arrayContaining("<logstash-{now/M{YYYY.MM|UTC}}>", "log", "_search"));

assertThat(trie.splitPath("/<logstash-{now/M}>,<logstash-{now/M-1M}>/_search"), arrayContaining("<logstash-{now/M}>,<logstash-{now/M-1M}>", "_search"));
assertThat(trie.splitPath("/<logstash-{now/M}>,<logstash-{now/M-1M}>/_search"), arrayContaining("<logstash-{now/M}>,<logstash-{now/M-1M}>", "_search"));
assertThat(trie.splitPath("/<logstash-{now/M{YYYY.MM}}>,<logstash-{now/M-1M{YYYY.MM}}>/_search"), arrayContaining("<logstash-{now/M{YYYY.MM}}>,<logstash-{now/M-1M{YYYY.MM}}>", "_search"));
assertThat(trie.splitPath("/<logstash-{now/M{YYYY.MM|UTC}}>,<logstash-{now/M-1M{YYYY.MM|UTC}}>/_search"), arrayContaining("<logstash-{now/M{YYYY.MM|UTC}}>,<logstash-{now/M-1M{YYYY.MM|UTC}}>", "_search"));
}

}
@@ -0,0 +1,7 @@
---
"Missing index with catch":

- do:
catch: /index=logstash-\d{4}\.\d{2}\.\d{2}/
search:
index: <logstash-{now/M}>

0 comments on commit f3fe3bb

Please sign in to comment.