Skip to content

Commit cb9b4a8

Browse files
Reindex from Remote allow date math (#40303)
Previously, reindexing from remote using date math in the source index name did not work if the math contained / or ,. A workaround was to then URL escape the index name in the request. With this change, we now support any index name in the remote request that the remote source supports, doing the URL escape when sending the request. Related to #23533
1 parent 0a32b60 commit cb9b4a8

File tree

2 files changed

+48
-17
lines changed

2 files changed

+48
-17
lines changed

modules/reindex/src/main/java/org/elasticsearch/index/reindex/remote/RemoteRequestBuilders.java

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
import org.elasticsearch.search.sort.SortBuilder;
3939

4040
import java.io.IOException;
41+
import java.io.UnsupportedEncodingException;
42+
import java.net.URLEncoder;
43+
import java.util.Arrays;
44+
import java.util.stream.Collectors;
4145

4246
import static org.elasticsearch.common.unit.TimeValue.timeValueMillis;
4347

@@ -54,8 +58,8 @@ private RemoteRequestBuilders() {}
5458
static Request initialSearch(SearchRequest searchRequest, BytesReference query, Version remoteVersion) {
5559
// It is nasty to build paths with StringBuilder but we'll be careful....
5660
StringBuilder path = new StringBuilder("/");
57-
addIndexesOrTypes(path, "Index", searchRequest.indices());
58-
addIndexesOrTypes(path, "Type", searchRequest.types());
61+
addIndices(path, searchRequest.indices());
62+
addTypes(path, searchRequest.types());
5963
path.append("_search");
6064
Request request = new Request("POST", path.toString());
6165

@@ -158,14 +162,34 @@ static Request initialSearch(SearchRequest searchRequest, BytesReference query,
158162
return request;
159163
}
160164

161-
private static void addIndexesOrTypes(StringBuilder path, String name, String[] indicesOrTypes) {
162-
if (indicesOrTypes == null || indicesOrTypes.length == 0) {
165+
private static void addIndices(StringBuilder path, String[] indices) {
166+
if (indices == null || indices.length == 0) {
163167
return;
164168
}
165-
for (String indexOrType : indicesOrTypes) {
166-
checkIndexOrType(name, indexOrType);
169+
170+
path.append(Arrays.stream(indices).map(RemoteRequestBuilders::encodeIndex).collect(Collectors.joining(","))).append('/');
171+
}
172+
173+
private static String encodeIndex(String s) {
174+
if (s.contains("%")) { // already encoded, pass-through to allow this in mixed version clusters
175+
checkIndexOrType("Index", s);
176+
return s;
177+
}
178+
try {
179+
return URLEncoder.encode(s, "utf-8");
180+
} catch (UnsupportedEncodingException e) {
181+
throw new RuntimeException(e);
182+
}
183+
}
184+
185+
private static void addTypes(StringBuilder path, String[] types) {
186+
if (types == null || types.length == 0) {
187+
return;
188+
}
189+
for (String indexOrType : types) {
190+
checkIndexOrType("Type", indexOrType);
167191
}
168-
path.append(Strings.arrayToCommaDelimitedString(indicesOrTypes)).append('/');
192+
path.append(Strings.arrayToCommaDelimitedString(types)).append('/');
169193
}
170194

171195
private static void checkIndexOrType(String name, String indexOrType) {

modules/reindex/src/test/java/org/elasticsearch/index/reindex/remote/RemoteRequestBuildersTests.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,19 +68,26 @@ public void testIntialSearchPath() {
6868
searchRequest.indices("a", "b");
6969
searchRequest.types("c", "d");
7070
assertEquals("/a,b/c,d/_search", initialSearch(searchRequest, query, remoteVersion).getEndpoint());
71-
7271
searchRequest.indices("cat,");
73-
expectBadStartRequest(searchRequest, "Index", ",", "cat,");
74-
searchRequest.indices("cat,", "dog");
75-
expectBadStartRequest(searchRequest, "Index", ",", "cat,");
76-
searchRequest.indices("dog", "cat,");
77-
expectBadStartRequest(searchRequest, "Index", ",", "cat,");
72+
assertEquals("/cat%2C/c,d/_search", initialSearch(searchRequest, query, remoteVersion).getEndpoint());
7873
searchRequest.indices("cat/");
79-
expectBadStartRequest(searchRequest, "Index", "/", "cat/");
74+
assertEquals("/cat%2F/c,d/_search", initialSearch(searchRequest, query, remoteVersion).getEndpoint());
8075
searchRequest.indices("cat/", "dog");
81-
expectBadStartRequest(searchRequest, "Index", "/", "cat/");
82-
searchRequest.indices("dog", "cat/");
83-
expectBadStartRequest(searchRequest, "Index", "/", "cat/");
76+
assertEquals("/cat%2F,dog/c,d/_search", initialSearch(searchRequest, query, remoteVersion).getEndpoint());
77+
// test a specific date math + all characters that need escaping.
78+
searchRequest.indices("<cat{now/d}>", "<>/{}|+:,");
79+
assertEquals("/%3Ccat%7Bnow%2Fd%7D%3E,%3C%3E%2F%7B%7D%7C%2B%3A%2C/c,d/_search",
80+
initialSearch(searchRequest, query, remoteVersion).getEndpoint());
81+
82+
// pass-through if already escaped.
83+
searchRequest.indices("%2f", "%3a");
84+
assertEquals("/%2f,%3a/c,d/_search", initialSearch(searchRequest, query, remoteVersion).getEndpoint());
85+
86+
// do not allow , and / if already escaped.
87+
searchRequest.indices("%2fcat,");
88+
expectBadStartRequest(searchRequest, "Index", ",", "%2fcat,");
89+
searchRequest.indices("%3ccat/");
90+
expectBadStartRequest(searchRequest, "Index", "/", "%3ccat/");
8491

8592
searchRequest.indices("ok");
8693
searchRequest.types("cat,");

0 commit comments

Comments
 (0)