Skip to content

Commit 20ea956

Browse files
committed
Adds a new Rollup V2 Action
This commit adds a new endpoint for Rollup V2, a new way to rollup indices. Instead of relying on a cron-job, this action will rollup a whole index on the spot. When an index is rolled up using a Rollup Config, it does the following 1. check that original index is read-only 2. runs an aggregation and indexes results into a temporary hidden rollup index 3. "resizes" the temporary index into the final rollup-index (in-place segment pointer juggling) 4. adds RollupMetadata about the rollup-group (keyed by original index name) and adds custom index-metadata with data about what the rollup index's original index is so that its group information in RollupMetadata can be looked up example usage: ``` POST /_rollup_vtwo/index { "rollup_index": "index_rolled", "groups": { "date_histogram": { "field": "date", "calendar_interval": "1M" }, "terms": { "fields": ["unit"] } }, "metrics": [ { "field": "temperature", "metrics": ["sum"] } ] } ```
1 parent 7369b15 commit 20ea956

File tree

19 files changed

+1519
-162
lines changed

19 files changed

+1519
-162
lines changed

server/src/main/java/org/elasticsearch/cluster/ClusterModule.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
package org.elasticsearch.cluster;
2121

22+
import org.elasticsearch.Build;
2223
import org.elasticsearch.cluster.action.index.MappingUpdatedAction;
2324
import org.elasticsearch.cluster.action.index.NodeMappingRefreshAction;
2425
import org.elasticsearch.cluster.action.shard.ShardStateAction;
@@ -143,7 +144,8 @@ public static List<Entry> getNamedWriteables() {
143144
ComposableIndexTemplateMetadata::readDiffFrom);
144145
registerMetadataCustom(entries, DataStreamMetadata.TYPE, DataStreamMetadata::new, DataStreamMetadata::readDiffFrom);
145146

