From d98b3e476033da4e4559d8c32255a454e151b05a Mon Sep 17 00:00:00 2001 From: Yannick Welsch Date: Wed, 17 Jul 2019 16:53:10 +0200 Subject: [PATCH] Move frozen indices to x-pack module (#44490) Backport of #44408 and #44286. --- docs/reference/rest-api/info.asciidoc | 4 + .../protocol/xpack/frozen/FreezeRequest.java | 127 ++++++++++++++ .../protocol/xpack/frozen/FreezeResponse.java | 21 +++ .../elasticsearch/xpack/core/XPackClient.java | 6 +- .../xpack/core/XPackClientPlugin.java | 9 +- .../elasticsearch/xpack/core/XPackField.java | 2 + .../elasticsearch/xpack/core/XPackPlugin.java | 20 +-- .../frozen/FrozenIndicesFeatureSetUsage.java | 65 ++++++++ .../core/frozen/action/FreezeIndexAction.java | 25 +++ .../xpack/core/indexlifecycle/FreezeStep.java | 7 +- .../FrozenIndicesFeatureSetUsageTests.java | 48 ++++++ .../core/indexlifecycle/FreezeStepTests.java | 7 +- x-pack/plugin/frozen-indices/build.gradle | 23 +++ .../index/engine/FrozenEngine.java | 0 .../engine/RewriteCachingDirectoryReader.java | 0 .../xpack/frozen/FrozenIndices.java | 97 +++++++++++ .../xpack/frozen/FrozenIndicesFeatureSet.java | 58 +++++++ .../action/TransportFreezeIndexAction.java | 156 +----------------- .../rest/action/RestFreezeIndexAction.java | 7 +- .../index/engine/FrozenEngineTests.java | 0 .../engine/FrozenIndexRecoveryTests.java | 0 .../index/engine/FrozenIndexTests.java | 55 +++--- .../RewriteCachingDirectoryReaderTests.java | 0 .../TimeSeriesLifecycleActionsIT.java | 5 +- .../test/indices.freeze/20_stats.yml | 2 +- .../test/indices.freeze/30_usage.yml | 60 +++++++ 26 files changed, 588 insertions(+), 216 deletions(-) create mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/protocol/xpack/frozen/FreezeRequest.java create mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/protocol/xpack/frozen/FreezeResponse.java create mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/frozen/FrozenIndicesFeatureSetUsage.java create mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/frozen/action/FreezeIndexAction.java create mode 100644 x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/frozen/FrozenIndicesFeatureSetUsageTests.java create mode 100644 x-pack/plugin/frozen-indices/build.gradle rename x-pack/plugin/{core => frozen-indices}/src/main/java/org/elasticsearch/index/engine/FrozenEngine.java (100%) rename x-pack/plugin/{core => frozen-indices}/src/main/java/org/elasticsearch/index/engine/RewriteCachingDirectoryReader.java (100%) create mode 100644 x-pack/plugin/frozen-indices/src/main/java/org/elasticsearch/xpack/frozen/FrozenIndices.java create mode 100644 x-pack/plugin/frozen-indices/src/main/java/org/elasticsearch/xpack/frozen/FrozenIndicesFeatureSet.java rename x-pack/plugin/{core/src/main/java/org/elasticsearch/xpack/core => frozen-indices/src/main/java/org/elasticsearch/xpack/frozen}/action/TransportFreezeIndexAction.java (63%) rename x-pack/plugin/{core/src/main/java/org/elasticsearch/xpack/core => frozen-indices/src/main/java/org/elasticsearch/xpack/frozen}/rest/action/RestFreezeIndexAction.java (86%) rename x-pack/plugin/{core => frozen-indices}/src/test/java/org/elasticsearch/index/engine/FrozenEngineTests.java (100%) rename x-pack/plugin/{core => frozen-indices}/src/test/java/org/elasticsearch/index/engine/FrozenIndexRecoveryTests.java (100%) rename x-pack/plugin/{core => frozen-indices}/src/test/java/org/elasticsearch/index/engine/FrozenIndexTests.java (90%) rename x-pack/plugin/{core => frozen-indices}/src/test/java/org/elasticsearch/index/engine/RewriteCachingDirectoryReaderTests.java (100%) create mode 100644 x-pack/plugin/src/test/resources/rest-api-spec/test/indices.freeze/30_usage.yml diff --git a/docs/reference/rest-api/info.asciidoc b/docs/reference/rest-api/info.asciidoc index f6a4c3d4454..de85128f342 100644 --- a/docs/reference/rest-api/info.asciidoc +++ b/docs/reference/rest-api/info.asciidoc @@ -75,6 +75,10 @@ Example response: "available" : true, "enabled" : true }, + "frozen_indices" : { + "available" : true, + "enabled" : true + }, "graph" : { "available" : true, "enabled" : true diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/protocol/xpack/frozen/FreezeRequest.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/protocol/xpack/frozen/FreezeRequest.java new file mode 100644 index 00000000000..f4ce44e6b97 --- /dev/null +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/protocol/xpack/frozen/FreezeRequest.java @@ -0,0 +1,127 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.protocol.xpack.frozen; + +import org.elasticsearch.action.ActionRequestValidationException; +import org.elasticsearch.action.IndicesRequest; +import org.elasticsearch.action.admin.indices.open.OpenIndexResponse; +import org.elasticsearch.action.support.ActiveShardCount; +import org.elasticsearch.action.support.IndicesOptions; +import org.elasticsearch.action.support.master.AcknowledgedRequest; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.util.CollectionUtils; + +import java.io.IOException; + +import static org.elasticsearch.action.ValidateActions.addValidationError; + +public class FreezeRequest extends AcknowledgedRequest + implements IndicesRequest.Replaceable { + private String[] indices; + private boolean freeze = true; + private IndicesOptions indicesOptions = IndicesOptions.strictExpandOpen(); + private ActiveShardCount waitForActiveShards = ActiveShardCount.DEFAULT; + + public FreezeRequest(String... indices) { + this.indices = indices; + } + + public FreezeRequest(StreamInput in) throws IOException { + super(in); + indicesOptions = IndicesOptions.readIndicesOptions(in); + indices = in.readStringArray(); + freeze = in.readBoolean(); + waitForActiveShards = ActiveShardCount.readFrom(in); + } + + @Override + public ActionRequestValidationException validate() { + ActionRequestValidationException validationException = null; + if (CollectionUtils.isEmpty(indices)) { + validationException = addValidationError("index is missing", validationException); + } + return validationException; + } + + public FreezeRequest setFreeze(boolean freeze) { + this.freeze = freeze; + return this; + } + + public boolean freeze() { + return freeze; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + indicesOptions.writeIndicesOptions(out); + out.writeStringArray(indices); + out.writeBoolean(freeze); + waitForActiveShards.writeTo(out); + } + + /** + * @return the indices to be frozen or unfrozen + */ + @Override + public String[] indices() { + return indices; + } + + /** + * Specifies what type of requested indices to ignore and how to deal with wildcard expressions. + * For example indices that don't exist. + * + * @return the current behaviour when it comes to index names and wildcard indices expressions + */ + @Override + public IndicesOptions indicesOptions() { + return indicesOptions; + } + + /** + * Specifies what type of requested indices to ignore and how to deal with wildcard expressions. + * For example indices that don't exist. + * + * @param indicesOptions the desired behaviour regarding indices to ignore and wildcard indices expressions + * @return the request itself + */ + public FreezeRequest indicesOptions(IndicesOptions indicesOptions) { + this.indicesOptions = indicesOptions; + return this; + } + + @Override + public IndicesRequest indices(String... indices) { + this.indices = indices; + return this; + } + + public ActiveShardCount waitForActiveShards() { + return waitForActiveShards; + } + + /** + * Sets the number of shard copies that should be active for indices opening to return. + * Defaults to {@link ActiveShardCount#DEFAULT}, which will wait for one shard copy + * (the primary) to become active. Set this value to {@link ActiveShardCount#ALL} to + * wait for all shards (primary and all replicas) to be active before returning. + * Otherwise, use {@link ActiveShardCount#from(int)} to set this value to any + * non-negative integer, up to the number of copies per shard (number of replicas + 1), + * to wait for the desired amount of shard copies to become active before returning. + * Indices opening will only wait up until the timeout value for the number of shard copies + * to be active before returning. Check {@link OpenIndexResponse#isShardsAcknowledged()} to + * determine if the requisite shard copies were all started before returning or timing out. + * + * @param waitForActiveShards number of active shard copies to wait on + */ + public FreezeRequest waitForActiveShards(ActiveShardCount waitForActiveShards) { + this.waitForActiveShards = waitForActiveShards; + return this; + } +} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/protocol/xpack/frozen/FreezeResponse.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/protocol/xpack/frozen/FreezeResponse.java new file mode 100644 index 00000000000..bb2f2a14196 --- /dev/null +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/protocol/xpack/frozen/FreezeResponse.java @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.protocol.xpack.frozen; + +import org.elasticsearch.action.admin.indices.open.OpenIndexResponse; +import org.elasticsearch.common.io.stream.StreamInput; + +import java.io.IOException; + +public class FreezeResponse extends OpenIndexResponse { + public FreezeResponse(StreamInput in) throws IOException { + super(in); + } + + public FreezeResponse(boolean acknowledged, boolean shardsAcknowledged) { + super(acknowledged, shardsAcknowledged); + } +} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClient.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClient.java index e6cd2ed176c..656a3b392c0 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClient.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClient.java @@ -12,12 +12,12 @@ import org.elasticsearch.common.settings.SecureString; import org.elasticsearch.license.LicensingClient; import org.elasticsearch.protocol.xpack.XPackInfoRequest; import org.elasticsearch.protocol.xpack.XPackInfoResponse; -import org.elasticsearch.xpack.core.action.TransportFreezeIndexAction.FreezeIndexAction; -import org.elasticsearch.xpack.core.action.TransportFreezeIndexAction.FreezeRequest; -import org.elasticsearch.xpack.core.action.TransportFreezeIndexAction.FreezeResponse; +import org.elasticsearch.protocol.xpack.frozen.FreezeRequest; +import org.elasticsearch.protocol.xpack.frozen.FreezeResponse; import org.elasticsearch.xpack.core.action.XPackInfoAction; import org.elasticsearch.xpack.core.action.XPackInfoRequestBuilder; import org.elasticsearch.xpack.core.ccr.client.CcrClient; +import org.elasticsearch.xpack.core.frozen.action.FreezeIndexAction; import org.elasticsearch.xpack.core.indexlifecycle.client.ILMClient; import org.elasticsearch.xpack.core.ml.client.MachineLearningClient; import org.elasticsearch.xpack.core.monitoring.client.MonitoringClient; diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClientPlugin.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClientPlugin.java index 75d3228c209..27cae23cd89 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClientPlugin.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClientPlugin.java @@ -36,7 +36,6 @@ import org.elasticsearch.plugins.Plugin; import org.elasticsearch.tasks.Task; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.Transport; -import org.elasticsearch.xpack.core.action.TransportFreezeIndexAction; import org.elasticsearch.xpack.core.action.XPackInfoAction; import org.elasticsearch.xpack.core.action.XPackUsageAction; import org.elasticsearch.xpack.core.beats.BeatsFeatureSetUsage; @@ -58,6 +57,8 @@ import org.elasticsearch.xpack.core.dataframe.transforms.SyncConfig; import org.elasticsearch.xpack.core.dataframe.transforms.TimeSyncConfig; import org.elasticsearch.xpack.core.deprecation.DeprecationInfoAction; import org.elasticsearch.xpack.core.flattened.FlattenedFeatureSetUsage; +import org.elasticsearch.xpack.core.frozen.FrozenIndicesFeatureSetUsage; +import org.elasticsearch.xpack.core.frozen.action.FreezeIndexAction; import org.elasticsearch.xpack.core.graph.GraphFeatureSetUsage; import org.elasticsearch.xpack.core.graph.action.GraphExploreAction; import org.elasticsearch.xpack.core.indexlifecycle.AllocateAction; @@ -412,7 +413,7 @@ public class XPackClientPlugin extends Plugin implements ActionPlugin, NetworkPl DeleteSnapshotLifecycleAction.INSTANCE, ExecuteSnapshotLifecycleAction.INSTANCE, // Freeze - TransportFreezeIndexAction.FreezeIndexAction.INSTANCE, + FreezeIndexAction.INSTANCE, // Data Frame PutDataFrameTransformAction.INSTANCE, StartDataFrameTransformAction.INSTANCE, @@ -534,7 +535,9 @@ public class XPackClientPlugin extends Plugin implements ActionPlugin, NetworkPl // Vectors new NamedWriteableRegistry.Entry(XPackFeatureSet.Usage.class, XPackField.VECTORS, VectorsFeatureSetUsage::new), // Voting Only Node - new NamedWriteableRegistry.Entry(XPackFeatureSet.Usage.class, XPackField.VOTING_ONLY, VotingOnlyNodeFeatureSetUsage::new) + new NamedWriteableRegistry.Entry(XPackFeatureSet.Usage.class, XPackField.VOTING_ONLY, VotingOnlyNodeFeatureSetUsage::new), + // Frozen indices + new NamedWriteableRegistry.Entry(XPackFeatureSet.Usage.class, XPackField.FROZEN_INDICES, FrozenIndicesFeatureSetUsage::new) ); } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackField.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackField.java index 351606e3218..b3f6f2fbd36 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackField.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackField.java @@ -43,6 +43,8 @@ public final class XPackField { public static final String VECTORS = "vectors"; /** Name constant for the voting-only-node feature. */ public static final String VOTING_ONLY = "voting_only"; + /** Name constant for the frozen index feature. */ + public static final String FROZEN_INDICES = "frozen_indices"; private XPackField() {} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackPlugin.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackPlugin.java index 525ddc949cd..3898ee999cb 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackPlugin.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackPlugin.java @@ -10,9 +10,9 @@ import org.apache.logging.log4j.Logger; import org.apache.lucene.util.SetOnce; import org.elasticsearch.SpecialPermission; import org.elasticsearch.Version; -import org.elasticsearch.action.ActionType; import org.elasticsearch.action.ActionRequest; import org.elasticsearch.action.ActionResponse; +import org.elasticsearch.action.ActionType; import org.elasticsearch.action.support.ActionFilter; import org.elasticsearch.client.Client; import org.elasticsearch.client.transport.TransportClient; @@ -37,10 +37,8 @@ import org.elasticsearch.common.settings.SettingsFilter; import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.env.Environment; import org.elasticsearch.env.NodeEnvironment; -import org.elasticsearch.index.IndexModule; import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.engine.EngineFactory; -import org.elasticsearch.index.engine.FrozenEngine; import org.elasticsearch.license.LicenseService; import org.elasticsearch.license.LicensesMetaData; import org.elasticsearch.license.Licensing; @@ -57,14 +55,12 @@ import org.elasticsearch.snapshots.SourceOnlySnapshotRepository; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.xpack.core.action.ReloadAnalyzerAction; -import org.elasticsearch.xpack.core.action.TransportFreezeIndexAction; import org.elasticsearch.xpack.core.action.TransportReloadAnalyzersAction; import org.elasticsearch.xpack.core.action.TransportXPackInfoAction; import org.elasticsearch.xpack.core.action.TransportXPackUsageAction; import org.elasticsearch.xpack.core.action.XPackInfoAction; import org.elasticsearch.xpack.core.action.XPackUsageAction; import org.elasticsearch.xpack.core.ml.MlMetadata; -import org.elasticsearch.xpack.core.rest.action.RestFreezeIndexAction; import org.elasticsearch.xpack.core.rest.action.RestReloadAnalyzersAction; import org.elasticsearch.xpack.core.rest.action.RestXPackInfoAction; import org.elasticsearch.xpack.core.rest.action.RestXPackUsageAction; @@ -272,8 +268,6 @@ public class XPackPlugin extends XPackClientPlugin implements ExtensiblePlugin, List> actions = new ArrayList<>(); actions.add(new ActionHandler<>(XPackInfoAction.INSTANCE, TransportXPackInfoAction.class)); actions.add(new ActionHandler<>(XPackUsageAction.INSTANCE, TransportXPackUsageAction.class)); - actions.add(new ActionHandler<>(TransportFreezeIndexAction.FreezeIndexAction.INSTANCE, - TransportFreezeIndexAction.class)); actions.addAll(licensing.getActions()); actions.add(new ActionHandler<>(ReloadAnalyzerAction.INSTANCE, TransportReloadAnalyzersAction.class)); return actions; @@ -301,7 +295,6 @@ public class XPackPlugin extends XPackClientPlugin implements ExtensiblePlugin, List handlers = new ArrayList<>(); handlers.add(new RestXPackInfoAction(settings, restController)); handlers.add(new RestXPackUsageAction(settings, restController)); - handlers.add(new RestFreezeIndexAction(settings, restController)); handlers.add(new RestReloadAnalyzersAction(settings, restController)); handlers.addAll(licensing.getRestHandlers(settings, restController, clusterSettings, indexScopedSettings, settingsFilter, indexNameExpressionResolver, nodesInCluster)); @@ -371,8 +364,6 @@ public class XPackPlugin extends XPackClientPlugin implements ExtensiblePlugin, public Optional getEngineFactory(IndexSettings indexSettings) { if (indexSettings.getValue(SourceOnlySnapshotRepository.SOURCE_ONLY)) { return Optional.of(SourceOnlySnapshotRepository.getEngineFactory()); - } else if (indexSettings.getValue(FrozenEngine.INDEX_FROZEN)) { - return Optional.of(FrozenEngine::new); } return Optional.empty(); @@ -382,15 +373,6 @@ public class XPackPlugin extends XPackClientPlugin implements ExtensiblePlugin, public List> getSettings() { List> settings = super.getSettings(); settings.add(SourceOnlySnapshotRepository.SOURCE_ONLY); - settings.add(FrozenEngine.INDEX_FROZEN); return settings; } - - @Override - public void onIndexModule(IndexModule indexModule) { - if (FrozenEngine.INDEX_FROZEN.get(indexModule.getSettings())) { - indexModule.addSearchOperationListener(new FrozenEngine.ReacquireEngineSearcherListener()); - } - super.onIndexModule(indexModule); - } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/frozen/FrozenIndicesFeatureSetUsage.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/frozen/FrozenIndicesFeatureSetUsage.java new file mode 100644 index 00000000000..cc556330497 --- /dev/null +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/frozen/FrozenIndicesFeatureSetUsage.java @@ -0,0 +1,65 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.core.frozen; + +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.xpack.core.XPackFeatureSet; +import org.elasticsearch.xpack.core.XPackField; + +import java.io.IOException; +import java.util.Objects; + +public class FrozenIndicesFeatureSetUsage extends XPackFeatureSet.Usage { + + private final int numberOfFrozenIndices; + + public FrozenIndicesFeatureSetUsage(StreamInput input) throws IOException { + super(input); + numberOfFrozenIndices = input.readVInt(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + out.writeVInt(numberOfFrozenIndices); + } + + public FrozenIndicesFeatureSetUsage(boolean available, boolean enabled, int numberOfFrozenIndices) { + super(XPackField.FROZEN_INDICES, available, enabled); + this.numberOfFrozenIndices = numberOfFrozenIndices; + } + + @Override + protected void innerXContent(XContentBuilder builder, Params params) throws IOException { + super.innerXContent(builder, params); + builder.field("indices_count", numberOfFrozenIndices); + } + + public int getNumberOfFrozenIndices() { + return numberOfFrozenIndices; + } + + @Override + public int hashCode() { + return Objects.hash(available, enabled, numberOfFrozenIndices); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + FrozenIndicesFeatureSetUsage other = (FrozenIndicesFeatureSetUsage) obj; + return Objects.equals(available, other.available) && + Objects.equals(enabled, other.enabled) && + Objects.equals(numberOfFrozenIndices, other.numberOfFrozenIndices); + } +} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/frozen/action/FreezeIndexAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/frozen/action/FreezeIndexAction.java new file mode 100644 index 00000000000..9635db931ea --- /dev/null +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/frozen/action/FreezeIndexAction.java @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.core.frozen.action; + +import org.elasticsearch.action.ActionType; +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.protocol.xpack.frozen.FreezeResponse; + +public class FreezeIndexAction extends ActionType { + + public static final FreezeIndexAction INSTANCE = new FreezeIndexAction(); + public static final String NAME = "indices:admin/freeze"; + + private FreezeIndexAction() { + super(NAME); + } + + @Override + public Writeable.Reader getResponseReader() { + return FreezeResponse::new; + } +} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/FreezeStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/FreezeStep.java index ae7b0af6222..f5e44a863cb 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/FreezeStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/FreezeStep.java @@ -9,7 +9,8 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.IndexMetaData; -import org.elasticsearch.xpack.core.action.TransportFreezeIndexAction; +import org.elasticsearch.protocol.xpack.frozen.FreezeRequest; +import org.elasticsearch.xpack.core.frozen.action.FreezeIndexAction; /** * Freezes an index. @@ -23,8 +24,8 @@ public class FreezeStep extends AsyncRetryDuringSnapshotActionStep { @Override public void performDuringNoSnapshot(IndexMetaData indexMetaData, ClusterState currentState, Listener listener) { - getClient().admin().indices().execute(TransportFreezeIndexAction.FreezeIndexAction.INSTANCE, - new TransportFreezeIndexAction.FreezeRequest(indexMetaData.getIndex().getName()), + getClient().admin().indices().execute(FreezeIndexAction.INSTANCE, + new FreezeRequest(indexMetaData.getIndex().getName()), ActionListener.wrap(response -> listener.onResponse(true), listener::onFailure)); } } diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/frozen/FrozenIndicesFeatureSetUsageTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/frozen/FrozenIndicesFeatureSetUsageTests.java new file mode 100644 index 00000000000..34f7757fa2f --- /dev/null +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/frozen/FrozenIndicesFeatureSetUsageTests.java @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.core.frozen; + +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.test.AbstractWireSerializingTestCase; + +import java.io.IOException; + +public class FrozenIndicesFeatureSetUsageTests extends AbstractWireSerializingTestCase { + + @Override + protected FrozenIndicesFeatureSetUsage createTestInstance() { + boolean available = randomBoolean(); + boolean enabled = randomBoolean(); + return new FrozenIndicesFeatureSetUsage(available, enabled, randomIntBetween(0, 100000)); + } + + @Override + protected FrozenIndicesFeatureSetUsage mutateInstance(FrozenIndicesFeatureSetUsage instance) throws IOException { + boolean available = instance.available(); + boolean enabled = instance.enabled(); + int numFrozenIndices = instance.getNumberOfFrozenIndices(); + switch (between(0, 2)) { + case 0: + available = available == false; + break; + case 1: + enabled = enabled == false; + break; + case 2: + numFrozenIndices = randomValueOtherThan(numFrozenIndices, () -> randomIntBetween(0, 100000)); + break; + default: + throw new AssertionError("Illegal randomisation branch"); + } + return new FrozenIndicesFeatureSetUsage(available, enabled, numFrozenIndices); + } + + @Override + protected Writeable.Reader instanceReader() { + return FrozenIndicesFeatureSetUsage::new; + } + +} diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/FreezeStepTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/FreezeStepTests.java index 0198ed7abee..5f71604d24e 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/FreezeStepTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/FreezeStepTests.java @@ -14,7 +14,8 @@ import org.elasticsearch.client.AdminClient; import org.elasticsearch.client.Client; import org.elasticsearch.client.IndicesAdminClient; import org.elasticsearch.cluster.metadata.IndexMetaData; -import org.elasticsearch.xpack.core.action.TransportFreezeIndexAction; +import org.elasticsearch.protocol.xpack.frozen.FreezeRequest; +import org.elasticsearch.xpack.core.frozen.action.FreezeIndexAction; import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey; import org.junit.Before; import org.mockito.Mockito; @@ -78,8 +79,8 @@ public class FreezeStepTests extends AbstractStepTestCase { Mockito.when(client.admin()).thenReturn(adminClient); Mockito.when(adminClient.indices()).thenReturn(indicesClient); Mockito.doAnswer(invocation -> { - assertSame(invocation.getArguments()[0], TransportFreezeIndexAction.FreezeIndexAction.INSTANCE); - TransportFreezeIndexAction.FreezeRequest request = (TransportFreezeIndexAction.FreezeRequest) invocation.getArguments()[1]; + assertSame(invocation.getArguments()[0], FreezeIndexAction.INSTANCE); + FreezeRequest request = (FreezeRequest) invocation.getArguments()[1]; @SuppressWarnings("unchecked") ActionListener listener = (ActionListener) invocation.getArguments()[2]; assertNotNull(request); diff --git a/x-pack/plugin/frozen-indices/build.gradle b/x-pack/plugin/frozen-indices/build.gradle new file mode 100644 index 00000000000..dd69f6bd168 --- /dev/null +++ b/x-pack/plugin/frozen-indices/build.gradle @@ -0,0 +1,23 @@ +evaluationDependsOn(xpackModule('core')) + +apply plugin: 'elasticsearch.esplugin' +esplugin { + name 'frozen-indices' + description 'A plugin for the frozen indices functionality' + classname 'org.elasticsearch.xpack.frozen.FrozenIndices' + extendedPlugins = ['x-pack-core'] +} +archivesBaseName = 'x-pack-frozen-indices' + +dependencies { + compileOnly project(path: xpackModule('core'), configuration: 'default') + testCompile project(path: xpackModule('core'), configuration: 'testArtifacts') + if (isEclipse) { + testCompile project(path: xpackModule('core-tests'), configuration: 'testArtifacts') + } +} + +// xpack modules are installed in real clusters as the meta plugin, so +// installing them as individual plugins for integ tests doesn't make sense, +// so we disable integ tests +integTest.enabled = false diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/index/engine/FrozenEngine.java b/x-pack/plugin/frozen-indices/src/main/java/org/elasticsearch/index/engine/FrozenEngine.java similarity index 100% rename from x-pack/plugin/core/src/main/java/org/elasticsearch/index/engine/FrozenEngine.java rename to x-pack/plugin/frozen-indices/src/main/java/org/elasticsearch/index/engine/FrozenEngine.java diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/index/engine/RewriteCachingDirectoryReader.java b/x-pack/plugin/frozen-indices/src/main/java/org/elasticsearch/index/engine/RewriteCachingDirectoryReader.java similarity index 100% rename from x-pack/plugin/core/src/main/java/org/elasticsearch/index/engine/RewriteCachingDirectoryReader.java rename to x-pack/plugin/frozen-indices/src/main/java/org/elasticsearch/index/engine/RewriteCachingDirectoryReader.java diff --git a/x-pack/plugin/frozen-indices/src/main/java/org/elasticsearch/xpack/frozen/FrozenIndices.java b/x-pack/plugin/frozen-indices/src/main/java/org/elasticsearch/xpack/frozen/FrozenIndices.java new file mode 100644 index 00000000000..95198c89939 --- /dev/null +++ b/x-pack/plugin/frozen-indices/src/main/java/org/elasticsearch/xpack/frozen/FrozenIndices.java @@ -0,0 +1,97 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.frozen; + +import org.elasticsearch.action.ActionRequest; +import org.elasticsearch.action.ActionResponse; +import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; +import org.elasticsearch.cluster.node.DiscoveryNodes; +import org.elasticsearch.common.inject.Module; +import org.elasticsearch.common.settings.ClusterSettings; +import org.elasticsearch.common.settings.IndexScopedSettings; +import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.settings.SettingsFilter; +import org.elasticsearch.index.IndexModule; +import org.elasticsearch.index.IndexSettings; +import org.elasticsearch.index.engine.EngineFactory; +import org.elasticsearch.index.engine.FrozenEngine; +import org.elasticsearch.plugins.ActionPlugin; +import org.elasticsearch.plugins.EnginePlugin; +import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.rest.RestController; +import org.elasticsearch.rest.RestHandler; +import org.elasticsearch.xpack.core.XPackPlugin; +import org.elasticsearch.xpack.core.frozen.action.FreezeIndexAction; +import org.elasticsearch.xpack.frozen.action.TransportFreezeIndexAction; +import org.elasticsearch.xpack.frozen.rest.action.RestFreezeIndexAction; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.function.Supplier; + +public class FrozenIndices extends Plugin implements ActionPlugin, EnginePlugin { + + private boolean transportClientMode; + + public FrozenIndices(Settings settings) { + this.transportClientMode = XPackPlugin.transportClientMode(settings); + } + + @Override + public Optional getEngineFactory(IndexSettings indexSettings) { + if (indexSettings.getValue(FrozenEngine.INDEX_FROZEN)) { + return Optional.of(FrozenEngine::new); + } else { + return Optional.empty(); + } + } + + @Override + public List> getSettings() { + return Arrays.asList(FrozenEngine.INDEX_FROZEN); + } + + @Override + public void onIndexModule(IndexModule indexModule) { + if (FrozenEngine.INDEX_FROZEN.get(indexModule.getSettings())) { + indexModule.addSearchOperationListener(new FrozenEngine.ReacquireEngineSearcherListener()); + } + super.onIndexModule(indexModule); + } + + @Override + public Collection createGuiceModules() { + List modules = new ArrayList<>(); + + if (transportClientMode) { + return modules; + } + + modules.add(b -> XPackPlugin.bindFeatureSet(b, FrozenIndicesFeatureSet.class)); + + return modules; + } + + @Override + public List> getActions() { + List> actions = new ArrayList<>(); + actions.add(new ActionHandler<>(FreezeIndexAction.INSTANCE, TransportFreezeIndexAction.class)); + return actions; + } + + @Override + public List getRestHandlers(Settings settings, RestController restController, ClusterSettings clusterSettings, + IndexScopedSettings indexScopedSettings, SettingsFilter settingsFilter, + IndexNameExpressionResolver indexNameExpressionResolver, + Supplier nodesInCluster) { + return Collections.singletonList(new RestFreezeIndexAction(settings, restController)); + } +} diff --git a/x-pack/plugin/frozen-indices/src/main/java/org/elasticsearch/xpack/frozen/FrozenIndicesFeatureSet.java b/x-pack/plugin/frozen-indices/src/main/java/org/elasticsearch/xpack/frozen/FrozenIndicesFeatureSet.java new file mode 100644 index 00000000000..f9b0f9cba13 --- /dev/null +++ b/x-pack/plugin/frozen-indices/src/main/java/org/elasticsearch/xpack/frozen/FrozenIndicesFeatureSet.java @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.frozen; + +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.cluster.metadata.IndexMetaData; +import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.index.engine.FrozenEngine; +import org.elasticsearch.xpack.core.XPackFeatureSet; +import org.elasticsearch.xpack.core.XPackField; +import org.elasticsearch.xpack.core.frozen.FrozenIndicesFeatureSetUsage; + +import java.util.Map; + +public class FrozenIndicesFeatureSet implements XPackFeatureSet { + + private final ClusterService clusterService; + + @Inject + public FrozenIndicesFeatureSet(ClusterService clusterService) { + this.clusterService = clusterService; + } + + @Override + public String name() { + return XPackField.FROZEN_INDICES; + } + + @Override + public boolean available() { + return true; + } + + @Override + public boolean enabled() { + return true; + } + + @Override + public Map nativeCodeInfo() { + return null; + } + + @Override + public void usage(ActionListener listener) { + int numFrozenIndices = 0; + for (IndexMetaData indexMetaData : clusterService.state().metaData()) { + if (FrozenEngine.INDEX_FROZEN.get(indexMetaData.getSettings())) { + numFrozenIndices++; + } + } + listener.onResponse(new FrozenIndicesFeatureSetUsage(true, true, numFrozenIndices)); + } +} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/action/TransportFreezeIndexAction.java b/x-pack/plugin/frozen-indices/src/main/java/org/elasticsearch/xpack/frozen/action/TransportFreezeIndexAction.java similarity index 63% rename from x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/action/TransportFreezeIndexAction.java rename to x-pack/plugin/frozen-indices/src/main/java/org/elasticsearch/xpack/frozen/action/TransportFreezeIndexAction.java index 43e17555a54..852981e7ff7 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/action/TransportFreezeIndexAction.java +++ b/x-pack/plugin/frozen-indices/src/main/java/org/elasticsearch/xpack/frozen/action/TransportFreezeIndexAction.java @@ -3,24 +3,17 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.xpack.core.action; +package org.elasticsearch.xpack.frozen.action; import org.apache.logging.log4j.message.ParameterizedMessage; import org.elasticsearch.ResourceNotFoundException; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.ActionRequestValidationException; -import org.elasticsearch.action.ActionType; -import org.elasticsearch.action.IndicesRequest; import org.elasticsearch.action.admin.indices.close.CloseIndexClusterStateUpdateRequest; import org.elasticsearch.action.admin.indices.close.CloseIndexResponse; import org.elasticsearch.action.admin.indices.close.TransportCloseIndexAction; import org.elasticsearch.action.admin.indices.open.OpenIndexClusterStateUpdateRequest; -import org.elasticsearch.action.admin.indices.open.OpenIndexResponse; import org.elasticsearch.action.support.ActionFilters; -import org.elasticsearch.action.support.ActiveShardCount; import org.elasticsearch.action.support.DestructiveOperations; -import org.elasticsearch.action.support.IndicesOptions; -import org.elasticsearch.action.support.master.AcknowledgedRequest; import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.action.support.master.TransportMasterNodeAction; import org.elasticsearch.cluster.AckedClusterStateUpdateTask; @@ -37,25 +30,23 @@ import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.Priority; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.util.CollectionUtils; import org.elasticsearch.index.Index; import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.engine.FrozenEngine; import org.elasticsearch.tasks.Task; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; +import org.elasticsearch.xpack.core.frozen.action.FreezeIndexAction; +import org.elasticsearch.protocol.xpack.frozen.FreezeRequest; +import org.elasticsearch.protocol.xpack.frozen.FreezeResponse; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import static org.elasticsearch.action.ValidateActions.addValidationError; - public final class TransportFreezeIndexAction extends - TransportMasterNodeAction { + TransportMasterNodeAction { private final DestructiveOperations destructiveOperations; private final MetaDataIndexStateService indexStateService; @@ -115,8 +106,8 @@ public final class TransportFreezeIndexAction extends } @Override - protected void masterOperation(Task task, TransportFreezeIndexAction.FreezeRequest request, ClusterState state, - ActionListener listener) throws Exception { + protected void masterOperation(Task task, FreezeRequest request, ClusterState state, + ActionListener listener) throws Exception { final Index[] concreteIndices = resolveIndices(request, state); if (concreteIndices.length == 0) { listener.onResponse(new FreezeResponse(true, true)); @@ -216,137 +207,4 @@ public final class TransportFreezeIndexAction extends return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_WRITE, indexNameExpressionResolver.concreteIndexNames(state, request)); } - - public static class FreezeResponse extends OpenIndexResponse { - FreezeResponse(StreamInput in) throws IOException { - super(in); - } - - public FreezeResponse(boolean acknowledged, boolean shardsAcknowledged) { - super(acknowledged, shardsAcknowledged); - } - } - - public static class FreezeIndexAction extends ActionType { - - public static final FreezeIndexAction INSTANCE = new FreezeIndexAction(); - public static final String NAME = "indices:admin/freeze"; - - private FreezeIndexAction() { - super(NAME); - } - - @Override - public Writeable.Reader getResponseReader() { - return FreezeResponse::new; - } - } - - public static class FreezeRequest extends AcknowledgedRequest - implements IndicesRequest.Replaceable { - private String[] indices; - private boolean freeze = true; - private IndicesOptions indicesOptions = IndicesOptions.strictExpandOpen(); - private ActiveShardCount waitForActiveShards = ActiveShardCount.DEFAULT; - - public FreezeRequest(String... indices) { - this.indices = indices; - } - - @Override - public ActionRequestValidationException validate() { - ActionRequestValidationException validationException = null; - if (CollectionUtils.isEmpty(indices)) { - validationException = addValidationError("index is missing", validationException); - } - return validationException; - } - - public FreezeRequest setFreeze(boolean freeze) { - this.freeze = freeze; - return this; - } - - public boolean freeze() { - return freeze; - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - indicesOptions = IndicesOptions.readIndicesOptions(in); - indices = in.readStringArray(); - freeze = in.readBoolean(); - waitForActiveShards = ActiveShardCount.readFrom(in); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - indicesOptions.writeIndicesOptions(out); - out.writeStringArray(indices); - out.writeBoolean(freeze); - waitForActiveShards.writeTo(out); - } - - /** - * @return the indices to be frozen or unfrozen - */ - @Override - public String[] indices() { - return indices; - } - - /** - * Specifies what type of requested indices to ignore and how to deal with wildcard expressions. - * For example indices that don't exist. - * - * @return the current behaviour when it comes to index names and wildcard indices expressions - */ - @Override - public IndicesOptions indicesOptions() { - return indicesOptions; - } - - /** - * Specifies what type of requested indices to ignore and how to deal with wildcard expressions. - * For example indices that don't exist. - * - * @param indicesOptions the desired behaviour regarding indices to ignore and wildcard indices expressions - * @return the request itself - */ - public FreezeRequest indicesOptions(IndicesOptions indicesOptions) { - this.indicesOptions = indicesOptions; - return this; - } - - @Override - public IndicesRequest indices(String... indices) { - this.indices = indices; - return this; - } - - public ActiveShardCount waitForActiveShards() { - return waitForActiveShards; - } - - /** - * Sets the number of shard copies that should be active for indices opening to return. - * Defaults to {@link ActiveShardCount#DEFAULT}, which will wait for one shard copy - * (the primary) to become active. Set this value to {@link ActiveShardCount#ALL} to - * wait for all shards (primary and all replicas) to be active before returning. - * Otherwise, use {@link ActiveShardCount#from(int)} to set this value to any - * non-negative integer, up to the number of copies per shard (number of replicas + 1), - * to wait for the desired amount of shard copies to become active before returning. - * Indices opening will only wait up until the timeout value for the number of shard copies - * to be active before returning. Check {@link OpenIndexResponse#isShardsAcknowledged()} to - * determine if the requisite shard copies were all started before returning or timing out. - * - * @param waitForActiveShards number of active shard copies to wait on - */ - public FreezeRequest waitForActiveShards(ActiveShardCount waitForActiveShards) { - this.waitForActiveShards = waitForActiveShards; - return this; - } - } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rest/action/RestFreezeIndexAction.java b/x-pack/plugin/frozen-indices/src/main/java/org/elasticsearch/xpack/frozen/rest/action/RestFreezeIndexAction.java similarity index 86% rename from x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rest/action/RestFreezeIndexAction.java rename to x-pack/plugin/frozen-indices/src/main/java/org/elasticsearch/xpack/frozen/rest/action/RestFreezeIndexAction.java index 9604cdd8b31..b8271724177 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rest/action/RestFreezeIndexAction.java +++ b/x-pack/plugin/frozen-indices/src/main/java/org/elasticsearch/xpack/frozen/rest/action/RestFreezeIndexAction.java @@ -3,17 +3,17 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -package org.elasticsearch.xpack.core.rest.action; +package org.elasticsearch.xpack.frozen.rest.action; import org.elasticsearch.action.support.ActiveShardCount; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.protocol.xpack.frozen.FreezeRequest; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestRequest; import org.elasticsearch.rest.action.RestToXContentListener; import org.elasticsearch.xpack.core.XPackClient; -import org.elasticsearch.xpack.core.action.TransportFreezeIndexAction; import org.elasticsearch.xpack.core.rest.XPackRestHandler; public final class RestFreezeIndexAction extends XPackRestHandler { @@ -26,8 +26,7 @@ public final class RestFreezeIndexAction extends XPackRestHandler { @Override protected RestChannelConsumer doPrepareRequest(RestRequest request, XPackClient client) { boolean freeze = request.path().endsWith("/_freeze"); - TransportFreezeIndexAction.FreezeRequest freezeRequest = - new TransportFreezeIndexAction.FreezeRequest(Strings.splitStringByCommaToArray(request.param("index"))); + FreezeRequest freezeRequest = new FreezeRequest(Strings.splitStringByCommaToArray(request.param("index"))); freezeRequest.timeout(request.paramAsTime("timeout", freezeRequest.timeout())); freezeRequest.masterNodeTimeout(request.paramAsTime("master_timeout", freezeRequest.masterNodeTimeout())); freezeRequest.indicesOptions(IndicesOptions.fromRequest(request, freezeRequest.indicesOptions())); diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/index/engine/FrozenEngineTests.java b/x-pack/plugin/frozen-indices/src/test/java/org/elasticsearch/index/engine/FrozenEngineTests.java similarity index 100% rename from x-pack/plugin/core/src/test/java/org/elasticsearch/index/engine/FrozenEngineTests.java rename to x-pack/plugin/frozen-indices/src/test/java/org/elasticsearch/index/engine/FrozenEngineTests.java diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/index/engine/FrozenIndexRecoveryTests.java b/x-pack/plugin/frozen-indices/src/test/java/org/elasticsearch/index/engine/FrozenIndexRecoveryTests.java similarity index 100% rename from x-pack/plugin/core/src/test/java/org/elasticsearch/index/engine/FrozenIndexRecoveryTests.java rename to x-pack/plugin/frozen-indices/src/test/java/org/elasticsearch/index/engine/FrozenIndexRecoveryTests.java diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/index/engine/FrozenIndexTests.java b/x-pack/plugin/frozen-indices/src/test/java/org/elasticsearch/index/engine/FrozenIndexTests.java similarity index 90% rename from x-pack/plugin/core/src/test/java/org/elasticsearch/index/engine/FrozenIndexTests.java rename to x-pack/plugin/frozen-indices/src/test/java/org/elasticsearch/index/engine/FrozenIndexTests.java index 406c4e1b5d3..3e93062cf15 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/index/engine/FrozenIndexTests.java +++ b/x-pack/plugin/frozen-indices/src/test/java/org/elasticsearch/index/engine/FrozenIndexTests.java @@ -31,6 +31,7 @@ import org.elasticsearch.index.shard.IndexShardTestCase; import org.elasticsearch.indices.IndicesService; import org.elasticsearch.indices.recovery.RecoveryState; import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.protocol.xpack.frozen.FreezeRequest; import org.elasticsearch.rest.RestStatus; import org.elasticsearch.search.SearchService; import org.elasticsearch.search.builder.SearchSourceBuilder; @@ -38,8 +39,7 @@ import org.elasticsearch.search.internal.AliasFilter; import org.elasticsearch.search.internal.ShardSearchLocalRequest; import org.elasticsearch.test.ESSingleNodeTestCase; import org.elasticsearch.xpack.core.XPackClient; -import org.elasticsearch.xpack.core.XPackPlugin; -import org.elasticsearch.xpack.core.action.TransportFreezeIndexAction; +import org.elasticsearch.xpack.frozen.FrozenIndices; import org.hamcrest.Matchers; import java.io.IOException; @@ -61,7 +61,7 @@ public class FrozenIndexTests extends ESSingleNodeTestCase { @Override protected Collection> getPlugins() { - return pluginList(XPackPlugin.class); + return pluginList(FrozenIndices.class); } public void testCloseFreezeAndOpen() throws ExecutionException, InterruptedException { @@ -70,7 +70,7 @@ public class FrozenIndexTests extends ESSingleNodeTestCase { client().prepareIndex("index", "_doc", "2").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get(); client().prepareIndex("index", "_doc", "3").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get(); XPackClient xPackClient = new XPackClient(client()); - assertAcked(xPackClient.freeze(new TransportFreezeIndexAction.FreezeRequest("index"))); + assertAcked(xPackClient.freeze(new FreezeRequest("index"))); expectThrows(ClusterBlockException.class, () -> client().prepareIndex("index", "_doc", "4").setSource("field", "value") .setRefreshPolicy(IMMEDIATE).get()); IndicesService indexServices = getInstanceFromNode(IndicesService.class); @@ -116,30 +116,29 @@ public class FrozenIndexTests extends ESSingleNodeTestCase { client().prepareIndex("index", "_doc", "" + i).setSource("field", "foo bar baz").get(); } XPackClient xPackClient = new XPackClient(client()); - assertAcked(xPackClient.freeze(new TransportFreezeIndexAction.FreezeRequest("index"))); + assertAcked(xPackClient.freeze(new FreezeRequest("index"))); int numRequests = randomIntBetween(20, 50); CountDownLatch latch = new CountDownLatch(numRequests); - ActionListener listener = ActionListener.wrap(latch::countDown); int numRefreshes = 0; for (int i = 0; i < numRequests; i++) { numRefreshes++; switch (randomIntBetween(0, 3)) { case 0: - client().prepareGet("index", "_doc", "" + randomIntBetween(0, 9)).execute(listener); + client().prepareGet("index", "_doc", "" + randomIntBetween(0, 9)).execute(ActionListener.wrap(latch::countDown)); break; case 1: client().prepareSearch("index").setIndicesOptions(IndicesOptions.STRICT_EXPAND_OPEN_FORBID_CLOSED) .setSearchType(SearchType.QUERY_THEN_FETCH) - .execute(listener); + .execute(ActionListener.wrap(latch::countDown)); // in total 4 refreshes 1x query & 1x fetch per shard (we have 2) numRefreshes += 3; break; case 2: - client().prepareTermVectors("index", "_doc", "" + randomIntBetween(0, 9)).execute(listener); + client().prepareTermVectors("index", "_doc", "" + randomIntBetween(0, 9)).execute(ActionListener.wrap(latch::countDown)); break; case 3: client().prepareExplain("index", "_doc", "" + randomIntBetween(0, 9)).setQuery(new MatchAllQueryBuilder()) - .execute(listener); + .execute(ActionListener.wrap(latch::countDown)); break; default: assert false; @@ -160,7 +159,7 @@ public class FrozenIndexTests extends ESSingleNodeTestCase { assertAcked(client().admin().indices().prepareClose("index").get()); } XPackClient xPackClient = new XPackClient(client()); - assertAcked(xPackClient.freeze(new TransportFreezeIndexAction.FreezeRequest("index"))); + assertAcked(xPackClient.freeze(new FreezeRequest("index"))); { IndicesService indexServices = getInstanceFromNode(IndicesService.class); Index index = resolveIndex("index"); @@ -169,7 +168,7 @@ public class FrozenIndexTests extends ESSingleNodeTestCase { IndexShard shard = indexService.getShard(0); assertEquals(0, shard.refreshStats().getTotal()); } - assertAcked(xPackClient.freeze(new TransportFreezeIndexAction.FreezeRequest("index").setFreeze(false))); + assertAcked(xPackClient.freeze(new FreezeRequest("index").setFreeze(false))); { IndicesService indexServices = getInstanceFromNode(IndicesService.class); Index index = resolveIndex("index"); @@ -193,9 +192,9 @@ public class FrozenIndexTests extends ESSingleNodeTestCase { public void testDoubleFreeze() throws ExecutionException, InterruptedException { createIndex("test-idx", Settings.builder().put("index.number_of_shards", 2).build()); XPackClient xPackClient = new XPackClient(client()); - assertAcked(xPackClient.freeze(new TransportFreezeIndexAction.FreezeRequest("test-idx"))); + assertAcked(xPackClient.freeze(new FreezeRequest("test-idx"))); ExecutionException executionException = expectThrows(ExecutionException.class, - () -> xPackClient.freeze(new TransportFreezeIndexAction.FreezeRequest("test-idx") + () -> xPackClient.freeze(new FreezeRequest("test-idx") .indicesOptions(new IndicesOptions(EnumSet.noneOf(IndicesOptions.Option.class), EnumSet.of(IndicesOptions.WildcardStates.OPEN))))); assertEquals("no index found to freeze", executionException.getCause().getMessage()); @@ -207,9 +206,9 @@ public class FrozenIndexTests extends ESSingleNodeTestCase { createIndex("idx-closed", Settings.builder().put("index.number_of_shards", 1).build()); client().prepareIndex("idx-closed", "_doc", "1").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get(); XPackClient xPackClient = new XPackClient(client()); - assertAcked(xPackClient.freeze(new TransportFreezeIndexAction.FreezeRequest("idx"))); + assertAcked(xPackClient.freeze(new FreezeRequest("idx"))); assertAcked(client().admin().indices().prepareClose("idx-closed").get()); - assertAcked(xPackClient.freeze(new TransportFreezeIndexAction.FreezeRequest("idx*").setFreeze(false) + assertAcked(xPackClient.freeze(new FreezeRequest("idx*").setFreeze(false) .indicesOptions(IndicesOptions.strictExpand()))); ClusterStateResponse stateResponse = client().admin().cluster().prepareState().get(); assertEquals(IndexMetaData.State.CLOSE, stateResponse.getState().getMetaData().index("idx-closed").getState()); @@ -223,7 +222,7 @@ public class FrozenIndexTests extends ESSingleNodeTestCase { createIndex("test-idx-1", Settings.builder().put("index.number_of_shards", 1).build()); client().prepareIndex("test-idx-1", "_doc", "1").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get(); XPackClient xPackClient = new XPackClient(client()); - assertAcked(xPackClient.freeze(new TransportFreezeIndexAction.FreezeRequest("test-idx"))); + assertAcked(xPackClient.freeze(new FreezeRequest("test-idx"))); assertIndexFrozen("test-idx"); IndicesStatsResponse index = client().admin().indices().prepareStats("test-idx").clear().setRefresh(true).get(); @@ -232,7 +231,7 @@ public class FrozenIndexTests extends ESSingleNodeTestCase { index = client().admin().indices().prepareStats("test-idx").clear().setRefresh(true).get(); assertEquals(1, index.getTotal().refresh.getTotal()); - assertAcked(xPackClient.freeze(new TransportFreezeIndexAction.FreezeRequest("test*"))); + assertAcked(xPackClient.freeze(new FreezeRequest("test*"))); assertIndexFrozen("test-idx"); assertIndexFrozen("test-idx-1"); index = client().admin().indices().prepareStats("test-idx").clear().setRefresh(true).get(); @@ -270,7 +269,7 @@ public class FrozenIndexTests extends ESSingleNodeTestCase { } XPackClient xPackClient = new XPackClient(client()); - assertAcked(xPackClient.freeze(new TransportFreezeIndexAction.FreezeRequest("index"))); + assertAcked(xPackClient.freeze(new FreezeRequest("index"))); { IndicesService indexServices = getInstanceFromNode(IndicesService.class); @@ -302,7 +301,7 @@ public class FrozenIndexTests extends ESSingleNodeTestCase { createIndex("idx", Settings.builder().put("index.number_of_shards", 1).build()); client().prepareIndex("idx", "_doc", "1").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get(); XPackClient xPackClient = new XPackClient(client()); - assertAcked(xPackClient.freeze(new TransportFreezeIndexAction.FreezeRequest("idx"))); + assertAcked(xPackClient.freeze(new FreezeRequest("idx"))); assertIndexFrozen("idx"); expectThrows(ClusterBlockException.class, () -> client().prepareIndex("idx", "_doc", "2").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get()); @@ -313,7 +312,7 @@ public class FrozenIndexTests extends ESSingleNodeTestCase { createIndex("idx-close", Settings.builder().put("index.number_of_shards", 1).build()); assertAcked(client().admin().indices().prepareClose("idx-close")); XPackClient xPackClient = new XPackClient(client()); - assertAcked(xPackClient.freeze(new TransportFreezeIndexAction.FreezeRequest("idx*", "not_available") + assertAcked(xPackClient.freeze(new FreezeRequest("idx*", "not_available") .indicesOptions(IndicesOptions.fromParameters(null, "true", null, null, IndicesOptions.strictExpandOpen())))); assertIndexFrozen("idx"); assertEquals(IndexMetaData.State.CLOSE, @@ -323,16 +322,16 @@ public class FrozenIndexTests extends ESSingleNodeTestCase { public void testUnfreezeClosedIndex() throws ExecutionException, InterruptedException { createIndex("idx", Settings.builder().put("index.number_of_shards", 1).build()); XPackClient xPackClient = new XPackClient(client()); - assertAcked(xPackClient.freeze(new TransportFreezeIndexAction.FreezeRequest("idx"))); + assertAcked(xPackClient.freeze(new FreezeRequest("idx"))); assertAcked(client().admin().indices().prepareClose("idx")); assertEquals(IndexMetaData.State.CLOSE, client().admin().cluster().prepareState().get().getState().metaData().index("idx").getState()); expectThrows(ExecutionException.class, - () -> xPackClient.freeze(new TransportFreezeIndexAction.FreezeRequest("id*").setFreeze(false) + () -> xPackClient.freeze(new FreezeRequest("id*").setFreeze(false) .indicesOptions(new IndicesOptions(EnumSet.noneOf(IndicesOptions.Option.class), EnumSet.of(IndicesOptions.WildcardStates.OPEN))))); // we don't resolve to closed indices - assertAcked(xPackClient.freeze(new TransportFreezeIndexAction.FreezeRequest("idx").setFreeze(false))); + assertAcked(xPackClient.freeze(new FreezeRequest("idx").setFreeze(false))); assertEquals(IndexMetaData.State.OPEN, client().admin().cluster().prepareState().get().getState().metaData().index("idx").getState()); } @@ -346,7 +345,7 @@ public class FrozenIndexTests extends ESSingleNodeTestCase { .getState().metaData().index(index).getSettingsVersion(); XPackClient xPackClient = new XPackClient(client()); - assertAcked(xPackClient.freeze(new TransportFreezeIndexAction.FreezeRequest(index))); + assertAcked(xPackClient.freeze(new FreezeRequest(index))); assertIndexFrozen(index); assertThat(client().admin().cluster().prepareState().get().getState().metaData().index(index).getSettingsVersion(), greaterThan(settingsVersion)); @@ -374,7 +373,7 @@ public class FrozenIndexTests extends ESSingleNodeTestCase { assertThat(indexService.getShard(0).getLastKnownGlobalCheckpoint(), greaterThanOrEqualTo(nbNoOps - 1L)); }); - assertAcked(new XPackClient(client()).freeze(new TransportFreezeIndexAction.FreezeRequest(indexName))); + assertAcked(new XPackClient(client()).freeze(new FreezeRequest(indexName))); assertIndexFrozen(indexName); } @@ -390,7 +389,7 @@ public class FrozenIndexTests extends ESSingleNodeTestCase { assertThat(indexResponse.status(), is(RestStatus.CREATED)); } - assertAcked(new XPackClient(client()).freeze(new TransportFreezeIndexAction.FreezeRequest(indexName))); + assertAcked(new XPackClient(client()).freeze(new FreezeRequest(indexName))); assertIndexFrozen(indexName); final IndexMetaData indexMetaData = client().admin().cluster().prepareState().get().getState().metaData().index(indexName); @@ -435,7 +434,7 @@ public class FrozenIndexTests extends ESSingleNodeTestCase { assertThat(stats.getIndex(indexName).getPrimaries().getTranslog().estimatedNumberOfOperations(), equalTo(nbDocs)); assertThat(stats.getIndex(indexName).getPrimaries().getTranslog().getUncommittedOperations(), equalTo(uncommittedOps)); - assertAcked(new XPackClient(client()).freeze(new TransportFreezeIndexAction.FreezeRequest(indexName))); + assertAcked(new XPackClient(client()).freeze(new FreezeRequest(indexName))); assertIndexFrozen(indexName); IndicesOptions indicesOptions = IndicesOptions.STRICT_EXPAND_OPEN_CLOSED; diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/index/engine/RewriteCachingDirectoryReaderTests.java b/x-pack/plugin/frozen-indices/src/test/java/org/elasticsearch/index/engine/RewriteCachingDirectoryReaderTests.java similarity index 100% rename from x-pack/plugin/core/src/test/java/org/elasticsearch/index/engine/RewriteCachingDirectoryReaderTests.java rename to x-pack/plugin/frozen-indices/src/test/java/org/elasticsearch/index/engine/RewriteCachingDirectoryReaderTests.java diff --git a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/indexlifecycle/TimeSeriesLifecycleActionsIT.java b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/indexlifecycle/TimeSeriesLifecycleActionsIT.java index 06dc968a4ce..8611977c26a 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/indexlifecycle/TimeSeriesLifecycleActionsIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/indexlifecycle/TimeSeriesLifecycleActionsIT.java @@ -21,7 +21,6 @@ import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.index.IndexSettings; -import org.elasticsearch.index.engine.FrozenEngine; import org.elasticsearch.test.rest.ESRestTestCase; import org.elasticsearch.xpack.core.indexlifecycle.AllocateAction; import org.elasticsearch.xpack.core.indexlifecycle.DeleteAction; @@ -548,7 +547,7 @@ public class TimeSeriesLifecycleActionsIT extends ESRestTestCase { assertThat(getStepKeyForIndex(index), equalTo(TerminalPolicyStep.KEY)); assertThat(settings.get(IndexMetaData.INDEX_BLOCKS_WRITE_SETTING.getKey()), equalTo("true")); assertThat(settings.get(IndexSettings.INDEX_SEARCH_THROTTLED.getKey()), equalTo("true")); - assertThat(settings.get(FrozenEngine.INDEX_FROZEN.getKey()), equalTo("true")); + assertThat(settings.get("index.frozen"), equalTo("true")); }); } @@ -586,7 +585,7 @@ public class TimeSeriesLifecycleActionsIT extends ESRestTestCase { assertThat(getStepKeyForIndex(index), equalTo(TerminalPolicyStep.KEY)); assertThat(settings.get(IndexMetaData.INDEX_BLOCKS_WRITE_SETTING.getKey()), equalTo("true")); assertThat(settings.get(IndexSettings.INDEX_SEARCH_THROTTLED.getKey()), equalTo("true")); - assertThat(settings.get(FrozenEngine.INDEX_FROZEN.getKey()), equalTo("true")); + assertThat(settings.get("index.frozen"), equalTo("true")); }, 2, TimeUnit.MINUTES); // assert that snapshot is still in progress and clean up assertThat(getSnapshotState("snapshot"), equalTo("SUCCESS")); diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/test/indices.freeze/20_stats.yml b/x-pack/plugin/src/test/resources/rest-api-spec/test/indices.freeze/20_stats.yml index 8c6cb329d0b..e73c7793022 100644 --- a/x-pack/plugin/src/test/resources/rest-api-spec/test/indices.freeze/20_stats.yml +++ b/x-pack/plugin/src/test/resources/rest-api-spec/test/indices.freeze/20_stats.yml @@ -52,7 +52,7 @@ setup: # unfreeze index - do: - indices.freeze: + indices.unfreeze: index: test wait_for_active_shards: 1 - is_true: acknowledged diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/test/indices.freeze/30_usage.yml b/x-pack/plugin/src/test/resources/rest-api-spec/test/indices.freeze/30_usage.yml new file mode 100644 index 00000000000..9135c19f679 --- /dev/null +++ b/x-pack/plugin/src/test/resources/rest-api-spec/test/indices.freeze/30_usage.yml @@ -0,0 +1,60 @@ +--- +setup: + - do: + indices.create: + index: test + - do: + cluster.health: + wait_for_no_initializing_shards: true + +--- +"Usage stats on frozen indices": + - skip: + version: " - 7.9.99" + reason: "frozen indices have usage stats starting in version 8.0.0" + + - do: + index: + index: test + id: 1 + body: { "foo": "bar" } + + - do: + index: + index: test + id: 2 + body: { "foo": "bar" } + + - do: + index: + index: test + id: 3 + body: { "foo": "bar" } + + - do: {xpack.usage: {}} + - match: { frozen_indices.available: true } + - match: { frozen_indices.enabled: true } + - match: { frozen_indices.indices_count: 0 } + + # freeze index + - do: + indices.freeze: + index: test + - is_true: acknowledged + + + - do: {xpack.usage: {}} + - match: { frozen_indices.available: true } + - match: { frozen_indices.enabled: true } + - match: { frozen_indices.indices_count: 1 } + + # unfreeze index + - do: + indices.unfreeze: + index: test + - is_true: acknowledged + + - do: {xpack.usage: {}} + - match: { frozen_indices.available: true } + - match: { frozen_indices.enabled: true } + - match: { frozen_indices.indices_count: 0 }