Skip to content

Commit 6af1cb8

Browse files
committed
Warn when searching a frozen index.
The coordinating node should warn when a search request is targeting a frozen index. Relates to #70192
1 parent e30e9d8 commit 6af1cb8

File tree

7 files changed

+92
-39
lines changed

7 files changed

+92
-39
lines changed

server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.elasticsearch.cluster.ClusterState;
2121
import org.elasticsearch.cluster.block.ClusterBlockException;
2222
import org.elasticsearch.cluster.block.ClusterBlockLevel;
23+
import org.elasticsearch.cluster.metadata.IndexMetadata;
2324
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
2425
import org.elasticsearch.cluster.node.DiscoveryNode;
2526
import org.elasticsearch.cluster.node.DiscoveryNodes;
@@ -33,6 +34,8 @@
3334
import org.elasticsearch.common.inject.Inject;
3435
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
3536
import org.elasticsearch.common.io.stream.Writeable;
37+
import org.elasticsearch.common.logging.DeprecationCategory;
38+
import org.elasticsearch.common.logging.DeprecationLogger;
3639
import org.elasticsearch.common.settings.Setting;
3740
import org.elasticsearch.common.settings.Setting.Property;
3841
import org.elasticsearch.common.util.concurrent.AtomicArray;
@@ -92,6 +95,10 @@
9295

