mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-03-25 09:28:27 +00:00
Add set_priority action to ILM (#37397)
This commit adds a set_priority action to the hot, warm, and cold phases for an ILM policy. This action sets the `index.priority` on the managed index to allow different priorities between the hot, warm, and cold recoveries. This commit also includes the HLRC and documentation changes. closes #36905
This commit is contained in:
parent
20ed3dd1a8
commit
587034dfa7
@ -53,7 +53,10 @@ public class IndexLifecycleNamedXContentProvider implements NamedXContentProvide
|
||||
ShrinkAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class,
|
||||
new ParseField(FreezeAction.NAME),
|
||||
FreezeAction::parse)
|
||||
FreezeAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class,
|
||||
new ParseField(SetPriorityAction.NAME),
|
||||
SetPriorityAction::parse)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -57,9 +57,10 @@ public class LifecyclePolicy implements ToXContentObject {
|
||||
throw new IllegalArgumentException("ordered " + PHASES_FIELD.getPreferredName() + " are not supported");
|
||||
}, PHASES_FIELD);
|
||||
|
||||
ALLOWED_ACTIONS.put("hot", Sets.newHashSet(RolloverAction.NAME));
|
||||
ALLOWED_ACTIONS.put("warm", Sets.newHashSet(AllocateAction.NAME, ForceMergeAction.NAME, ReadOnlyAction.NAME, ShrinkAction.NAME));
|
||||
ALLOWED_ACTIONS.put("cold", Sets.newHashSet(AllocateAction.NAME, FreezeAction.NAME));
|
||||
ALLOWED_ACTIONS.put("hot", Sets.newHashSet(SetPriorityAction.NAME, RolloverAction.NAME));
|
||||
ALLOWED_ACTIONS.put("warm", Sets.newHashSet(SetPriorityAction.NAME, AllocateAction.NAME, ForceMergeAction.NAME,
|
||||
ReadOnlyAction.NAME, ShrinkAction.NAME));
|
||||
ALLOWED_ACTIONS.put("cold", Sets.newHashSet(SetPriorityAction.NAME, AllocateAction.NAME, FreezeAction.NAME));
|
||||
ALLOWED_ACTIONS.put("delete", Sets.newHashSet(DeleteAction.NAME));
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.elasticsearch.client.indexlifecycle;
|
||||
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A {@link LifecycleAction} which sets the index's priority. The higher the priority, the faster the recovery.
|
||||
*/
|
||||
public class SetPriorityAction implements LifecycleAction, ToXContentObject {
|
||||
public static final String NAME = "set_priority";
|
||||
private static final ParseField RECOVERY_PRIORITY_FIELD = new ParseField("priority");
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static final ConstructingObjectParser<SetPriorityAction, Void> PARSER = new ConstructingObjectParser<>(NAME, true,
|
||||
a -> new SetPriorityAction((Integer) a[0]));
|
||||
|
||||
//package private for testing
|
||||
final Integer recoveryPriority;
|
||||
|
||||
static {
|
||||
PARSER.declareField(ConstructingObjectParser.constructorArg(),
|
||||
(p) -> p.currentToken() == XContentParser.Token.VALUE_NULL ? null : p.intValue()
|
||||
, RECOVERY_PRIORITY_FIELD, ObjectParser.ValueType.INT_OR_NULL);
|
||||
}
|
||||
|
||||
public static SetPriorityAction parse(XContentParser parser) {
|
||||
return PARSER.apply(parser, null);
|
||||
}
|
||||
|
||||
public SetPriorityAction(@Nullable Integer recoveryPriority) {
|
||||
if (recoveryPriority != null && recoveryPriority <= 0) {
|
||||
throw new IllegalArgumentException("[" + RECOVERY_PRIORITY_FIELD.getPreferredName() + "] must be 0 or greater");
|
||||
}
|
||||
this.recoveryPriority = recoveryPriority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException {
|
||||
builder.startObject();
|
||||
builder.field(RECOVERY_PRIORITY_FIELD.getPreferredName(), recoveryPriority);
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
SetPriorityAction that = (SetPriorityAction) o;
|
||||
|
||||
return recoveryPriority != null ? recoveryPriority.equals(that.recoveryPriority) : that.recoveryPriority == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return recoveryPriority != null ? recoveryPriority.hashCode() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Strings.toString(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
}
|
@ -54,6 +54,7 @@ import org.elasticsearch.client.indexlifecycle.FreezeAction;
|
||||
import org.elasticsearch.client.indexlifecycle.LifecycleAction;
|
||||
import org.elasticsearch.client.indexlifecycle.ReadOnlyAction;
|
||||
import org.elasticsearch.client.indexlifecycle.RolloverAction;
|
||||
import org.elasticsearch.client.indexlifecycle.SetPriorityAction;
|
||||
import org.elasticsearch.client.indexlifecycle.ShrinkAction;
|
||||
import org.elasticsearch.cluster.ClusterName;
|
||||
import org.elasticsearch.common.CheckedFunction;
|
||||
@ -644,7 +645,7 @@ public class RestHighLevelClientTests extends ESTestCase {
|
||||
|
||||
public void testProvidedNamedXContents() {
|
||||
List<NamedXContentRegistry.Entry> namedXContents = RestHighLevelClient.getProvidedNamedXContents();
|
||||
assertEquals(18, namedXContents.size());
|
||||
assertEquals(19, namedXContents.size());
|
||||
Map<Class<?>, Integer> categories = new HashMap<>();
|
||||
List<String> names = new ArrayList<>();
|
||||
for (NamedXContentRegistry.Entry namedXContent : namedXContents) {
|
||||
@ -668,7 +669,7 @@ public class RestHighLevelClientTests extends ESTestCase {
|
||||
assertTrue(names.contains(MeanReciprocalRank.NAME));
|
||||
assertTrue(names.contains(DiscountedCumulativeGain.NAME));
|
||||
assertTrue(names.contains(ExpectedReciprocalRank.NAME));
|
||||
assertEquals(Integer.valueOf(7), categories.get(LifecycleAction.class));
|
||||
assertEquals(Integer.valueOf(8), categories.get(LifecycleAction.class));
|
||||
assertTrue(names.contains(AllocateAction.NAME));
|
||||
assertTrue(names.contains(DeleteAction.NAME));
|
||||
assertTrue(names.contains(ForceMergeAction.NAME));
|
||||
@ -676,6 +677,7 @@ public class RestHighLevelClientTests extends ESTestCase {
|
||||
assertTrue(names.contains(RolloverAction.NAME));
|
||||
assertTrue(names.contains(ShrinkAction.NAME));
|
||||
assertTrue(names.contains(FreezeAction.NAME));
|
||||
assertTrue(names.contains(SetPriorityAction.NAME));
|
||||
}
|
||||
|
||||
public void testApiNamingConventions() throws Exception {
|
||||
|
@ -67,7 +67,8 @@ public class GetLifecyclePolicyResponseTests extends AbstractXContentTestCase<Ge
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ReadOnlyAction.NAME), ReadOnlyAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(RolloverAction.NAME), RolloverAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse)
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(SetPriorityAction.NAME), SetPriorityAction::parse)
|
||||
));
|
||||
return new NamedXContentRegistry(entries);
|
||||
}
|
||||
|
@ -63,7 +63,8 @@ public class LifecyclePolicyMetadataTests extends AbstractXContentTestCase<Lifec
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ReadOnlyAction.NAME), ReadOnlyAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(RolloverAction.NAME), RolloverAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse)
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(SetPriorityAction.NAME), SetPriorityAction::parse)
|
||||
));
|
||||
return new NamedXContentRegistry(entries);
|
||||
}
|
||||
|
@ -39,10 +39,10 @@ import java.util.stream.Collectors;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
public class LifecyclePolicyTests extends AbstractXContentTestCase<LifecyclePolicy> {
|
||||
private static final Set<String> VALID_HOT_ACTIONS = Sets.newHashSet(RolloverAction.NAME);
|
||||
private static final Set<String> VALID_WARM_ACTIONS = Sets.newHashSet(AllocateAction.NAME, ForceMergeAction.NAME,
|
||||
ReadOnlyAction.NAME, ShrinkAction.NAME);
|
||||
private static final Set<String> VALID_COLD_ACTIONS = Sets.newHashSet(AllocateAction.NAME, FreezeAction.NAME);
|
||||
private static final Set<String> VALID_HOT_ACTIONS = Sets.newHashSet(SetPriorityAction.NAME, RolloverAction.NAME);
|
||||
private static final Set<String> VALID_WARM_ACTIONS = Sets.newHashSet(SetPriorityAction.NAME, AllocateAction.NAME,
|
||||
ForceMergeAction.NAME, ReadOnlyAction.NAME, ShrinkAction.NAME);
|
||||
private static final Set<String> VALID_COLD_ACTIONS = Sets.newHashSet(SetPriorityAction.NAME, AllocateAction.NAME, FreezeAction.NAME);
|
||||
private static final Set<String> VALID_DELETE_ACTIONS = Sets.newHashSet(DeleteAction.NAME);
|
||||
|
||||
private String lifecycleName;
|
||||
@ -67,7 +67,8 @@ public class LifecyclePolicyTests extends AbstractXContentTestCase<LifecyclePoli
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ReadOnlyAction.NAME), ReadOnlyAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(RolloverAction.NAME), RolloverAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse)
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(SetPriorityAction.NAME), SetPriorityAction::parse)
|
||||
));
|
||||
return new NamedXContentRegistry(entries);
|
||||
}
|
||||
@ -210,6 +211,8 @@ public class LifecyclePolicyTests extends AbstractXContentTestCase<LifecyclePoli
|
||||
return ShrinkActionTests.randomInstance();
|
||||
case FreezeAction.NAME:
|
||||
return new FreezeAction();
|
||||
case SetPriorityAction.NAME:
|
||||
return SetPriorityActionTests.randomInstance();
|
||||
default:
|
||||
throw new IllegalArgumentException("invalid action [" + action + "]");
|
||||
}};
|
||||
@ -241,6 +244,8 @@ public class LifecyclePolicyTests extends AbstractXContentTestCase<LifecyclePoli
|
||||
return ShrinkActionTests.randomInstance();
|
||||
case FreezeAction.NAME:
|
||||
return new FreezeAction();
|
||||
case SetPriorityAction.NAME:
|
||||
return SetPriorityActionTests.randomInstance();
|
||||
default:
|
||||
throw new IllegalArgumentException("unsupported phase action [" + actionName + "]");
|
||||
}
|
||||
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.elasticsearch.client.indexlifecycle;
|
||||
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.test.AbstractXContentTestCase;
|
||||
import org.elasticsearch.test.EqualsHashCodeTestUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
public class SetPriorityActionTests extends AbstractXContentTestCase<SetPriorityAction> {
|
||||
|
||||
@Override
|
||||
protected SetPriorityAction doParseInstance(XContentParser parser) throws IOException {
|
||||
return SetPriorityAction.parse(parser);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SetPriorityAction createTestInstance() {
|
||||
return randomInstance();
|
||||
}
|
||||
|
||||
static SetPriorityAction randomInstance() {
|
||||
return new SetPriorityAction(randomIntBetween(1, 100));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsUnknownFields() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void testNonPositivePriority() {
|
||||
Exception e = expectThrows(Exception.class, () -> new SetPriorityAction(randomIntBetween(-100, 0)));
|
||||
assertThat(e.getMessage(), equalTo("[priority] must be 0 or greater"));
|
||||
}
|
||||
|
||||
public void testNullPriorityAllowed(){
|
||||
SetPriorityAction nullPriority = new SetPriorityAction(null);
|
||||
assertNull(nullPriority.recoveryPriority);
|
||||
}
|
||||
|
||||
public void testEqualsAndHashCode() {
|
||||
EqualsHashCodeTestUtils.checkEqualsAndHashCode(createTestInstance(), this::copy);
|
||||
}
|
||||
|
||||
SetPriorityAction copy(SetPriorityAction setPriorityAction) {
|
||||
return new SetPriorityAction(setPriorityAction.recoveryPriority);
|
||||
}
|
||||
|
||||
SetPriorityAction notCopy(SetPriorityAction setPriorityAction) {
|
||||
return new SetPriorityAction(setPriorityAction.recoveryPriority + 1);
|
||||
}
|
||||
}
|
@ -85,13 +85,16 @@ executing.
|
||||
The below list shows the actions which are available in each phase.
|
||||
|
||||
* Hot
|
||||
- <<ilm-set-priority-action,Set Priority>>
|
||||
- <<ilm-rollover-action,Rollover>>
|
||||
* Warm
|
||||
- <<ilm-set-priority-action,Set Priority>>
|
||||
- <<ilm-allocate-action,Allocate>>
|
||||
- <<ilm-readonly-action,Read-Only>>
|
||||
- <<ilm-forcemerge-action,Force Merge>>
|
||||
- <<ilm-shrink-action,Shrink>>
|
||||
* Cold
|
||||
- <<ilm-set-priority-action,Set Priority>>
|
||||
- <<ilm-allocate-action,Allocate>>
|
||||
- <<ilm-freeze-action,Freeze>>
|
||||
* Delete
|
||||
@ -525,6 +528,48 @@ The above example illustrates a policy which attempts to delete an
|
||||
index one day after the index has been rolled over. It does not
|
||||
delete the index one day after it has been created.
|
||||
|
||||
[[ilm-set-priority-action]]
|
||||
==== Set Priority
|
||||
|
||||
Phases allowed: hot, warm, cold.
|
||||
|
||||
This action sets the <<recovery-prioritization, index priority>> on the index as
|
||||
soon as the policy enters the hot, warm, or cold phase. Indices with a higher
|
||||
priority will be recovered before indices with lower priorities following a node
|
||||
restart. Generally, indexes in the hot phase should have the highest value and
|
||||
indexes in the cold phase should have the lowest values. For example:
|
||||
100 for the hot phase, 50 for the warm phase, and 0 for the cold phase.
|
||||
Indicies that don't set this value have an implicit default priority of 1.
|
||||
|
||||
[[ilm-set-priority-options]]
|
||||
.Set Priority Options
|
||||
[options="header"]
|
||||
|======
|
||||
| Name | Required | Default | Description
|
||||
| `priority` | yes | - | The priority for the index. Must be 0 or greater.
|
||||
The value may also be set to null to remove the priority.
|
||||
|
||||
|======
|
||||
|
||||
[source,js]
|
||||
--------------------------------------------------
|
||||
PUT _ilm/policy/my_policy
|
||||
{
|
||||
"policy": {
|
||||
"phases": {
|
||||
"warm": {
|
||||
"actions": {
|
||||
"set_priority" : {
|
||||
"priority": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
--------------------------------------------------
|
||||
// CONSOLE
|
||||
|
||||
[[ilm-shrink-action]]
|
||||
==== Shrink
|
||||
|
||||
|
@ -52,6 +52,7 @@ import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleFeatureSetUsage
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleMetadata;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleType;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.SetPriorityAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.ReadOnlyAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.RolloverAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.ShrinkAction;
|
||||
@ -427,7 +428,8 @@ public class XPackClientPlugin extends Plugin implements ActionPlugin, NetworkPl
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, RolloverAction.NAME, RolloverAction::new),
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, ShrinkAction.NAME, ShrinkAction::new),
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, DeleteAction.NAME, DeleteAction::new),
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, FreezeAction.NAME, FreezeAction::new)
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, FreezeAction.NAME, FreezeAction::new),
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, SetPriorityAction.NAME, SetPriorityAction::new)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A {@link LifecycleAction} which force-merges the index.
|
||||
* A {@link LifecycleAction} which sets the index to be read-only.
|
||||
*/
|
||||
public class ReadOnlyAction implements LifecycleAction {
|
||||
public static final String NAME = "readonly";
|
||||
|
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
package org.elasticsearch.xpack.core.indexlifecycle;
|
||||
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A {@link LifecycleAction} which sets the index's priority. The higher the priority, the faster the recovery.
|
||||
*/
|
||||
public class SetPriorityAction implements LifecycleAction {
|
||||
public static final String NAME = "set_priority";
|
||||
private static final ParseField RECOVERY_PRIORITY_FIELD = new ParseField("priority");
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static final ConstructingObjectParser<SetPriorityAction, Void> PARSER = new ConstructingObjectParser<>(NAME,
|
||||
a -> new SetPriorityAction((Integer) a[0]));
|
||||
|
||||
//package private for testing
|
||||
final Integer recoveryPriority;
|
||||
|
||||
static {
|
||||
PARSER.declareField(ConstructingObjectParser.constructorArg(),
|
||||
(p) -> p.currentToken() == XContentParser.Token.VALUE_NULL ? null : p.intValue()
|
||||
, RECOVERY_PRIORITY_FIELD, ObjectParser.ValueType.INT_OR_NULL);
|
||||
}
|
||||
|
||||
public static SetPriorityAction parse(XContentParser parser) {
|
||||
return PARSER.apply(parser, null);
|
||||
}
|
||||
|
||||
public SetPriorityAction(@Nullable Integer recoveryPriority) {
|
||||
if (recoveryPriority != null && recoveryPriority < 0) {
|
||||
throw new IllegalArgumentException("[" + RECOVERY_PRIORITY_FIELD.getPreferredName() + "] must be 0 or greater");
|
||||
}
|
||||
this.recoveryPriority = recoveryPriority;
|
||||
}
|
||||
|
||||
public SetPriorityAction(StreamInput in) throws IOException {
|
||||
this(in.readOptionalVInt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWriteableName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
builder.field(RECOVERY_PRIORITY_FIELD.getPreferredName(), recoveryPriority);
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
out.writeOptionalVInt(recoveryPriority);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSafeAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Step> toSteps(Client client, String phase, StepKey nextStepKey) {
|
||||
StepKey key = new StepKey(phase, NAME, NAME);
|
||||
Settings indexPriority = recoveryPriority == null ?
|
||||
Settings.builder().putNull(IndexMetaData.INDEX_PRIORITY_SETTING.getKey()).build()
|
||||
: Settings.builder().put(IndexMetaData.INDEX_PRIORITY_SETTING.getKey(), recoveryPriority).build();
|
||||
return Collections.singletonList(new UpdateSettingsStep(key, nextStepKey, client, indexPriority));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StepKey> toStepKeys(String phase) {
|
||||
return Collections.singletonList(new StepKey(phase, NAME, NAME));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
SetPriorityAction that = (SetPriorityAction) o;
|
||||
|
||||
return recoveryPriority != null ? recoveryPriority.equals(that.recoveryPriority) : that.recoveryPriority == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return recoveryPriority != null ? recoveryPriority.hashCode() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Strings.toString(this);
|
||||
}
|
||||
}
|
@ -34,10 +34,10 @@ public class TimeseriesLifecycleType implements LifecycleType {
|
||||
|
||||
public static final String TYPE = "timeseries";
|
||||
static final List<String> VALID_PHASES = Arrays.asList("hot", "warm", "cold", "delete");
|
||||
static final List<String> ORDERED_VALID_HOT_ACTIONS = Collections.singletonList(RolloverAction.NAME);
|
||||
static final List<String> ORDERED_VALID_WARM_ACTIONS = Arrays.asList(ReadOnlyAction.NAME, AllocateAction.NAME,
|
||||
static final List<String> ORDERED_VALID_HOT_ACTIONS = Arrays.asList(SetPriorityAction.NAME, RolloverAction.NAME);
|
||||
static final List<String> ORDERED_VALID_WARM_ACTIONS = Arrays.asList(SetPriorityAction.NAME, ReadOnlyAction.NAME, AllocateAction.NAME,
|
||||
ShrinkAction.NAME, ForceMergeAction.NAME);
|
||||
static final List<String> ORDERED_VALID_COLD_ACTIONS = Arrays.asList(AllocateAction.NAME, FreezeAction.NAME);
|
||||
static final List<String> ORDERED_VALID_COLD_ACTIONS = Arrays.asList(SetPriorityAction.NAME, AllocateAction.NAME, FreezeAction.NAME);
|
||||
static final List<String> ORDERED_VALID_DELETE_ACTIONS = Arrays.asList(DeleteAction.NAME);
|
||||
static final Set<String> VALID_HOT_ACTIONS = Sets.newHashSet(ORDERED_VALID_HOT_ACTIONS);
|
||||
static final Set<String> VALID_WARM_ACTIONS = Sets.newHashSet(ORDERED_VALID_WARM_ACTIONS);
|
||||
|
@ -44,7 +44,8 @@ public class LifecyclePolicyMetadataTests extends AbstractSerializingTestCase<Li
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, ReadOnlyAction.NAME, ReadOnlyAction::new),
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, RolloverAction.NAME, RolloverAction::new),
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, ShrinkAction.NAME, ShrinkAction::new),
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, FreezeAction.NAME, FreezeAction::new)
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, FreezeAction.NAME, FreezeAction::new),
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, SetPriorityAction.NAME, SetPriorityAction::new)
|
||||
));
|
||||
}
|
||||
|
||||
@ -60,7 +61,8 @@ public class LifecyclePolicyMetadataTests extends AbstractSerializingTestCase<Li
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ReadOnlyAction.NAME), ReadOnlyAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(RolloverAction.NAME), RolloverAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse)
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(SetPriorityAction.NAME), SetPriorityAction::parse)
|
||||
));
|
||||
return new NamedXContentRegistry(entries);
|
||||
}
|
||||
|
@ -53,7 +53,8 @@ public class LifecyclePolicyTests extends AbstractSerializingTestCase<LifecycleP
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, ReadOnlyAction.NAME, ReadOnlyAction::new),
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, RolloverAction.NAME, RolloverAction::new),
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, ShrinkAction.NAME, ShrinkAction::new),
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, FreezeAction.NAME, FreezeAction::new)
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, FreezeAction.NAME, FreezeAction::new),
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, SetPriorityAction.NAME, SetPriorityAction::new)
|
||||
));
|
||||
}
|
||||
|
||||
@ -69,7 +70,8 @@ public class LifecyclePolicyTests extends AbstractSerializingTestCase<LifecycleP
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ReadOnlyAction.NAME), ReadOnlyAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(RolloverAction.NAME), RolloverAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse)
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(SetPriorityAction.NAME), SetPriorityAction::parse)
|
||||
));
|
||||
return new NamedXContentRegistry(entries);
|
||||
}
|
||||
@ -116,6 +118,8 @@ public class LifecyclePolicyTests extends AbstractSerializingTestCase<LifecycleP
|
||||
return ShrinkActionTests.randomInstance();
|
||||
case FreezeAction.NAME:
|
||||
return new FreezeAction();
|
||||
case SetPriorityAction.NAME:
|
||||
return SetPriorityActionTests.randomInstance();
|
||||
default:
|
||||
throw new IllegalArgumentException("invalid action [" + action + "]");
|
||||
}};
|
||||
@ -164,6 +168,8 @@ public class LifecyclePolicyTests extends AbstractSerializingTestCase<LifecycleP
|
||||
return ShrinkActionTests.randomInstance();
|
||||
case FreezeAction.NAME:
|
||||
return new FreezeAction();
|
||||
case SetPriorityAction.NAME:
|
||||
return SetPriorityActionTests.randomInstance();
|
||||
default:
|
||||
throw new IllegalArgumentException("invalid action [" + action + "]");
|
||||
}};
|
||||
|
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
package org.elasticsearch.xpack.core.indexlifecycle;
|
||||
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.common.io.stream.Writeable.Reader;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.test.EqualsHashCodeTestUtils;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
public class SetPriorityActionTests extends AbstractActionTestCase<SetPriorityAction> {
|
||||
|
||||
private final int priority = randomIntBetween(0, Integer.MAX_VALUE);
|
||||
|
||||
static SetPriorityAction randomInstance() {
|
||||
return new SetPriorityAction(randomIntBetween(2, Integer.MAX_VALUE - 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SetPriorityAction doParseInstance(XContentParser parser) {
|
||||
return SetPriorityAction.parse(parser);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SetPriorityAction createTestInstance() {
|
||||
return new SetPriorityAction(priority);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Reader<SetPriorityAction> instanceReader() {
|
||||
return SetPriorityAction::new;
|
||||
}
|
||||
|
||||
public void testNonPositivePriority() {
|
||||
Exception e = expectThrows(Exception.class, () -> new SetPriorityAction(randomIntBetween(-100, 0)));
|
||||
assertThat(e.getMessage(), equalTo("[priority] must be 0 or greater"));
|
||||
}
|
||||
|
||||
public void testNullPriorityAllowed(){
|
||||
SetPriorityAction nullPriority = new SetPriorityAction((Integer) null);
|
||||
assertNull(nullPriority.recoveryPriority);
|
||||
}
|
||||
|
||||
public void testToSteps() {
|
||||
SetPriorityAction action = createTestInstance();
|
||||
String phase = randomAlphaOfLengthBetween(1, 10);
|
||||
StepKey nextStepKey = new StepKey(randomAlphaOfLengthBetween(1, 10), randomAlphaOfLengthBetween(1, 10),
|
||||
randomAlphaOfLengthBetween(1, 10));
|
||||
List<Step> steps = action.toSteps(null, phase, nextStepKey);
|
||||
assertNotNull(steps);
|
||||
assertEquals(1, steps.size());
|
||||
StepKey expectedFirstStepKey = new StepKey(phase, SetPriorityAction.NAME, SetPriorityAction.NAME);
|
||||
UpdateSettingsStep firstStep = (UpdateSettingsStep) steps.get(0);
|
||||
assertThat(firstStep.getKey(), equalTo(expectedFirstStepKey));
|
||||
assertThat(firstStep.getNextStepKey(), equalTo(nextStepKey));
|
||||
assertThat(firstStep.getSettings().size(), equalTo(1));
|
||||
assertEquals(priority, (long) IndexMetaData.INDEX_PRIORITY_SETTING.get(firstStep.getSettings()));
|
||||
}
|
||||
|
||||
public void testNullPriorityStep() {
|
||||
SetPriorityAction action = new SetPriorityAction((Integer)null);
|
||||
String phase = randomAlphaOfLengthBetween(1, 10);
|
||||
StepKey nextStepKey = new StepKey(randomAlphaOfLengthBetween(1, 10), randomAlphaOfLengthBetween(1, 10),
|
||||
randomAlphaOfLengthBetween(1, 10));
|
||||
List<Step> steps = action.toSteps(null, phase, nextStepKey);
|
||||
assertNotNull(steps);
|
||||
assertEquals(1, steps.size());
|
||||
StepKey expectedFirstStepKey = new StepKey(phase, SetPriorityAction.NAME, SetPriorityAction.NAME);
|
||||
UpdateSettingsStep firstStep = (UpdateSettingsStep) steps.get(0);
|
||||
assertThat(firstStep.getKey(), equalTo(expectedFirstStepKey));
|
||||
assertThat(firstStep.getNextStepKey(), equalTo(nextStepKey));
|
||||
assertThat(firstStep.getSettings().size(), equalTo(1));
|
||||
assertThat(IndexMetaData.INDEX_PRIORITY_SETTING.get(firstStep.getSettings()),
|
||||
equalTo(IndexMetaData.INDEX_PRIORITY_SETTING.getDefault(firstStep.getSettings())));
|
||||
}
|
||||
|
||||
public void testEqualsAndHashCode() {
|
||||
EqualsHashCodeTestUtils.checkEqualsAndHashCode(createTestInstance(), this::copy, this::notCopy);
|
||||
}
|
||||
|
||||
SetPriorityAction copy(SetPriorityAction setPriorityAction) {
|
||||
return new SetPriorityAction(setPriorityAction.recoveryPriority);
|
||||
}
|
||||
|
||||
SetPriorityAction notCopy(SetPriorityAction setPriorityAction) {
|
||||
return new SetPriorityAction(setPriorityAction.recoveryPriority + 1);
|
||||
}
|
||||
}
|
@ -39,6 +39,7 @@ public class TimeseriesLifecycleTypeTests extends ESTestCase {
|
||||
private static final ShrinkAction TEST_SHRINK_ACTION = new ShrinkAction(1);
|
||||
private static final ReadOnlyAction TEST_READ_ONLY_ACTION = new ReadOnlyAction();
|
||||
private static final FreezeAction TEST_FREEZE_ACTION = new FreezeAction();
|
||||
private static final SetPriorityAction TEST_PRIORITY_ACTION = new SetPriorityAction(0);
|
||||
|
||||
public void testValidatePhases() {
|
||||
boolean invalid = randomBoolean();
|
||||
@ -61,7 +62,7 @@ public class TimeseriesLifecycleTypeTests extends ESTestCase {
|
||||
Map<String, LifecycleAction> actions = VALID_HOT_ACTIONS
|
||||
.stream().map(this::getTestAction).collect(Collectors.toMap(LifecycleAction::getWriteableName, Function.identity()));
|
||||
if (randomBoolean()) {
|
||||
invalidAction = getTestAction(randomFrom("allocate", "forcemerge", "delete", "shrink"));
|
||||
invalidAction = getTestAction(randomFrom("allocate", "forcemerge", "delete", "shrink", "freeze"));
|
||||
actions.put(invalidAction.getWriteableName(), invalidAction);
|
||||
}
|
||||
Map<String, Phase> hotPhase = Collections.singletonMap("hot",
|
||||
@ -82,7 +83,7 @@ public class TimeseriesLifecycleTypeTests extends ESTestCase {
|
||||
Map<String, LifecycleAction> actions = randomSubsetOf(VALID_WARM_ACTIONS)
|
||||
.stream().map(this::getTestAction).collect(Collectors.toMap(LifecycleAction::getWriteableName, Function.identity()));
|
||||
if (randomBoolean()) {
|
||||
invalidAction = getTestAction(randomFrom("rollover", "delete"));
|
||||
invalidAction = getTestAction(randomFrom("rollover", "delete", "freeze"));
|
||||
actions.put(invalidAction.getWriteableName(), invalidAction);
|
||||
}
|
||||
Map<String, Phase> warmPhase = Collections.singletonMap("warm",
|
||||
@ -124,7 +125,7 @@ public class TimeseriesLifecycleTypeTests extends ESTestCase {
|
||||
Map<String, LifecycleAction> actions = VALID_DELETE_ACTIONS
|
||||
.stream().map(this::getTestAction).collect(Collectors.toMap(LifecycleAction::getWriteableName, Function.identity()));
|
||||
if (randomBoolean()) {
|
||||
invalidAction = getTestAction(randomFrom("allocate", "rollover", "forcemerge", "shrink"));
|
||||
invalidAction = getTestAction(randomFrom("allocate", "rollover", "forcemerge", "shrink", "freeze", "set_priority"));
|
||||
actions.put(invalidAction.getWriteableName(), invalidAction);
|
||||
}
|
||||
Map<String, Phase> deletePhase = Collections.singletonMap("delete",
|
||||
@ -163,6 +164,7 @@ public class TimeseriesLifecycleTypeTests extends ESTestCase {
|
||||
Phase hotPhase = new Phase("hot", TimeValue.ZERO, actions);
|
||||
List<LifecycleAction> orderedActions = TimeseriesLifecycleType.INSTANCE.getOrderedActions(hotPhase);
|
||||
assertTrue(isSorted(orderedActions, LifecycleAction::getWriteableName, ORDERED_VALID_HOT_ACTIONS));
|
||||
assertThat(orderedActions.indexOf(TEST_PRIORITY_ACTION), equalTo(0));
|
||||
}
|
||||
|
||||
public void testGetOrderedActionsWarm() {
|
||||
@ -171,6 +173,7 @@ public class TimeseriesLifecycleTypeTests extends ESTestCase {
|
||||
Phase warmPhase = new Phase("warm", TimeValue.ZERO, actions);
|
||||
List<LifecycleAction> orderedActions = TimeseriesLifecycleType.INSTANCE.getOrderedActions(warmPhase);
|
||||
assertTrue(isSorted(orderedActions, LifecycleAction::getWriteableName, ORDERED_VALID_WARM_ACTIONS));
|
||||
assertThat(orderedActions.indexOf(TEST_PRIORITY_ACTION), equalTo(0));
|
||||
}
|
||||
|
||||
public void testGetOrderedActionsCold() {
|
||||
@ -179,6 +182,7 @@ public class TimeseriesLifecycleTypeTests extends ESTestCase {
|
||||
Phase coldPhase = new Phase("cold", TimeValue.ZERO, actions);
|
||||
List<LifecycleAction> orderedActions = TimeseriesLifecycleType.INSTANCE.getOrderedActions(coldPhase);
|
||||
assertTrue(isSorted(orderedActions, LifecycleAction::getWriteableName, ORDERED_VALID_COLD_ACTIONS));
|
||||
assertThat(orderedActions.indexOf(TEST_PRIORITY_ACTION), equalTo(0));
|
||||
}
|
||||
|
||||
public void testGetOrderedActionsDelete() {
|
||||
@ -301,6 +305,8 @@ public class TimeseriesLifecycleTypeTests extends ESTestCase {
|
||||
|
||||
public void testGetNextActionName() {
|
||||
// Hot Phase
|
||||
assertNextActionName("hot", SetPriorityAction.NAME, null, new String[] {});
|
||||
assertNextActionName("hot", SetPriorityAction.NAME, RolloverAction.NAME, new String[]{SetPriorityAction.NAME, RolloverAction.NAME});
|
||||
assertNextActionName("hot", RolloverAction.NAME, null, new String[] {});
|
||||
assertNextActionName("hot", RolloverAction.NAME, null, new String[] { RolloverAction.NAME });
|
||||
assertInvalidAction("hot", "foo", new String[] { RolloverAction.NAME });
|
||||
@ -311,6 +317,16 @@ public class TimeseriesLifecycleTypeTests extends ESTestCase {
|
||||
assertInvalidAction("hot", ShrinkAction.NAME, new String[] { RolloverAction.NAME });
|
||||
|
||||
// Warm Phase
|
||||
assertNextActionName("warm", SetPriorityAction.NAME, ReadOnlyAction.NAME,
|
||||
new String[]{SetPriorityAction.NAME, ReadOnlyAction.NAME, AllocateAction.NAME, ShrinkAction.NAME, ForceMergeAction.NAME});
|
||||
assertNextActionName("warm", SetPriorityAction.NAME, AllocateAction.NAME,
|
||||
new String[]{SetPriorityAction.NAME, AllocateAction.NAME, ShrinkAction.NAME, ForceMergeAction.NAME});
|
||||
assertNextActionName("warm", SetPriorityAction.NAME, ShrinkAction.NAME,
|
||||
new String[]{SetPriorityAction.NAME, ShrinkAction.NAME, ForceMergeAction.NAME});
|
||||
assertNextActionName("warm", SetPriorityAction.NAME, ForceMergeAction.NAME,
|
||||
new String[]{SetPriorityAction.NAME, ForceMergeAction.NAME});
|
||||
assertNextActionName("warm", SetPriorityAction.NAME, null, new String[]{SetPriorityAction.NAME});
|
||||
|
||||
assertNextActionName("warm", ReadOnlyAction.NAME, AllocateAction.NAME,
|
||||
new String[] { ReadOnlyAction.NAME, AllocateAction.NAME, ShrinkAction.NAME, ForceMergeAction.NAME });
|
||||
assertNextActionName("warm", ReadOnlyAction.NAME, ShrinkAction.NAME,
|
||||
@ -355,6 +371,11 @@ public class TimeseriesLifecycleTypeTests extends ESTestCase {
|
||||
new String[] { ReadOnlyAction.NAME, AllocateAction.NAME, ShrinkAction.NAME, ForceMergeAction.NAME });
|
||||
|
||||
// Cold Phase
|
||||
assertNextActionName("cold", SetPriorityAction.NAME, FreezeAction.NAME, new String[]{SetPriorityAction.NAME, FreezeAction.NAME});
|
||||
assertNextActionName("cold", SetPriorityAction.NAME, AllocateAction.NAME,
|
||||
new String[]{SetPriorityAction.NAME, AllocateAction.NAME});
|
||||
assertNextActionName("cold", SetPriorityAction.NAME, null, new String[] { SetPriorityAction.NAME });
|
||||
assertNextActionName("cold", SetPriorityAction.NAME, null, new String[] {});
|
||||
assertNextActionName("cold", AllocateAction.NAME, null, new String[] { AllocateAction.NAME });
|
||||
assertNextActionName("cold", AllocateAction.NAME, null, new String[] {});
|
||||
assertNextActionName("cold", AllocateAction.NAME, null, new String[] {});
|
||||
@ -378,6 +399,8 @@ public class TimeseriesLifecycleTypeTests extends ESTestCase {
|
||||
assertInvalidAction("delete", ReadOnlyAction.NAME, new String[] { DeleteAction.NAME });
|
||||
assertInvalidAction("delete", RolloverAction.NAME, new String[] { DeleteAction.NAME });
|
||||
assertInvalidAction("delete", ShrinkAction.NAME, new String[] { DeleteAction.NAME });
|
||||
assertInvalidAction("delete", FreezeAction.NAME, new String[] { DeleteAction.NAME });
|
||||
assertInvalidAction("delete", SetPriorityAction.NAME, new String[] { DeleteAction.NAME });
|
||||
|
||||
Phase phase = new Phase("foo", TimeValue.ZERO, Collections.emptyMap());
|
||||
IllegalArgumentException exception = expectThrows(IllegalArgumentException.class,
|
||||
@ -419,6 +442,8 @@ public class TimeseriesLifecycleTypeTests extends ESTestCase {
|
||||
return new ShrinkAction(1);
|
||||
case FreezeAction.NAME:
|
||||
return new FreezeAction();
|
||||
case SetPriorityAction.NAME:
|
||||
return new SetPriorityAction(0);
|
||||
}
|
||||
return new DeleteAction();
|
||||
}).collect(Collectors.toConcurrentMap(LifecycleAction::getWriteableName, Function.identity()));
|
||||
@ -482,6 +507,8 @@ public class TimeseriesLifecycleTypeTests extends ESTestCase {
|
||||
return TEST_SHRINK_ACTION;
|
||||
case FreezeAction.NAME:
|
||||
return TEST_FREEZE_ACTION;
|
||||
case SetPriorityAction.NAME:
|
||||
return TEST_PRIORITY_ACTION;
|
||||
default:
|
||||
throw new IllegalArgumentException("unsupported timeseries phase action [" + actionName + "]");
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import org.elasticsearch.xpack.core.indexlifecycle.LifecyclePolicyTests;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleType;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.ReadOnlyAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.RolloverAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.SetPriorityAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.ShrinkAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.TimeseriesLifecycleType;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.action.PutLifecycleAction.Request;
|
||||
@ -66,7 +67,8 @@ public class PutLifecycleRequestTests extends AbstractStreamableXContentTestCase
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, ReadOnlyAction.NAME, ReadOnlyAction::new),
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, RolloverAction.NAME, RolloverAction::new),
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, ShrinkAction.NAME, ShrinkAction::new),
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, FreezeAction.NAME, FreezeAction::new)
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, FreezeAction.NAME, FreezeAction::new),
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, SetPriorityAction.NAME, SetPriorityAction::new)
|
||||
));
|
||||
}
|
||||
|
||||
@ -82,7 +84,8 @@ public class PutLifecycleRequestTests extends AbstractStreamableXContentTestCase
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ReadOnlyAction.NAME), ReadOnlyAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(RolloverAction.NAME), RolloverAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse)
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(SetPriorityAction.NAME), SetPriorityAction::parse)
|
||||
));
|
||||
return new NamedXContentRegistry(entries);
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ import org.elasticsearch.xpack.core.indexlifecycle.LifecycleSettings;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.Phase;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.ReadOnlyAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.RolloverAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.SetPriorityAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.ShrinkAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.ShrinkStep;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
|
||||
@ -440,6 +441,31 @@ public class TimeSeriesLifecycleActionsIT extends ESRestTestCase {
|
||||
});
|
||||
}
|
||||
|
||||
public void testSetPriority() throws Exception {
|
||||
createIndexWithSettings(index, Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)
|
||||
.put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0).put(IndexMetaData.INDEX_PRIORITY_SETTING.getKey(), 100));
|
||||
int priority = randomIntBetween(0, 99);
|
||||
createNewSingletonPolicy("warm", new SetPriorityAction(priority));
|
||||
updatePolicy(index, policy);
|
||||
assertBusy(() -> {
|
||||
Map<String, Object> settings = getOnlyIndexSettings(index);
|
||||
assertThat(getStepKeyForIndex(index), equalTo(TerminalPolicyStep.KEY));
|
||||
assertThat(settings.get(IndexMetaData.INDEX_PRIORITY_SETTING.getKey()), equalTo(String.valueOf(priority)));
|
||||
});
|
||||
}
|
||||
|
||||
public void testSetNullPriority() throws Exception {
|
||||
createIndexWithSettings(index, Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)
|
||||
.put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0).put(IndexMetaData.INDEX_PRIORITY_SETTING.getKey(), 100));
|
||||
createNewSingletonPolicy("warm", new SetPriorityAction((Integer) null));
|
||||
updatePolicy(index, policy);
|
||||
assertBusy(() -> {
|
||||
Map<String, Object> settings = getOnlyIndexSettings(index);
|
||||
assertThat(getStepKeyForIndex(index), equalTo(TerminalPolicyStep.KEY));
|
||||
assertNull(settings.get(IndexMetaData.INDEX_PRIORITY_SETTING.getKey()));
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testNonexistentPolicy() throws Exception {
|
||||
String indexPrefix = randomAlphaOfLengthBetween(5,15).toLowerCase(Locale.ROOT);
|
||||
@ -601,16 +627,21 @@ public class TimeSeriesLifecycleActionsIT extends ESRestTestCase {
|
||||
}
|
||||
|
||||
private void createFullPolicy(TimeValue hotTime) throws IOException {
|
||||
Map<String, LifecycleAction> hotActions = new HashMap<>();
|
||||
hotActions.put(SetPriorityAction.NAME, new SetPriorityAction(100));
|
||||
hotActions.put(RolloverAction.NAME, new RolloverAction(null, null, 1L));
|
||||
Map<String, LifecycleAction> warmActions = new HashMap<>();
|
||||
warmActions.put(SetPriorityAction.NAME, new SetPriorityAction(50));
|
||||
warmActions.put(ForceMergeAction.NAME, new ForceMergeAction(1));
|
||||
warmActions.put(AllocateAction.NAME, new AllocateAction(1, singletonMap("_name", "node-1,node-2"), null, null));
|
||||
warmActions.put(ShrinkAction.NAME, new ShrinkAction(1));
|
||||
Map<String, LifecycleAction> coldActions = new HashMap<>();
|
||||
coldActions.put(SetPriorityAction.NAME, new SetPriorityAction(0));
|
||||
coldActions.put(AllocateAction.NAME, new AllocateAction(0, singletonMap("_name", "node-3"), null, null));
|
||||
Map<String, Phase> phases = new HashMap<>();
|
||||
phases.put("hot", new Phase("hot", hotTime, singletonMap(RolloverAction.NAME,
|
||||
new RolloverAction(null, null, 1L))));
|
||||
phases.put("hot", new Phase("hot", hotTime, hotActions));
|
||||
phases.put("warm", new Phase("warm", TimeValue.ZERO, warmActions));
|
||||
phases.put("cold", new Phase("cold", TimeValue.ZERO, singletonMap(AllocateAction.NAME,
|
||||
new AllocateAction(0, singletonMap("_name", "node-3"), null, null))));
|
||||
phases.put("cold", new Phase("cold", TimeValue.ZERO, coldActions));
|
||||
phases.put("delete", new Phase("delete", TimeValue.ZERO, singletonMap(DeleteAction.NAME, new DeleteAction())));
|
||||
LifecyclePolicy lifecyclePolicy = new LifecyclePolicy(policy, phases);
|
||||
// PUT policy
|
||||
|
@ -42,6 +42,7 @@ import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleMetadata;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleSettings;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleType;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.SetPriorityAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.ReadOnlyAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.RolloverAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.ShrinkAction;
|
||||
@ -159,7 +160,8 @@ public class IndexLifecycle extends Plugin implements ActionPlugin {
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(RolloverAction.NAME), RolloverAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(DeleteAction.NAME), DeleteAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse)
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(SetPriorityAction.NAME), SetPriorityAction::parse)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ import org.elasticsearch.xpack.core.indexlifecycle.LifecycleType;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.Phase;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.ReadOnlyAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.RolloverAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.SetPriorityAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.ShrinkAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.TimeseriesLifecycleType;
|
||||
|
||||
@ -83,7 +84,8 @@ public class IndexLifecycleMetadataTests extends AbstractDiffableSerializationTe
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, ReadOnlyAction.NAME, ReadOnlyAction::new),
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, RolloverAction.NAME, RolloverAction::new),
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, ShrinkAction.NAME, ShrinkAction::new),
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, FreezeAction.NAME, FreezeAction::new)
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, FreezeAction.NAME, FreezeAction::new),
|
||||
new NamedWriteableRegistry.Entry(LifecycleAction.class, SetPriorityAction.NAME, SetPriorityAction::new)
|
||||
));
|
||||
}
|
||||
|
||||
@ -99,7 +101,8 @@ public class IndexLifecycleMetadataTests extends AbstractDiffableSerializationTe
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ReadOnlyAction.NAME), ReadOnlyAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(RolloverAction.NAME), RolloverAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse)
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse),
|
||||
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(SetPriorityAction.NAME), SetPriorityAction::parse)
|
||||
));
|
||||
return new NamedXContentRegistry(entries);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user