Adds tests for AllocateAction and its steps
Also tweaks some of the code in the steps of the allocate action
This commit is contained in:
parent
47ed2e5b23
commit
2eb8fd9336
|
@ -7,15 +7,11 @@ package org.elasticsearch.xpack.core.indexlifecycle;
|
|||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.AllocationDeciders;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.FilterAllocationDecider;
|
||||
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.logging.ESLoggerFactory;
|
||||
import org.elasticsearch.common.settings.ClusterSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
@ -50,9 +46,6 @@ public class AllocateAction implements LifecycleAction {
|
|||
private final Map<String, String> include;
|
||||
private final Map<String, String> exclude;
|
||||
private final Map<String, String> require;
|
||||
private static final AllocationDeciders ALLOCATION_DECIDERS = new AllocationDeciders(Settings.EMPTY,
|
||||
Collections.singletonList(new FilterAllocationDecider(Settings.EMPTY,
|
||||
new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS))));
|
||||
|
||||
public static AllocateAction parse(XContentParser parser) {
|
||||
return PARSER.apply(parser, null);
|
||||
|
@ -124,12 +117,12 @@ public class AllocateAction implements LifecycleAction {
|
|||
|
||||
@Override
|
||||
public List<Step> toSteps(Client client, String phase, StepKey nextStepKey) {
|
||||
StepKey enoughKey = new StepKey(phase, NAME, "enough-shards-allocated");
|
||||
StepKey allocateKey = new StepKey(phase, NAME, "update-allocation");
|
||||
StepKey allocationRoutedKey = new StepKey(phase, NAME, "check-allocation");
|
||||
StepKey enoughKey = new StepKey(phase, NAME, EnoughShardsWaitStep.NAME);
|
||||
StepKey allocateKey = new StepKey(phase, NAME, UpdateAllocationSettingsStep.NAME);
|
||||
StepKey allocationRoutedKey = new StepKey(phase, NAME, AllocationRoutedStep.NAME);
|
||||
UpdateAllocationSettingsStep allocateStep = new UpdateAllocationSettingsStep(allocateKey, allocationRoutedKey,
|
||||
include, exclude, require);
|
||||
AllocationRoutedStep routedCheckStep = new AllocationRoutedStep(allocationRoutedKey, nextStepKey, ALLOCATION_DECIDERS);
|
||||
AllocationRoutedStep routedCheckStep = new AllocationRoutedStep(allocationRoutedKey, nextStepKey);
|
||||
return Arrays.asList(new EnoughShardsWaitStep(enoughKey, allocateKey), allocateStep, routedCheckStep);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,46 +6,65 @@
|
|||
package org.elasticsearch.xpack.core.indexlifecycle;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.elasticsearch.action.support.ActiveShardCount;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.routing.ShardRouting;
|
||||
import org.elasticsearch.cluster.routing.allocation.RoutingAllocation;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.AllocationDeciders;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.Decision;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.FilterAllocationDecider;
|
||||
import org.elasticsearch.common.logging.ESLoggerFactory;
|
||||
import org.elasticsearch.common.settings.ClusterSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.IndexNotFoundException;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class AllocationRoutedStep extends ClusterStateWaitStep {
|
||||
public static final String NAME = "check-allocation";
|
||||
|
||||
private static final Logger logger = ESLoggerFactory.getLogger(AllocationRoutedStep.class);
|
||||
|
||||
private AllocationDeciders allocationDeciders;
|
||||
private static final AllocationDeciders ALLOCATION_DECIDERS = new AllocationDeciders(Settings.EMPTY, Collections.singletonList(
|
||||
new FilterAllocationDecider(Settings.EMPTY, new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS))));
|
||||
|
||||
AllocationRoutedStep(StepKey key, StepKey nextStepKey, AllocationDeciders allocationDeciders) {
|
||||
AllocationRoutedStep(StepKey key, StepKey nextStepKey) {
|
||||
super(key, nextStepKey);
|
||||
this.allocationDeciders = allocationDeciders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConditionMet(Index index, ClusterState clusterState) {
|
||||
// All the allocation attributes are already set so just need to check if the allocation has happened
|
||||
RoutingAllocation allocation = new RoutingAllocation(allocationDeciders, clusterState.getRoutingNodes(), clusterState, null,
|
||||
System.nanoTime());
|
||||
if (ActiveShardCount.ALL.enoughShardsActive(clusterState, index.getName()) == false) {
|
||||
logger.debug("[{}] lifecycle action for index [{}] cannot make progress because not all shards are active",
|
||||
getKey().getAction(), index.getName());
|
||||
return false;
|
||||
}
|
||||
IndexMetaData idxMeta = clusterState.metaData().index(index);
|
||||
if (idxMeta == null) {
|
||||
throw new IndexNotFoundException("Index not found when executing " + getKey().getAction() + " lifecycle action.",
|
||||
index.getName());
|
||||
}
|
||||
// All the allocation attributes are already set so just need to check
|
||||
// if the allocation has happened
|
||||
RoutingAllocation allocation = new RoutingAllocation(ALLOCATION_DECIDERS, clusterState.getRoutingNodes(), clusterState, null,
|
||||
System.nanoTime());
|
||||
int allocationPendingShards = 0;
|
||||
List<ShardRouting> allShards = clusterState.getRoutingTable().allShards(index.getName());
|
||||
for (ShardRouting shardRouting : allShards) {
|
||||
assert shardRouting.active() : "Shard not active, found " + shardRouting.state() + "for shard with id: "
|
||||
+ shardRouting.shardId();
|
||||
String currentNodeId = shardRouting.currentNodeId();
|
||||
boolean canRemainOnCurrentNode = allocationDeciders.canRemain(shardRouting,
|
||||
clusterState.getRoutingNodes().node(currentNodeId), allocation).type() == Decision.Type.YES;
|
||||
boolean canRemainOnCurrentNode = ALLOCATION_DECIDERS
|
||||
.canRemain(shardRouting, clusterState.getRoutingNodes().node(currentNodeId), allocation).type() == Decision.Type.YES;
|
||||
if (canRemainOnCurrentNode == false) {
|
||||
allocationPendingShards++;
|
||||
}
|
||||
}
|
||||
if (allocationPendingShards > 0) {
|
||||
logger.debug("[{}] lifecycle action for index [{}] waiting for [{}] shards "
|
||||
+ "to be allocated to nodes matching the given filters", getKey().getAction(), index, allocationPendingShards);
|
||||
logger.debug(
|
||||
"[{}] lifecycle action for index [{}] waiting for [{}] shards " + "to be allocated to nodes matching the given filters",
|
||||
getKey().getAction(), index, allocationPendingShards);
|
||||
return false;
|
||||
} else {
|
||||
logger.debug("[{}] lifecycle action for index [{}] complete", getKey().getAction(), index);
|
||||
|
|
|
@ -10,6 +10,8 @@ import org.elasticsearch.cluster.ClusterState;
|
|||
import org.elasticsearch.index.Index;
|
||||
|
||||
public class EnoughShardsWaitStep extends ClusterStateWaitStep {
|
||||
public static final String NAME = "enough-shards-allocated";
|
||||
|
||||
public EnoughShardsWaitStep(StepKey key, StepKey nextStepKey) {
|
||||
super(key, nextStepKey);
|
||||
}
|
||||
|
|
|
@ -42,7 +42,8 @@ public abstract class Step {
|
|||
return false;
|
||||
}
|
||||
Step other = (Step) obj;
|
||||
return Objects.equals(key, other.key) && Objects.equals(nextStepKey, other.nextStepKey);
|
||||
return Objects.equals(key, other.key) &&
|
||||
Objects.equals(nextStepKey, other.nextStepKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -87,7 +88,9 @@ public abstract class Step {
|
|||
return false;
|
||||
}
|
||||
StepKey other = (StepKey) obj;
|
||||
return Objects.equals(phase, other.phase) && Objects.equals(action, other.action) && Objects.equals(name, other.name);
|
||||
return Objects.equals(phase, other.phase) &&
|
||||
Objects.equals(action, other.action) &&
|
||||
Objects.equals(name, other.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12,8 +12,11 @@ import org.elasticsearch.common.settings.Settings;
|
|||
import org.elasticsearch.index.Index;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class UpdateAllocationSettingsStep extends ClusterStateActionStep {
|
||||
public static final String NAME = "update-allocation";
|
||||
|
||||
private final Map<String, String> include;
|
||||
private final Map<String, String> exclude;
|
||||
private final Map<String, String> require;
|
||||
|
@ -54,4 +57,36 @@ public class UpdateAllocationSettingsStep extends ClusterStateActionStep {
|
|||
return existingValue == null || (existingValue.equals(e.getValue()) == false);
|
||||
}).forEach(e -> newSettingsBuilder.put(settingPrefix + e.getKey(), e.getValue()));
|
||||
}
|
||||
|
||||
Map<String, String> getInclude() {
|
||||
return include;
|
||||
}
|
||||
|
||||
Map<String, String> getExclude() {
|
||||
return exclude;
|
||||
}
|
||||
|
||||
Map<String, String> getRequire() {
|
||||
return require;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), include, exclude, require);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
UpdateAllocationSettingsStep other = (UpdateAllocationSettingsStep) obj;
|
||||
return super.equals(obj) &&
|
||||
Objects.equals(include, other.include) &&
|
||||
Objects.equals(exclude, other.exclude) &&
|
||||
Objects.equals(require, other.require);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,39 +5,15 @@
|
|||
*/
|
||||
package org.elasticsearch.xpack.core.indexlifecycle;
|
||||
|
||||
import org.apache.lucene.util.SetOnce;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNodes;
|
||||
import org.elasticsearch.cluster.routing.IndexRoutingTable;
|
||||
import org.elasticsearch.cluster.routing.RoutingTable;
|
||||
import org.elasticsearch.cluster.routing.ShardRoutingState;
|
||||
import org.elasticsearch.cluster.routing.TestShardRouting;
|
||||
import org.elasticsearch.cluster.routing.UnassignedInfo;
|
||||
import org.elasticsearch.cluster.routing.UnassignedInfo.Reason;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.FilterAllocationDecider;
|
||||
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
||||
import org.elasticsearch.common.io.stream.Writeable.Reader;
|
||||
import org.elasticsearch.common.settings.ClusterSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.transport.TransportAddress;
|
||||
import org.elasticsearch.common.util.set.Sets;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.IndexNotFoundException;
|
||||
import org.elasticsearch.index.shard.ShardId;
|
||||
import org.elasticsearch.node.Node;
|
||||
import org.elasticsearch.test.AbstractSerializingTestCase;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
|
||||
public class AllocateActionTests extends AbstractSerializingTestCase<AllocateAction> {
|
||||
|
||||
|
@ -112,371 +88,7 @@ public class AllocateActionTests extends AbstractSerializingTestCase<AllocateAct
|
|||
+ "must contain attributes for action " + AllocateAction.NAME, exception.getMessage());
|
||||
}
|
||||
|
||||
// public void testExecuteNoExistingSettings() throws Exception {
|
||||
// Map<String, String> includes = randomMap(1, 5);
|
||||
// Map<String, String> excludes = randomMap(1, 5);
|
||||
// Map<String, String> requires = randomMap(1, 5);
|
||||
// Settings.Builder existingSettings = Settings.builder().put("index.version.created", Version.CURRENT.id);
|
||||
// Settings.Builder expectedSettings = Settings.builder();
|
||||
// includes.forEach((k, v) -> expectedSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + k, v));
|
||||
// excludes.forEach((k, v) -> expectedSettings.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + k, v));
|
||||
// requires.forEach((k, v) -> expectedSettings.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + k, v));
|
||||
// AllocateAction action = new AllocateAction(includes, excludes, requires);
|
||||
//
|
||||
// assertSettingsUpdate(action, existingSettings, expectedSettings.build());
|
||||
// }
|
||||
//
|
||||
// public void testExecuteSettingsUnassignedShards() throws Exception {
|
||||
// Map<String, String> includes = randomMap(1, 5);
|
||||
// Map<String, String> excludes = randomMap(1, 5);
|
||||
// Map<String, String> requires = randomMap(1, 5);
|
||||
// Settings.Builder existingSettings = Settings.builder().put("index.version.created", Version.CURRENT.id);
|
||||
// Settings.Builder expectedSettings = Settings.builder();
|
||||
// includes.forEach((k, v) -> expectedSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + k, v));
|
||||
// excludes.forEach((k, v) -> expectedSettings.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + k, v));
|
||||
// requires.forEach((k, v) -> expectedSettings.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + k, v));
|
||||
// AllocateAction action = new AllocateAction(includes, excludes, requires);
|
||||
//
|
||||
// assertSettingsUpdate(action, existingSettings, expectedSettings.build());
|
||||
// }
|
||||
//
|
||||
// public void testExecuteSomeExistingSettings() throws Exception {
|
||||
// Map<String, String> includes = randomMap(1, 5);
|
||||
// Map<String, String> excludes = randomMap(1, 5);
|
||||
// Map<String, String> requires = randomMap(1, 5);
|
||||
// Settings.Builder existingSettings = Settings.builder().put("index.version.created", Version.CURRENT.id);
|
||||
// Settings.Builder expectedSettings = Settings.builder();
|
||||
// includes.forEach((k, v) -> {
|
||||
// if (randomBoolean()) {
|
||||
// existingSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
// } else {
|
||||
// expectedSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
// }
|
||||
// });
|
||||
// excludes.forEach((k, v) -> {
|
||||
// if (randomBoolean()) {
|
||||
// existingSettings.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
// } else {
|
||||
// expectedSettings.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
// }
|
||||
// });
|
||||
// requires.forEach((k, v) -> {
|
||||
// if (randomBoolean()) {
|
||||
// existingSettings.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + k, v);
|
||||
// } else {
|
||||
// expectedSettings.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + k, v);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// // make sure there is at least one setting that is missing
|
||||
// if (expectedSettings.keys().isEmpty()) {
|
||||
// String key = randomAlphaOfLengthBetween(1, 20);
|
||||
// String value = randomAlphaOfLengthBetween(1, 20);
|
||||
// includes.put(key, value);
|
||||
// expectedSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + key, value);
|
||||
// }
|
||||
// AllocateAction action = new AllocateAction(includes, excludes, requires);
|
||||
//
|
||||
// assertSettingsUpdate(action, existingSettings, expectedSettings.build());
|
||||
// }
|
||||
//
|
||||
// public void testExecuteSomeExistingSettingsDifferentValue() throws Exception {
|
||||
// Map<String, String> includes = randomMap(1, 5);
|
||||
// Map<String, String> excludes = randomMap(1, 5);
|
||||
// Map<String, String> requires = randomMap(1, 5);
|
||||
// Settings.Builder existingSettings = Settings.builder().put("index.version.created", Version.CURRENT.id);
|
||||
// Settings.Builder expectedSettings = Settings.builder();
|
||||
// includes.forEach((k, v) -> {
|
||||
// if (randomBoolean()) {
|
||||
// existingSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
// } else {
|
||||
// expectedSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
// existingSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + k, v + randomAlphaOfLength(4));
|
||||
// }
|
||||
// });
|
||||
// excludes.forEach((k, v) -> {
|
||||
// if (randomBoolean()) {
|
||||
// existingSettings.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
// } else {
|
||||
// expectedSettings.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
// existingSettings.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + k, v + randomAlphaOfLength(4));
|
||||
// }
|
||||
// });
|
||||
// requires.forEach((k, v) -> {
|
||||
// if (randomBoolean()) {
|
||||
// existingSettings.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + k, v);
|
||||
// } else {
|
||||
// expectedSettings.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + k, v);
|
||||
// existingSettings.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + k, v + randomAlphaOfLength(4));
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// // make sure there is at least one setting that is different
|
||||
// if (expectedSettings.keys().isEmpty()) {
|
||||
// String key = randomAlphaOfLengthBetween(1, 20);
|
||||
// String value = randomAlphaOfLengthBetween(1, 20);
|
||||
// includes.put(key, value);
|
||||
// expectedSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + key, value);
|
||||
// existingSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + key, value + randomAlphaOfLength(4));
|
||||
// }
|
||||
// AllocateAction action = new AllocateAction(includes, excludes, requires);
|
||||
//
|
||||
// assertSettingsUpdate(action, existingSettings, expectedSettings.build());
|
||||
// }
|
||||
//
|
||||
// public void testExecuteUpdateSettingsFail() throws Exception {
|
||||
// Settings expectedSettings = Settings.builder().put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + "box_type", "foo")
|
||||
// .put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + "box_type", "bar")
|
||||
// .put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + "box_type", "baz").build();
|
||||
// IndexMetaData indexMetadata = IndexMetaData.builder(randomAlphaOfLengthBetween(1, 20))
|
||||
// .settings(Settings.builder().put("index.version.created", Version.CURRENT.id)).numberOfShards(randomIntBetween(1, 5))
|
||||
// .numberOfReplicas(randomIntBetween(0, 5)).build();
|
||||
// Index index = indexMetadata.getIndex();
|
||||
// ImmutableOpenMap.Builder<String, IndexMetaData> indices = ImmutableOpenMap.<String, IndexMetaData> builder().fPut(index.getName(),
|
||||
// indexMetadata);
|
||||
// ClusterState clusterState = ClusterState.builder(ClusterState.EMPTY_STATE).metaData(MetaData.builder().indices(indices.build()))
|
||||
// .routingTable(RoutingTable.builder()
|
||||
// .add(IndexRoutingTable.builder(index).addShard(
|
||||
// TestShardRouting.newShardRouting(new ShardId(index, 0), "node1", true, ShardRoutingState.STARTED)))
|
||||
// .build())
|
||||
// .build();
|
||||
// Exception exception = new RuntimeException();
|
||||
//
|
||||
// BiConsumer<Settings, Listener> settingsUpdater = (s, l) -> {
|
||||
// assertEquals(expectedSettings, s);
|
||||
// l.onFailure(exception);
|
||||
// };
|
||||
//
|
||||
// Map<String, String> includes = new HashMap<>();
|
||||
// includes.put("box_type", "foo");
|
||||
// Map<String, String> excludes = new HashMap<>();
|
||||
// excludes.put("box_type", "bar");
|
||||
// Map<String, String> requires = new HashMap<>();
|
||||
// requires.put("box_type", "baz");
|
||||
//
|
||||
// AllocateAction action = new AllocateAction(includes, excludes, requires);
|
||||
//
|
||||
// RuntimeException thrownException =
|
||||
// expectActionFailure(index, clusterState, null, action, settingsUpdater, RuntimeException.class);
|
||||
// assertSame(exception, thrownException);
|
||||
//
|
||||
// }
|
||||
//
|
||||
// public void testExecuteAllocateComplete() throws Exception {
|
||||
// Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
|
||||
// Map<String, String> includes = randomMap(1, 5);
|
||||
// Map<String, String> excludes = randomMap(1, 5);
|
||||
// Map<String, String> requires = randomMap(1, 5);
|
||||
// Settings.Builder existingSettings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT.id)
|
||||
// .put(IndexMetaData.SETTING_INDEX_UUID, index.getUUID());
|
||||
// Settings.Builder expectedSettings = Settings.builder();
|
||||
// Settings.Builder node1Settings = Settings.builder();
|
||||
// Settings.Builder node2Settings = Settings.builder();
|
||||
// includes.forEach((k, v) -> {
|
||||
// existingSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
// expectedSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
// node1Settings.put(Node.NODE_ATTRIBUTES.getKey() + k, v);
|
||||
// });
|
||||
// excludes.forEach((k, v) -> {
|
||||
// existingSettings.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
// expectedSettings.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
// });
|
||||
// requires.forEach((k, v) -> {
|
||||
// existingSettings.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + k, v);
|
||||
// expectedSettings.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + k, v);
|
||||
// node1Settings.put(Node.NODE_ATTRIBUTES.getKey() + k, v);
|
||||
// });
|
||||
//
|
||||
// IndexRoutingTable.Builder indexRoutingTable = IndexRoutingTable.builder(index)
|
||||
// .addShard(TestShardRouting.newShardRouting(new ShardId(index, 0), "node1", true, ShardRoutingState.STARTED));
|
||||
//
|
||||
// AllocateAction action = new AllocateAction(includes, excludes, requires);
|
||||
// assertAllocateStatus(index, 1, 0, action, existingSettings, node1Settings, node2Settings, indexRoutingTable,
|
||||
// true);
|
||||
// }
|
||||
//
|
||||
// public void testExecuteAllocateNotComplete() throws Exception {
|
||||
// Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
|
||||
// Map<String, String> includes = randomMap(1, 5);
|
||||
// Map<String, String> excludes = randomMap(1, 5);
|
||||
// Map<String, String> requires = randomMap(1, 5);
|
||||
// Settings.Builder existingSettings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT.id)
|
||||
// .put(IndexMetaData.SETTING_INDEX_UUID, index.getUUID());
|
||||
// Settings.Builder expectedSettings = Settings.builder();
|
||||
// Settings.Builder node1Settings = Settings.builder();
|
||||
// Settings.Builder node2Settings = Settings.builder();
|
||||
// includes.forEach((k, v) -> {
|
||||
// existingSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
// expectedSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
// node1Settings.put(Node.NODE_ATTRIBUTES.getKey() + k, v);
|
||||
// });
|
||||
// excludes.forEach((k, v) -> {
|
||||
// existingSettings.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
// expectedSettings.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
// });
|
||||
// requires.forEach((k, v) -> {
|
||||
// existingSettings.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + k, v);
|
||||
// expectedSettings.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + k, v);
|
||||
// node1Settings.put(Node.NODE_ATTRIBUTES.getKey() + k, v);
|
||||
// });
|
||||
//
|
||||
// IndexRoutingTable.Builder indexRoutingTable = IndexRoutingTable.builder(index)
|
||||
// .addShard(TestShardRouting.newShardRouting(new ShardId(index, 0), "node1", true, ShardRoutingState.STARTED))
|
||||
// .addShard(TestShardRouting.newShardRouting(new ShardId(index, 1), "node2", true, ShardRoutingState.STARTED));
|
||||
//
|
||||
// AllocateAction action = new AllocateAction(includes, excludes, requires);
|
||||
// assertAllocateStatus(index, 2, 0, action, existingSettings, node1Settings, node2Settings, indexRoutingTable,
|
||||
// false);
|
||||
// }
|
||||
//
|
||||
// public void testExecuteAllocateUnassigned() throws Exception {
|
||||
// Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
|
||||
// Map<String, String> includes = randomMap(1, 5);
|
||||
// Map<String, String> excludes = randomMap(1, 5);
|
||||
// Map<String, String> requires = randomMap(1, 5);
|
||||
// Settings.Builder existingSettings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT.id)
|
||||
// .put(IndexMetaData.SETTING_INDEX_UUID, index.getUUID());
|
||||
// Settings.Builder expectedSettings = Settings.builder();
|
||||
// Settings.Builder node1Settings = Settings.builder();
|
||||
// Settings.Builder node2Settings = Settings.builder();
|
||||
// includes.forEach((k, v) -> {
|
||||
// existingSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
// expectedSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
// node1Settings.put(Node.NODE_ATTRIBUTES.getKey() + k, v);
|
||||
// });
|
||||
// excludes.forEach((k, v) -> {
|
||||
// existingSettings.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
// expectedSettings.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
// });
|
||||
// requires.forEach((k, v) -> {
|
||||
// existingSettings.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + k, v);
|
||||
// expectedSettings.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + k, v);
|
||||
// node1Settings.put(Node.NODE_ATTRIBUTES.getKey() + k, v);
|
||||
// });
|
||||
//
|
||||
// IndexRoutingTable.Builder indexRoutingTable = IndexRoutingTable.builder(index)
|
||||
// .addShard(TestShardRouting.newShardRouting(new ShardId(index, 0), "node1", true, ShardRoutingState.STARTED))
|
||||
// .addShard(TestShardRouting.newShardRouting(new ShardId(index, 1), null, null, true, ShardRoutingState.UNASSIGNED,
|
||||
// new UnassignedInfo(randomFrom(Reason.values()), "the shard is intentionally unassigned")));
|
||||
//
|
||||
// AllocateAction action = new AllocateAction(includes, excludes, requires);
|
||||
// assertAllocateStatus(index, 2, 0, action, existingSettings, node1Settings, node2Settings, indexRoutingTable,
|
||||
// false);
|
||||
// }
|
||||
//
|
||||
// public void testExecuteIndexMissing() throws Exception {
|
||||
// Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
|
||||
// ClusterState clusterState = ClusterState.builder(ClusterState.EMPTY_STATE).build();
|
||||
//
|
||||
// BiConsumer<Settings, Listener> settingsUpdater = (s, l) -> {
|
||||
// throw new AssertionError("Unexpected settings update");
|
||||
// };
|
||||
//
|
||||
// Map<String, String> includes = new HashMap<>();
|
||||
// includes.put("box_type", "foo");
|
||||
// Map<String, String> excludes = new HashMap<>();
|
||||
// excludes.put("box_type", "bar");
|
||||
// Map<String, String> requires = new HashMap<>();
|
||||
// requires.put("box_type", "baz");
|
||||
//
|
||||
// AllocateAction action = new AllocateAction(includes, excludes, requires);
|
||||
//
|
||||
// IndexNotFoundException thrownException = expectActionFailure(index, clusterState, null, action, settingsUpdater,
|
||||
// IndexNotFoundException.class);
|
||||
// assertEquals("Index not found when executing " + AllocateAction.NAME + " lifecycle action.", thrownException.getMessage());
|
||||
// assertEquals(index.getName(), thrownException.getIndex().getName());
|
||||
// }
|
||||
//
|
||||
// private void assertSettingsUpdate(AllocateAction action, Settings.Builder existingSettings, Settings expectedSettings) {
|
||||
// IndexMetaData indexMetadata = IndexMetaData.builder(randomAlphaOfLengthBetween(1, 20)).settings(existingSettings)
|
||||
// .numberOfShards(randomIntBetween(1, 5)).numberOfReplicas(randomIntBetween(0, 5)).build();
|
||||
// Index index = indexMetadata.getIndex();
|
||||
// ImmutableOpenMap.Builder<String, IndexMetaData> indices = ImmutableOpenMap.<String, IndexMetaData> builder().fPut(index.getName(),
|
||||
// indexMetadata);
|
||||
// ClusterState clusterState = ClusterState.builder(ClusterState.EMPTY_STATE).metaData(MetaData.builder().indices(indices.build()))
|
||||
// .routingTable(RoutingTable.builder()
|
||||
// .add(IndexRoutingTable.builder(index).addShard(
|
||||
// TestShardRouting.newShardRouting(new ShardId(index, 0), "node1", true, ShardRoutingState.STARTED)))
|
||||
// .build())
|
||||
// .build();
|
||||
//
|
||||
// BiConsumer<Settings, Listener> settingsUpdater = (s, l) -> {
|
||||
// assertEquals(expectedSettings, s);
|
||||
// l.onSuccess(false);
|
||||
// };
|
||||
// assertActionStatus(index, clusterState, null, action, settingsUpdater, false);
|
||||
// }
|
||||
//
|
||||
// private void assertAllocateStatus(Index index, int shards, int replicas, AllocateAction action, Settings.Builder existingSettings,
|
||||
// Settings.Builder node1Settings, Settings.Builder node2Settings, IndexRoutingTable.Builder indexRoutingTable,
|
||||
// boolean expectComplete) {
|
||||
// IndexMetaData indexMetadata = IndexMetaData.builder(index.getName()).settings(existingSettings).numberOfShards(shards)
|
||||
// .numberOfReplicas(replicas).build();
|
||||
// ImmutableOpenMap.Builder<String, IndexMetaData> indices = ImmutableOpenMap.<String, IndexMetaData> builder().fPut(index.getName(),
|
||||
// indexMetadata);
|
||||
//
|
||||
// ClusterState clusterState = ClusterState.builder(ClusterState.EMPTY_STATE).metaData(MetaData.builder().indices(indices.build()))
|
||||
// .nodes(DiscoveryNodes.builder()
|
||||
// .add(DiscoveryNode.createLocal(node1Settings.build(), new TransportAddress(TransportAddress.META_ADDRESS, 9200),
|
||||
// "node1"))
|
||||
// .add(DiscoveryNode.createLocal(node2Settings.build(), new TransportAddress(TransportAddress.META_ADDRESS, 9201),
|
||||
// "node2")))
|
||||
// .routingTable(RoutingTable.builder().add(indexRoutingTable).build()).build();
|
||||
// ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY,
|
||||
// Sets.newHashSet(FilterAllocationDecider.CLUSTER_ROUTING_INCLUDE_GROUP_SETTING,
|
||||
// FilterAllocationDecider.CLUSTER_ROUTING_EXCLUDE_GROUP_SETTING,
|
||||
// FilterAllocationDecider.CLUSTER_ROUTING_REQUIRE_GROUP_SETTING));
|
||||
//
|
||||
// BiConsumer<Settings, Listener> settingsUpdater = (s, l) -> {
|
||||
// throw new AssertionError("Unexpected settings update");
|
||||
// };
|
||||
//
|
||||
// assertActionStatus(index, clusterState, clusterSettings, action, settingsUpdater, expectComplete);
|
||||
// }
|
||||
//
|
||||
// private void assertActionStatus(Index index, ClusterState clusterState, ClusterSettings clusterSettings, AllocateAction action,
|
||||
// BiConsumer<Settings, Listener> settingsUpdater, boolean expectComplete) {
|
||||
//
|
||||
// SetOnce<Boolean> actionCompleted = new SetOnce<>();
|
||||
// action.execute(index, settingsUpdater, clusterState, clusterSettings, new Listener() {
|
||||
//
|
||||
// @Override
|
||||
// public void onSuccess(boolean completed) {
|
||||
// actionCompleted.set(completed);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onFailure(Exception e) {
|
||||
// throw new AssertionError("Unexpected method call");
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// assertEquals(expectComplete, actionCompleted.get());
|
||||
// }
|
||||
//
|
||||
// private <E> E expectActionFailure(Index index, ClusterState clusterState, ClusterSettings clusterSettings, AllocateAction action,
|
||||
// BiConsumer<Settings, Listener> settingsUpdater, Class<E> expectedExceptionType) {
|
||||
//
|
||||
// SetOnce<E> exceptionThrown = new SetOnce<>();
|
||||
// action.execute(index, settingsUpdater, clusterState, clusterSettings, new Listener() {
|
||||
//
|
||||
// @Override
|
||||
// public void onSuccess(boolean completed) {
|
||||
// throw new AssertionError("Unexpected method call");
|
||||
// }
|
||||
//
|
||||
// @SuppressWarnings("unchecked")
|
||||
// @Override
|
||||
// public void onFailure(Exception e) {
|
||||
// assertThat(e, instanceOf(expectedExceptionType));
|
||||
// exceptionThrown.set((E) e);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// return exceptionThrown.get();
|
||||
// }
|
||||
|
||||
private Map<String, String> randomMap(int minEntries, int maxEntries) {
|
||||
public static Map<String, String> randomMap(int minEntries, int maxEntries) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
int numIncludes = randomIntBetween(minEntries, maxEntries);
|
||||
for (int i = 0; i < numIncludes; i++) {
|
||||
|
@ -485,4 +97,29 @@ public class AllocateActionTests extends AbstractSerializingTestCase<AllocateAct
|
|||
return map;
|
||||
}
|
||||
|
||||
public void testToSteps() {
|
||||
AllocateAction 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(3, steps.size());
|
||||
StepKey expectedFirstStepKey = new StepKey(phase, AllocateAction.NAME, EnoughShardsWaitStep.NAME);
|
||||
StepKey expectedSecondStepKey = new StepKey(phase, AllocateAction.NAME, UpdateAllocationSettingsStep.NAME);
|
||||
StepKey expectedThirdStepKey = new StepKey(phase, AllocateAction.NAME, AllocationRoutedStep.NAME);
|
||||
EnoughShardsWaitStep firstStep = (EnoughShardsWaitStep) steps.get(0);
|
||||
assertEquals(expectedFirstStepKey, firstStep.getKey());
|
||||
assertEquals(expectedSecondStepKey, firstStep.getNextStepKey());
|
||||
UpdateAllocationSettingsStep secondStep = (UpdateAllocationSettingsStep) steps.get(1);
|
||||
assertEquals(expectedSecondStepKey, secondStep.getKey());
|
||||
assertEquals(expectedThirdStepKey, secondStep.getNextStepKey());
|
||||
assertEquals(action.getInclude(), secondStep.getInclude());
|
||||
assertEquals(action.getExclude(), secondStep.getExclude());
|
||||
assertEquals(action.getRequire(), secondStep.getRequire());
|
||||
AllocationRoutedStep thirdStep = (AllocationRoutedStep) steps.get(2);
|
||||
assertEquals(expectedThirdStepKey, thirdStep.getKey());
|
||||
assertEquals(nextStepKey, thirdStep.getNextStepKey());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
package org.elasticsearch.xpack.core.indexlifecycle;
|
||||
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
|
@ -13,22 +14,166 @@ import org.elasticsearch.cluster.node.DiscoveryNode;
|
|||
import org.elasticsearch.cluster.node.DiscoveryNodes;
|
||||
import org.elasticsearch.cluster.routing.IndexRoutingTable;
|
||||
import org.elasticsearch.cluster.routing.RoutingTable;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.FilterAllocationDecider;
|
||||
import org.elasticsearch.cluster.routing.ShardRoutingState;
|
||||
import org.elasticsearch.cluster.routing.TestShardRouting;
|
||||
import org.elasticsearch.cluster.routing.UnassignedInfo;
|
||||
import org.elasticsearch.cluster.routing.UnassignedInfo.Reason;
|
||||
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
||||
import org.elasticsearch.common.settings.ClusterSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.transport.TransportAddress;
|
||||
import org.elasticsearch.common.util.set.Sets;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.IndexNotFoundException;
|
||||
import org.elasticsearch.index.shard.ShardId;
|
||||
import org.elasticsearch.node.Node;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.test.EqualsHashCodeTestUtils;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class AllocationRoutedStepTests extends ESTestCase {
|
||||
|
||||
public void testCanStay() {
|
||||
public AllocationRoutedStep createRandomInstance() {
|
||||
StepKey stepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
StepKey nextStepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
|
||||
return new AllocationRoutedStep(stepKey, nextStepKey);
|
||||
}
|
||||
|
||||
private void assertAllocateStatus(Index index, int shards, int replicas, AllocateAction action, Settings.Builder existingSettings,
|
||||
public AllocationRoutedStep mutateInstance(AllocationRoutedStep instance) {
|
||||
StepKey key = instance.getKey();
|
||||
StepKey nextKey = instance.getNextStepKey();
|
||||
|
||||
switch (between(0, 1)) {
|
||||
case 0:
|
||||
key = new StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5));
|
||||
break;
|
||||
case 1:
|
||||
nextKey = new StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5));
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError("Illegal randomisation branch");
|
||||
}
|
||||
|
||||
return new AllocationRoutedStep(key, nextKey);
|
||||
}
|
||||
|
||||
public void testHashcodeAndEquals() {
|
||||
EqualsHashCodeTestUtils.checkEqualsAndHashCode(createRandomInstance(),
|
||||
instance -> new AllocationRoutedStep(instance.getKey(), instance.getNextStepKey()), this::mutateInstance);
|
||||
}
|
||||
|
||||
public void testConditionMet() {
|
||||
Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
|
||||
Map<String, String> includes = AllocateActionTests.randomMap(1, 5);
|
||||
Map<String, String> excludes = AllocateActionTests.randomMap(1, 5);
|
||||
Map<String, String> requires = AllocateActionTests.randomMap(1, 5);
|
||||
Settings.Builder existingSettings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT.id)
|
||||
.put(IndexMetaData.SETTING_INDEX_UUID, index.getUUID());
|
||||
Settings.Builder expectedSettings = Settings.builder();
|
||||
Settings.Builder node1Settings = Settings.builder();
|
||||
Settings.Builder node2Settings = Settings.builder();
|
||||
includes.forEach((k, v) -> {
|
||||
existingSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
expectedSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
node1Settings.put(Node.NODE_ATTRIBUTES.getKey() + k, v);
|
||||
});
|
||||
excludes.forEach((k, v) -> {
|
||||
existingSettings.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
expectedSettings.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
});
|
||||
requires.forEach((k, v) -> {
|
||||
existingSettings.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + k, v);
|
||||
expectedSettings.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + k, v);
|
||||
node1Settings.put(Node.NODE_ATTRIBUTES.getKey() + k, v);
|
||||
});
|
||||
|
||||
IndexRoutingTable.Builder indexRoutingTable = IndexRoutingTable.builder(index)
|
||||
.addShard(TestShardRouting.newShardRouting(new ShardId(index, 0), "node1", true, ShardRoutingState.STARTED));
|
||||
|
||||
AllocationRoutedStep step = createRandomInstance();
|
||||
assertAllocateStatus(index, 1, 0, step, existingSettings, node1Settings, node2Settings, indexRoutingTable, true);
|
||||
}
|
||||
|
||||
public void testExecuteAllocateNotComplete() throws Exception {
|
||||
Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
|
||||
Map<String, String> includes = AllocateActionTests.randomMap(1, 5);
|
||||
Map<String, String> excludes = AllocateActionTests.randomMap(1, 5);
|
||||
Map<String, String> requires = AllocateActionTests.randomMap(1, 5);
|
||||
Settings.Builder existingSettings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT.id)
|
||||
.put(IndexMetaData.SETTING_INDEX_UUID, index.getUUID());
|
||||
Settings.Builder expectedSettings = Settings.builder();
|
||||
Settings.Builder node1Settings = Settings.builder();
|
||||
Settings.Builder node2Settings = Settings.builder();
|
||||
includes.forEach((k, v) -> {
|
||||
existingSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
expectedSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
node1Settings.put(Node.NODE_ATTRIBUTES.getKey() + k, v);
|
||||
});
|
||||
excludes.forEach((k, v) -> {
|
||||
existingSettings.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
expectedSettings.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
});
|
||||
requires.forEach((k, v) -> {
|
||||
existingSettings.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + k, v);
|
||||
expectedSettings.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + k, v);
|
||||
node1Settings.put(Node.NODE_ATTRIBUTES.getKey() + k, v);
|
||||
});
|
||||
|
||||
IndexRoutingTable.Builder indexRoutingTable = IndexRoutingTable.builder(index)
|
||||
.addShard(TestShardRouting.newShardRouting(new ShardId(index, 0), "node1", true, ShardRoutingState.STARTED))
|
||||
.addShard(TestShardRouting.newShardRouting(new ShardId(index, 1), "node2", true, ShardRoutingState.STARTED));
|
||||
|
||||
AllocationRoutedStep step = createRandomInstance();
|
||||
assertAllocateStatus(index, 2, 0, step, existingSettings, node1Settings, node2Settings, indexRoutingTable, false);
|
||||
}
|
||||
|
||||
public void testExecuteAllocateUnassigned() throws Exception {
|
||||
Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
|
||||
Map<String, String> includes = AllocateActionTests.randomMap(1, 5);
|
||||
Map<String, String> excludes = AllocateActionTests.randomMap(1, 5);
|
||||
Map<String, String> requires = AllocateActionTests.randomMap(1, 5);
|
||||
Settings.Builder existingSettings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT.id)
|
||||
.put(IndexMetaData.SETTING_INDEX_UUID, index.getUUID());
|
||||
Settings.Builder expectedSettings = Settings.builder();
|
||||
Settings.Builder node1Settings = Settings.builder();
|
||||
Settings.Builder node2Settings = Settings.builder();
|
||||
includes.forEach((k, v) -> {
|
||||
existingSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
expectedSettings.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
node1Settings.put(Node.NODE_ATTRIBUTES.getKey() + k, v);
|
||||
});
|
||||
excludes.forEach((k, v) -> {
|
||||
existingSettings.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
expectedSettings.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + k, v);
|
||||
});
|
||||
requires.forEach((k, v) -> {
|
||||
existingSettings.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + k, v);
|
||||
expectedSettings.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + k, v);
|
||||
node1Settings.put(Node.NODE_ATTRIBUTES.getKey() + k, v);
|
||||
});
|
||||
|
||||
IndexRoutingTable.Builder indexRoutingTable = IndexRoutingTable.builder(index)
|
||||
.addShard(TestShardRouting.newShardRouting(new ShardId(index, 0), "node1", true, ShardRoutingState.STARTED))
|
||||
.addShard(TestShardRouting.newShardRouting(new ShardId(index, 1), null, null, true, ShardRoutingState.UNASSIGNED,
|
||||
new UnassignedInfo(randomFrom(Reason.values()), "the shard is intentionally unassigned")));
|
||||
|
||||
AllocationRoutedStep step = createRandomInstance();
|
||||
assertAllocateStatus(index, 2, 0, step, existingSettings, node1Settings, node2Settings, indexRoutingTable, false);
|
||||
}
|
||||
|
||||
public void testExecuteIndexMissing() throws Exception {
|
||||
Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
|
||||
ClusterState clusterState = ClusterState.builder(ClusterState.EMPTY_STATE).build();
|
||||
|
||||
AllocationRoutedStep step = createRandomInstance();
|
||||
|
||||
IndexNotFoundException thrownException = expectThrows(IndexNotFoundException.class, () -> step.isConditionMet(index, clusterState));
|
||||
assertEquals("Index not found when executing " + step.getKey().getAction() + " lifecycle action.", thrownException.getMessage());
|
||||
assertEquals(index.getName(), thrownException.getIndex().getName());
|
||||
}
|
||||
|
||||
private void assertAllocateStatus(Index index, int shards, int replicas, AllocationRoutedStep step, Settings.Builder existingSettings,
|
||||
Settings.Builder node1Settings, Settings.Builder node2Settings,
|
||||
IndexRoutingTable.Builder indexRoutingTable, boolean expectComplete) {
|
||||
IndexMetaData indexMetadata = IndexMetaData.builder(index.getName()).settings(existingSettings).numberOfShards(shards)
|
||||
|
@ -43,9 +188,6 @@ public class AllocationRoutedStepTests extends ESTestCase {
|
|||
.add(DiscoveryNode.createLocal(node2Settings.build(), new TransportAddress(TransportAddress.META_ADDRESS, 9201),
|
||||
"node2")))
|
||||
.routingTable(RoutingTable.builder().add(indexRoutingTable).build()).build();
|
||||
ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY,
|
||||
Sets.newHashSet(FilterAllocationDecider.CLUSTER_ROUTING_INCLUDE_GROUP_SETTING,
|
||||
FilterAllocationDecider.CLUSTER_ROUTING_EXCLUDE_GROUP_SETTING,
|
||||
FilterAllocationDecider.CLUSTER_ROUTING_REQUIRE_GROUP_SETTING));
|
||||
assertEquals(expectComplete, step.isConditionMet(index, clusterState));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
package org.elasticsearch.xpack.core.indexlifecycle;
|
||||
|
||||
|
||||
import com.carrotsearch.randomizedtesting.annotations.Repeat;
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cluster.ClusterName;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
|
@ -22,9 +24,42 @@ import org.elasticsearch.index.Index;
|
|||
import org.elasticsearch.index.shard.ShardId;
|
||||
import org.elasticsearch.node.Node;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.test.EqualsHashCodeTestUtils;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
|
||||
|
||||
@Repeat(iterations = 1000, useConstantSeed = false)
|
||||
public class EnoughShardsWaitStepTests extends ESTestCase {
|
||||
|
||||
public EnoughShardsWaitStep createRandomInstance() {
|
||||
StepKey stepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
StepKey nextStepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
|
||||
return new EnoughShardsWaitStep(stepKey, nextStepKey);
|
||||
}
|
||||
|
||||
public EnoughShardsWaitStep mutateInstance(EnoughShardsWaitStep instance) {
|
||||
StepKey key = instance.getKey();
|
||||
StepKey nextKey = instance.getNextStepKey();
|
||||
|
||||
switch (between(0, 1)) {
|
||||
case 0:
|
||||
key = new StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5));
|
||||
break;
|
||||
case 1:
|
||||
nextKey = new StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5));
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError("Illegal randomisation branch");
|
||||
}
|
||||
|
||||
return new EnoughShardsWaitStep(key, nextKey);
|
||||
}
|
||||
|
||||
public void testHashcodeAndEquals() {
|
||||
EqualsHashCodeTestUtils.checkEqualsAndHashCode(createRandomInstance(),
|
||||
instance -> new EnoughShardsWaitStep(instance.getKey(), instance.getNextStepKey()), this::mutateInstance);
|
||||
}
|
||||
|
||||
public void testConditionMet() {
|
||||
IndexMetaData indexMetadata = IndexMetaData.builder(randomAlphaOfLength(5))
|
||||
.settings(settings(Version.CURRENT))
|
||||
|
@ -51,7 +86,7 @@ public class EnoughShardsWaitStepTests extends ESTestCase {
|
|||
.build())
|
||||
.build();
|
||||
|
||||
EnoughShardsWaitStep step = new EnoughShardsWaitStep(null, null);
|
||||
EnoughShardsWaitStep step = createRandomInstance();
|
||||
assertTrue(step.isConditionMet(indexMetadata.getIndex(), clusterState));
|
||||
}
|
||||
|
||||
|
@ -81,7 +116,7 @@ public class EnoughShardsWaitStepTests extends ESTestCase {
|
|||
.build())
|
||||
.build();
|
||||
|
||||
EnoughShardsWaitStep step = new EnoughShardsWaitStep(null, null);
|
||||
EnoughShardsWaitStep step = createRandomInstance();
|
||||
assertFalse(step.isConditionMet(indexMetadata.getIndex(), clusterState));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,8 +14,11 @@ import org.elasticsearch.cluster.metadata.MetaData;
|
|||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.test.EqualsHashCodeTestUtils;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -24,7 +27,57 @@ import static org.hamcrest.Matchers.equalTo;
|
|||
|
||||
public class UpdateAllocationSettingsStepTests extends ESTestCase {
|
||||
|
||||
public void testModify() {
|
||||
public UpdateAllocationSettingsStep createRandomInstance() {
|
||||
StepKey stepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
StepKey nextStepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
Map<String, String> include = AllocateActionTests.randomMap(0, 10);
|
||||
Map<String, String> exclude = AllocateActionTests.randomMap(0, 10);
|
||||
Map<String, String> require = AllocateActionTests.randomMap(0, 10);
|
||||
|
||||
return new UpdateAllocationSettingsStep(stepKey, nextStepKey, include, exclude, require);
|
||||
}
|
||||
|
||||
public UpdateAllocationSettingsStep mutateInstance(UpdateAllocationSettingsStep instance) {
|
||||
StepKey key = instance.getKey();
|
||||
StepKey nextKey = instance.getNextStepKey();
|
||||
Map<String, String> include = instance.getInclude();
|
||||
Map<String, String> exclude = instance.getExclude();
|
||||
Map<String, String> require = instance.getRequire();
|
||||
|
||||
switch (between(0, 4)) {
|
||||
case 0:
|
||||
key = new StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5));
|
||||
break;
|
||||
case 1:
|
||||
nextKey = new StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5));
|
||||
break;
|
||||
case 2:
|
||||
include = new HashMap<>(include);
|
||||
include.put(randomAlphaOfLengthBetween(11, 15), randomAlphaOfLengthBetween(1, 20));
|
||||
break;
|
||||
case 3:
|
||||
exclude = new HashMap<>(exclude);
|
||||
exclude.put(randomAlphaOfLengthBetween(11, 15), randomAlphaOfLengthBetween(1, 20));
|
||||
break;
|
||||
case 4:
|
||||
require = new HashMap<>(require);
|
||||
require.put(randomAlphaOfLengthBetween(11, 15), randomAlphaOfLengthBetween(1, 20));
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError("Illegal randomisation branch");
|
||||
}
|
||||
|
||||
return new UpdateAllocationSettingsStep(key, nextKey, include, exclude, require);
|
||||
}
|
||||
|
||||
public void testHashcodeAndEquals() {
|
||||
EqualsHashCodeTestUtils.checkEqualsAndHashCode(createRandomInstance(),
|
||||
instance -> new UpdateAllocationSettingsStep(instance.getKey(), instance.getNextStepKey(), instance.getInclude(),
|
||||
instance.getExclude(), instance.getRequire()),
|
||||
this::mutateInstance);
|
||||
}
|
||||
|
||||
public void testPerformAction() {
|
||||
IndexMetaData indexMetadata = IndexMetaData.builder(randomAlphaOfLength(5))
|
||||
.settings(settings(Version.CURRENT))
|
||||
.numberOfShards(1)
|
||||
|
@ -36,18 +89,21 @@ public class UpdateAllocationSettingsStepTests extends ESTestCase {
|
|||
Index index = indexMetadata.getIndex();
|
||||
ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT).metaData(metaData).build();
|
||||
|
||||
Map<String, String> include =
|
||||
randomBoolean() ? Collections.singletonMap(randomAlphaOfLength(5), randomAlphaOfLength(5)) : Collections.emptyMap();
|
||||
Map<String, String> exclude =
|
||||
randomBoolean() ? Collections.singletonMap(randomAlphaOfLength(5), randomAlphaOfLength(5)) : Collections.emptyMap();
|
||||
Map<String, String> require =
|
||||
randomBoolean() ? Collections.singletonMap(randomAlphaOfLength(5), randomAlphaOfLength(5)) : Collections.emptyMap();
|
||||
|
||||
UpdateAllocationSettingsStep step = new UpdateAllocationSettingsStep(null, null, include, exclude, require);
|
||||
UpdateAllocationSettingsStep step = createRandomInstance();
|
||||
ClusterState newState = step.performAction(index, clusterState);
|
||||
assertThat(getRouting(index, newState, IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey()), equalTo(include));
|
||||
assertThat(getRouting(index, newState, IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey()), equalTo(exclude));
|
||||
assertThat(getRouting(index, newState, IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey()), equalTo(require));
|
||||
assertThat(getRouting(index, newState, IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey()), equalTo(step.getInclude()));
|
||||
assertThat(getRouting(index, newState, IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey()), equalTo(step.getExclude()));
|
||||
assertThat(getRouting(index, newState, IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey()), equalTo(step.getRequire()));
|
||||
}
|
||||
|
||||
public void testPerformActionNoIndex() {
|
||||
MetaData metaData = MetaData.builder().persistentSettings(settings(Version.CURRENT).build()).build();
|
||||
Index index = new Index("invalid_index", "invalid_index_id");
|
||||
ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT).metaData(metaData).build();
|
||||
|
||||
UpdateAllocationSettingsStep step = createRandomInstance();
|
||||
ClusterState newState = step.performAction(index, clusterState);
|
||||
assertSame(clusterState, newState);
|
||||
}
|
||||
|
||||
public void testAddMissingAttr() {
|
||||
|
@ -67,6 +123,45 @@ public class UpdateAllocationSettingsStepTests extends ESTestCase {
|
|||
assertThat(newSettingsBuilder.build(), equalTo(expectedSettingsBuilder.build()));
|
||||
}
|
||||
|
||||
public void testAddMissingAttrDiffenerentValue() {
|
||||
String prefix = randomFrom(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey(),
|
||||
IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey(),
|
||||
IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey());
|
||||
String newKey = randomAlphaOfLength(4);
|
||||
String newValue = randomAlphaOfLength(5);
|
||||
Map<String, String> newAttrs = Collections.singletonMap(newKey, newValue);
|
||||
Settings existingSettings = Settings.builder()
|
||||
.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + "box_type", "foo")
|
||||
.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + "box_type", "bar")
|
||||
.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + "box_type", "baz")
|
||||
.put(prefix + newKey, "1234").build();
|
||||
Settings.Builder newSettingsBuilder = Settings.builder();
|
||||
UpdateAllocationSettingsStep.addMissingAttrs(newAttrs, prefix, existingSettings, newSettingsBuilder);
|
||||
|
||||
Settings.Builder expectedSettingsBuilder = Settings.builder();
|
||||
newAttrs.forEach((k, v) -> expectedSettingsBuilder.put(prefix + k, v));
|
||||
assertThat(newSettingsBuilder.build(), equalTo(expectedSettingsBuilder.build()));
|
||||
}
|
||||
|
||||
public void testAddMissingAttrNoneMissing() {
|
||||
String prefix = randomFrom(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey(),
|
||||
IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey(),
|
||||
IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey());
|
||||
String newKey = randomAlphaOfLength(4);
|
||||
String newValue = randomAlphaOfLength(5);
|
||||
Map<String, String> newAttrs = Collections.singletonMap(newKey, newValue);
|
||||
Settings existingSettings = Settings.builder()
|
||||
.put(IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING.getKey() + "box_type", "foo")
|
||||
.put(IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getKey() + "box_type", "bar")
|
||||
.put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + "box_type", "baz")
|
||||
.put(prefix + newKey, newValue).build();
|
||||
Settings.Builder newSettingsBuilder = Settings.builder();
|
||||
UpdateAllocationSettingsStep.addMissingAttrs(newAttrs, prefix, existingSettings, newSettingsBuilder);
|
||||
|
||||
Settings.Builder expectedSettingsBuilder = Settings.builder();
|
||||
assertThat(newSettingsBuilder.build(), equalTo(expectedSettingsBuilder.build()));
|
||||
}
|
||||
|
||||
private Map<String, String> getRouting(Index index, ClusterState clusterState, String settingPrefix) {
|
||||
Settings includeSettings = clusterState.metaData().index(index).getSettings()
|
||||
.getByPrefix(settingPrefix);
|
||||
|
|
Loading…
Reference in New Issue