9396
public class TransportSearchAction extends HandledTransportAction<SearchRequest, SearchResponse> {
9497

98+
private static final DeprecationLogger DEPRECATION_LOGGER = DeprecationLogger.getLogger(TransportSearchAction.class);
99+
public static final String FROZEN_INDICES_DEPRECATION_MESSAGE = "Searching frozen indices [{}] is deprecated." +
100+
" Consider cold or frozen tiers in place of frozen indices. The frozen feature will be removed in a feature release.";
101+
95102
/** The maximum number of shards for a single search request. */
96103
public static final Setting<Long> SHARD_COUNT_LIMIT_SETTING = Setting.longSetting(
97104
"action.search.shard_count.limit", Long.MAX_VALUE, 1L, Property.Dynamic, Property.NodeScope);
@@ -592,7 +599,23 @@ private Index[] resolveLocalIndices(OriginalIndices localIndices,
592599
if (localIndices == null) {
593600
return Index.EMPTY_ARRAY; //don't search on any local index (happens when only remote indices were specified)
594601
}
595-
return indexNameExpressionResolver.concreteIndices(clusterState, localIndices, timeProvider.getAbsoluteStartMillis());
602+
603+
List<String> frozenIndices = null;
604+
Index[] indices = indexNameExpressionResolver.concreteIndices(clusterState, localIndices, timeProvider.getAbsoluteStartMillis());
605+
for (Index index : indices) {
606+
IndexMetadata indexMetadata = clusterState.metadata().index(index);
607+
if (indexMetadata.getSettings().getAsBoolean("index.frozen", false)) {
608+
if (frozenIndices == null) {
609+
frozenIndices = new ArrayList<>();
610+
}
611+
frozenIndices.add(index.getName());
612+
}
613+
}
614+
if (frozenIndices != null) {
615+
DEPRECATION_LOGGER.critical(DeprecationCategory.INDICES, "search-frozen-indices", FROZEN_INDICES_DEPRECATION_MESSAGE,
616+
String.join(",", frozenIndices));
617+
}
618+
return indices;
596619
}
597620

598621
private void executeSearch(SearchTask task, SearchTimeProvider timeProvider, SearchRequest searchRequest,

server/src/test/java/org/elasticsearch/search/SearchServiceTests.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.elasticsearch.action.search.SearchScrollRequest;
2727
import org.elasticsearch.action.search.SearchShardTask;
2828
import org.elasticsearch.action.search.SearchType;
29+
import org.elasticsearch.action.search.TransportSearchAction;
2930
import org.elasticsearch.action.support.IndicesOptions;
3031
import org.elasticsearch.action.support.PlainActionFuture;
3132
import org.elasticsearch.action.support.WriteRequest;
@@ -917,16 +918,18 @@ public void testExpandSearchThrottled() {
917918
}
918919

919920
public void testExpandSearchFrozen() {
920-
createIndex("frozen_index");
921+
String indexName = "frozen_index";
922+
createIndex(indexName);
921923
client().execute(
922924
InternalOrPrivateSettingsPlugin.UpdateInternalOrPrivateAction.INSTANCE,
923-
new InternalOrPrivateSettingsPlugin.UpdateInternalOrPrivateAction.Request("frozen_index",
925+
new InternalOrPrivateSettingsPlugin.UpdateInternalOrPrivateAction.Request(indexName,
924926
"index.frozen", "true"))
925927
.actionGet();
926928

927-
client().prepareIndex("frozen_index").setId("1").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get();
929+
client().prepareIndex(indexName).setId("1").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get();
928930
assertHitCount(client().prepareSearch().get(), 0L);
929931
assertHitCount(client().prepareSearch().setIndicesOptions(IndicesOptions.STRICT_EXPAND_OPEN_FORBID_CLOSED).get(), 1L);
932+
assertWarnings(TransportSearchAction.FROZEN_INDICES_DEPRECATION_MESSAGE.replace("{}", indexName));
930933
}
931934

932935
public void testCreateReduceContext() {

x-pack/plugin/build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ tasks.named("yamlRestTestV7CompatTransform").configure({ task ->
166166
})
167167
tasks.named("yamlRestTestV7CompatTest").configure {
168168
systemProperty 'tests.rest.blacklist', [
169+
// UNMUTE after #78184 is backported to 7.x
170+
'indices.freeze/10_basic/Basic',
171+
'indices.freeze/10_basic/Test index options',
172+
'',
169173
// to support it, it would require to almost revert back the #48725 and complicate the code
170174
'vectors/10_dense_vector_basic/Deprecated function signature',
171175
// not going to be supported

x-pack/plugin/frozen-indices/src/internalClusterTest/java/org/elasticsearch/index/engine/frozen/FrozenIndexTests.java

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.elasticsearch.action.search.SearchRequest;
2121
import org.elasticsearch.action.search.SearchResponse;
2222
import org.elasticsearch.action.search.SearchType;
23+
import org.elasticsearch.action.search.TransportSearchAction;
2324
import org.elasticsearch.action.support.IndicesOptions;
2425
import org.elasticsearch.action.support.PlainActionFuture;
2526
import org.elasticsearch.cluster.block.ClusterBlockException;
@@ -92,17 +93,18 @@ String openReaders(TimeValue keepAlive, String... indices) {
9293
}
9394

9495
public void testCloseFreezeAndOpen() throws Exception {
95-
createIndex("index", Settings.builder().put("index.number_of_shards", 2).build());
96-
client().prepareIndex("index").setId("1").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get();
97-
client().prepareIndex("index").setId("2").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get();
98-
client().prepareIndex("index").setId("3").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get();
99-
assertAcked(client().execute(FreezeIndexAction.INSTANCE, new FreezeRequest("index")).actionGet());
96+
String indexName = "index";
97+
createIndex(indexName, Settings.builder().put("index.number_of_shards", 2).build());
98+
client().prepareIndex(indexName).setId("1").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get();
99+
client().prepareIndex(indexName).setId("2").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get();
100+
client().prepareIndex(indexName).setId("3").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get();
101+
assertAcked(client().execute(FreezeIndexAction.INSTANCE, new FreezeRequest(indexName)).actionGet());
100102
expectThrows(
101103
ClusterBlockException.class,
102-
() -> client().prepareIndex("index").setId("4").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get()
104+
() -> client().prepareIndex(indexName).setId("4").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get()
103105
);
104106
IndicesService indexServices = getInstanceFromNode(IndicesService.class);
105-
Index index = resolveIndex("index");
107+
Index index = resolveIndex(indexName);
106108
IndexService indexService = indexServices.indexServiceSafe(index);
107109
IndexShard shard = indexService.getShard(0);
108110
Engine engine = IndexShardTestCase.getEngine(shard);
@@ -141,7 +143,7 @@ public void testCloseFreezeAndOpen() throws Exception {
141143
} while (searchResponse.getHits().getHits().length > 0);
142144
client().prepareClearScroll().addScrollId(searchResponse.getScrollId()).get();
143145

144-
String pitId = openReaders(TimeValue.timeValueMinutes(1), "index");
146+
String pitId = openReaders(TimeValue.timeValueMinutes(1), indexName);
145147
try {
146148
for (int from = 0; from < 3; from++) {
147149
searchResponse = client().prepareSearch()
@@ -160,6 +162,7 @@ public void testCloseFreezeAndOpen() throws Exception {
160162
assertFalse(((FrozenEngine) engine).isReaderOpen());
161163
}
162164
}
165+
assertWarnings(TransportSearchAction.FROZEN_INDICES_DEPRECATION_MESSAGE.replace("{}", indexName));
163166
} finally {
164167
client().execute(ClosePointInTimeAction.INSTANCE, new ClosePointInTimeRequest(pitId)).get();
165168
}
@@ -177,11 +180,12 @@ public void testSearchAndGetAPIsAreThrottled() throws IOException {
177180
.endObject()
178181
.endObject()
179182
.endObject();
180-
createIndex("index", Settings.builder().put("index.number_of_shards", 2).build(), mapping);
183+
String indexName = "index";
184+
createIndex(indexName, Settings.builder().put("index.number_of_shards", 2).build(), mapping);
181185
for (int i = 0; i < 10; i++) {
182-
client().prepareIndex("index").setId("" + i).setSource("field", "foo bar baz").get();
186+
client().prepareIndex(indexName).setId("" + i).setSource("field", "foo bar baz").get();
183187
}
184-
assertAcked(client().execute(FreezeIndexAction.INSTANCE, new FreezeRequest("index")).actionGet());
188+
assertAcked(client().execute(FreezeIndexAction.INSTANCE, new FreezeRequest(indexName)).actionGet());
185189
int numRequests = randomIntBetween(20, 50);
186190
int numRefreshes = 0;
187191
for (int i = 0; i < numRequests; i++) {
@@ -190,29 +194,30 @@ public void testSearchAndGetAPIsAreThrottled() throws IOException {
190194
// searcher and rewrite the request outside of the search-throttle thread pool
191195
switch (randomFrom(Arrays.asList(0, 1, 2))) {
192196
case 0:
193-
client().prepareGet("index", "" + randomIntBetween(0, 9)).get();
197+
client().prepareGet(indexName, "" + randomIntBetween(0, 9)).get();
194198
break;
195199
case 1:
196-
client().prepareSearch("index")
200+
client().prepareSearch(indexName)
197201
.setIndicesOptions(IndicesOptions.STRICT_EXPAND_OPEN_FORBID_CLOSED)
198202
.setSearchType(SearchType.QUERY_THEN_FETCH)
199203
.get();
200204
// in total 4 refreshes 1x query & 1x fetch per shard (we have 2)
201205
numRefreshes += 3;
202206
break;
203207
case 2:
204-
client().prepareTermVectors("index", "" + randomIntBetween(0, 9)).get();
208+
client().prepareTermVectors(indexName, "" + randomIntBetween(0, 9)).get();
205209
break;
206210
case 3:
207-
client().prepareExplain("index", "" + randomIntBetween(0, 9)).setQuery(new MatchAllQueryBuilder()).get();
211+
client().prepareExplain(indexName, "" + randomIntBetween(0, 9)).setQuery(new MatchAllQueryBuilder()).get();
208212
break;
209213

210214
default:
211215
assert false;
212216
}
213217
}
214-
IndicesStatsResponse index = client().admin().indices().prepareStats("index").clear().setRefresh(true).get();
218+
IndicesStatsResponse index = client().admin().indices().prepareStats(indexName).clear().setRefresh(true).get();
215219
assertEquals(numRefreshes, index.getTotal().refresh.getTotal());
220+
assertWarnings(TransportSearchAction.FROZEN_INDICES_DEPRECATION_MESSAGE.replace("{}", indexName));
216221
}
217222

218223
public void testFreezeAndUnfreeze() {
@@ -298,26 +303,28 @@ public void testUnfreezeClosedIndices() {
298303
}
299304

300305
public void testFreezePattern() {
301-
createIndex("test-idx", Settings.builder().put("index.number_of_shards", 1).build());
302-
client().prepareIndex("test-idx").setId("1").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get();
306+
String indexName = "test-idx";
307+
createIndex(indexName, Settings.builder().put("index.number_of_shards", 1).build());
308+
client().prepareIndex(indexName).setId("1").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get();
303309
createIndex("test-idx-1", Settings.builder().put("index.number_of_shards", 1).build());
304310
client().prepareIndex("test-idx-1").setId("1").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get();
305-
assertAcked(client().execute(FreezeIndexAction.INSTANCE, new FreezeRequest("test-idx")).actionGet());
306-
assertIndexFrozen("test-idx");
311+
assertAcked(client().execute(FreezeIndexAction.INSTANCE, new FreezeRequest(indexName)).actionGet());
312+
assertIndexFrozen(indexName);
307313

308-
IndicesStatsResponse index = client().admin().indices().prepareStats("test-idx").clear().setRefresh(true).get();
314+
IndicesStatsResponse index = client().admin().indices().prepareStats(indexName).clear().setRefresh(true).get();
309315
assertEquals(0, index.getTotal().refresh.getTotal());
310-
assertHitCount(client().prepareSearch("test-idx").setIndicesOptions(IndicesOptions.STRICT_EXPAND_OPEN_FORBID_CLOSED).get(), 1);
311-
index = client().admin().indices().prepareStats("test-idx").clear().setRefresh(true).get();
316+
assertHitCount(client().prepareSearch(indexName).setIndicesOptions(IndicesOptions.STRICT_EXPAND_OPEN_FORBID_CLOSED).get(), 1);
317+
index = client().admin().indices().prepareStats(indexName).clear().setRefresh(true).get();
312318
assertEquals(1, index.getTotal().refresh.getTotal());
313319

314320
assertAcked(client().execute(FreezeIndexAction.INSTANCE, new FreezeRequest("test*")).actionGet());
315-
assertIndexFrozen("test-idx");
321+
assertIndexFrozen(indexName);
316322
assertIndexFrozen("test-idx-1");
317-
index = client().admin().indices().prepareStats("test-idx").clear().setRefresh(true).get();
323+
index = client().admin().indices().prepareStats(indexName).clear().setRefresh(true).get();
318324
assertEquals(1, index.getTotal().refresh.getTotal());
319325
index = client().admin().indices().prepareStats("test-idx-1").clear().setRefresh(true).get();
320326
assertEquals(0, index.getTotal().refresh.getTotal());
327+
assertWarnings(TransportSearchAction.FROZEN_INDICES_DEPRECATION_MESSAGE.replace("{}", indexName));
321328
}
322329

323330
public void testCanMatch() throws IOException {

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

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.apache.http.client.methods.HttpPut;
1313
import org.apache.http.entity.ContentType;
1414
import org.apache.http.entity.StringEntity;
15+
import org.elasticsearch.action.search.TransportSearchAction;
1516
import org.elasticsearch.client.Request;
1617
import org.elasticsearch.client.RequestOptions;
1718
import org.elasticsearch.client.Response;
@@ -29,6 +30,7 @@
2930
import org.elasticsearch.test.rest.ESRestTestCase;
3031

3132
import java.io.IOException;
33+
import java.util.HashSet;
3234
import java.util.List;
3335
import java.util.Locale;
3436
import java.util.Map;
@@ -470,19 +472,28 @@ protected static Number count(String index) throws IOException {
470472
protected static Map<String, Object> search(String index, QueryBuilder query, Boolean ignoreThrottled) throws IOException {
471473
final Request request = new Request(HttpPost.METHOD_NAME, '/' + index + "/_search");
472474
request.setJsonEntity(new SearchSourceBuilder().trackTotalHits(true).query(query).toString());
475+
476+
// If warning are returned than these must exist in this set:
477+
Set<String> expectedWarnings = new HashSet<>();
478+
expectedWarnings.add(TransportSearchAction.FROZEN_INDICES_DEPRECATION_MESSAGE.replace("{}", index));
473479
if (ignoreThrottled != null) {
474480
request.addParameter("ignore_throttled", ignoreThrottled.toString());
475-
RequestOptions requestOptions = RequestOptions.DEFAULT.toBuilder()
476-
.setWarningsHandler(
477-
warnings -> List.of(
478-
"[ignore_throttled] parameter is deprecated because frozen indices have been deprecated. "
479-
+ "Consider cold or frozen tiers in place of frozen indices."
480-
).equals(warnings) == false
481-
)
482-
.build();
483-
request.setOptions(requestOptions);
481+
expectedWarnings.add(
482+
"[ignore_throttled] parameter is deprecated because frozen indices have been deprecated. "
483+
+ "Consider cold or frozen tiers in place of frozen indices."
484+
);
484485
}
485486

487+
RequestOptions requestOptions = RequestOptions.DEFAULT.toBuilder().setWarningsHandler(warnings -> {
488+
for (String warning : warnings) {
489+
if (expectedWarnings.contains(warning) == false) {
490+
return true;
491+
}
492+
}
493+
return false;
494+
}).build();
495+
request.setOptions(requestOptions);
496+
486497
final Response response = client().performRequest(request);
487498
assertThat(
488499
"Failed to execute search request on index [" + index + "]: " + response,

x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/indices.freeze/10_basic.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
- do:
2424
warnings:
2525
- "[ignore_throttled] parameter is deprecated because frozen indices have been deprecated. Consider cold or frozen tiers in place of frozen indices."
26+
- "Searching frozen indices [test] is deprecated. Consider cold or frozen tiers in place of frozen indices. The frozen feature will be removed in a feature release."
2627
search:
2728
rest_total_hits_as_int: true
2829
index: test
@@ -68,6 +69,7 @@
6869
- do:
6970
warnings:
7071
- "[ignore_throttled] parameter is deprecated because frozen indices have been deprecated. Consider cold or frozen tiers in place of frozen indices."
72+
- "Searching frozen indices [test,test-01] is deprecated. Consider cold or frozen tiers in place of frozen indices. The frozen feature will be removed in a feature release."
7173
search:
7274
rest_total_hits_as_int: true
7375
index: _all
@@ -134,6 +136,7 @@
134136
- do:
135137
warnings:
136138
- "[ignore_throttled] parameter is deprecated because frozen indices have been deprecated. Consider cold or frozen tiers in place of frozen indices."
139+
- "Searching frozen indices [test] is deprecated. Consider cold or frozen tiers in place of frozen indices. The frozen feature will be removed in a feature release."
137140
search:
138141
rest_total_hits_as_int: true
139142
index: _all

x-pack/qa/full-cluster-restart/src/test/java/org/elasticsearch/xpack/restart/FullClusterRestartIT.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,9 @@ public void testFrozenIndexAfterRestarted() throws Exception {
739739
assertNoFileBasedRecovery(index, n -> true);
740740
final Request request = new Request("GET", "/" + index + "/_search");
741741
request.setOptions(expectWarnings("[ignore_throttled] parameter is deprecated because frozen " +
742-
"indices have been deprecated. Consider cold or frozen tiers in place of frozen indices."));
742+
"indices have been deprecated. Consider cold or frozen tiers in place of frozen indices.",
743+
"Searching frozen indices [" + index + "] is deprecated. " +
744+
"Consider cold or frozen tiers in place of frozen indices. The frozen feature will be removed in a feature release."));
743745
request.addParameter("ignore_throttled", "false");
744746
assertThat(XContentMapValues.extractValue("hits.total.value", entityAsMap(client().performRequest(request))),
745747
equalTo(totalHits));

0 commit comments

Comments
 (0)