Skip to content

Commit a6bb033

Browse files
committed
copy LifecyclePolicy to protocol.xpack
This is the final PR for copying over the necessary components for clients to parse/render LifecyclePolicy. Changes include: - move of named-x-content server objects away from client - move validation into the client copy of LifecyclePolicy - move LifecycleAction into an interface with `getName`
1 parent 6281982 commit a6bb033

File tree

18 files changed

+700
-30
lines changed

18 files changed

+700
-30
lines changed

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

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -440,20 +440,7 @@ public List<NamedXContentRegistry.Entry> getNamedXContent() {
440440
RollupJobStatus::fromXContent),
441441
new NamedXContentRegistry.Entry(PersistentTaskState.class, new ParseField(RollupJobStatus.NAME),
442442
RollupJobStatus::fromXContent),
443-
// ILM - Custom Metadata
444-
new NamedXContentRegistry.Entry(MetaData.Custom.class, new ParseField(IndexLifecycleMetadata.TYPE),
445-
parser -> IndexLifecycleMetadata.PARSER.parse(parser, null)),
446-
// ILM - Lifecycle Types
447-
new NamedXContentRegistry.Entry(LifecycleType.class, new ParseField(TimeseriesLifecycleType.TYPE),
448-
(p, c) -> TimeseriesLifecycleType.INSTANCE),
449-
// ILM - Lifecycle Actions
450-
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(AllocateAction.NAME), AllocateAction::parse),
451-
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ForceMergeAction.NAME), ForceMergeAction::parse),
452-
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ReadOnlyAction.NAME), ReadOnlyAction::parse),
453-
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(RolloverAction.NAME), RolloverAction::parse),
454-
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse),
455-
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(DeleteAction.NAME), DeleteAction::parse),
456-
// ILM - Client - Lifecycle Actions
443+
// ILM
457444
new NamedXContentRegistry.Entry(org.elasticsearch.protocol.xpack.indexlifecycle.LifecycleAction.class,
458445
new ParseField(org.elasticsearch.protocol.xpack.indexlifecycle.AllocateAction.NAME),
459446
org.elasticsearch.protocol.xpack.indexlifecycle.AllocateAction::parse),

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,9 @@
3434
/**
3535
* Represents the lifecycle of an index from creation to deletion. A
3636
* {@link LifecyclePolicy} is made up of a set of {@link Phase}s which it will
37-
* move through. Soon we will constrain the phases using some kinda of lifecycle
38-
* type which will allow only particular {@link Phase}s to be defined, will
39-
* dictate the order in which the {@link Phase}s are executed and will define
40-
* which {@link LifecycleAction}s are allowed in each phase.
37+
* move through. Policies are constrained by a {@link LifecycleType} which governs which
38+
* {@link Phase}s and {@link LifecycleAction}s are allowed to be defined and in which order
39+
* they are executed.
4140
*/
4241
public class LifecyclePolicy extends AbstractDiffable<LifecyclePolicy>
4342
implements ToXContentObject, Diffable<LifecyclePolicy> {
@@ -58,9 +57,9 @@ public class LifecyclePolicy extends AbstractDiffable<LifecyclePolicy>
5857
}, PHASES_FIELD);
5958
}
6059

61-
protected final String name;
62-
protected final LifecycleType type;
63-
protected final Map<String, Phase> phases;
60+
private final String name;
61+
private final LifecycleType type;
62+
private final Map<String, Phase> phases;
6463