146-
if (RollupV2.ROLLUPV2_FEATURE_FLAG_REGISTERED != null && RollupV2.ROLLUPV2_FEATURE_FLAG_REGISTERED) {
147+
if (Build.CURRENT.isSnapshot() ||
148+
(RollupV2.ROLLUPV2_FEATURE_FLAG_REGISTERED != null && RollupV2.ROLLUPV2_FEATURE_FLAG_REGISTERED)) {
147149
registerMetadataCustom(entries, RollupMetadata.TYPE, RollupMetadata::new, RollupMetadata::readDiffFrom);
148150
}
149151
// Task Status (not Diffable)
@@ -170,7 +172,8 @@ public static List<NamedXContentRegistry.Entry> getNamedXWriteables() {
170172
ComposableIndexTemplateMetadata::fromXContent));
171173
entries.add(new NamedXContentRegistry.Entry(Metadata.Custom.class, new ParseField(DataStreamMetadata.TYPE),
172174
DataStreamMetadata::fromXContent));
173-
if (RollupV2.ROLLUPV2_FEATURE_FLAG_REGISTERED != null && RollupV2.ROLLUPV2_FEATURE_FLAG_REGISTERED) {
175+
if (Build.CURRENT.isSnapshot() ||
176+
(RollupV2.ROLLUPV2_FEATURE_FLAG_REGISTERED != null && RollupV2.ROLLUPV2_FEATURE_FLAG_REGISTERED)) {
174177
entries.add(new NamedXContentRegistry.Entry(Metadata.Custom.class, new ParseField(RollupMetadata.TYPE),
175178
RollupMetadata::fromXContent));
176179
}

server/src/main/java/org/elasticsearch/rollup/RollupV2.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public class RollupV2 {
2929
if (Build.CURRENT.isSnapshot() && property != null) {
3030
throw new IllegalArgumentException("es.rollupv2_feature_flag_registered is only supported in non-snapshot builds");
3131
}
32+
3233
if ("true".equals(property)) {
3334
ROLLUPV2_FEATURE_FLAG_REGISTERED = true;
3435
} else if ("false".equals(property)) {

server/src/main/java/org/elasticsearch/tasks/Task.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ public String getHeader(String header) {
185185
return headers.get(header);
186186
}
187187

188+
public Map<String, String> headers() {
189+
return headers;
190+
}
191+
188192
public TaskResult result(DiscoveryNode node, Exception error) throws IOException {
189193
return new TaskResult(taskInfo(node.getId(), true), error);
190194
}

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClientPlugin.java

Lines changed: 160 additions & 152 deletions
Large diffs are not rendered by default.

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/rollup/job/MetricConfig.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ public class MetricConfig implements Writeable, ToXContentObject {
5050
public static final ParseField SUM = new ParseField("sum");
5151
public static final ParseField AVG = new ParseField("avg");
5252
public static final ParseField VALUE_COUNT = new ParseField("value_count");
53+
public static final String NAME = "metrics";
5354

54-
static final String NAME = "metrics";
5555
private static final String FIELD = "field";
5656
private static final String METRICS = "metrics";
5757
private static final ConstructingObjectParser<MetricConfig, Void> PARSER;
@@ -84,7 +84,7 @@ public MetricConfig(final String field, final List<String> metrics) {
8484
this.metrics = metrics;
8585
}
8686

87-
MetricConfig(final StreamInput in) throws IOException {
87+
public MetricConfig(final StreamInput in) throws IOException {
8888
field = in.readString();
8989
metrics = in.readStringList();
9090
}
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
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+
package org.elasticsearch.xpack.core.rollup.v2;
7+
8+
9+
import org.elasticsearch.action.ActionRequest;
10+
import org.elasticsearch.action.ActionRequestBuilder;
11+
import org.elasticsearch.action.ActionRequestValidationException;
12+
import org.elasticsearch.action.ActionResponse;
13+
import org.elasticsearch.action.ActionType;
14+
import org.elasticsearch.client.ElasticsearchClient;
15+
import org.elasticsearch.common.io.stream.StreamInput;
16+
import org.elasticsearch.common.io.stream.StreamOutput;
17+
import org.elasticsearch.common.io.stream.Writeable;
18+
import org.elasticsearch.common.xcontent.ToXContentObject;
19+
import org.elasticsearch.common.xcontent.XContentBuilder;
20+
import org.elasticsearch.tasks.Task;
21+
import org.elasticsearch.tasks.TaskId;
22+
23+
import java.io.IOException;
24+
import java.util.Map;
25+
import java.util.Objects;
26+
27+
public class RollupV2Action extends ActionType<RollupV2Action.Response> {
28+
29+
public static final RollupV2Action INSTANCE = new RollupV2Action();
30+
public static final String NAME = "cluster:admin/xpack/rollupV2";
31+
32+
private RollupV2Action() {
33+
super(NAME, RollupV2Action.Response::new);
34+
}
35+
36+
public static class Request extends ActionRequest implements ToXContentObject {
37+
private RollupV2Config rollupConfig;
38+
39+
public Request(RollupV2Config rollupConfig) {
40+
this.rollupConfig = rollupConfig;
41+
}
42+
43+
public Request() {}
44+
45+
public Request(StreamInput in) throws IOException {
46+
super(in);
47+
rollupConfig = new RollupV2Config(in);
48+
}
49+
50+
@Override
51+
public Task createTask(long id, String type, String action, TaskId parentTaskId, Map<String, String> headers) {
52+
return new RollupV2Task(id, type, action, parentTaskId, rollupConfig, headers);
53+
}
54+
55+
@Override
56+
public void writeTo(StreamOutput out) throws IOException {
57+
super.writeTo(out);
58+
rollupConfig.writeTo(out);
59+
}
60+
61+
public RollupV2Config getRollupConfig() {
62+
return rollupConfig;
63+
}
64+
65+
@Override
66+
public ActionRequestValidationException validate() {
67+
return null;
68+
}
69+
70+
@Override
71+
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
72+
builder.startObject();
73+
rollupConfig.toXContent(builder, params);
74+
builder.endObject();
75+
return builder;
76+
}
77+
78+
@Override
79+
public int hashCode() {
80+
return Objects.hash(rollupConfig);
81+
}
82+
83+
@Override
84+
public boolean equals(Object obj) {
85+
if (obj == null) {
86+
return false;
87+
}
88+
if (getClass() != obj.getClass()) {
89+
return false;
90+
}
91+
Request other = (Request) obj;
92+
return Objects.equals(rollupConfig, other.rollupConfig);
93+
}
94+
}
95+
96+
public static class RequestBuilder extends ActionRequestBuilder<Request, Response> {
97+
98+
protected RequestBuilder(ElasticsearchClient client, RollupV2Action action) {
99+
super(client, action, new Request());
100+
}
101+
}
102+
103+
public static class Response extends ActionResponse implements Writeable, ToXContentObject {
104+
105+
private final boolean created;
106+
107+
public Response(boolean created) {
108+
this.created = created;
109+
}
110+
111+
public Response(StreamInput in) throws IOException {
112+
super(in);
113+
created = in.readBoolean();
114+
}
115+
116+
@Override
117+
public void writeTo(StreamOutput out) throws IOException {
118+
out.writeBoolean(created);
119+
}
120+
121+
public boolean isCreated() {
122+
return created;
123+
}
124+
125+
@Override
126+
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
127+
builder.startObject();
128+
builder.field("created", created);
129+
builder.endObject();
130+
return builder;
131+
}
132+
133+
@Override
134+
public boolean equals(Object o) {
135+
if (this == o) return true;
136+
if (o == null || getClass() != o.getClass()) return false;
137+
Response response = (Response) o;
138+
return created == response.created;
139+
}
140+
141+
@Override
142+
public int hashCode() {
143+
return Objects.hash(created);
144+
}
145+
}
146+
}

0 commit comments

Comments
 (0)