Skip to content

Commit 050583e

Browse files
authored
Allow freezing searchable snapshots (#52653)
Today it does not work to freeze an index restored as a searchable snapshot, because both features try and supply their own `Engine` implementation. However a searchable snapshot works with both a `ReadOnlyEngine` and a `FrozenEngine`, so we can check to see if the searchable snapshot is frozen and, if so, avoid supplying a second `Engine` in that case.
1 parent 10e830a commit 050583e

File tree

2 files changed

+81
-31
lines changed

2 files changed

+81
-31
lines changed

x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/SearchableSnapshots.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ public Map<String, DirectoryFactory> getDirectoryFactories() {
111111

112112
@Override
113113
public Optional<EngineFactory> getEngineFactory(IndexSettings indexSettings) {
114-
if (SearchableSnapshotRepository.SNAPSHOT_DIRECTORY_FACTORY_KEY.equals(INDEX_STORE_TYPE_SETTING.get(indexSettings.getSettings()))) {
114+
if (SearchableSnapshotRepository.SNAPSHOT_DIRECTORY_FACTORY_KEY.equals(INDEX_STORE_TYPE_SETTING.get(indexSettings.getSettings()))
115+
&& indexSettings.getSettings().getAsBoolean("index.frozen", false) == false) {
115116
return Optional.of(engineConfig -> new ReadOnlyEngine(engineConfig, null, new TranslogStats(), false, Function.identity()));
116117
}
117118
return Optional.empty();

x-pack/plugin/searchable-snapshots/src/test/java/org/elasticsearch/xpack/searchablesnapshots/AbstractSearchableSnapshotsRestTestCase.java

Lines changed: 79 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public abstract class AbstractSearchableSnapshotsRestTestCase extends ESRestTest
4343

4444
protected abstract Settings repositorySettings();
4545

46-
public void testSearchableSnapshots() throws Exception {
46+
private void runSearchableSnapshotsTest(SearchableSnapshotsTestCaseBody testCaseBody) throws Exception {
4747
final String repositoryType = repositoryType();
4848
final Settings repositorySettings = repositorySettings();
4949

@@ -117,34 +117,7 @@ public void testSearchableSnapshots() throws Exception {
117117
final Number count = count(restoredIndexName);
118118
assertThat("Wrong index count for index " + restoredIndexName, count.intValue(), equalTo(numDocs));
119119

120-
for (int i = 0; i < 10; i++) {
121-
final int randomTieBreaker = randomIntBetween(1, numDocs - 1);
122-
Map<String, Object> searchResults;
123-
switch (randomInt(3)) {
124-
case 0:
125-
searchResults = search(restoredIndexName, QueryBuilders.termQuery("field", String.valueOf(randomTieBreaker)));
126-
assertThat(extractValue(searchResults, "hits.total.value"), equalTo(1));
127-
@SuppressWarnings("unchecked")
128-
Map<String, Object> searchHit = (Map<String, Object>) ((List<?>) extractValue(searchResults, "hits.hits")).get(0);
129-
assertThat(extractValue(searchHit, "_index"), equalTo(restoredIndexName));
130-
assertThat(extractValue(searchHit, "_source.field"), equalTo(randomTieBreaker));
131-
break;
132-
case 1:
133-
searchResults = search(restoredIndexName, QueryBuilders.rangeQuery("field").lt(randomTieBreaker));
134-
assertThat(extractValue(searchResults, "hits.total.value"), equalTo(randomTieBreaker));
135-
break;
136-
case 2:
137-
searchResults = search(restoredIndexName, QueryBuilders.rangeQuery("field").gte(randomTieBreaker));
138-
assertThat(extractValue(searchResults, "hits.total.value"), equalTo(numDocs - randomTieBreaker));
139-
break;
140-
case 3:
141-
searchResults = search(restoredIndexName, QueryBuilders.matchQuery("text", "document"));
142-
assertThat(extractValue(searchResults, "hits.total.value"), equalTo(numDocs));
143-
break;
144-
default:
145-
fail("Unsupported randomized search query");
146-
}
147-
}
120+
testCaseBody.runTest(restoredIndexName, numDocs);
148121

149122
logger.info("deleting snapshot [{}]", snapshot);
150123
deleteSnapshot(repository, snapshot, false);
@@ -154,6 +127,71 @@ public void testSearchableSnapshots() throws Exception {
154127
searchableSnapshotStats.size(), equalTo(numberOfShards));
155128
}
156129

130+
public void testSearchResults() throws Exception {
131+
runSearchableSnapshotsTest((restoredIndexName, numDocs) -> {
132+
for (int i = 0; i < 10; i++) {
133+
assertSearchResults(restoredIndexName, numDocs, randomFrom(Boolean.TRUE, Boolean.FALSE, null));
134+
}
135+
});
136+
}
137+
138+
public void testSearchResultsWhenFrozen() throws Exception {
139+
runSearchableSnapshotsTest((restoredIndexName, numDocs) -> {
140+
final Request freezeRequest = new Request(HttpPost.METHOD_NAME, restoredIndexName + "/_freeze");
141+
assertOK(client().performRequest(freezeRequest));
142+
ensureGreen(restoredIndexName);
143+
for (int i = 0; i < 10; i++) {
144+
assertSearchResults(restoredIndexName, numDocs, Boolean.FALSE);
145+
}
146+
});
147+
}
148+
149+
public void testCloseAndReopen() throws Exception {
150+
runSearchableSnapshotsTest((restoredIndexName, numDocs) -> {
151+
final Request closeRequest = new Request(HttpPost.METHOD_NAME, restoredIndexName + "/_close");
152+
assertOK(client().performRequest(closeRequest));
153+
ensureGreen(restoredIndexName);
154+
155+
final Request openRequest = new Request(HttpPost.METHOD_NAME, restoredIndexName + "/_open");
156+
assertOK(client().performRequest(openRequest));
157+
ensureGreen(restoredIndexName);
158+
159+
for (int i = 0; i < 10; i++) {
160+
assertSearchResults(restoredIndexName, numDocs, randomFrom(Boolean.TRUE, Boolean.FALSE, null));
161+
}
162+
});
163+
}
164+
165+
public void assertSearchResults(String indexName, int numDocs, Boolean ignoreThrottled) throws IOException {
166+
final int randomTieBreaker = randomIntBetween(1, numDocs - 1);
167+
Map<String, Object> searchResults;
168+
switch (randomInt(3)) {
169+
case 0:
170+
searchResults
171+
= search(indexName, QueryBuilders.termQuery("field", String.valueOf(randomTieBreaker)), ignoreThrottled);
172+
assertThat(extractValue(searchResults, "hits.total.value"), equalTo(1));
173+
@SuppressWarnings("unchecked")
174+
Map<String, Object> searchHit = (Map<String, Object>) ((List<?>) extractValue(searchResults, "hits.hits")).get(0);
175+
assertThat(extractValue(searchHit, "_index"), equalTo(indexName));
176+
assertThat(extractValue(searchHit, "_source.field"), equalTo(randomTieBreaker));
177+
break;
178+
case 1:
179+
searchResults = search(indexName, QueryBuilders.rangeQuery("field").lt(randomTieBreaker), ignoreThrottled);
180+
assertThat(extractValue(searchResults, "hits.total.value"), equalTo(randomTieBreaker));
181+
break;
182+
case 2:
183+
searchResults = search(indexName, QueryBuilders.rangeQuery("field").gte(randomTieBreaker), ignoreThrottled);
184+
assertThat(extractValue(searchResults, "hits.total.value"), equalTo(numDocs - randomTieBreaker));
185+
break;
186+
case 3:
187+
searchResults = search(indexName, QueryBuilders.matchQuery("text", "document"), ignoreThrottled);
188+
assertThat(extractValue(searchResults, "hits.total.value"), equalTo(numDocs));
189+
break;
190+
default:
191+
fail("Unsupported randomized search query");
192+
}
193+
}
194+
157195
protected static void registerRepository(String repository, String type, boolean verify, Settings settings) throws IOException {
158196
final Request request = new Request(HttpPut.METHOD_NAME, "_snapshot/" + repository);
159197
request.setJsonEntity(Strings.toString(new PutRepositoryRequest(repository).type(type).verify(verify).settings(settings)));
@@ -218,9 +256,12 @@ protected static Number count(String index) throws IOException {
218256
return (Number) extractValue(responseAsMap, "count");
219257
}
220258

221-
protected static Map<String, Object> search(String index, QueryBuilder query) throws IOException {
259+
protected static Map<String, Object> search(String index, QueryBuilder query, Boolean ignoreThrottled) throws IOException {
222260
final Request request = new Request(HttpPost.METHOD_NAME, '/' + index + "/_search");
223261
request.setJsonEntity(new SearchSourceBuilder().trackTotalHits(true).query(query).toString());
262+
if (ignoreThrottled != null) {
263+
request.addParameter("ignore_throttled", ignoreThrottled.toString());
264+
}
224265

225266
final Response response = client().performRequest(request);
226267
assertThat("Failed to execute search request on index [" + index + "]: " + response,
@@ -260,4 +301,12 @@ protected static Map<String, Object> responseAsMap(Response response) throws IOE
260301
protected static <T> T extractValue(Map<String, Object> map, String path) {
261302
return (T) XContentMapValues.extractValue(path, map);
262303
}
304+
305+
/**
306+
* The body of a test case, which runs after the searchable snapshot has been created and restored.
307+
*/
308+
@FunctionalInterface
309+
interface SearchableSnapshotsTestCaseBody {
310+
void runTest(String indexName, int numDocs) throws IOException;
311+
}
263312
}

0 commit comments

Comments
 (0)