/*
* 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.cluster.routing;
import com.carrotsearch.randomizedtesting.RandomizedContext;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.cluster.health.ClusterHealthStatus;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.index.shard.ShardId;
import static org.elasticsearch.cluster.health.ClusterShardHealth.getInactivePrimaryHealth;
public class RoutingTableGenerator {
private static int node_id = 1;
private ShardRouting genShardRouting(String index, int shardId, boolean primary) {
ShardRoutingState state;
int stateRandomizer = RandomizedContext.current().getRandom().nextInt(40);
if (stateRandomizer > 5) {
state = ShardRoutingState.STARTED;
} else if (stateRandomizer > 3) {
state = ShardRoutingState.RELOCATING;
} else {
state = ShardRoutingState.INITIALIZING;
}
switch (state) {
case STARTED:
return TestShardRouting.newShardRouting(index, shardId, "node_" + Integer.toString(node_id++),
null, primary, ShardRoutingState.STARTED);
case INITIALIZING:
return TestShardRouting.newShardRouting(index, shardId, "node_" + Integer.toString(node_id++),
null, primary, ShardRoutingState.INITIALIZING);
case RELOCATING:
return TestShardRouting.newShardRouting(index, shardId, "node_" + Integer.toString(node_id++),
"node_" + Integer.toString(node_id++), primary, ShardRoutingState.RELOCATING);
default:
throw new ElasticsearchException("Unknown state: " + state.name());
}
}
public IndexShardRoutingTable genShardRoutingTable(IndexMetaData indexMetaData, int shardId, ShardCounter counter) {
final String index = indexMetaData.getIndex().getName();
IndexShardRoutingTable.Builder builder = new IndexShardRoutingTable.Builder(new ShardId(index, "_na_", shardId));
ShardRouting shardRouting = genShardRouting(index, shardId, true);
counter.update(shardRouting);
builder.addShard(shardRouting);
for (int replicas = indexMetaData.getNumberOfReplicas(); replicas > 0; replicas--) {
shardRouting = genShardRouting(index, shardId, false);
counter.update(shardRouting);
builder.addShard(shardRouting);
}
return builder.build();
}
public IndexRoutingTable genIndexRoutingTable(IndexMetaData indexMetaData, ShardCounter counter) {
IndexRoutingTable.Builder builder = IndexRoutingTable.builder(indexMetaData.getIndex());
for (int shard = 0; shard < indexMetaData.getNumberOfShards(); shard++) {
builder.addIndexShard(genShardRoutingTable(indexMetaData, shard, counter));
}
return builder.build();
}
public static class ShardCounter {
public int active;
public int relocating;
public int initializing;
public int unassigned;
public int primaryActive;
public int primaryInactive;
private boolean inactivePrimaryCausesRed = false;
public ClusterHealthStatus status() {
if (primaryInactive > 0) {
if (inactivePrimaryCausesRed) {
return ClusterHealthStatus.RED;
} else {
return ClusterHealthStatus.YELLOW;
}
}
if (unassigned > 0 || initializing > 0) {
return ClusterHealthStatus.YELLOW;
}
return ClusterHealthStatus.GREEN;
}
public void update(ShardRouting shardRouting) {
if (shardRouting.active()) {
active++;
if (shardRouting.primary()) {
primaryActive++;
}
if (shardRouting.relocating()) {
relocating++;
}
return;
}
if (shardRouting.primary()) {
primaryInactive++;
if (inactivePrimaryCausesRed == false) {
inactivePrimaryCausesRed = getInactivePrimaryHealth(shardRouting) == ClusterHealthStatus.RED;
}
}
if (shardRouting.initializing()) {
initializing++;
} else {
unassigned++;
}
}
}
}