Skip to content

Commit 1d1abe0

Browse files
masseykejoegallo
authored andcommitted
Adding rest actions to get and set data stream settings (#127858)
1 parent a5f30f2 commit 1d1abe0

File tree

10 files changed

+412
-1
lines changed

10 files changed

+412
-1
lines changed

modules/data-streams/src/main/java/org/elasticsearch/datastreams/DataStreamFeatures.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ public class DataStreamFeatures implements FeatureSpecification {
3333
"data_stream.downsample.default_aggregate_metric_fix"
3434
);
3535

36+
public static final NodeFeature LOGS_STREAM_FEATURE = new NodeFeature("logs_stream");
37+
3638
@Override
3739
public Map<NodeFeature, Version> getHistoricalFeatures() {
3840
return Map.of(DATA_STREAM_LIFECYCLE, Version.V_8_11_0);
@@ -51,6 +53,6 @@ public Set<NodeFeature> getFeatures() {
5153

5254
@Override
5355
public Set<NodeFeature> getTestFeatures() {
54-
return Set.of(DATA_STREAM_FAILURE_STORE_TSDB_FIX, DOWNSAMPLE_AGGREGATE_DEFAULT_METRIC_FIX);
56+
return Set.of(DATA_STREAM_FAILURE_STORE_TSDB_FIX, DOWNSAMPLE_AGGREGATE_DEFAULT_METRIC_FIX, LOGS_STREAM_FEATURE);
5557
}
5658
}

modules/data-streams/src/main/java/org/elasticsearch/datastreams/DataStreamsPlugin.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.elasticsearch.action.datastreams.lifecycle.GetDataStreamLifecycleAction;
2727
import org.elasticsearch.action.datastreams.lifecycle.PutDataStreamLifecycleAction;
2828
import org.elasticsearch.client.internal.OriginSettingClient;
29+
import org.elasticsearch.cluster.metadata.DataStream;
2930
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
3031
import org.elasticsearch.cluster.node.DiscoveryNodes;
3132
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
@@ -72,10 +73,12 @@
7273
import org.elasticsearch.datastreams.rest.RestCreateDataStreamAction;
7374
import org.elasticsearch.datastreams.rest.RestDataStreamsStatsAction;
7475
import org.elasticsearch.datastreams.rest.RestDeleteDataStreamAction;
76+
import org.elasticsearch.datastreams.rest.RestGetDataStreamSettingsAction;
7577
import org.elasticsearch.datastreams.rest.RestGetDataStreamsAction;
7678
import org.elasticsearch.datastreams.rest.RestMigrateToDataStreamAction;
7779
import org.elasticsearch.datastreams.rest.RestModifyDataStreamsAction;
7880
import org.elasticsearch.datastreams.rest.RestPromoteDataStreamAction;
81+
import org.elasticsearch.datastreams.rest.RestUpdateDataStreamSettingsAction;
7982
import org.elasticsearch.features.NodeFeature;
8083
import org.elasticsearch.health.HealthIndicatorService;
8184
import org.elasticsearch.index.IndexSettingProvider;
@@ -282,6 +285,10 @@ public List<RestHandler> getRestHandlers(
282285
handlers.add(new RestGetDataStreamOptionsAction());
283286
handlers.add(new RestPutDataStreamOptionsAction());
284287
handlers.add(new RestDeleteDataStreamOptionsAction());
288+
if (DataStream.LOGS_STREAM_FEATURE_FLAG) {
289+
handlers.add(new RestGetDataStreamSettingsAction());
290+
handlers.add(new RestUpdateDataStreamSettingsAction());
291+
}
285292
return handlers;
286293
}
287294

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.datastreams.rest;
11+
12+
import org.elasticsearch.action.datastreams.GetDataStreamSettingsAction;
13+
import org.elasticsearch.client.internal.node.NodeClient;
14+
import org.elasticsearch.common.Strings;
15+
import org.elasticsearch.rest.BaseRestHandler;
16+
import org.elasticsearch.rest.RestRequest;
17+
import org.elasticsearch.rest.RestUtils;
18+
import org.elasticsearch.rest.Scope;
19+
import org.elasticsearch.rest.ServerlessScope;
20+
import org.elasticsearch.rest.action.RestCancellableNodeClient;
21+
import org.elasticsearch.rest.action.RestRefCountedChunkedToXContentListener;
22+
23+
import java.io.IOException;
24+
import java.util.List;
25+
26+
import static org.elasticsearch.rest.RestRequest.Method.GET;
27+
28+
@ServerlessScope(Scope.PUBLIC)
29+
public class RestGetDataStreamSettingsAction extends BaseRestHandler {
30+
@Override
31+
public String getName() {
32+
return "get_data_stream_settings_action";
33+
}
34+
35+
@Override
36+
public List<Route> routes() {
37+
return List.of(new Route(GET, "/_data_stream/{name}/_settings"));
38+
}
39+
40+
@Override
41+
protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
42+
GetDataStreamSettingsAction.Request getDataStreamRequest = new GetDataStreamSettingsAction.Request(
43+
RestUtils.getMasterNodeTimeout(request)
44+
).indices(Strings.splitStringByCommaToArray(request.param("name")));
45+
return channel -> new RestCancellableNodeClient(client, request.getHttpChannel()).execute(
46+
GetDataStreamSettingsAction.INSTANCE,
47+
getDataStreamRequest,
48+
new RestRefCountedChunkedToXContentListener<>(channel)
49+
);
50+
}
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
package org.elasticsearch.datastreams.rest;
10+
11+
import org.elasticsearch.action.datastreams.UpdateDataStreamSettingsAction;
12+
import org.elasticsearch.client.internal.node.NodeClient;
13+
import org.elasticsearch.common.Strings;
14+
import org.elasticsearch.common.settings.Settings;
15+
import org.elasticsearch.rest.BaseRestHandler;
16+
import org.elasticsearch.rest.RestRequest;
17+
import org.elasticsearch.rest.RestUtils;
18+
import org.elasticsearch.rest.Scope;
19+
import org.elasticsearch.rest.ServerlessScope;
20+
import org.elasticsearch.rest.action.RestCancellableNodeClient;
21+
import org.elasticsearch.rest.action.RestRefCountedChunkedToXContentListener;
22+
import org.elasticsearch.xcontent.XContentParser;
23+
24+
import java.io.IOException;
25+
import java.util.List;
26+
27+
import static org.elasticsearch.rest.RestRequest.Method.PUT;
28+
29+
@ServerlessScope(Scope.PUBLIC)
30+
public class RestUpdateDataStreamSettingsAction extends BaseRestHandler {
31+
32+
@Override
33+
public String getName() {
34+
return "update_data_stream_settings_action";
35+
}
36+
37+
@Override
38+
public List<Route> routes() {
39+
return List.of(new Route(PUT, "/_data_stream/{name}/_settings"));
40+
}
41+
42+
@Override
43+
protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
44+
Settings settings;
45+
try (XContentParser parser = request.contentParser()) {
46+
settings = Settings.fromXContent(parser);
47+
}
48+
UpdateDataStreamSettingsAction.Request putDataStreamRequest = new UpdateDataStreamSettingsAction.Request(
49+
settings,
50+
RestUtils.getMasterNodeTimeout(request),
51+
RestUtils.getAckTimeout(request)
52+
).indices(Strings.splitStringByCommaToArray(request.param("name")));
53+
return channel -> new RestCancellableNodeClient(client, request.getHttpChannel()).execute(
54+
UpdateDataStreamSettingsAction.INSTANCE,
55+
putDataStreamRequest,
56+
new RestRefCountedChunkedToXContentListener<>(channel)
57+
);
58+
}
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
setup:
2+
- skip:
3+
features: allowed_warnings
4+
5+
---
6+
"Test single data stream":
7+
- requires:
8+
cluster_features: [ "logs_stream" ]
9+
reason: requires setting 'logs_stream' to get or set data stream settings
10+
- do:
11+
allowed_warnings:
12+
- "index template [my-template] has index patterns [my-data-stream-*] matching patterns from existing older templates [global] with patterns (global => [*]); this template [my-template] will take precedence during new index creation"
13+
indices.put_index_template:
14+
name: my-template
15+
body:
16+
index_patterns: [ my-data-stream-* ]
17+
data_stream: { }
18+
template:
19+
settings:
20+
number_of_replicas: 0
21+
lifecycle.name: my-policy
22+
23+
- do:
24+
indices.create_data_stream:
25+
name: my-data-stream-1
26+
27+
- do:
28+
cluster.health:
29+
index: "my-data-stream-1"
30+
wait_for_status: green
31+
32+
- do:
33+
indices.get_data_stream_settings:
34+
name: my-data-stream-1
35+
- match: { data_streams.0.name: my-data-stream-1 }
36+
- match: { data_streams.0.settings: {} }
37+
- match: { data_streams.0.effective_settings.index.number_of_shards: null }
38+
- match: { data_streams.0.effective_settings.index.number_of_replicas: "0" }
39+
- match: { data_streams.0.effective_settings.index.lifecycle.name: "my-policy" }
40+
41+
- do:
42+
indices.get_data_stream:
43+
name: my-data-stream-1
44+
- match: { data_streams.0.name: my-data-stream-1 }
45+
- match: { data_streams.0.settings: {} }
46+
- match: { data_streams.0.effective_settings: null }
47+
48+
- do:
49+
indices.put_data_stream_settings:
50+
name: my-data-stream-1
51+
body:
52+
index:
53+
number_of_shards: 2
54+
lifecycle.name: my-new-policy
55+
- match: { data_streams.0.name: my-data-stream-1 }
56+
- match: { data_streams.0.applied_to_data_stream: true }
57+
- match: { data_streams.0.index_settings_results.applied_to_data_stream_only: [index.number_of_shards]}
58+
- match: { data_streams.0.index_settings_results.applied_to_data_stream_and_backing_indices: [index.lifecycle.name] }
59+
- match: { data_streams.0.settings.index.number_of_shards: "2" }
60+
- match: { data_streams.0.settings.index.lifecycle.name: "my-new-policy" }
61+
- match: { data_streams.0.effective_settings.index.number_of_shards: "2" }
62+
- match: { data_streams.0.effective_settings.index.number_of_replicas: "0" }
63+
- match: { data_streams.0.effective_settings.index.lifecycle.name: "my-new-policy" }
64+
65+
- do:
66+
indices.rollover:
67+
alias: "my-data-stream-1"
68+
69+
- do:
70+
cluster.health:
71+
index: "my-data-stream-1"
72+
wait_for_status: green
73+
74+
- do:
75+
indices.get_data_stream_settings:
76+
name: my-data-stream-1
77+
- match: { data_streams.0.name: my-data-stream-1 }
78+
- match: { data_streams.0.settings.index.number_of_shards: "2" }
79+
- match: { data_streams.0.effective_settings.index.number_of_shards: "2" }
80+
- match: { data_streams.0.effective_settings.index.number_of_replicas: "0" }
81+
- match: { data_streams.0.effective_settings.index.lifecycle.name: "my-new-policy" }
82+
83+
- do:
84+
indices.get_data_stream:
85+
name: my-data-stream-1
86+
- match: { data_streams.0.name: my-data-stream-1 }
87+
- match: { data_streams.0.settings.index.number_of_shards: "2" }
88+
- match: { data_streams.0.settings.index.lifecycle.name: "my-new-policy" }
89+
- match: { data_streams.0.effective_settings: null }
90+
91+
- do:
92+
indices.get_data_stream:
93+
name: my-data-stream-1
94+
- set: { data_streams.0.indices.0.index_name: idx0name }
95+
- set: { data_streams.0.indices.1.index_name: idx1name }
96+
97+
- do:
98+
indices.get_settings:
99+
index: my-data-stream-1
100+
- match: { .$idx0name.settings.index.number_of_shards: "1" }
101+
- match: { .$idx0name.settings.index.lifecycle.name: "my-new-policy" }
102+
- match: { .$idx1name.settings.index.number_of_shards: "2" }
103+
- match: { .$idx1name.settings.index.lifecycle.name: "my-new-policy" }
104+
105+
---
106+
"Test multiple data streams":
107+
- requires:
108+
cluster_features: [ "logs_stream" ]
109+
reason: requires setting 'logs_stream' to get or set data stream settings
110+
- do:
111+
allowed_warnings:
112+
- "index template [my-template] has index patterns [my-data-stream-*] matching patterns from existing older templates [global] with patterns (global => [*]); this template [my-template] will take precedence during new index creation"
113+
indices.put_index_template:
114+
name: my-template
115+
body:
116+
index_patterns: [ my-data-stream-* ]
117+
data_stream: { }
118+
template:
119+
settings:
120+
number_of_replicas: 0
121+
lifecycle.name: my-policy
122+
123+
- do:
124+
indices.create_data_stream:
125+
name: my-data-stream-1
126+
127+
- do:
128+
indices.create_data_stream:
129+
name: my-data-stream-2
130+
131+
- do:
132+
indices.create_data_stream:
133+
name: my-data-stream-3
134+
135+
- do:
136+
cluster.health:
137+
index: "my-data-stream-1,my-data-stream-2,my-data-stream-3"
138+
wait_for_status: green
139+
140+
- do:
141+
indices.get_data_stream_settings:
142+
name: "*"
143+
- length: { data_streams: 3 }
144+
145+
- do:
146+
indices.get_data_stream_settings:
147+
name: "my-data-stream-1,my-data-stream-2"
148+
- length: { data_streams: 2 }
149+
150+
- do:
151+
indices.put_data_stream_settings:
152+
name: my-data-stream-1,my-data-stream-2
153+
body:
154+
index:
155+
number_of_shards: 2
156+
lifecycle.name: my-new-policy
157+
- length: { data_streams: 2 }
158+
159+
---
160+
"Test invalid settings":
161+
- requires:
162+
cluster_features: [ "logs_stream" ]
163+
reason: requires setting 'logs_stream' to get or set data stream settings
164+
- do:
165+
allowed_warnings:
166+
- "index template [my-template] has index patterns [my-data-stream-*] matching patterns from existing older templates [global] with patterns (global => [*]); this template [my-template] will take precedence during new index creation"
167+
indices.put_index_template:
168+
name: my-template
169+
body:
170+
index_patterns: [ my-data-stream-* ]
171+
data_stream: { }
172+
template:
173+
settings:
174+
number_of_replicas: 0
175+
lifecycle.name: my-policy
176+
177+
- do:
178+
indices.create_data_stream:
179+
name: my-data-stream-1
180+
181+
- do:
182+
cluster.health:
183+
index: "my-data-stream-1"
184+
wait_for_status: green
185+
186+
- do:
187+
indices.put_data_stream_settings:
188+
name: my-data-stream-1
189+
body:
190+
index:
191+
fake_setting: 1234
192+
- match: { data_streams.0.name: my-data-stream-1 }
193+
- match: { data_streams.0.applied_to_data_stream: false }
194+
- match: { data_streams.0.error: "Cannot set the following settings on a data stream: [index.fake_setting]" }
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"indices.get_data_stream_settings":{
3+
"documentation":{
4+
"url":"https://www.elastic.co/guide/en/elasticsearch/reference/master/data-streams.html",
5+
"description":"Gets a data stream's settings"
6+
},
7+
"stability":"stable",
8+
"visibility": "feature_flag",
9+
"feature_flag": "logs_stream",
10+
"headers":{
11+
"accept": [ "application/json"]
12+
},
13+
"url":{
14+
"paths":[
15+
{
16+
"path":"/_data_stream/{name}/_settings",
17+
"methods":[
18+
"GET"
19+
],
20+
"parts":{
21+
"name":{
22+
"type":"string",
23+
"description":"The name of the data stream or data stream pattern"
24+
}
25+
}
26+
}
27+
]
28+
},
29+
"params":{
30+
"timeout":{
31+
"type":"time",
32+
"description":"Specify timeout for acknowledging the cluster state update"
33+
},
34+
"master_timeout":{
35+
"type":"time",
36+
"description":"Specify timeout for connection to master"
37+
}
38+
}
39+
}
40+
}

0 commit comments

Comments
 (0)