diff --git a/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/SearchableSnapshots.java b/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/SearchableSnapshots.java index d20821de9a41e..9b5b88d7fd847 100644 --- a/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/SearchableSnapshots.java +++ b/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/SearchableSnapshots.java @@ -111,7 +111,8 @@ public Map getDirectoryFactories() { @Override public Optional getEngineFactory(IndexSettings indexSettings) { - if (SearchableSnapshotRepository.SNAPSHOT_DIRECTORY_FACTORY_KEY.equals(INDEX_STORE_TYPE_SETTING.get(indexSettings.getSettings()))) { + if (SearchableSnapshotRepository.SNAPSHOT_DIRECTORY_FACTORY_KEY.equals(INDEX_STORE_TYPE_SETTING.get(indexSettings.getSettings())) + && indexSettings.getSettings().getAsBoolean("index.frozen", false) == false) { return Optional.of(engineConfig -> new ReadOnlyEngine(engineConfig, null, new TranslogStats(), false, Function.identity())); } return Optional.empty(); diff --git a/x-pack/plugin/searchable-snapshots/src/test/java/org/elasticsearch/xpack/searchablesnapshots/AbstractSearchableSnapshotsRestTestCase.java b/x-pack/plugin/searchable-snapshots/src/test/java/org/elasticsearch/xpack/searchablesnapshots/AbstractSearchableSnapshotsRestTestCase.java index 042131bd09a51..3449abcab1102 100644 --- a/x-pack/plugin/searchable-snapshots/src/test/java/org/elasticsearch/xpack/searchablesnapshots/AbstractSearchableSnapshotsRestTestCase.java +++ b/x-pack/plugin/searchable-snapshots/src/test/java/org/elasticsearch/xpack/searchablesnapshots/AbstractSearchableSnapshotsRestTestCase.java @@ -43,7 +43,7 @@ public abstract class AbstractSearchableSnapshotsRestTestCase extends ESRestTest protected abstract Settings repositorySettings(); - public void testSearchableSnapshots() throws Exception { + private void runSearchableSnapshotsTest(SearchableSnapshotsTestCaseBody testCaseBody) throws Exception { final String repositoryType = repositoryType(); final Settings repositorySettings = repositorySettings(); @@ -117,34 +117,7 @@ public void testSearchableSnapshots() throws Exception { final Number count = count(restoredIndexName); assertThat("Wrong index count for index " + restoredIndexName, count.intValue(), equalTo(numDocs)); - for (int i = 0; i < 10; i++) { - final int randomTieBreaker = randomIntBetween(1, numDocs - 1); - Map searchResults; - switch (randomInt(3)) { - case 0: - searchResults = search(restoredIndexName, QueryBuilders.termQuery("field", String.valueOf(randomTieBreaker))); - assertThat(extractValue(searchResults, "hits.total.value"), equalTo(1)); - @SuppressWarnings("unchecked") - Map searchHit = (Map) ((List) extractValue(searchResults, "hits.hits")).get(0); - assertThat(extractValue(searchHit, "_index"), equalTo(restoredIndexName)); - assertThat(extractValue(searchHit, "_source.field"), equalTo(randomTieBreaker)); - break; - case 1: - searchResults = search(restoredIndexName, QueryBuilders.rangeQuery("field").lt(randomTieBreaker)); - assertThat(extractValue(searchResults, "hits.total.value"), equalTo(randomTieBreaker)); - break; - case 2: - searchResults = search(restoredIndexName, QueryBuilders.rangeQuery("field").gte(randomTieBreaker)); - assertThat(extractValue(searchResults, "hits.total.value"), equalTo(numDocs - randomTieBreaker)); - break; - case 3: - searchResults = search(restoredIndexName, QueryBuilders.matchQuery("text", "document")); - assertThat(extractValue(searchResults, "hits.total.value"), equalTo(numDocs)); - break; - default: - fail("Unsupported randomized search query"); - } - } + testCaseBody.runTest(restoredIndexName, numDocs); logger.info("deleting snapshot [{}]", snapshot); deleteSnapshot(repository, snapshot, false); @@ -154,6 +127,71 @@ public void testSearchableSnapshots() throws Exception { searchableSnapshotStats.size(), equalTo(numberOfShards)); } + public void testSearchResults() throws Exception { + runSearchableSnapshotsTest((restoredIndexName, numDocs) -> { + for (int i = 0; i < 10; i++) { + assertSearchResults(restoredIndexName, numDocs, randomFrom(Boolean.TRUE, Boolean.FALSE, null)); + } + }); + } + + public void testSearchResultsWhenFrozen() throws Exception { + runSearchableSnapshotsTest((restoredIndexName, numDocs) -> { + final Request freezeRequest = new Request(HttpPost.METHOD_NAME, restoredIndexName + "/_freeze"); + assertOK(client().performRequest(freezeRequest)); + ensureGreen(restoredIndexName); + for (int i = 0; i < 10; i++) { + assertSearchResults(restoredIndexName, numDocs, Boolean.FALSE); + } + }); + } + + public void testCloseAndReopen() throws Exception { + runSearchableSnapshotsTest((restoredIndexName, numDocs) -> { + final Request closeRequest = new Request(HttpPost.METHOD_NAME, restoredIndexName + "/_close"); + assertOK(client().performRequest(closeRequest)); + ensureGreen(restoredIndexName); + + final Request openRequest = new Request(HttpPost.METHOD_NAME, restoredIndexName + "/_open"); + assertOK(client().performRequest(openRequest)); + ensureGreen(restoredIndexName); + + for (int i = 0; i < 10; i++) { + assertSearchResults(restoredIndexName, numDocs, randomFrom(Boolean.TRUE, Boolean.FALSE, null)); + } + }); + } + + public void assertSearchResults(String indexName, int numDocs, Boolean ignoreThrottled) throws IOException { + final int randomTieBreaker = randomIntBetween(1, numDocs - 1); + Map searchResults; + switch (randomInt(3)) { + case 0: + searchResults + = search(indexName, QueryBuilders.termQuery("field", String.valueOf(randomTieBreaker)), ignoreThrottled); + assertThat(extractValue(searchResults, "hits.total.value"), equalTo(1)); + @SuppressWarnings("unchecked") + Map searchHit = (Map) ((List) extractValue(searchResults, "hits.hits")).get(0); + assertThat(extractValue(searchHit, "_index"), equalTo(indexName)); + assertThat(extractValue(searchHit, "_source.field"), equalTo(randomTieBreaker)); + break; + case 1: + searchResults = search(indexName, QueryBuilders.rangeQuery("field").lt(randomTieBreaker), ignoreThrottled); + assertThat(extractValue(searchResults, "hits.total.value"), equalTo(randomTieBreaker)); + break; + case 2: + searchResults = search(indexName, QueryBuilders.rangeQuery("field").gte(randomTieBreaker), ignoreThrottled); + assertThat(extractValue(searchResults, "hits.total.value"), equalTo(numDocs - randomTieBreaker)); + break; + case 3: + searchResults = search(indexName, QueryBuilders.matchQuery("text", "document"), ignoreThrottled); + assertThat(extractValue(searchResults, "hits.total.value"), equalTo(numDocs)); + break; + default: + fail("Unsupported randomized search query"); + } + } + protected static void registerRepository(String repository, String type, boolean verify, Settings settings) throws IOException { final Request request = new Request(HttpPut.METHOD_NAME, "_snapshot/" + repository); 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 { return (Number) extractValue(responseAsMap, "count"); } - protected static Map search(String index, QueryBuilder query) throws IOException { + protected static Map search(String index, QueryBuilder query, Boolean ignoreThrottled) throws IOException { final Request request = new Request(HttpPost.METHOD_NAME, '/' + index + "/_search"); request.setJsonEntity(new SearchSourceBuilder().trackTotalHits(true).query(query).toString()); + if (ignoreThrottled != null) { + request.addParameter("ignore_throttled", ignoreThrottled.toString()); + } final Response response = client().performRequest(request); assertThat("Failed to execute search request on index [" + index + "]: " + response, @@ -260,4 +301,12 @@ protected static Map responseAsMap(Response response) throws IOE protected static T extractValue(Map map, String path) { return (T) XContentMapValues.extractValue(path, map); } + + /** + * The body of a test case, which runs after the searchable snapshot has been created and restored. + */ + @FunctionalInterface + interface SearchableSnapshotsTestCaseBody { + void runTest(String indexName, int numDocs) throws IOException; + } }