6564
/**
6665
* @param name
@@ -97,6 +96,7 @@ public LifecyclePolicy(StreamInput in) throws IOException {
9796
this.type = type;
9897
this.type.validate(phases.values());
9998
}
99+
100100
public static LifecyclePolicy parse(XContentParser parser, String name) {
101101
return PARSER.apply(parser, name);
102102
}

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

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
import org.elasticsearch.action.ActionResponse;
1111
import org.elasticsearch.client.Client;
1212
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
13+
import org.elasticsearch.cluster.metadata.MetaData;
1314
import org.elasticsearch.cluster.node.DiscoveryNodes;
1415
import org.elasticsearch.cluster.service.ClusterService;
16+
import org.elasticsearch.common.ParseField;
1517
import org.elasticsearch.common.inject.Module;
1618
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
1719
import org.elasticsearch.common.io.stream.NamedWriteableRegistry.Entry;
@@ -32,8 +34,17 @@
3234
import org.elasticsearch.watcher.ResourceWatcherService;
3335
import org.elasticsearch.xpack.core.XPackPlugin;
3436
import org.elasticsearch.xpack.core.XPackSettings;
37+
import org.elasticsearch.xpack.core.indexlifecycle.AllocateAction;
38+
import org.elasticsearch.xpack.core.indexlifecycle.DeleteAction;
39+
import org.elasticsearch.xpack.core.indexlifecycle.ForceMergeAction;
40+
import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleMetadata;
41+
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleAction;
3542
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleSettings;
43+
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleType;
44+
import org.elasticsearch.xpack.core.indexlifecycle.ReadOnlyAction;
3645
import org.elasticsearch.xpack.core.indexlifecycle.RolloverAction;
46+
import org.elasticsearch.xpack.core.indexlifecycle.ShrinkAction;
47+
import org.elasticsearch.xpack.core.indexlifecycle.TimeseriesLifecycleType;
3748
import org.elasticsearch.xpack.core.indexlifecycle.action.DeleteLifecycleAction;
3849
import org.elasticsearch.xpack.core.indexlifecycle.action.ExplainLifecycleAction;
3950
import org.elasticsearch.xpack.core.indexlifecycle.action.GetLifecycleAction;
@@ -146,7 +157,21 @@ public List<Entry> getNamedWriteables() {
146157

147158
@Override
148159
public List<org.elasticsearch.common.xcontent.NamedXContentRegistry.Entry> getNamedXContent() {
149-
return Arrays.asList();
160+
return Arrays.asList(
161+
// Custom Metadata
162+
new NamedXContentRegistry.Entry(MetaData.Custom.class, new ParseField(IndexLifecycleMetadata.TYPE),
163+
parser -> IndexLifecycleMetadata.PARSER.parse(parser, null)),
164+
// Lifecycle Types
165+
new NamedXContentRegistry.Entry(LifecycleType.class, new ParseField(TimeseriesLifecycleType.TYPE),
166+
(p, c) -> TimeseriesLifecycleType.INSTANCE),
167+
// Lifecycle Actions
168+
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(AllocateAction.NAME), AllocateAction::parse),
169+
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ForceMergeAction.NAME), ForceMergeAction::parse),
170+
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ReadOnlyAction.NAME), ReadOnlyAction::parse),
171+
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(RolloverAction.NAME), RolloverAction::parse),
172+
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse),
173+
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(DeleteAction.NAME), DeleteAction::parse)
174+
);
150175
}
151176

152177
@Override

x-pack/protocol/src/main/java/org/elasticsearch/protocol/xpack/indexlifecycle/AllocateAction.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
import java.util.Map;
3232
import java.util.Objects;
3333

34-
public class AllocateAction extends LifecycleAction implements ToXContentObject {
34+
public class AllocateAction implements LifecycleAction, ToXContentObject {
3535

3636
public static final String NAME = "allocate";
3737
static final ParseField NUMBER_OF_REPLICAS_FIELD = new ParseField("number_of_replicas");
@@ -102,6 +102,11 @@ public Map<String, String> getRequire() {
102102
return require;
103103
}
104104

105+
@Override
106+
public String getName() {
107+
return NAME;
108+
}
109+
105110
@Override
106111
public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException {
107112
builder.startObject();

x-pack/protocol/src/main/java/org/elasticsearch/protocol/xpack/indexlifecycle/DeleteAction.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
import java.io.IOException;
2929

30-
public class DeleteAction extends LifecycleAction implements ToXContentObject {
30+
public class DeleteAction implements LifecycleAction, ToXContentObject {
3131
public static final String NAME = "delete";
3232

3333
private static final ObjectParser<DeleteAction, Void> PARSER = new ObjectParser<>(NAME, DeleteAction::new);
@@ -46,6 +46,11 @@ public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params par
4646
return builder;
4747
}
4848

49+
@Override
50+
public String getName() {
51+
return NAME;
52+
}
53+
4954
@Override
5055
public int hashCode() {
5156
return 1;

x-pack/protocol/src/main/java/org/elasticsearch/protocol/xpack/indexlifecycle/ForceMergeAction.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import java.io.IOException;
2929
import java.util.Objects;
3030

31-
public class ForceMergeAction extends LifecycleAction implements ToXContentObject {
31+
public class ForceMergeAction implements LifecycleAction, ToXContentObject {
3232
public static final String NAME = "forcemerge";
3333
private static final ParseField MAX_NUM_SEGMENTS_FIELD = new ParseField("max_num_segments");
3434

@@ -60,6 +60,11 @@ public int getMaxNumSegments() {
6060
return maxNumSegments;
6161
}
6262

63+
@Override
64+
public String getName() {
65+
return NAME;
66+
}
67+
6368
@Override
6469
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
6570
builder.startObject();

x-pack/protocol/src/main/java/org/elasticsearch/protocol/xpack/indexlifecycle/LifecycleAction.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,12 @@
1919
package org.elasticsearch.protocol.xpack.indexlifecycle;
2020

2121
/**
22-
* Marker interface for index lifecycle management actions
22+
* interface for index lifecycle management actions
2323
*/
24-
public class LifecycleAction {
24+
public interface LifecycleAction {
25+
26+
/**
27+
* @return the name of this action
28+
*/
29+
String getName();
2530
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.elasticsearch.protocol.xpack.indexlifecycle;
20+
21+
import org.elasticsearch.common.ParseField;
22+
import org.elasticsearch.common.Strings;
23+
import org.elasticsearch.common.util.set.Sets;
24+
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
25+
import org.elasticsearch.common.xcontent.ToXContentObject;
26+
import org.elasticsearch.common.xcontent.XContentBuilder;
27+
import org.elasticsearch.common.xcontent.XContentParser;
28+
29+
import java.io.IOException;
30+
import java.util.Collection;
31+
import java.util.HashMap;
32+
import java.util.List;
33+
import java.util.Map;
34+
import java.util.Objects;
35+
import java.util.Set;
36+
import java.util.function.Function;
37+
import java.util.stream.Collectors;
38+
39+
/**
40+
* Represents the lifecycle of an index from creation to deletion. A
41+
* {@link LifecyclePolicy} is made up of a set of {@link Phase}s which it will
42+
* move through.
43+
*/
44+
public class LifecyclePolicy implements ToXContentObject {
45+
static final ParseField PHASES_FIELD = new ParseField("phases");
46+
47+
@SuppressWarnings("unchecked")
48+
public static ConstructingObjectParser<LifecyclePolicy, String> PARSER = new ConstructingObjectParser<>("lifecycle_policy", false,
49+
(a, name) -> {
50+
List<Phase> phases = (List<Phase>) a[0];
51+
Map<String, Phase> phaseMap = phases.stream().collect(Collectors.toMap(Phase::getName, Function.identity()));
52+
return new LifecyclePolicy(name, phaseMap);
53+
});
54+
static {
55+
PARSER.declareNamedObjects(ConstructingObjectParser.constructorArg(), (p, c, n) -> Phase.parse(p, n), v -> {
56+
throw new IllegalArgumentException("ordered " + PHASES_FIELD.getPreferredName() + " are not supported");
57+
}, PHASES_FIELD);
58+
}
59+
60+
private final String name;
61+
private final Map<String, Phase> phases;
62+
63+
/**
64+
* @param name
65+
* the name of this {@link LifecyclePolicy}
66+
* @param phases
67+
* a {@link Map} of {@link Phase}s which make up this
68+
* {@link LifecyclePolicy}.
69+
*/
70+
public LifecyclePolicy(String name, Map<String, Phase> phases) {
71+
this.name = name;
72+
this.phases = phases;
73+
validate(phases.values());
74+
}
75+
76+
public static LifecyclePolicy parse(XContentParser parser, String name) {
77+
return PARSER.apply(parser, name);
78+
}
79+
80+
/**
81+
* @return the name of this {@link LifecyclePolicy}
82+
*/
83+
public String getName() {
84+
return name;
85+
}
86+
87+
/**
88+
* @return the {@link Phase}s for this {@link LifecyclePolicy} in the order
89+
* in which they will be executed.
90+
*/
91+
public Map<String, Phase> getPhases() {
92+
return phases;
93+
}
94+
95+
@Override
96+
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
97+
builder.startObject();
98+
builder.startObject(PHASES_FIELD.getPreferredName());
99+
for (Phase phase : phases.values()) {
100+
builder.field(phase.getName(), phase);
101+
}
102+
builder.endObject();
103+
builder.endObject();
104+
return builder;
105+
}
106+
107+
@Override
108+
public int hashCode() {
109+
return Objects.hash(name, phases);
110+
}
111+
112+
@Override
113+
public boolean equals(Object obj) {
114+
if (obj == null) {
115+
return false;
116+
}
117+
if (obj.getClass() != getClass()) {
118+
return false;
119+
}
120+
LifecyclePolicy other = (LifecyclePolicy) obj;
121+
return Objects.equals(name, other.name) &&
122+
Objects.equals(phases, other.phases);
123+
}
124+
125+
@Override
126+
public String toString() {
127+
return Strings.toString(this, true, true);
128+
}
129+
130+
static void validate(Collection<Phase> phases) {
131+
Set<String> allowedPhases = Sets.newHashSet("hot", "warm", "cold", "delete");
132+
Map<String, Set<String>> allowedActions = new HashMap<>(allowedPhases.size());
133+
allowedActions.put("hot", Sets.newHashSet(RolloverAction.NAME));
134+
allowedActions.put("warm", Sets.newHashSet(AllocateAction.NAME, ForceMergeAction.NAME, ReadOnlyAction.NAME, ShrinkAction.NAME));
135+
allowedActions.put("cold", Sets.newHashSet(AllocateAction.NAME));
136+
allowedActions.put("delete", Sets.newHashSet(DeleteAction.NAME));
137+
phases.forEach(phase -> {
138+
if (allowedPhases.contains(phase.getName()) == false) {
139+
throw new IllegalArgumentException("Lifecycle does not support phase [" + phase.getName() + "]");
140+
}
141+
phase.getActions().forEach((actionName, action) -> {
142+
if (allowedActions.get(phase.getName()).contains(actionName) == false) {
143+
throw new IllegalArgumentException("invalid action [" + actionName + "] " +
144+
"defined in phase [" + phase.getName() +"]");
145+
}
146+
});
147+
});
148+
}
149+
}

0 commit comments

Comments
 (0)