From ff09c82319f902f71c77b6bbf464ab0763b2bd0a Mon Sep 17 00:00:00 2001 From: Luca Cavanna Date: Tue, 20 Mar 2018 10:39:36 +0100 Subject: [PATCH] REST high-level client: add clear cache API (#28866) * REST high-level client: add clear cache API Relates to #27205 Also Closes #26947 (rest-spec were outdated) --- .../elasticsearch/client/IndicesClient.java | 25 ++ .../org/elasticsearch/client/Request.java | 151 +++++++---- .../elasticsearch/client/IndicesClientIT.java | 33 ++- .../elasticsearch/client/RequestTests.java | 247 +++++++++++++++--- .../IndicesClientDocumentationIT.java | 87 ++++++ .../high-level/indices/clear_cache.asciidoc | 109 ++++++++ .../high-level/supported-apis.asciidoc | 2 + .../api/indices.clear_cache.json | 4 - .../clear/ClearIndicesCacheResponse.java | 31 ++- .../indices/RestClearIndicesCacheAction.java | 4 +- .../clear/ClearIndicesCacheResponseTests.java | 40 +++ 11 files changed, 618 insertions(+), 115 deletions(-) create mode 100644 docs/java-rest/high-level/indices/clear_cache.asciidoc create mode 100644 server/src/test/java/org/elasticsearch/action/admin/indices/cache/clear/ClearIndicesCacheResponseTests.java diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java index b39b7801e27..0b366aa99e1 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java @@ -24,6 +24,8 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesResponse; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; +import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheRequest; +import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheResponse; import org.elasticsearch.action.admin.indices.close.CloseIndexRequest; import org.elasticsearch.action.admin.indices.close.CloseIndexResponse; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; @@ -259,6 +261,29 @@ public final class IndicesClient { listener, emptySet(), headers); } + /** + * Clears the cache of one or more indices using the Clear Cache API + *

+ * See + * Clear Cache API on elastic.co + */ + public ClearIndicesCacheResponse clearCache(ClearIndicesCacheRequest clearIndicesCacheRequest, Header... headers) throws IOException { + return restHighLevelClient.performRequestAndParseEntity(clearIndicesCacheRequest, Request::clearCache, + ClearIndicesCacheResponse::fromXContent, emptySet(), headers); + } + + /** + * Asynchronously clears the cache of one or more indices using the Clear Cache API + *

+ * See + * Clear Cache API on elastic.co + */ + public void clearCacheAsync(ClearIndicesCacheRequest clearIndicesCacheRequest, ActionListener listener, + Header... headers) { + restHighLevelClient.performRequestAsyncAndParseEntity(clearIndicesCacheRequest, Request::clearCache, + ClearIndicesCacheResponse::fromXContent, listener, emptySet(), headers); + } + /** * Checks if the index (indices) exists or not. *

diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/Request.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/Request.java index 8a5c333dc46..66b34da777b 100755 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/Request.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/Request.java @@ -32,6 +32,7 @@ import org.elasticsearch.action.DocWriteRequest; import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; +import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheRequest; import org.elasticsearch.action.admin.indices.close.CloseIndexRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; @@ -170,13 +171,10 @@ public final class Request { static Request closeIndex(CloseIndexRequest closeIndexRequest) { String endpoint = endpoint(closeIndexRequest.indices(), "_close"); - Params parameters = Params.builder(); - parameters.withTimeout(closeIndexRequest.timeout()); parameters.withMasterTimeout(closeIndexRequest.masterNodeTimeout()); parameters.withIndicesOptions(closeIndexRequest.indicesOptions()); - return new Request(HttpPost.METHOD_NAME, endpoint, parameters.getParams(), null); } @@ -218,14 +216,16 @@ public final class Request { } static Request refresh(RefreshRequest refreshRequest) { - String endpoint = endpoint(refreshRequest.indices(), "_refresh"); + String[] indices = refreshRequest.indices() == null ? Strings.EMPTY_ARRAY : refreshRequest.indices(); + String endpoint = endpoint(indices, "_refresh"); Params parameters = Params.builder(); parameters.withIndicesOptions(refreshRequest.indicesOptions()); return new Request(HttpPost.METHOD_NAME, endpoint, parameters.getParams(), null); } static Request flush(FlushRequest flushRequest) { - String endpoint = endpoint(flushRequest.indices(), "_flush"); + String[] indices = flushRequest.indices() == null ? Strings.EMPTY_ARRAY : flushRequest.indices(); + String endpoint = endpoint(indices, "_flush"); Params parameters = Params.builder(); parameters.withIndicesOptions(flushRequest.indicesOptions()); parameters.putParam("wait_if_ongoing", Boolean.toString(flushRequest.waitIfOngoing())); @@ -233,6 +233,18 @@ public final class Request { return new Request(HttpPost.METHOD_NAME, endpoint, parameters.getParams(), null); } + static Request clearCache(ClearIndicesCacheRequest clearIndicesCacheRequest) { + String[] indices = clearIndicesCacheRequest.indices() == null ? Strings.EMPTY_ARRAY :clearIndicesCacheRequest.indices(); + String endpoint = endpoint(indices, "_cache/clear"); + Params parameters = Params.builder(); + parameters.withIndicesOptions(clearIndicesCacheRequest.indicesOptions()); + parameters.putParam("query", Boolean.toString(clearIndicesCacheRequest.queryCache())); + parameters.putParam("fielddata", Boolean.toString(clearIndicesCacheRequest.fieldDataCache())); + parameters.putParam("request", Boolean.toString(clearIndicesCacheRequest.requestCache())); + parameters.putParam("fields", String.join(",", clearIndicesCacheRequest.fields())); + return new Request(HttpPost.METHOD_NAME, endpoint, parameters.getParams(), null); + } + static Request info() { return new Request(HttpGet.METHOD_NAME, "/", Collections.emptyMap(), null); } @@ -508,10 +520,13 @@ public final class Request { Params params = Params.builder(); params.withIndicesOptions(getAliasesRequest.indicesOptions()); params.withLocal(getAliasesRequest.local()); - if (getAliasesRequest.indices().length == 0 && getAliasesRequest.aliases().length == 0) { + if ((getAliasesRequest.indices() == null || getAliasesRequest.indices().length == 0) && + (getAliasesRequest.aliases() == null || getAliasesRequest.aliases().length == 0)) { throw new IllegalArgumentException("existsAlias requires at least an alias or an index"); } - String endpoint = endpoint(getAliasesRequest.indices(), "_alias", getAliasesRequest.aliases()); + String[] indices = getAliasesRequest.indices() == null ? Strings.EMPTY_ARRAY : getAliasesRequest.indices(); + String[] aliases = getAliasesRequest.aliases() == null ? Strings.EMPTY_ARRAY : getAliasesRequest.aliases(); + String endpoint = endpoint(indices, "_alias", aliases); return new Request(HttpHead.METHOD_NAME, endpoint, params.getParams(), null); } @@ -540,8 +555,9 @@ public final class Request { params.withTimeout(resizeRequest.timeout()); params.withMasterTimeout(resizeRequest.masterNodeTimeout()); params.withWaitForActiveShards(resizeRequest.getTargetIndexRequest().waitForActiveShards()); - String endpoint = buildEndpoint(resizeRequest.getSourceIndex(), "_" + resizeRequest.getResizeType().name().toLowerCase(Locale.ROOT), - resizeRequest.getTargetIndexRequest().index()); + String endpoint = new EndpointBuilder().addPathPart(resizeRequest.getSourceIndex()) + .addPathPartAsIs("_" + resizeRequest.getResizeType().name().toLowerCase(Locale.ROOT)) + .addPathPart(resizeRequest.getTargetIndexRequest().index()).build(); HttpEntity entity = createEntity(resizeRequest, REQUEST_BODY_CONTENT_TYPE); return new Request(HttpPut.METHOD_NAME, endpoint, params.getParams(), entity); } @@ -551,10 +567,8 @@ public final class Request { parameters.withFlatSettings(clusterUpdateSettingsRequest.flatSettings()); parameters.withTimeout(clusterUpdateSettingsRequest.timeout()); parameters.withMasterTimeout(clusterUpdateSettingsRequest.masterNodeTimeout()); - - String endpoint = buildEndpoint("_cluster", "settings"); HttpEntity entity = createEntity(clusterUpdateSettingsRequest, REQUEST_BODY_CONTENT_TYPE); - return new Request(HttpPut.METHOD_NAME, endpoint, parameters.getParams(), entity); + return new Request(HttpPut.METHOD_NAME, "/_cluster/settings", parameters.getParams(), entity); } static Request rollover(RolloverRequest rolloverRequest) throws IOException { @@ -565,64 +579,60 @@ public final class Request { if (rolloverRequest.isDryRun()) { params.putParam("dry_run", Boolean.TRUE.toString()); } - String endpoint = buildEndpoint(rolloverRequest.getAlias(), "_rollover", rolloverRequest.getNewIndexName()); + String endpoint = new EndpointBuilder().addPathPart(rolloverRequest.getAlias()).addPathPartAsIs("_rollover") + .addPathPart(rolloverRequest.getNewIndexName()).build(); HttpEntity entity = createEntity(rolloverRequest, REQUEST_BODY_CONTENT_TYPE); return new Request(HttpPost.METHOD_NAME, endpoint, params.getParams(), entity); } + static Request indicesExist(GetIndexRequest request) { + //this can be called with no indices as argument by transport client, not via REST though + if (request.indices() == null || request.indices().length == 0) { + throw new IllegalArgumentException("indices are mandatory"); + } + String endpoint = endpoint(request.indices(), ""); + Params params = Params.builder(); + params.withLocal(request.local()); + params.withHuman(request.humanReadable()); + params.withIndicesOptions(request.indicesOptions()); + params.withFlatSettings(request.flatSettings()); + params.withIncludeDefaults(request.includeDefaults()); + return new Request(HttpHead.METHOD_NAME, endpoint, params.getParams(), null); + } + private static HttpEntity createEntity(ToXContent toXContent, XContentType xContentType) throws IOException { BytesRef source = XContentHelper.toXContent(toXContent, xContentType, false).toBytesRef(); return new ByteArrayEntity(source.bytes, source.offset, source.length, createContentType(xContentType)); } static String endpoint(String index, String type, String id) { - return buildEndpoint(index, type, id); + return new EndpointBuilder().addPathPart(index, type, id).build(); } static String endpoint(String index, String type, String id, String endpoint) { - return buildEndpoint(index, type, id, endpoint); + return new EndpointBuilder().addPathPart(index, type, id).addPathPartAsIs(endpoint).build(); } static String endpoint(String[] indices) { - return buildEndpoint(String.join(",", indices)); + return new EndpointBuilder().addCommaSeparatedPathParts(indices).build(); } static String endpoint(String[] indices, String endpoint) { - return buildEndpoint(String.join(",", indices), endpoint); + return new EndpointBuilder().addCommaSeparatedPathParts(indices).addPathPartAsIs(endpoint).build(); } static String endpoint(String[] indices, String[] types, String endpoint) { - return buildEndpoint(String.join(",", indices), String.join(",", types), endpoint); + return new EndpointBuilder().addCommaSeparatedPathParts(indices).addCommaSeparatedPathParts(types) + .addPathPartAsIs(endpoint).build(); } static String endpoint(String[] indices, String endpoint, String[] suffixes) { - return buildEndpoint(String.join(",", indices), endpoint, String.join(",", suffixes)); + return new EndpointBuilder().addCommaSeparatedPathParts(indices).addPathPartAsIs(endpoint) + .addCommaSeparatedPathParts(suffixes).build(); } static String endpoint(String[] indices, String endpoint, String type) { - return endpoint(String.join(",", indices), endpoint, type); - } - - /** - * Utility method to build request's endpoint given its parts as strings - */ - static String buildEndpoint(String... parts) { - StringJoiner joiner = new StringJoiner("/", "/", ""); - for (String part : parts) { - if (Strings.hasLength(part)) { - try { - //encode each part (e.g. index, type and id) separately before merging them into the path - //we prepend "/" to the path part to make this pate absolute, otherwise there can be issues with - //paths that start with `-` or contain `:` - URI uri = new URI(null, null, null, -1, "/" + part, null, null); - //manually encode any slash that each part may contain - joiner.add(uri.getRawPath().substring(1).replaceAll("/", "%2F")); - } catch (URISyntaxException e) { - throw new IllegalArgumentException("Path part [" + part + "] couldn't be encoded", e); - } - } - } - return joiner.toString(); + return new EndpointBuilder().addCommaSeparatedPathParts(indices).addPathPartAsIs(endpoint).addPathPart(type).build(); } /** @@ -636,17 +646,6 @@ public final class Request { return ContentType.create(xContentType.mediaTypeWithoutParameters(), (Charset) null); } - static Request indicesExist(GetIndexRequest request) { - String endpoint = endpoint(request.indices(), Strings.EMPTY_ARRAY, ""); - Params params = Params.builder(); - params.withLocal(request.local()); - params.withHuman(request.humanReadable()); - params.withIndicesOptions(request.indicesOptions()); - params.withFlatSettings(request.flatSettings()); - params.withIncludeDefaults(request.includeDefaults()); - return new Request(HttpHead.METHOD_NAME, endpoint, params.getParams(), null); - } - /** * Utility class to build request's parameters map and centralize all parameter names. */ @@ -852,4 +851,50 @@ public final class Request { } return xContentType; } + + /** + * Utility class to build request's endpoint given its parts as strings + */ + static class EndpointBuilder { + + private final StringJoiner joiner = new StringJoiner("/", "/", ""); + + EndpointBuilder addPathPart(String... parts) { + for (String part : parts) { + if (Strings.hasLength(part)) { + joiner.add(encodePart(part)); + } + } + return this; + } + + EndpointBuilder addCommaSeparatedPathParts(String[] parts) { + addPathPart(String.join(",", parts)); + return this; + } + + EndpointBuilder addPathPartAsIs(String part) { + if (Strings.hasLength(part)) { + joiner.add(part); + } + return this; + } + + String build() { + return joiner.toString(); + } + + private static String encodePart(String pathPart) { + try { + //encode each part (e.g. index, type and id) separately before merging them into the path + //we prepend "/" to the path part to make this pate absolute, otherwise there can be issues with + //paths that start with `-` or contain `:` + URI uri = new URI(null, null, null, -1, "/" + pathPart, null, null); + //manually encode any slash that each part may contain + return uri.getRawPath().substring(1).replaceAll("/", "%2F"); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("Path part [" + pathPart + "] couldn't be encoded", e); + } + } + } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java index 7f777531440..8a2ba447911 100755 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java @@ -28,6 +28,8 @@ import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesResponse; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; +import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheRequest; +import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheResponse; import org.elasticsearch.action.admin.indices.close.CloseIndexRequest; import org.elasticsearch.action.admin.indices.close.CloseIndexResponse; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; @@ -431,9 +433,36 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase { { String nonExistentIndex = "non_existent_index"; assertFalse(indexExists(nonExistentIndex)); - FlushRequest refreshRequest = new FlushRequest(nonExistentIndex); + FlushRequest flushRequest = new FlushRequest(nonExistentIndex); ElasticsearchException exception = expectThrows(ElasticsearchException.class, - () -> execute(refreshRequest, highLevelClient().indices()::flush, highLevelClient().indices()::flushAsync)); + () -> execute(flushRequest, highLevelClient().indices()::flush, highLevelClient().indices()::flushAsync)); + assertEquals(RestStatus.NOT_FOUND, exception.status()); + } + } + + public void testClearCache() throws IOException { + { + String index = "index"; + Settings settings = Settings.builder() + .put("number_of_shards", 1) + .put("number_of_replicas", 0) + .build(); + createIndex(index, settings); + ClearIndicesCacheRequest clearCacheRequest = new ClearIndicesCacheRequest(index); + ClearIndicesCacheResponse clearCacheResponse = + execute(clearCacheRequest, highLevelClient().indices()::clearCache, highLevelClient().indices()::clearCacheAsync); + assertThat(clearCacheResponse.getTotalShards(), equalTo(1)); + assertThat(clearCacheResponse.getSuccessfulShards(), equalTo(1)); + assertThat(clearCacheResponse.getFailedShards(), equalTo(0)); + assertThat(clearCacheResponse.getShardFailures(), equalTo(BroadcastResponse.EMPTY)); + } + { + String nonExistentIndex = "non_existent_index"; + assertFalse(indexExists(nonExistentIndex)); + ClearIndicesCacheRequest clearCacheRequest = new ClearIndicesCacheRequest(nonExistentIndex); + ElasticsearchException exception = expectThrows(ElasticsearchException.class, + () -> execute(clearCacheRequest, highLevelClient().indices()::clearCache, + highLevelClient().indices()::clearCacheAsync)); assertEquals(RestStatus.NOT_FOUND, exception.status()); } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestTests.java index beddadf859b..f79135c44f5 100755 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestTests.java @@ -29,11 +29,13 @@ import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.util.EntityUtils; +import org.elasticsearch.action.ActionRequestValidationException; import org.elasticsearch.action.DocWriteRequest; import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; +import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheRequest; import org.elasticsearch.action.admin.indices.close.CloseIndexRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; @@ -288,6 +290,11 @@ public class RequestTests extends ESTestCase { assertNull(request.getEntity()); } + public void testIndicesExistEmptyIndices() { + expectThrows(IllegalArgumentException.class, () -> Request.indicesExist(new GetIndexRequest())); + expectThrows(IllegalArgumentException.class, () -> Request.indicesExist(new GetIndexRequest().indices((String[])null))); + } + private static void getAndExistsTest(Function requestConverter, String method) { String index = randomAlphaOfLengthBetween(3, 10); String type = randomAlphaOfLengthBetween(3, 10); @@ -361,6 +368,11 @@ public class RequestTests extends ESTestCase { assertToXContentBody(createIndexRequest, request.getEntity()); } + public void testCreateIndexNullIndex() { + ActionRequestValidationException validationException = new CreateIndexRequest(null).validate(); + assertNotNull(validationException); + } + public void testUpdateAliases() throws IOException { IndicesAliasesRequest indicesAliasesRequest = new IndicesAliasesRequest(); AliasActions aliasAction = randomAliasAction(); @@ -422,6 +434,12 @@ public class RequestTests extends ESTestCase { assertNull(request.getEntity()); } + public void testDeleteIndexEmptyIndices() { + String[] indices = randomBoolean() ? null : Strings.EMPTY_ARRAY; + ActionRequestValidationException validationException = new DeleteIndexRequest(indices).validate(); + assertNotNull(validationException); + } + public void testOpenIndex() { String[] indices = randomIndicesNames(1, 5); OpenIndexRequest openIndexRequest = new OpenIndexRequest(indices); @@ -441,6 +459,12 @@ public class RequestTests extends ESTestCase { assertThat(request.getEntity(), nullValue()); } + public void testOpenIndexEmptyIndices() { + String[] indices = randomBoolean() ? null : Strings.EMPTY_ARRAY; + ActionRequestValidationException validationException = new OpenIndexRequest(indices).validate(); + assertNotNull(validationException); + } + public void testCloseIndex() { String[] indices = randomIndicesNames(1, 5); CloseIndexRequest closeIndexRequest = new CloseIndexRequest(indices); @@ -458,6 +482,12 @@ public class RequestTests extends ESTestCase { assertThat(request.getEntity(), nullValue()); } + public void testCloseIndexEmptyIndices() { + String[] indices = randomBoolean() ? null : Strings.EMPTY_ARRAY; + ActionRequestValidationException validationException = new CloseIndexRequest(indices).validate(); + assertNotNull(validationException); + } + public void testIndex() throws IOException { String index = randomAlphaOfLengthBetween(3, 10); String type = randomAlphaOfLengthBetween(3, 10); @@ -537,13 +567,19 @@ public class RequestTests extends ESTestCase { } public void testRefresh() { - String[] indices = randomIndicesNames(0, 5); - RefreshRequest refreshRequest = new RefreshRequest(indices); + String[] indices = randomBoolean() ? null : randomIndicesNames(0, 5); + RefreshRequest refreshRequest; + if (randomBoolean()) { + refreshRequest = new RefreshRequest(indices); + } else { + refreshRequest = new RefreshRequest(); + refreshRequest.indices(indices); + } Map expectedParams = new HashMap<>(); setRandomIndicesOptions(refreshRequest::indicesOptions, refreshRequest::indicesOptions, expectedParams); Request request = Request.refresh(refreshRequest); StringJoiner endpoint = new StringJoiner("/", "/", ""); - if (indices.length > 0) { + if (indices != null && indices.length > 0) { endpoint.add(String.join(",", indices)); } endpoint.add("_refresh"); @@ -554,8 +590,14 @@ public class RequestTests extends ESTestCase { } public void testFlush() { - String[] indices = randomIndicesNames(0, 5); - FlushRequest flushRequest = new FlushRequest(indices); + String[] indices = randomBoolean() ? null : randomIndicesNames(0, 5); + FlushRequest flushRequest; + if (randomBoolean()) { + flushRequest = new FlushRequest(indices); + } else { + flushRequest = new FlushRequest(); + flushRequest.indices(indices); + } Map expectedParams = new HashMap<>(); setRandomIndicesOptions(flushRequest::indicesOptions, flushRequest::indicesOptions, expectedParams); if (randomBoolean()) { @@ -569,7 +611,7 @@ public class RequestTests extends ESTestCase { Request request = Request.flush(flushRequest); StringJoiner endpoint = new StringJoiner("/", "/", ""); - if (indices.length > 0) { + if (indices != null && indices.length > 0) { endpoint.add(String.join(",", indices)); } endpoint.add("_flush"); @@ -579,6 +621,46 @@ public class RequestTests extends ESTestCase { assertThat(request.getMethod(), equalTo(HttpPost.METHOD_NAME)); } + public void testClearCache() { + String[] indices = randomBoolean() ? null : randomIndicesNames(0, 5); + ClearIndicesCacheRequest clearIndicesCacheRequest; + if (randomBoolean()) { + clearIndicesCacheRequest = new ClearIndicesCacheRequest(indices); + } else { + clearIndicesCacheRequest = new ClearIndicesCacheRequest(); + clearIndicesCacheRequest.indices(indices); + } + Map expectedParams = new HashMap<>(); + setRandomIndicesOptions(clearIndicesCacheRequest::indicesOptions, clearIndicesCacheRequest::indicesOptions, expectedParams); + if (randomBoolean()) { + clearIndicesCacheRequest.queryCache(randomBoolean()); + } + expectedParams.put("query", Boolean.toString(clearIndicesCacheRequest.queryCache())); + if (randomBoolean()) { + clearIndicesCacheRequest.fieldDataCache(randomBoolean()); + } + expectedParams.put("fielddata", Boolean.toString(clearIndicesCacheRequest.fieldDataCache())); + if (randomBoolean()) { + clearIndicesCacheRequest.requestCache(randomBoolean()); + } + expectedParams.put("request", Boolean.toString(clearIndicesCacheRequest.requestCache())); + if (randomBoolean()) { + clearIndicesCacheRequest.fields(randomIndicesNames(1, 5)); + expectedParams.put("fields", String.join(",", clearIndicesCacheRequest.fields())); + } + + Request request = Request.clearCache(clearIndicesCacheRequest); + StringJoiner endpoint = new StringJoiner("/", "/", ""); + if (indices != null && indices.length > 0) { + endpoint.add(String.join(",", indices)); + } + endpoint.add("_cache/clear"); + assertThat(request.getEndpoint(), equalTo(endpoint.toString())); + assertThat(request.getParameters(), equalTo(expectedParams)); + assertThat(request.getEntity(), nullValue()); + assertThat(request.getMethod(), equalTo(HttpPost.METHOD_NAME)); + } + public void testUpdate() throws IOException { XContentType xContentType = randomFrom(XContentType.values()); @@ -991,6 +1073,12 @@ public class RequestTests extends ESTestCase { assertToXContentBody(searchSourceBuilder, request.getEntity()); } + public void testSearchNullIndicesAndTypes() { + expectThrows(NullPointerException.class, () -> new SearchRequest((String[]) null)); + expectThrows(NullPointerException.class, () -> new SearchRequest().indices((String[]) null)); + expectThrows(NullPointerException.class, () -> new SearchRequest().types((String[]) null)); + } + public void testMultiSearch() throws IOException { int numberOfSearchRequests = randomIntBetween(0, 32); MultiSearchRequest multiSearchRequest = new MultiSearchRequest(); @@ -1071,10 +1159,16 @@ public class RequestTests extends ESTestCase { public void testExistsAlias() { GetAliasesRequest getAliasesRequest = new GetAliasesRequest(); - String[] indices = randomIndicesNames(0, 5); + String[] indices = randomBoolean() ? null : randomIndicesNames(0, 5); getAliasesRequest.indices(indices); //the HEAD endpoint requires at least an alias or an index - String[] aliases = randomIndicesNames(indices.length == 0 ? 1 : 0, 5); + boolean hasIndices = indices != null && indices.length > 0; + String[] aliases; + if (hasIndices) { + aliases = randomBoolean() ? null : randomIndicesNames(0, 5); + } else { + aliases = randomIndicesNames(1, 5); + } getAliasesRequest.aliases(aliases); Map expectedParams = new HashMap<>(); setRandomLocal(getAliasesRequest, expectedParams); @@ -1082,14 +1176,12 @@ public class RequestTests extends ESTestCase { Request request = Request.existsAlias(getAliasesRequest); StringJoiner expectedEndpoint = new StringJoiner("/", "/", ""); - String index = String.join(",", indices); - if (Strings.hasLength(index)) { - expectedEndpoint.add(index); + if (indices != null && indices.length > 0) { + expectedEndpoint.add(String.join(",", indices)); } expectedEndpoint.add("_alias"); - String alias = String.join(",", aliases); - if (Strings.hasLength(alias)) { - expectedEndpoint.add(alias); + if (aliases != null && aliases.length > 0) { + expectedEndpoint.add(String.join(",", aliases)); } assertEquals(HttpHead.METHOD_NAME, request.getMethod()); assertEquals(expectedEndpoint.toString(), request.getEndpoint()); @@ -1098,9 +1190,17 @@ public class RequestTests extends ESTestCase { } public void testExistsAliasNoAliasNoIndex() { - GetAliasesRequest getAliasesRequest = new GetAliasesRequest(); - IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> Request.existsAlias(getAliasesRequest)); - assertEquals("existsAlias requires at least an alias or an index", iae.getMessage()); + { + GetAliasesRequest getAliasesRequest = new GetAliasesRequest(); + IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> Request.existsAlias(getAliasesRequest)); + assertEquals("existsAlias requires at least an alias or an index", iae.getMessage()); + } + { + GetAliasesRequest getAliasesRequest = new GetAliasesRequest((String[])null); + getAliasesRequest.indices((String[])null); + IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> Request.existsAlias(getAliasesRequest)); + assertEquals("existsAlias requires at least an alias or an index", iae.getMessage()); + } } public void testRankEval() throws Exception { @@ -1259,30 +1359,99 @@ public class RequestTests extends ESTestCase { assertEquals("1", requestParams.values().iterator().next()); } - public void testBuildEndpoint() { - assertEquals("/", Request.buildEndpoint()); - assertEquals("/", Request.buildEndpoint(Strings.EMPTY_ARRAY)); - assertEquals("/", Request.buildEndpoint("")); - assertEquals("/a/b", Request.buildEndpoint("a", "b")); - assertEquals("/a/b/_create", Request.buildEndpoint("a", "b", "_create")); - assertEquals("/a/b/c/_create", Request.buildEndpoint("a", "b", "c", "_create")); - assertEquals("/a/_create", Request.buildEndpoint("a", null, null, "_create")); + public void testEndpointBuilder() { + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder(); + assertEquals("/", endpointBuilder.build()); + } + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder().addPathPart(Strings.EMPTY_ARRAY); + assertEquals("/", endpointBuilder.build()); + } + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder().addPathPart(""); + assertEquals("/", endpointBuilder.build()); + } + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder().addPathPart("a", "b"); + assertEquals("/a/b", endpointBuilder.build()); + } + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder().addPathPart("a").addPathPart("b") + .addPathPartAsIs("_create"); + assertEquals("/a/b/_create", endpointBuilder.build()); + } + + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder().addPathPart("a", "b", "c") + .addPathPartAsIs("_create"); + assertEquals("/a/b/c/_create", endpointBuilder.build()); + } + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder().addPathPart("a").addPathPartAsIs("_create"); + assertEquals("/a/_create", endpointBuilder.build()); + } } - public void testBuildEndPointEncodeParts() { - assertEquals("/-%23index1,index%232/type/id", Request.buildEndpoint("-#index1,index#2", "type", "id")); - assertEquals("/index/type%232/id", Request.buildEndpoint("index", "type#2", "id")); - assertEquals("/index/type/this%2Fis%2Fthe%2Fid", Request.buildEndpoint("index", "type", "this/is/the/id")); - assertEquals("/index/type/this%7Cis%7Cthe%7Cid", Request.buildEndpoint("index", "type", "this|is|the|id")); - assertEquals("/index/type/id%231", Request.buildEndpoint("index", "type", "id#1")); - assertEquals("/%3Clogstash-%7Bnow%2FM%7D%3E/_search", Request.buildEndpoint("", "_search")); - assertEquals("/中文", Request.buildEndpoint("中文")); - assertEquals("/foo%20bar", Request.buildEndpoint("foo bar")); - assertEquals("/foo+bar", Request.buildEndpoint("foo+bar")); - assertEquals("/foo%2Fbar", Request.buildEndpoint("foo/bar")); - assertEquals("/foo%5Ebar", Request.buildEndpoint("foo^bar")); - assertEquals("/cluster1:index1,index2/_search", Request.buildEndpoint("cluster1:index1,index2", "_search")); - assertEquals("/*", Request.buildEndpoint("*")); + public void testEndpointBuilderEncodeParts() { + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder().addPathPart("-#index1,index#2", "type", "id"); + assertEquals("/-%23index1,index%232/type/id", endpointBuilder.build()); + } + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder().addPathPart("index", "type#2", "id"); + assertEquals("/index/type%232/id", endpointBuilder.build()); + } + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder().addPathPart("index", "type", "this/is/the/id"); + assertEquals("/index/type/this%2Fis%2Fthe%2Fid", endpointBuilder.build()); + } + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder().addPathPart("index", "type", "this|is|the|id"); + assertEquals("/index/type/this%7Cis%7Cthe%7Cid", endpointBuilder.build()); + } + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder().addPathPart("index", "type", "id#1"); + assertEquals("/index/type/id%231", endpointBuilder.build()); + } + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder().addPathPart("", "_search"); + assertEquals("/%3Clogstash-%7Bnow%2FM%7D%3E/_search", endpointBuilder.build()); + } + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder().addPathPart("中文"); + assertEquals("/中文", endpointBuilder.build()); + } + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder().addPathPart("foo bar"); + assertEquals("/foo%20bar", endpointBuilder.build()); + } + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder().addPathPart("foo+bar"); + assertEquals("/foo+bar", endpointBuilder.build()); + } + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder().addPathPart("foo+bar"); + assertEquals("/foo+bar", endpointBuilder.build()); + } + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder().addPathPart("foo/bar"); + assertEquals("/foo%2Fbar", endpointBuilder.build()); + } + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder().addPathPart("foo^bar"); + assertEquals("/foo%5Ebar", endpointBuilder.build()); + } + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder().addPathPart("cluster1:index1,index2") + .addPathPartAsIs("_search"); + assertEquals("/cluster1:index1,index2/_search", endpointBuilder.build()); + } + { + Request.EndpointBuilder endpointBuilder = new Request.EndpointBuilder() + .addCommaSeparatedPathParts(new String[]{"index1", "index2"}).addPathPartAsIs("cache/clear"); + assertEquals("/index1,index2/cache/clear", endpointBuilder.build()); + } } public void testEndpoint() { diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java index 4bbc00fb411..fb9e56d2220 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java @@ -27,6 +27,8 @@ import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesResponse; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; +import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheRequest; +import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheResponse; import org.elasticsearch.action.admin.indices.close.CloseIndexRequest; import org.elasticsearch.action.admin.indices.close.CloseIndexResponse; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; @@ -769,6 +771,91 @@ public class IndicesClientDocumentationIT extends ESRestHighLevelClientTestCase } } + public void testClearCache() throws Exception { + RestHighLevelClient client = highLevelClient(); + + { + createIndex("index1", Settings.EMPTY); + } + + { + // tag::clear-cache-request + ClearIndicesCacheRequest request = new ClearIndicesCacheRequest("index1"); // <1> + ClearIndicesCacheRequest requestMultiple = new ClearIndicesCacheRequest("index1", "index2"); // <2> + ClearIndicesCacheRequest requestAll = new ClearIndicesCacheRequest(); // <3> + // end::clear-cache-request + + // tag::clear-cache-request-indicesOptions + request.indicesOptions(IndicesOptions.lenientExpandOpen()); // <1> + // end::clear-cache-request-indicesOptions + + // tag::clear-cache-request-query + request.queryCache(true); // <1> + // end::clear-cache-request-query + + // tag::clear-cache-request-request + request.requestCache(true); // <1> + // end::clear-cache-request-request + + // tag::clear-cache-request-fielddata + request.fieldDataCache(true); // <1> + // end::clear-cache-request-fielddata + + // tag::clear-cache-request-fields + request.fields("field1", "field2", "field3"); // <1> + // end::clear-cache-request-fields + + // tag::clear-cache-execute + ClearIndicesCacheResponse clearCacheResponse = client.indices().clearCache(request); + // end::clear-cache-execute + + // tag::clear-cache-response + int totalShards = clearCacheResponse.getTotalShards(); // <1> + int successfulShards = clearCacheResponse.getSuccessfulShards(); // <2> + int failedShards = clearCacheResponse.getFailedShards(); // <3> + DefaultShardOperationFailedException[] failures = clearCacheResponse.getShardFailures(); // <4> + // end::clear-cache-response + + // tag::clear-cache-execute-listener + ActionListener listener = new ActionListener() { + @Override + public void onResponse(ClearIndicesCacheResponse clearCacheResponse) { + // <1> + } + + @Override + public void onFailure(Exception e) { + // <2> + } + }; + // end::clear-cache-execute-listener + + // Replace the empty listener by a blocking listener in test + final CountDownLatch latch = new CountDownLatch(1); + listener = new LatchedActionListener<>(listener, latch); + + // tag::clear-cache-execute-async + client.indices().clearCacheAsync(request, listener); // <1> + // end::clear-cache-execute-async + + assertTrue(latch.await(30L, TimeUnit.SECONDS)); + } + + { + // tag::clear-cache-notfound + try { + ClearIndicesCacheRequest request = new ClearIndicesCacheRequest("does_not_exist"); + client.indices().clearCache(request); + } catch (ElasticsearchException exception) { + if (exception.status() == RestStatus.NOT_FOUND) { + // <1> + } + } + // end::clear-cache-notfound + } + } + + public void testCloseIndex() throws Exception { RestHighLevelClient client = highLevelClient(); diff --git a/docs/java-rest/high-level/indices/clear_cache.asciidoc b/docs/java-rest/high-level/indices/clear_cache.asciidoc new file mode 100644 index 00000000000..9e73283abd8 --- /dev/null +++ b/docs/java-rest/high-level/indices/clear_cache.asciidoc @@ -0,0 +1,109 @@ +[[java-rest-high-clear-cache]] +=== Clear Cache API + +[[java-rest-high-clear-cache-request]] +==== Clear Cache Request + +A `ClearIndicesCacheRquest` can be applied to one or more indices, or even on +`_all` the indices: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[clear-cache-request] +-------------------------------------------------- +<1> Clears the cache of one index +<2> Clears the cache of multiple indices +<3> Clears the cache of all the indices + +==== Optional arguments + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[clear-cache-request-indicesOptions] +-------------------------------------------------- +<1> Setting `IndicesOptions` controls how unavailable indices are resolved and +how wildcard expressions are expanded + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[clear-cache-request-query] +-------------------------------------------------- +<1> Set the `query` flag to `true` + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[clear-cache-request-fielddata] +-------------------------------------------------- +<1> Set the `fielddata` flag to `true` + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[clear-cache-request-request] +-------------------------------------------------- +<1> Set the `request` flag to `true` + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[clear-cache-request-fields] +-------------------------------------------------- +<1> Set the `fields` parameter + +[[java-rest-high-clear-cache-sync]] +==== Synchronous Execution + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[clear-cache-execute] +-------------------------------------------------- + +[[java-rest-high-clear-cache-async]] +==== Asynchronous Execution + +The asynchronous execution of a clear cache request requires both the `ClearIndicesCacheRequest` +instance and an `ActionListener` instance to be passed to the asynchronous +method: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[clear-cache-execute-async] +-------------------------------------------------- +<1> The `ClearIndicesCacheRequest` to execute and the `ActionListener` to use when +the execution completes + +The asynchronous method does not block and returns immediately. Once it is +completed the `ActionListener` is called back using the `onResponse` method +if the execution successfully completed or using the `onFailure` method if +it failed. + +A typical listener for `ClearIndicesCacheResponse` looks like: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[clear-cache-execute-listener] +-------------------------------------------------- +<1> Called when the execution is successfully completed. The response is +provided as an argument +<2> Called in case of failure. The raised exception is provided as an argument + +[[java-rest-high-clear-cache-response]] +==== Clear Cache Response + +The returned `ClearIndicesCacheResponse` allows to retrieve information about the +executed operation as follows: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[clear-cache-response] +-------------------------------------------------- +<1> Total number of shards hit by the clear cache request +<2> Number of shards where the clear cache has succeeded +<3> Number of shards where the clear cache has failed +<4> A list of failures if the operation failed on one or more shards + +By default, if the indices were not found, an `ElasticsearchException` will be thrown: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[clear-cache-notfound] +-------------------------------------------------- +<1> Do something if the indices to be cleared were not found \ No newline at end of file diff --git a/docs/java-rest/high-level/supported-apis.asciidoc b/docs/java-rest/high-level/supported-apis.asciidoc index 615634b65f1..bea30690fe1 100644 --- a/docs/java-rest/high-level/supported-apis.asciidoc +++ b/docs/java-rest/high-level/supported-apis.asciidoc @@ -59,6 +59,7 @@ Index Management:: * <> * <> * <> +* <> * <> Mapping Management:: @@ -77,6 +78,7 @@ include::indices/shrink_index.asciidoc[] include::indices/split_index.asciidoc[] include::indices/refresh.asciidoc[] include::indices/flush.asciidoc[] +include::indices/clear_cache.asciidoc[] include::indices/rollover.asciidoc[] include::indices/put_mapping.asciidoc[] include::indices/update_aliases.asciidoc[] diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.clear_cache.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.clear_cache.json index d89d90b25d5..9a0f7be1d65 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.clear_cache.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.clear_cache.json @@ -42,10 +42,6 @@ "type" : "list", "description" : "A comma-separated list of index name to limit the operation" }, - "recycler": { - "type" : "boolean", - "description" : "Clear the recycler cache" - }, "request": { "type" : "boolean", "description" : "Clear request cache" diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/cache/clear/ClearIndicesCacheResponse.java b/server/src/main/java/org/elasticsearch/action/admin/indices/cache/clear/ClearIndicesCacheResponse.java index d0f4b3cc20b..47b516137d7 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/cache/clear/ClearIndicesCacheResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/cache/clear/ClearIndicesCacheResponse.java @@ -21,19 +21,28 @@ package org.elasticsearch.action.admin.indices.cache.clear; import org.elasticsearch.action.support.DefaultShardOperationFailedException; import org.elasticsearch.action.support.broadcast.BroadcastResponse; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.xcontent.ConstructingObjectParser; +import org.elasticsearch.common.xcontent.XContentParser; -import java.io.IOException; +import java.util.Arrays; import java.util.List; /** - * The response of a refresh action. - * - * + * The response of a clear cache action. */ public class ClearIndicesCacheResponse extends BroadcastResponse { + private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>("clear_cache", + true, arg -> { + BroadcastResponse response = (BroadcastResponse) arg[0]; + return new ClearIndicesCacheResponse(response.getTotalShards(), response.getSuccessfulShards(), response.getFailedShards(), + Arrays.asList(response.getShardFailures())); + }); + + static { + declareBroadcastFields(PARSER); + } + ClearIndicesCacheResponse() { } @@ -43,13 +52,7 @@ public class ClearIndicesCacheResponse extends BroadcastResponse { super(totalShards, successfulShards, failedShards, shardFailures); } - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); + public static ClearIndicesCacheResponse fromXContent(XContentParser parser) { + return PARSER.apply(parser, null); } } \ No newline at end of file diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestClearIndicesCacheAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestClearIndicesCacheAction.java index f72ee8f2cb2..a63676c1e09 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestClearIndicesCacheAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestClearIndicesCacheAction.java @@ -38,7 +38,6 @@ import java.io.IOException; import static org.elasticsearch.rest.RestRequest.Method.GET; import static org.elasticsearch.rest.RestRequest.Method.POST; import static org.elasticsearch.rest.RestStatus.OK; -import static org.elasticsearch.rest.action.RestActions.buildBroadcastShardsHeader; public class RestClearIndicesCacheAction extends BaseRestHandler { @@ -67,7 +66,7 @@ public class RestClearIndicesCacheAction extends BaseRestHandler { @Override public RestResponse buildResponse(ClearIndicesCacheResponse response, XContentBuilder builder) throws Exception { builder.startObject(); - buildBroadcastShardsHeader(builder, request, response); + response.toXContent(builder, request); builder.endObject(); return new BytesRestResponse(OK, builder); } @@ -86,5 +85,4 @@ public class RestClearIndicesCacheAction extends BaseRestHandler { clearIndicesCacheRequest.fields(request.paramAsStringArray("fields", clearIndicesCacheRequest.fields())); return clearIndicesCacheRequest; } - } diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/cache/clear/ClearIndicesCacheResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/cache/clear/ClearIndicesCacheResponseTests.java new file mode 100644 index 00000000000..4b58d5fb702 --- /dev/null +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/cache/clear/ClearIndicesCacheResponseTests.java @@ -0,0 +1,40 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.action.admin.indices.cache.clear; + +import org.elasticsearch.action.support.DefaultShardOperationFailedException; +import org.elasticsearch.action.support.broadcast.AbstractBroadcastResponseTestCase; +import org.elasticsearch.common.xcontent.XContentParser; + +import java.util.List; + +public class ClearIndicesCacheResponseTests extends AbstractBroadcastResponseTestCase { + + @Override + protected ClearIndicesCacheResponse createTestInstance(int totalShards, int successfulShards, int failedShards, + List failures) { + return new ClearIndicesCacheResponse(totalShards, successfulShards, failedShards, failures); + } + + @Override + protected ClearIndicesCacheResponse doParseInstance(XContentParser parser) { + return ClearIndicesCacheResponse.fromXContent(parser); + } +}