Skip to content

Commit 427bc7f

Browse files
authored
Use ILM for Watcher history deletion (#37443)
* Use ILM for Watcher history deletion This commit adds an index lifecycle policy for the `.watch-history-*` indices. This policy is automatically used for all new watch history indices. This does not yet remove the automatic cleanup that the monitoring plugin does for the .watch-history indices, and it does not touch the `xpack.watcher.history.cleaner_service.enabled` setting. Relates to #32041
1 parent f0fc6e8 commit 427bc7f

File tree

13 files changed

+254
-12
lines changed

13 files changed

+254
-12
lines changed

docs/reference/ilm/apis/get-lifecycle.asciidoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ PUT _ilm/policy/my_policy
6969

7070
[source,js]
7171
--------------------------------------------------
72-
GET _ilm/policy
72+
GET _ilm/policy/my_policy
7373
--------------------------------------------------
7474
// CONSOLE
7575
// TEST[continued]

docs/reference/ilm/update-lifecycle-policy.asciidoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ PUT _ilm/policy/my_policy
8787
//////////
8888
[source,js]
8989
--------------------------------------------------
90-
GET _ilm/policy
90+
GET _ilm/policy/my_policy
9191
--------------------------------------------------
9292
// CONSOLE
9393
// TEST[continued]
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
package org.elasticsearch.xpack.core.indexlifecycle;
8+
9+
import org.elasticsearch.ElasticsearchParseException;
10+
import org.elasticsearch.common.bytes.BytesArray;
11+
import org.elasticsearch.common.bytes.BytesReference;
12+
import org.elasticsearch.common.compress.NotXContentException;
13+
import org.elasticsearch.common.io.Streams;
14+
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
15+
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
16+
import org.elasticsearch.common.xcontent.XContentHelper;
17+
import org.elasticsearch.common.xcontent.XContentParser;
18+
import org.elasticsearch.common.xcontent.XContentType;
19+
20+
import java.io.ByteArrayOutputStream;
21+
import java.io.IOException;
22+
import java.io.InputStream;
23+
24+
/**
25+
* A utility class used for loading index lifecycle policies from the resource classpath
26+
*/
27+
public class LifecyclePolicyUtils {
28+
29+
private LifecyclePolicyUtils() {};
30+
31+
/**
32+
* Loads a built-in index lifecycle policy and returns its source.
33+
*/
34+
public static LifecyclePolicy loadPolicy(String name, String resource, NamedXContentRegistry xContentRegistry) {
35+
try {
36+
BytesReference source = load(resource);
37+
validate(source);
38+
39+
try (XContentParser parser = XContentType.JSON.xContent()
40+
.createParser(xContentRegistry, LoggingDeprecationHandler.THROW_UNSUPPORTED_OPERATION, source.utf8ToString())) {
41+
return LifecyclePolicy.parse(parser, name);
42+
}
43+
} catch (Exception e) {
44+
throw new IllegalArgumentException("unable to load policy [" + name + "] from [" + resource + "]", e);
45+
}
46+
}
47+
48+
/**
49+
* Loads a resource from the classpath and returns it as a {@link BytesReference}
50+
*/
51+
private static BytesReference load(String name) throws IOException {
52+
try (InputStream is = LifecyclePolicyUtils.class.getResourceAsStream(name)) {
53+
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
54+
Streams.copy(is, out);
55+
return new BytesArray(out.toByteArray());
56+
}
57+
}
58+
}
59+
60+
/**
61+
* Parses and validates that the source is not empty.
62+
*/
63+
private static void validate(BytesReference source) {
64+
if (source == null) {
65+
throw new ElasticsearchParseException("policy must not be null");
66+
}
67+
68+
try {
69+
XContentHelper.convertToMap(source, false, XContentType.JSON).v2();
70+
} catch (NotXContentException e) {
71+
throw new ElasticsearchParseException("policy must not be empty");
72+
} catch (Exception e) {
73+
throw new ElasticsearchParseException("invalid policy", e);
74+
}
75+
}
76+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"phases": {
3+
"delete": {
4+
"min_age": "7d",
5+
"actions": {
6+
"delete": {}
7+
}
8+
}
9+
}
10+
}

x-pack/plugin/core/src/main/resources/watch-history.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"index.number_of_shards": 1,
66
"index.number_of_replicas": 0,
77
"index.auto_expand_replicas": "0-1",
8+
"index.lifecycle.name": "watch-history-ilm-policy",
89
"index.format": 6
910
},
1011
"mappings": {

x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/indexlifecycle/action/RestPutLifecycleAction.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,12 @@ public String getName() {
3232
@Override
3333
protected RestChannelConsumer prepareRequest(RestRequest restRequest, NodeClient client) throws IOException {
3434
String lifecycleName = restRequest.param("name");
35-
XContentParser parser = restRequest.contentParser();
36-
PutLifecycleAction.Request putLifecycleRequest = PutLifecycleAction.Request.parseRequest(lifecycleName, parser);
37-
putLifecycleRequest.timeout(restRequest.paramAsTime("timeout", putLifecycleRequest.timeout()));
38-
putLifecycleRequest.masterNodeTimeout(restRequest.paramAsTime("master_timeout", putLifecycleRequest.masterNodeTimeout()));
35+
try (XContentParser parser = restRequest.contentParser()) {
36+
PutLifecycleAction.Request putLifecycleRequest = PutLifecycleAction.Request.parseRequest(lifecycleName, parser);
37+
putLifecycleRequest.timeout(restRequest.paramAsTime("timeout", putLifecycleRequest.timeout()));
38+
putLifecycleRequest.masterNodeTimeout(restRequest.paramAsTime("master_timeout", putLifecycleRequest.masterNodeTimeout()));
3939

40-
return channel -> client.execute(PutLifecycleAction.INSTANCE, putLifecycleRequest, new RestToXContentListener<>(channel));
40+
return channel -> client.execute(PutLifecycleAction.INSTANCE, putLifecycleRequest, new RestToXContentListener<>(channel));
41+
}
4142
}
4243
}

x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/indexlifecycle/action/TransportPutLifecycleAction.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,12 @@ public ClusterState execute(ClusterState currentState) throws Exception {
8787
SortedMap<String, LifecyclePolicyMetadata> newPolicies = new TreeMap<>(currentMetadata.getPolicyMetadatas());
8888
LifecyclePolicyMetadata lifecyclePolicyMetadata = new LifecyclePolicyMetadata(request.getPolicy(), filteredHeaders,
8989
nextVersion, Instant.now().toEpochMilli());
90-
newPolicies.put(lifecyclePolicyMetadata.getName(), lifecyclePolicyMetadata);
90+
LifecyclePolicyMetadata oldPolicy = newPolicies.put(lifecyclePolicyMetadata.getName(), lifecyclePolicyMetadata);
91+
if (oldPolicy == null) {
92+
logger.info("adding index lifecycle policy [{}]", request.getPolicy().getName());
93+
} else {
94+
logger.info("updating index lifecycle policy [{}]", request.getPolicy().getName());
95+
}
9196
IndexLifecycleMetadata newMetadata = new IndexLifecycleMetadata(newPolicies, OperationMode.RUNNING);
9297
newState.metaData(MetaData.builder(currentState.getMetaData())
9398
.putCustom(IndexLifecycleMetadata.TYPE, newMetadata).build());

x-pack/plugin/ml/qa/native-multi-node-tests/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ integTestCluster {
3636
dependsOn copyKeyCerts
3737
setting 'xpack.security.enabled', 'true'
3838
setting 'xpack.ml.enabled', 'true'
39+
setting 'xpack.watcher.enabled', 'false'
3940
setting 'logger.org.elasticsearch.xpack.ml.datafeed', 'TRACE'
4041
setting 'xpack.monitoring.enabled', 'false'
4142
setting 'xpack.security.authc.token.enabled', 'true'

x-pack/plugin/watcher/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ dependencies {
3131
compileOnly project(path: ':plugins:transport-nio', configuration: 'runtime')
3232

3333
testCompile project(path: xpackModule('core'), configuration: 'testArtifacts')
34+
testCompile "org.elasticsearch.plugin:x-pack-ilm:${version}"
3435

3536
// watcher deps
3637
compile 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:r239'

x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ public Collection<Object> createComponents(Client client, ClusterService cluster
270270
throw new UncheckedIOException(e);
271271
}
272272

273-
new WatcherIndexTemplateRegistry(clusterService, threadPool, client);
273+
new WatcherIndexTemplateRegistry(clusterService, threadPool, client, xContentRegistry);
274274

275275
// http client
276276
httpClient = new HttpClient(settings, getSslService(), cryptoService, clusterService);

0 commit comments

Comments
 (0)