Persistent Node Ids (#19140)

Node IDs are currently randomly generated during node startup. That means they change every time the node is restarted. While this doesn't matter for ES proper, it makes it hard for external services to track nodes. Another, more minor, side effect is that indexing the output of, say, the node stats API results in creating new fields due to node ID being used as keys.

The first approach I considered was to use the node's published address as the base for the id. We already [treat nodes with the same address as the same](https://github.com/elastic/elasticsearch/blob/master/core/src/main/java/org/elasticsearch/discovery/zen/NodeJoinController.java#L387) so this is a simple change (see [here](https://github.com/elastic/elasticsearch/compare/master...bleskes:node_persistent_id_based_on_address)). While this is simple and it works for probably most cases, it is not perfect. For example, if after a node restart, the node is not able to bind to the same port (because it's not yet freed by the OS), it will cause the node to still change identity. Also in environments where the host IP can change due to a host restart, identity will not be the same. 

Due to those limitation, I opted to go with a different approach where the node id will be persisted in the node's data folder. This has the upside of connecting the id to the nodes data. It also means that the host can be adapted in any way (replace network cards, attach storage to a new VM). I

It does however also have downsides - we now run the risk of two nodes having the same id, if someone copies clones a data folder from one node to another. To mitigate this I changed the semantics of the protection against multiple nodes with the same address to be stricter - it will now reject the incoming join if a node exists with the same id but a different address. Note that if the existing node doesn't respond to pings (i.e., it's not alive) it will be removed and the new node will be accepted when it tries another join.

Last, and most importantly, this change requires that *all* nodes persist data to disk. This is a change from current behavior where only data & master nodes store local files. This is the main reason for marking this PR as breaking.

Other less important notes:
- DummyTransportAddress is removed as we need a unique network address per node. Use `LocalTransportAddress.buildUnique()` instead.
- I renamed `node.add_lid_to_custom_path` to `node.add_lock_id_to_custom_path` to avoid confusion with the node ID which is now part of the `NodeEnvironment` logic.
- I removed the `version` paramater from `MetaDataStateFormat#write` , it wasn't really used and was just in the way :)
- TribeNodes are special in the sense that they do start multiple sub-nodes (previously known as client nodes). Those sub-nodes do not store local files but derive their ID from the parent node id, so they are generated consistently.
This commit is contained in:
Boaz Leskes 2016-07-04 21:09:25 +02:00 committed by GitHub
parent ed444cd276
commit 6861d3571e
88 changed files with 862 additions and 494 deletions

View File

@ -31,7 +31,7 @@ import org.elasticsearch.cluster.routing.allocation.decider.AllocationDecider;
import org.elasticsearch.cluster.routing.allocation.decider.AllocationDeciders;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.gateway.GatewayAllocator;
@ -102,7 +102,7 @@ public final class Allocators {
}
public static DiscoveryNode newNode(String nodeId, Map<String, String> attributes) {
return new DiscoveryNode("", nodeId, DummyTransportAddress.INSTANCE, attributes, Sets.newHashSet(DiscoveryNode.Role.MASTER,
return new DiscoveryNode("", nodeId, LocalTransportAddress.buildUnique(), attributes, Sets.newHashSet(DiscoveryNode.Role.MASTER,
DiscoveryNode.Role.DATA), Version.CURRENT);
}
}

View File

@ -266,7 +266,6 @@
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]cluster[/\\]metadata[/\\]MetaDataMappingService.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]cluster[/\\]metadata[/\\]MetaDataUpdateSettingsService.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]cluster[/\\]metadata[/\\]RepositoriesMetaData.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]cluster[/\\]node[/\\]DiscoveryNodes.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]cluster[/\\]routing[/\\]IndexRoutingTable.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]cluster[/\\]routing[/\\]IndexShardRoutingTable.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]cluster[/\\]routing[/\\]OperationRouting.java" checks="LineLength" />
@ -341,12 +340,9 @@
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]DiscoveryService.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]DiscoverySettings.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]local[/\\]LocalDiscovery.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]zen[/\\]NodeJoinController.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]zen[/\\]ZenDiscovery.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]zen[/\\]elect[/\\]ElectMasterService.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]zen[/\\]fd[/\\]FaultDetection.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]zen[/\\]fd[/\\]MasterFaultDetection.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]zen[/\\]fd[/\\]NodesFaultDetection.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]zen[/\\]membership[/\\]MembershipAction.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]zen[/\\]ping[/\\]ZenPing.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]zen[/\\]publish[/\\]PendingClusterStatesQueue.java" checks="LineLength" />
@ -357,7 +353,6 @@
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]gateway[/\\]GatewayMetaState.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]gateway[/\\]GatewayService.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]gateway[/\\]LocalAllocateDangledIndices.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]gateway[/\\]MetaDataStateFormat.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]gateway[/\\]PrimaryShardAllocator.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]gateway[/\\]ReplicaShardAllocator.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]gateway[/\\]TransportNodesListGatewayMetaState.java" checks="LineLength" />
@ -847,7 +842,6 @@
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]BlockingClusterStatePublishResponseHandlerTests.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]DiscoveryWithServiceDisruptionsIT.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]ZenUnicastDiscoveryIT.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]zen[/\\]NodeJoinControllerTests.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]zen[/\\]ZenDiscoveryUnitTests.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]zen[/\\]publish[/\\]PublishClusterStateActionTests.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]document[/\\]DocumentActionsIT.java" checks="LineLength" />

View File

@ -397,9 +397,9 @@ public class TransportClientNodesService extends AbstractComponent implements Cl
// use discovered information but do keep the original transport address,
// so people can control which address is exactly used.
DiscoveryNode nodeWithInfo = livenessResponse.getDiscoveryNode();
newNodes.add(new DiscoveryNode(nodeWithInfo.getName(), nodeWithInfo.getId(), nodeWithInfo.getHostName(),
nodeWithInfo.getHostAddress(), listedNode.getAddress(), nodeWithInfo.getAttributes(),
nodeWithInfo.getRoles(), nodeWithInfo.getVersion()));
newNodes.add(new DiscoveryNode(nodeWithInfo.getName(), nodeWithInfo.getId(), nodeWithInfo.getEphemeralId(),
nodeWithInfo.getHostName(), nodeWithInfo.getHostAddress(), listedNode.getAddress(),
nodeWithInfo.getAttributes(), nodeWithInfo.getRoles(), nodeWithInfo.getVersion()));
} else {
// although we asked for one node, our target may not have completed
// initialization yet and doesn't have cluster nodes

View File

@ -20,7 +20,7 @@
package org.elasticsearch.cluster.node;
import org.elasticsearch.Version;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.UUIDs;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable;
@ -64,7 +64,15 @@ public class DiscoveryNode implements Writeable, ToXContent {
}
public static boolean nodeRequiresLocalStorage(Settings settings) {
return Node.NODE_DATA_SETTING.get(settings) || Node.NODE_MASTER_SETTING.get(settings);
boolean localStorageEnable = Node.NODE_LOCAL_STORAGE_SETTING.get(settings);
if (localStorageEnable == false &&
(Node.NODE_DATA_SETTING.get(settings) ||
Node.NODE_MASTER_SETTING.get(settings))
) {
// TODO: make this a proper setting validation logic, requiring multi-settings validation
throw new IllegalArgumentException("storage can not be disabled for master and data nodes");
}
return localStorageEnable;
}
public static boolean isMasterNode(Settings settings) {
@ -81,6 +89,7 @@ public class DiscoveryNode implements Writeable, ToXContent {
private final String nodeName;
private final String nodeId;
private final String ephemeralId;
private final String hostName;
private final String hostAddress;
private final TransportAddress address;
@ -97,14 +106,15 @@ public class DiscoveryNode implements Writeable, ToXContent {
* and updated.
* </p>
*
* @param nodeId the nodes unique id.
* @param id the nodes unique (persistent) node id. This constructor will auto generate a random ephemeral id.
* @param address the nodes transport address
* @param attributes node attributes
* @param roles node roles
* @param version the version of the node.
* @param version the version of the node
*/
public DiscoveryNode(String nodeId, TransportAddress address, Map<String, String> attributes, Set<Role> roles, Version version) {
this("", nodeId, address.getHost(), address.getAddress(), address, attributes, roles, version);
public DiscoveryNode(String id, TransportAddress address, Map<String, String> attributes, Set<Role> roles,
Version version) {
this("", id, address, attributes, roles, version);
}
/**
@ -117,15 +127,15 @@ public class DiscoveryNode implements Writeable, ToXContent {
* </p>
*
* @param nodeName the nodes name
* @param nodeId the nodes unique id.
* @param nodeId the nodes unique persistent id. An ephemeral id will be auto generated.
* @param address the nodes transport address
* @param attributes node attributes
* @param roles node roles
* @param version the version of the node.
* @param version the version of the node
*/
public DiscoveryNode(String nodeName, String nodeId, TransportAddress address, Map<String, String> attributes,
Set<Role> roles, Version version) {
this(nodeName, nodeId, address.getHost(), address.getAddress(), address, attributes, roles, version);
public DiscoveryNode(String nodeName, String nodeId, TransportAddress address,
Map<String, String> attributes, Set<Role> roles, Version version) {
this(nodeName, nodeId, UUIDs.randomBase64UUID(), address.getHost(), address.getAddress(), address, attributes, roles, version);
}
/**
@ -138,22 +148,23 @@ public class DiscoveryNode implements Writeable, ToXContent {
* </p>
*
* @param nodeName the nodes name
* @param nodeId the nodes unique id.
* @param hostName the nodes hostname
* @param nodeId the nodes unique persistent id
* @param ephemeralId the nodes unique ephemeral id
* @param hostAddress the nodes host address
* @param address the nodes transport address
* @param attributes node attributes
* @param roles node roles
* @param version the version of the node.
* @param version the version of the node
*/
public DiscoveryNode(String nodeName, String nodeId, String hostName, String hostAddress, TransportAddress address,
Map<String, String> attributes, Set<Role> roles, Version version) {
public DiscoveryNode(String nodeName, String nodeId, String ephemeralId, String hostName, String hostAddress,
TransportAddress address, Map<String, String> attributes, Set<Role> roles, Version version) {
if (nodeName != null) {
this.nodeName = nodeName.intern();
} else {
this.nodeName = "";
}
this.nodeId = nodeId.intern();
this.ephemeralId = ephemeralId.intern();
this.hostName = hostName.intern();
this.hostAddress = hostAddress.intern();
this.address = address;
@ -184,6 +195,7 @@ public class DiscoveryNode implements Writeable, ToXContent {
public DiscoveryNode(StreamInput in) throws IOException {
this.nodeName = in.readString().intern();
this.nodeId = in.readString().intern();
this.ephemeralId = in.readString().intern();
this.hostName = in.readString().intern();
this.hostAddress = in.readString().intern();
this.address = TransportAddressSerializers.addressFromStream(in);
@ -208,6 +220,7 @@ public class DiscoveryNode implements Writeable, ToXContent {
public void writeTo(StreamOutput out) throws IOException {
out.writeString(nodeName);
out.writeString(nodeId);
out.writeString(ephemeralId);
out.writeString(hostName);
out.writeString(hostAddress);
addressToStream(out, address);
@ -237,6 +250,17 @@ public class DiscoveryNode implements Writeable, ToXContent {
return nodeId;
}
/**
* The unique ephemeral id of the node. Ephemeral ids are meant to be attached the the life span
* of a node process. When ever a node is restarted, it's ephemeral id is required to change (while it's {@link #getId()}
* will be read from the data folder and will remain the same across restarts). Since all node attributes and addresses
* are maintained during the life span of a node process, we can (and are) using the ephemeralId in
* {@link DiscoveryNode#equals(Object)}.
*/
public String getEphemeralId() {
return ephemeralId;
}
/**
* The name of the node.
*/
@ -293,18 +317,25 @@ public class DiscoveryNode implements Writeable, ToXContent {
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof DiscoveryNode)) {
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
DiscoveryNode other = (DiscoveryNode) obj;
return this.nodeId.equals(other.nodeId);
DiscoveryNode that = (DiscoveryNode) o;
return ephemeralId.equals(that.ephemeralId);
}
@Override
public int hashCode() {
return nodeId.hashCode();
// we only need to hash the id because it's highly unlikely that two nodes
// in our system will have the same id but be different
// This is done so that this class can be used efficiently as a key in a map
return ephemeralId.hashCode();
}
@Override
@ -313,15 +344,10 @@ public class DiscoveryNode implements Writeable, ToXContent {
if (nodeName.length() > 0) {
sb.append('{').append(nodeName).append('}');
}
if (nodeId != null) {
sb.append('{').append(nodeId).append('}');
}
if (Strings.hasLength(hostName)) {
sb.append('{').append(ephemeralId).append('}');
sb.append('{').append(hostName).append('}');
}
if (address != null) {
sb.append('{').append(address).append('}');
}
if (!attributes.isEmpty()) {
sb.append(attributes);
}
@ -332,6 +358,7 @@ public class DiscoveryNode implements Writeable, ToXContent {
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(getId());
builder.field("name", getName());
builder.field("ephemeral_id", getEphemeralId());
builder.field("transport_address", getAddress().toString());
builder.startObject("attributes");

View File

@ -20,12 +20,8 @@
package org.elasticsearch.cluster.node;
import org.elasticsearch.Version;
import org.elasticsearch.common.Randomness;
import org.elasticsearch.common.UUIDs;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.node.Node;
@ -34,17 +30,14 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Supplier;
/**
*/
public class DiscoveryNodeService extends AbstractComponent {
public static final Setting<Long> NODE_ID_SEED_SETTING =
// don't use node.id.seed so it won't be seen as an attribute
Setting.longSetting("node_id.seed", 0L, Long.MIN_VALUE, Property.NodeScope);
private final List<CustomAttributesProvider> customAttributesProviders = new CopyOnWriteArrayList<>();
@Inject
@ -52,18 +45,12 @@ public class DiscoveryNodeService extends AbstractComponent {
super(settings);
}
public static String generateNodeId(Settings settings) {
Random random = Randomness.get(settings, NODE_ID_SEED_SETTING);
return UUIDs.randomBase64UUID(random);
}
public DiscoveryNodeService addCustomAttributeProvider(CustomAttributesProvider customAttributesProvider) {
customAttributesProviders.add(customAttributesProvider);
return this;
}
public DiscoveryNode buildLocalNode(TransportAddress publishAddress) {
final String nodeId = generateNodeId(settings);
public DiscoveryNode buildLocalNode(TransportAddress publishAddress, Supplier<String> nodeIdSupplier) {
Map<String, String> attributes = new HashMap<>(Node.NODE_ATTRIBUTES.get(this.settings).getAsMap());
Set<DiscoveryNode.Role> roles = new HashSet<>();
if (Node.NODE_INGEST_SETTING.get(settings)) {
@ -90,8 +77,8 @@ public class DiscoveryNodeService extends AbstractComponent {
logger.warn("failed to build custom attributes from provider [{}]", e, provider);
}
}
return new DiscoveryNode(Node.NODE_NAME_SETTING.get(settings), nodeId, publishAddress, attributes,
roles, Version.CURRENT);
return new DiscoveryNode(Node.NODE_NAME_SETTING.get(settings), nodeIdSupplier.get(), publishAddress, attributes, roles,
Version.CURRENT);
}
public interface CustomAttributesProvider {

View File

@ -153,7 +153,7 @@ public class DiscoveryNodes extends AbstractDiffable<DiscoveryNodes> implements
}
/**
* Determine if a given node exists
* Determine if a given node id exists
*
* @param nodeId id of the node which existence should be verified
* @return <code>true</code> if the node exists. Otherwise <code>false</code>
@ -162,6 +162,18 @@ public class DiscoveryNodes extends AbstractDiffable<DiscoveryNodes> implements
return nodes.containsKey(nodeId);
}
/**
* Determine if a given node exists
*
* @param node of the node which existence should be verified
* @return <code>true</code> if the node exists. Otherwise <code>false</code>
*/
public boolean nodeExists(DiscoveryNode node) {
DiscoveryNode existing = nodes.get(node.getId());
return existing != null && existing.equals(node);
}
/**
* Get the id of the master node
*
@ -247,7 +259,8 @@ public class DiscoveryNodes extends AbstractDiffable<DiscoveryNodes> implements
public DiscoveryNode resolveNode(String node) {
String[] resolvedNodeIds = resolveNodes(node);
if (resolvedNodeIds.length > 1) {
throw new IllegalArgumentException("resolved [" + node + "] into [" + resolvedNodeIds.length + "] nodes, where expected to be resolved to a single node");
throw new IllegalArgumentException("resolved [" + node + "] into [" + resolvedNodeIds.length
+ "] nodes, where expected to be resolved to a single node");
}
if (resolvedNodeIds.length == 0) {
throw new IllegalArgumentException("failed to resolve [" + node + "], no matching nodes");
@ -361,12 +374,12 @@ public class DiscoveryNodes extends AbstractDiffable<DiscoveryNodes> implements
List<DiscoveryNode> removed = new ArrayList<>();
List<DiscoveryNode> added = new ArrayList<>();
for (DiscoveryNode node : other) {
if (!this.nodeExists(node.getId())) {
if (!this.nodeExists(node)) {
removed.add(node);
}
}
for (DiscoveryNode node : this) {
if (!other.nodeExists(node.getId())) {
if (!other.nodeExists(node)) {
added.add(node);
}
}
@ -378,7 +391,8 @@ public class DiscoveryNodes extends AbstractDiffable<DiscoveryNodes> implements
newMasterNode = getMasterNode();
}
}
return new Delta(previousMasterNode, newMasterNode, localNodeId, Collections.unmodifiableList(removed), Collections.unmodifiableList(added));
return new Delta(previousMasterNode, newMasterNode, localNodeId, Collections.unmodifiableList(removed),
Collections.unmodifiableList(added));
}
@Override
@ -420,7 +434,8 @@ public class DiscoveryNodes extends AbstractDiffable<DiscoveryNodes> implements
this(null, null, localNodeId, removed, added);
}
public Delta(@Nullable DiscoveryNode previousMasterNode, @Nullable DiscoveryNode newMasterNode, String localNodeId, List<DiscoveryNode> removed, List<DiscoveryNode> added) {
public Delta(@Nullable DiscoveryNode previousMasterNode, @Nullable DiscoveryNode newMasterNode, String localNodeId,
List<DiscoveryNode> removed, List<DiscoveryNode> added) {
this.previousMasterNode = previousMasterNode;
this.newMasterNode = newMasterNode;
this.localNodeId = localNodeId;
@ -538,7 +553,10 @@ public class DiscoveryNodes extends AbstractDiffable<DiscoveryNodes> implements
// reuse the same instance of our address and local node id for faster equality
node = localNode;
}
builder.put(node);
// some one already built this and validated it's OK, skip the n2 scans
assert builder.validatePut(node) == null : "building disco nodes from network doesn't pass preflight: "
+ builder.validatePut(node);
builder.putUnsafe(node);
}
return builder.build();
}
@ -572,16 +590,36 @@ public class DiscoveryNodes extends AbstractDiffable<DiscoveryNodes> implements
this.nodes = ImmutableOpenMap.builder(nodes.getNodes());
}
/**
* adds a disco node to the builder. Will throw an {@link IllegalArgumentException} if
* the supplied node doesn't pass the pre-flight checks performed by {@link #validatePut(DiscoveryNode)}
*/
public Builder put(DiscoveryNode node) {
nodes.put(node.getId(), node);
final String preflight = validatePut(node);
if (preflight != null) {
throw new IllegalArgumentException(preflight);
}
putUnsafe(node);
return this;
}
private void putUnsafe(DiscoveryNode node) {
nodes.put(node.getId(), node);
}
public Builder remove(String nodeId) {
nodes.remove(nodeId);
return this;
}
public Builder remove(DiscoveryNode node) {
if (node.equals(nodes.get(node.getId()))) {
nodes.remove(node.getId());
}
return this;
}
public Builder masterNodeId(String masterNodeId) {
this.masterNodeId = masterNodeId;
return this;
@ -592,6 +630,30 @@ public class DiscoveryNodes extends AbstractDiffable<DiscoveryNodes> implements
return this;
}
/**
* Checks that a node can be safely added to this node collection.
*
* @return null if all is OK or an error message explaining why a node can not be added.
*
* Note: if this method returns a non-null value, calling {@link #put(DiscoveryNode)} will fail with an
* exception
*/
private String validatePut(DiscoveryNode node) {
for (ObjectCursor<DiscoveryNode> cursor : nodes.values()) {
final DiscoveryNode existingNode = cursor.value;
if (node.getAddress().equals(existingNode.getAddress()) &&
node.getId().equals(existingNode.getId()) == false) {
return "can't add node " + node + ", found existing node " + existingNode + " with same address";
}
if (node.getId().equals(existingNode.getId()) &&
node.getAddress().equals(existingNode.getAddress()) == false) {
return "can't add node " + node + ", found existing node " + existingNode
+ " with the same id, but a different address";
}
}
return null;
}
public DiscoveryNodes build() {
ImmutableOpenMap.Builder<String, DiscoveryNode> dataNodesBuilder = ImmutableOpenMap.builder();
ImmutableOpenMap.Builder<String, DiscoveryNode> masterNodesBuilder = ImmutableOpenMap.builder();

View File

@ -32,7 +32,10 @@ public enum MurmurHash3 {
* A 128-bits hash.
*/
public static class Hash128 {
public long h1, h2;
/** lower 64 bits part **/
public long h1;
/** higher 64 bits part **/
public long h2;
}
private static long C1 = 0x87c37b91114253d5L;

View File

@ -24,16 +24,14 @@ import org.elasticsearch.action.support.AutoCreateIndex;
import org.elasticsearch.action.support.DestructiveOperations;
import org.elasticsearch.action.support.master.TransportMasterNodeReadAction;
import org.elasticsearch.bootstrap.BootstrapSettings;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.common.util.PageCacheRecycler;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClientNodesService;
import org.elasticsearch.cluster.ClusterModule;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.InternalClusterInfoService;
import org.elasticsearch.cluster.NodeConnectionsService;
import org.elasticsearch.cluster.action.index.MappingUpdatedAction;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.node.DiscoveryNodeService;
import org.elasticsearch.cluster.routing.allocation.allocator.BalancedShardsAllocator;
import org.elasticsearch.cluster.routing.allocation.decider.AwarenessAllocationDecider;
import org.elasticsearch.cluster.routing.allocation.decider.ClusterRebalanceAllocationDecider;
@ -49,6 +47,7 @@ import org.elasticsearch.common.logging.ESLoggerFactory;
import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.common.network.NetworkService;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.util.PageCacheRecycler;
import org.elasticsearch.common.util.concurrent.EsExecutors;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.discovery.DiscoveryModule;
@ -336,7 +335,7 @@ public final class ClusterSettings extends AbstractScopedSettings {
Environment.PATH_SCRIPTS_SETTING,
Environment.PATH_SHARED_DATA_SETTING,
Environment.PIDFILE_SETTING,
DiscoveryNodeService.NODE_ID_SEED_SETTING,
NodeEnvironment.NODE_ID_SEED_SETTING,
DiscoverySettings.INITIAL_STATE_TIMEOUT_SETTING,
DiscoveryModule.DISCOVERY_TYPE_SETTING,
DiscoveryModule.ZEN_MASTER_SERVICE_TYPE_SETTING,
@ -365,6 +364,7 @@ public final class ClusterSettings extends AbstractScopedSettings {
Node.NODE_MODE_SETTING,
Node.NODE_INGEST_SETTING,
Node.NODE_ATTRIBUTES,
Node.NODE_LOCAL_STORAGE_SETTING,
URLRepository.ALLOWED_URLS_SETTING,
URLRepository.REPOSITORIES_URL_SETTING,
URLRepository.SUPPORTED_PROTOCOLS_SETTING,
@ -387,7 +387,7 @@ public final class ClusterSettings extends AbstractScopedSettings {
TribeService.TRIBE_NAME_SETTING,
NodeEnvironment.MAX_LOCAL_STORAGE_NODES_SETTING,
NodeEnvironment.ENABLE_LUCENE_SEGMENT_INFOS_TRACE_SETTING,
NodeEnvironment.ADD_NODE_ID_TO_CUSTOM_PATH,
NodeEnvironment.ADD_NODE_LOCK_ID_TO_CUSTOM_PATH,
OsService.REFRESH_INTERVAL_SETTING,
ProcessService.REFRESH_INTERVAL_SETTING,
JvmService.REFRESH_INTERVAL_SETTING,

View File

@ -1,74 +0,0 @@
/*
* 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.common.transport;
import org.elasticsearch.common.io.stream.StreamOutput;
import java.io.IOException;
/**
*
*/
public class DummyTransportAddress implements TransportAddress {
public static final DummyTransportAddress INSTANCE = new DummyTransportAddress();
private DummyTransportAddress() {
}
@Override
public short uniqueAddressTypeId() {
return 0;
}
@Override
public boolean sameHost(TransportAddress other) {
return other == INSTANCE;
}
@Override
public boolean isLoopbackOrLinkLocalAddress() {
return false;
}
@Override
public String getHost() {
return "dummy";
}
@Override
public String getAddress() {
return "0.0.0.0"; // see https://en.wikipedia.org/wiki/0.0.0.0
}
@Override
public int getPort() {
return 42;
}
@Override
public void writeTo(StreamOutput out) throws IOException {
}
@Override
public String toString() {
return "_dummy_addr_";
}
}

View File

@ -23,6 +23,7 @@ import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicLong;
/**
*
@ -30,6 +31,15 @@ import java.io.IOException;
public final class LocalTransportAddress implements TransportAddress {
public static final short TYPE_ID = 2;
private static final AtomicLong transportAddressIdGenerator = new AtomicLong();
/**
* generates a new unique address
*/
public static LocalTransportAddress buildUnique() {
return new LocalTransportAddress(Long.toString(transportAddressIdGenerator.incrementAndGet()));
}
private String id;
public LocalTransportAddress(String id) {

View File

@ -37,7 +37,6 @@ public abstract class TransportAddressSerializers {
static {
Map<Short, Writeable.Reader<TransportAddress>> registry = new HashMap<>();
addAddressType(registry, DummyTransportAddress.INSTANCE.uniqueAddressTypeId(), (in) -> DummyTransportAddress.INSTANCE);
addAddressType(registry, InetSocketTransportAddress.TYPE_ID, InetSocketTransportAddress::new);
addAddressType(registry, LocalTransportAddress.TYPE_ID, LocalTransportAddress::new);
ADDRESS_REGISTRY = unmodifiableMap(registry);

View File

@ -47,6 +47,7 @@ import org.elasticsearch.discovery.DiscoverySettings;
import org.elasticsearch.discovery.DiscoveryStats;
import java.util.HashSet;
import java.util.Optional;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
@ -100,6 +101,14 @@ public class LocalDiscovery extends AbstractLifecycleComponent implements Discov
}
logger.debug("Connected to cluster [{}]", clusterName);
Optional<LocalDiscovery> current = clusterGroup.members().stream().filter(other -> (
other.localNode().equals(this.localNode()) || other.localNode().getId().equals(this.localNode().getId())
)).findFirst();
if (current.isPresent()) {
throw new IllegalStateException("current cluster group already contains a node with the same id. current "
+ current.get().localNode() + ", this node " + localNode());
}
clusterGroup.members().add(this);
LocalDiscovery firstMaster = null;
@ -308,7 +317,7 @@ public class LocalDiscovery extends AbstractLifecycleComponent implements Discov
synchronized (this) {
// we do the marshaling intentionally, to check it works well...
// check if we published cluster state at least once and node was in the cluster when we published cluster state the last time
if (discovery.lastProcessedClusterState != null && clusterChangedEvent.previousState().nodes().nodeExists(discovery.localNode().getId())) {
if (discovery.lastProcessedClusterState != null && clusterChangedEvent.previousState().nodes().nodeExists(discovery.localNode())) {
// both conditions are true - which means we can try sending cluster state as diffs
if (clusterStateDiffBytes == null) {
Diff diff = clusterState.diff(clusterChangedEvent.previousState());

View File

@ -36,7 +36,7 @@ import org.elasticsearch.common.Priority;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.discovery.DiscoverySettings;
import org.elasticsearch.discovery.zen.elect.ElectMasterService;
@ -380,13 +380,13 @@ public class NodeJoinController extends AbstractComponent {
}
// a task indicated that the current node should become master, if no current master is known
private static final DiscoveryNode BECOME_MASTER_TASK = new DiscoveryNode("_BECOME_MASTER_TASK_", DummyTransportAddress.INSTANCE,
private static final DiscoveryNode BECOME_MASTER_TASK = new DiscoveryNode("_BECOME_MASTER_TASK_", LocalTransportAddress.buildUnique(),
Collections.emptyMap(), Collections.emptySet(), Version.CURRENT);
// a task that is used to process pending joins without explicitly becoming a master and listening to the results
// this task is used when election is stop without the local node becoming a master per se (though it might
private static final DiscoveryNode FINISH_ELECTION_NOT_MASTER_TASK = new DiscoveryNode("_NOT_MASTER_TASK_",
DummyTransportAddress.INSTANCE, Collections.emptyMap(), Collections.emptySet(), Version.CURRENT);
LocalTransportAddress.buildUnique(), Collections.emptyMap(), Collections.emptySet(), Version.CURRENT);
class JoinTaskExecutor implements ClusterStateTaskExecutor<DiscoveryNode> {
@ -418,17 +418,15 @@ public class NodeJoinController extends AbstractComponent {
for (final DiscoveryNode node : joiningNodes) {
if (node.equals(BECOME_MASTER_TASK) || node.equals(FINISH_ELECTION_NOT_MASTER_TASK)) {
// noop
} else if (currentNodes.nodeExists(node.getId())) {
} else if (currentNodes.nodeExists(node)) {
logger.debug("received a join request for an existing node [{}]", node);
} else {
nodesChanged = true;
try {
nodesBuilder.put(node);
for (DiscoveryNode existingNode : currentNodes) {
if (node.getAddress().equals(existingNode.getAddress())) {
nodesBuilder.remove(existingNode.getId());
logger.warn("received join request from node [{}], but found existing node {} with same address, " +
"removing existing node", node, existingNode);
}
nodesChanged = true;
} catch (IllegalArgumentException e) {
results.failure(node, e);
continue;
}
}
results.success(node);

View File

@ -548,12 +548,11 @@ public class ZenDiscovery extends AbstractLifecycleComponent implements Discover
clusterService.submitStateUpdateTask("zen-disco-node_failed(" + node + "), reason " + reason, new ClusterStateUpdateTask(Priority.IMMEDIATE) {
@Override
public ClusterState execute(ClusterState currentState) {
if (currentState.nodes().get(node.getId()) == null) {
if (currentState.nodes().nodeExists(node) == false) {
logger.debug("node [{}] already removed from cluster state. ignoring.", node);
return currentState;
}
DiscoveryNodes.Builder builder = DiscoveryNodes.builder(currentState.nodes())
.remove(node.getId());
DiscoveryNodes.Builder builder = DiscoveryNodes.builder(currentState.nodes()).remove(node);
currentState = ClusterState.builder(currentState).nodes(builder).build();
// check if we have enough master nodes, if not, we need to move into joining the cluster again
if (!electMaster.hasEnoughMasterNodes(currentState.nodes())) {
@ -642,14 +641,14 @@ public class ZenDiscovery extends AbstractLifecycleComponent implements Discover
@Override
public ClusterState execute(ClusterState currentState) {
if (!masterNode.getId().equals(currentState.nodes().getMasterNodeId())) {
if (!masterNode.equals(currentState.nodes().getMasterNode())) {
// master got switched on us, no need to send anything
return currentState;
}
DiscoveryNodes discoveryNodes = DiscoveryNodes.builder(currentState.nodes())
// make sure the old master node, which has failed, is not part of the nodes we publish
.remove(masterNode.getId())
.remove(masterNode)
.masterNodeId(null).build();
// flush any pending cluster states from old master, so it will not be set as master again

View File

@ -80,7 +80,8 @@ public class MasterFaultDetection extends FaultDetection {
super(settings, threadPool, transportService, clusterService.getClusterName());
this.clusterService = clusterService;
logger.debug("[master] uses ping_interval [{}], ping_timeout [{}], ping_retries [{}]", pingInterval, pingRetryTimeout, pingRetryCount);
logger.debug("[master] uses ping_interval [{}], ping_timeout [{}], ping_retries [{}]", pingInterval, pingRetryTimeout,
pingRetryCount);
transportService.registerRequestHandler(
MASTER_PING_ACTION_NAME, MasterPingRequest::new, ThreadPool.Names.SAME, false, false, new MasterPingRequestHandler());
@ -230,9 +231,11 @@ public class MasterFaultDetection extends FaultDetection {
threadPool.schedule(pingInterval, ThreadPool.Names.SAME, MasterPinger.this);
return;
}
final MasterPingRequest request = new MasterPingRequest(clusterService.localNode().getId(), masterToPing.getId(), clusterName);
final TransportRequestOptions options = TransportRequestOptions.builder().withType(TransportRequestOptions.Type.PING).withTimeout(pingRetryTimeout).build();
transportService.sendRequest(masterToPing, MASTER_PING_ACTION_NAME, request, options, new BaseTransportResponseHandler<MasterPingResponseResponse>() {
final MasterPingRequest request = new MasterPingRequest(clusterService.localNode(), masterToPing, clusterName);
final TransportRequestOptions options = TransportRequestOptions.builder().withType(TransportRequestOptions.Type.PING)
.withTimeout(pingRetryTimeout).build();
transportService.sendRequest(masterToPing, MASTER_PING_ACTION_NAME, request, options,
new BaseTransportResponseHandler<MasterPingResponseResponse>() {
@Override
public MasterPingResponseResponse newInstance() {
@ -273,17 +276,21 @@ public class MasterFaultDetection extends FaultDetection {
notifyMasterFailure(masterToPing, exp,"not master");
return;
} else if (exp.getCause() instanceof NodeDoesNotExistOnMasterException) {
logger.debug("[master] pinging a master {} but we do not exists on it, act as if its master failure", masterNode);
logger.debug("[master] pinging a master {} but we do not exists on it, act as if its master failure"
, masterNode);
notifyMasterFailure(masterToPing, exp,"do not exists on master, act as master failure");
return;
}
int retryCount = ++MasterFaultDetection.this.retryCount;
logger.trace("[master] failed to ping [{}], retry [{}] out of [{}]", exp, masterNode, retryCount, pingRetryCount);
logger.trace("[master] failed to ping [{}], retry [{}] out of [{}]", exp, masterNode, retryCount,
pingRetryCount);
if (retryCount >= pingRetryCount) {
logger.debug("[master] failed to ping [{}], tried [{}] times, each with maximum [{}] timeout", masterNode, pingRetryCount, pingRetryTimeout);
logger.debug("[master] failed to ping [{}], tried [{}] times, each with maximum [{}] timeout",
masterNode, pingRetryCount, pingRetryTimeout);
// not good, failure
notifyMasterFailure(masterToPing, null, "failed to ping, tried [" + pingRetryCount + "] times, each with maximum [" + pingRetryTimeout + "] timeout");
notifyMasterFailure(masterToPing, null, "failed to ping, tried [" + pingRetryCount
+ "] times, each with maximum [" + pingRetryTimeout + "] timeout");
} else {
// resend the request, not reschedule, rely on send timeout
transportService.sendRequest(masterToPing, MASTER_PING_ACTION_NAME, request, options, this);
@ -331,14 +338,16 @@ public class MasterFaultDetection extends FaultDetection {
final DiscoveryNodes nodes = clusterService.state().nodes();
// check if we are really the same master as the one we seemed to be think we are
// this can happen if the master got "kill -9" and then another node started using the same port
if (!request.masterNodeId.equals(nodes.getLocalNodeId())) {
if (!request.masterNode.equals(nodes.getLocalNode())) {
throw new ThisIsNotTheMasterYouAreLookingForException();
}
// ping from nodes of version < 1.4.0 will have the clustername set to null
if (request.clusterName != null && !request.clusterName.equals(clusterName)) {
logger.trace("master fault detection ping request is targeted for a different [{}] cluster then us [{}]", request.clusterName, clusterName);
throw new ThisIsNotTheMasterYouAreLookingForException("master fault detection ping request is targeted for a different [" + request.clusterName + "] cluster then us [" + clusterName + "]");
logger.trace("master fault detection ping request is targeted for a different [{}] cluster then us [{}]",
request.clusterName, clusterName);
throw new ThisIsNotTheMasterYouAreLookingForException("master fault detection ping request is targeted for a different ["
+ request.clusterName + "] cluster then us [" + clusterName + "]");
}
// when we are elected as master or when a node joins, we use a cluster state update thread
@ -349,15 +358,15 @@ public class MasterFaultDetection extends FaultDetection {
// all processing is finished.
//
if (!nodes.isLocalNodeElectedMaster() || !nodes.nodeExists(request.nodeId)) {
logger.trace("checking ping from [{}] under a cluster state thread", request.nodeId);
clusterService.submitStateUpdateTask("master ping (from: [" + request.nodeId + "])", new ClusterStateUpdateTask() {
if (!nodes.isLocalNodeElectedMaster() || !nodes.nodeExists(request.sourceNode)) {
logger.trace("checking ping from {} under a cluster state thread", request.sourceNode);
clusterService.submitStateUpdateTask("master ping (from: " + request.sourceNode + ")", new ClusterStateUpdateTask() {
@Override
public ClusterState execute(ClusterState currentState) throws Exception {
// if we are no longer master, fail...
DiscoveryNodes nodes = currentState.nodes();
if (!nodes.nodeExists(request.nodeId)) {
if (!nodes.nodeExists(request.sourceNode)) {
throw new NodeDoesNotExistOnMasterException();
}
return currentState;
@ -400,33 +409,33 @@ public class MasterFaultDetection extends FaultDetection {
public static class MasterPingRequest extends TransportRequest {
private String nodeId;
private DiscoveryNode sourceNode;
private String masterNodeId;
private DiscoveryNode masterNode;
private ClusterName clusterName;
public MasterPingRequest() {
}
private MasterPingRequest(String nodeId, String masterNodeId, ClusterName clusterName) {
this.nodeId = nodeId;
this.masterNodeId = masterNodeId;
private MasterPingRequest(DiscoveryNode sourceNode, DiscoveryNode masterNode, ClusterName clusterName) {
this.sourceNode = sourceNode;
this.masterNode = masterNode;
this.clusterName = clusterName;
}
@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
nodeId = in.readString();
masterNodeId = in.readString();
sourceNode = new DiscoveryNode(in);
masterNode = new DiscoveryNode(in);
clusterName = new ClusterName(in);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeString(nodeId);
out.writeString(masterNodeId);
sourceNode.writeTo(out);
masterNode.writeTo(out);
clusterName.writeTo(out);
}
}

View File

@ -70,7 +70,8 @@ public class NodesFaultDetection extends FaultDetection {
public NodesFaultDetection(Settings settings, ThreadPool threadPool, TransportService transportService, ClusterName clusterName) {
super(settings, threadPool, transportService, clusterName);
logger.debug("[node ] uses ping_interval [{}], ping_timeout [{}], ping_retries [{}]", pingInterval, pingRetryTimeout, pingRetryCount);
logger.debug("[node ] uses ping_interval [{}], ping_timeout [{}], ping_retries [{}]", pingInterval, pingRetryTimeout,
pingRetryCount);
transportService.registerRequestHandler(
PING_ACTION_NAME, PingRequest::new, ThreadPool.Names.SAME, false, false, new PingRequestHandler());
@ -95,7 +96,7 @@ public class NodesFaultDetection extends FaultDetection {
public void updateNodesAndPing(ClusterState clusterState) {
// remove any nodes we don't need, this will cause their FD to stop
for (DiscoveryNode monitoredNode : nodesFD.keySet()) {
if (!clusterState.nodes().nodeExists(monitoredNode.getId())) {
if (!clusterState.nodes().nodeExists(monitoredNode)) {
nodesFD.remove(monitoredNode);
}
}
@ -201,8 +202,9 @@ public class NodesFaultDetection extends FaultDetection {
if (!running()) {
return;
}
final PingRequest pingRequest = new PingRequest(node.getId(), clusterName, localNode, clusterStateVersion);
final TransportRequestOptions options = TransportRequestOptions.builder().withType(TransportRequestOptions.Type.PING).withTimeout(pingRetryTimeout).build();
final PingRequest pingRequest = new PingRequest(node, clusterName, localNode, clusterStateVersion);
final TransportRequestOptions options = TransportRequestOptions.builder().withType(TransportRequestOptions.Type.PING)
.withTimeout(pingRetryTimeout).build();
transportService.sendRequest(node, PING_ACTION_NAME, pingRequest, options, new BaseTransportResponseHandler<PingResponse>() {
@Override
public PingResponse newInstance() {
@ -231,10 +233,12 @@ public class NodesFaultDetection extends FaultDetection {
retryCount++;
logger.trace("[node ] failed to ping [{}], retry [{}] out of [{}]", exp, node, retryCount, pingRetryCount);
if (retryCount >= pingRetryCount) {
logger.debug("[node ] failed to ping [{}], tried [{}] times, each with maximum [{}] timeout", node, pingRetryCount, pingRetryTimeout);
logger.debug("[node ] failed to ping [{}], tried [{}] times, each with maximum [{}] timeout", node,
pingRetryCount, pingRetryTimeout);
// not good, failure
if (nodesFD.remove(node, NodeFD.this)) {
notifyNodeFailure(node, "failed to ping, tried [" + pingRetryCount + "] times, each with maximum [" + pingRetryTimeout + "] timeout");
notifyNodeFailure(node, "failed to ping, tried [" + pingRetryCount + "] times, each with maximum ["
+ pingRetryTimeout + "] timeout");
}
} else {
// resend the request, not reschedule, rely on send timeout
@ -256,14 +260,15 @@ public class NodesFaultDetection extends FaultDetection {
public void messageReceived(PingRequest request, TransportChannel channel) throws Exception {
// if we are not the node we are supposed to be pinged, send an exception
// this can happen when a kill -9 is sent, and another node is started using the same port
if (!localNode.getId().equals(request.nodeId)) {
throw new IllegalStateException("Got pinged as node [" + request.nodeId + "], but I am node [" + localNode.getId() + "]");
if (!localNode.equals(request.targetNode())) {
throw new IllegalStateException("Got pinged as node " + request.targetNode() + "], but I am node " + localNode );
}
// PingRequest will have clusterName set to null if it came from a node of version <1.4.0
if (request.clusterName != null && !request.clusterName.equals(clusterName)) {
// Don't introduce new exception for bwc reasons
throw new IllegalStateException("Got pinged with cluster name [" + request.clusterName + "], but I'm part of cluster [" + clusterName + "]");
throw new IllegalStateException("Got pinged with cluster name [" + request.clusterName + "], but I'm part of cluster ["
+ clusterName + "]");
}
notifyPingReceived(request);
@ -275,8 +280,8 @@ public class NodesFaultDetection extends FaultDetection {
public static class PingRequest extends TransportRequest {
// the (assumed) node id we are pinging
private String nodeId;
// the (assumed) node we are pinging
private DiscoveryNode targetNode;
private ClusterName clusterName;
@ -287,15 +292,15 @@ public class NodesFaultDetection extends FaultDetection {
public PingRequest() {
}
PingRequest(String nodeId, ClusterName clusterName, DiscoveryNode masterNode, long clusterStateVersion) {
this.nodeId = nodeId;
PingRequest(DiscoveryNode targetNode, ClusterName clusterName, DiscoveryNode masterNode, long clusterStateVersion) {
this.targetNode = targetNode;
this.clusterName = clusterName;
this.masterNode = masterNode;
this.clusterStateVersion = clusterStateVersion;
}
public String nodeId() {
return nodeId;
public DiscoveryNode targetNode() {
return targetNode;
}
public ClusterName clusterName() {
@ -313,7 +318,7 @@ public class NodesFaultDetection extends FaultDetection {
@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
nodeId = in.readString();
targetNode = new DiscoveryNode(in);
clusterName = new ClusterName(in);
masterNode = new DiscoveryNode(in);
clusterStateVersion = in.readLong();
@ -322,7 +327,7 @@ public class NodesFaultDetection extends FaultDetection {
@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeString(nodeId);
targetNode.writeTo(out);
clusterName.writeTo(out);
masterNode.writeTo(out);
out.writeLong(clusterStateVersion);

View File

@ -27,6 +27,7 @@ import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.UUIDs;
import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.io.stream.StreamInput;
@ -373,8 +374,8 @@ public class UnicastZenPing extends AbstractLifecycleComponent implements ZenPin
if (!nodeToSend.getId().startsWith(UNICAST_NODE_PREFIX)) {
DiscoveryNode tempNode = new DiscoveryNode("",
UNICAST_NODE_PREFIX + unicastNodeIdGenerator.incrementAndGet() + "_" + nodeToSend.getId() + "#",
nodeToSend.getHostName(), nodeToSend.getHostAddress(), nodeToSend.getAddress(), nodeToSend.getAttributes(),
nodeToSend.getRoles(), nodeToSend.getVersion());
UUIDs.randomBase64UUID(), nodeToSend.getHostName(), nodeToSend.getHostAddress(), nodeToSend.getAddress(),
nodeToSend.getAttributes(), nodeToSend.getRoles(), nodeToSend.getVersion());
logger.trace("replacing {} with temp node {}", nodeToSend, tempNode);
nodeToSend = tempNode;
@ -461,7 +462,7 @@ public class UnicastZenPing extends AbstractLifecycleComponent implements ZenPin
try {
DiscoveryNodes discoveryNodes = contextProvider.nodes();
for (PingResponse pingResponse : response.pingResponses) {
if (pingResponse.node().getId().equals(discoveryNodes.getLocalNodeId())) {
if (pingResponse.node().equals(discoveryNodes.getLocalNode())) {
// that's us, ignore
continue;
}

View File

@ -185,7 +185,7 @@ public class PublishClusterStateAction extends AbstractComponent {
// try and serialize the cluster state once (or per version), so we don't serialize it
// per node when we send it over the wire, compress it while we are at it...
// we don't send full version if node didn't exist in the previous version of cluster state
if (sendFullVersion || !previousState.nodes().nodeExists(node.getId())) {
if (sendFullVersion || !previousState.nodes().nodeExists(node)) {
sendFullClusterState(clusterState, serializedStates, node, publishTimeout, sendingController);
} else {
sendClusterStateDiff(clusterState, serializedDiffs, serializedStates, node, publishTimeout, sendingController);
@ -216,7 +216,7 @@ public class PublishClusterStateAction extends AbstractComponent {
Diff<ClusterState> diff = null;
for (final DiscoveryNode node : nodesToPublishTo) {
try {
if (sendFullVersion || !previousState.nodes().nodeExists(node.getId())) {
if (sendFullVersion || !previousState.nodes().nodeExists(node)) {
// will send a full reference
if (serializedStates.containsKey(node.getVersion()) == false) {
serializedStates.put(node.getVersion(), serializeFullClusterState(clusterState, node.getVersion()));

View File

@ -31,10 +31,13 @@ import org.apache.lucene.util.IOUtils;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.Randomness;
import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.common.UUIDs;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.io.FileSystemUtils;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.settings.Settings;
@ -65,6 +68,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
@ -76,6 +80,7 @@ import static java.util.Collections.unmodifiableSet;
* A component that holds all data paths for a single node.
*/
public final class NodeEnvironment extends AbstractComponent implements Closeable {
public static class NodePath {
/* ${data.paths}/nodes/{node.id} */
public final Path path;
@ -134,12 +139,14 @@ public final class NodeEnvironment extends AbstractComponent implements Closeabl
private final Path sharedDataPath;
private final Lock[] locks;
private final boolean addNodeId;
private final boolean addLockIdToCustomPath;
private final int localNodeId;
private final int nodeLockId;
private final AtomicBoolean closed = new AtomicBoolean(false);
private final Map<ShardId, InternalShardLock> shardLocks = new HashMap<>();
private final NodeMetaData nodeMetaData;
/**
* Maximum number of data nodes that should run in an environment.
*/
@ -147,10 +154,19 @@ public final class NodeEnvironment extends AbstractComponent implements Closeabl
Property.NodeScope);
/**
* If true automatically append node id to custom data paths.
* If true automatically append node lock id to custom data paths.
*/
public static final Setting<Boolean> ADD_NODE_ID_TO_CUSTOM_PATH =
Setting.boolSetting("node.add_id_to_custom_path", true, Property.NodeScope);
public static final Setting<Boolean> ADD_NODE_LOCK_ID_TO_CUSTOM_PATH =
Setting.boolSetting("node.add_lock_id_to_custom_path", true, Property.NodeScope);
/**
* Seed for determining a persisted unique uuid of this node. If the node has already a persisted uuid on disk,
* this seed will be ignored and the uuid from disk will be reused.
*/
public static final Setting<Long> NODE_ID_SEED_SETTING =
Setting.longSetting("node.id.seed", 0L, Long.MIN_VALUE, Property.NodeScope);
/**
* If true the [verbose] SegmentInfos.infoStream logging is sent to System.out.
@ -166,22 +182,23 @@ public final class NodeEnvironment extends AbstractComponent implements Closeabl
public NodeEnvironment(Settings settings, Environment environment) throws IOException {
super(settings);
this.addNodeId = ADD_NODE_ID_TO_CUSTOM_PATH.get(settings);
this.addLockIdToCustomPath = ADD_NODE_LOCK_ID_TO_CUSTOM_PATH.get(settings);
if (!DiscoveryNode.nodeRequiresLocalStorage(settings)) {
nodePaths = null;
sharedDataPath = null;
locks = null;
localNodeId = -1;
nodeLockId = -1;
nodeMetaData = new NodeMetaData(generateNodeId(settings));
return;
}
final NodePath[] nodePaths = new NodePath[environment.dataFiles().length];
final NodePath[] nodePaths = new NodePath[environment.dataWithClusterFiles().length];
final Lock[] locks = new Lock[nodePaths.length];
boolean success = false;
try {
sharedDataPath = environment.sharedDataFile();
int localNodeId = -1;
int nodeLockId = -1;
IOException lastException = null;
int maxLocalStorageNodes = MAX_LOCAL_STORAGE_NODES_SETTING.get(settings);
for (int possibleLockId = 0; possibleLockId < maxLocalStorageNodes; possibleLockId++) {
@ -203,7 +220,7 @@ public final class NodeEnvironment extends AbstractComponent implements Closeabl
try {
locks[dirIndex] = luceneDir.obtainLock(NODE_LOCK_FILENAME);
nodePaths[dirIndex] = new NodePath(dir);
localNodeId = possibleLockId;
nodeLockId = possibleLockId;
} catch (LockObtainFailedException ex) {
logger.trace("failed to obtain node lock on {}", dir.toAbsolutePath());
// release all the ones that were obtained up until now
@ -227,20 +244,22 @@ public final class NodeEnvironment extends AbstractComponent implements Closeabl
if (locks[0] == null) {
throw new IllegalStateException("Failed to obtain node lock, is the following location writable?: "
+ Arrays.toString(environment.dataFiles()), lastException);
+ Arrays.toString(environment.dataWithClusterFiles()), lastException);
}
this.localNodeId = localNodeId;
this.nodeLockId = nodeLockId;
this.locks = locks;
this.nodePaths = nodePaths;
if (logger.isDebugEnabled()) {
logger.debug("using node location [{}], local_node_id [{}]", nodePaths, localNodeId);
logger.debug("using node location [{}], local_lock_id [{}]", nodePaths, nodeLockId);
}
maybeLogPathDetails();
maybeLogHeapDetails();
this.nodeMetaData = loadOrCreateNodeMetaData(settings, logger, nodePaths);
applySegmentInfosTrace(settings);
assertCanWrite();
success = true;
@ -360,6 +379,27 @@ public final class NodeEnvironment extends AbstractComponent implements Closeabl
}
/**
* scans the node paths and loads existing metaData file. If not found a new meta data will be generated
* and persisted into the nodePaths
*/
private static NodeMetaData loadOrCreateNodeMetaData(Settings settings, ESLogger logger,
NodePath... nodePaths) throws IOException {
final Path[] paths = Arrays.stream(nodePaths).map(np -> np.path).toArray(Path[]::new);
NodeMetaData metaData = NodeMetaData.FORMAT.loadLatestState(logger, paths);
if (metaData == null) {
metaData = new NodeMetaData(generateNodeId(settings));
}
// we write again to make sure all paths have the latest state file
NodeMetaData.FORMAT.write(metaData, paths);
return metaData;
}
public static String generateNodeId(Settings settings) {
Random random = Randomness.get(settings, NODE_ID_SEED_SETTING);
return UUIDs.randomBase64UUID(random);
}
@SuppressForbidden(reason = "System.out.*")
static void applySegmentInfosTrace(Settings settings) {
if (ENABLE_LUCENE_SEGMENT_INFOS_TRACE_SETTING.get(settings)) {
@ -657,10 +697,6 @@ public final class NodeEnvironment extends AbstractComponent implements Closeabl
}
}
public int localNodeId() {
return this.localNodeId;
}
public boolean hasNodeFile() {
return nodePaths != null && locks != null;
}
@ -678,6 +714,17 @@ public final class NodeEnvironment extends AbstractComponent implements Closeabl
return paths;
}
/**
* returns the unique uuid describing this node. The uuid is persistent in the data folder of this node
* and remains across restarts.
**/
public String nodeId() {
// we currently only return the ID and hide the underlying nodeMetaData implementation in order to avoid
// confusion with other "metadata" like node settings found in elasticsearch.yml. In future
// we can encapsulate both (and more) in one NodeMetaData (or NodeSettings) object ala IndexSettings
return nodeMetaData.nodeId();
}
/**
* Returns an array of all of the {@link NodePath}s.
*/
@ -881,8 +928,8 @@ public final class NodeEnvironment extends AbstractComponent implements Closeabl
if (customDataDir != null) {
// This assert is because this should be caught by MetaDataCreateIndexService
assert sharedDataPath != null;
if (addNodeId) {
return sharedDataPath.resolve(customDataDir).resolve(Integer.toString(this.localNodeId));
if (addLockIdToCustomPath) {
return sharedDataPath.resolve(customDataDir).resolve(Integer.toString(this.nodeLockId));
} else {
return sharedDataPath.resolve(customDataDir);
}

View File

@ -0,0 +1,116 @@
/*
* 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.env;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.ParseFieldMatcherSupplier;
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.gateway.MetaDataStateFormat;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Objects;
/**
* Metadata associated with this node. Currently only contains the unique uuid describing this node.
* The metadata is persisted in the data folder of this node and is reused across restarts.
*/
public final class NodeMetaData {
private static final String NODE_ID_KEY = "node_id";
private final String nodeId;
public NodeMetaData(final String nodeId) {
this.nodeId = Objects.requireNonNull(nodeId);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
NodeMetaData that = (NodeMetaData) o;
return Objects.equals(this.nodeId, that.nodeId);
}
@Override
public int hashCode() {
return this.nodeId.hashCode();
}
@Override
public String toString() {
return "node_id [" + nodeId + "]";
}
private static ObjectParser<Builder, ParseFieldMatcherSupplier> PARSER = new ObjectParser<>("node_meta_data",
Builder::new);
static {
PARSER.declareString(Builder::setNodeId, new ParseField(NODE_ID_KEY));
}
public String nodeId() {
return nodeId;
}
private static class Builder {
String nodeId;
public void setNodeId(String nodeId) {
this.nodeId = nodeId;
}
public NodeMetaData build() {
return new NodeMetaData(nodeId);
}
}
public static final MetaDataStateFormat<NodeMetaData> FORMAT = new MetaDataStateFormat<NodeMetaData>(XContentType.SMILE, "node-") {
@Override
protected XContentBuilder newXContentBuilder(XContentType type, OutputStream stream) throws IOException {
XContentBuilder xContentBuilder = super.newXContentBuilder(type, stream);
xContentBuilder.prettyPrint();
return xContentBuilder;
}
@Override
public void toXContent(XContentBuilder builder, NodeMetaData nodeMetaData) throws IOException {
builder.field(NODE_ID_KEY, nodeMetaData.nodeId);
}
@Override
public NodeMetaData fromXContent(XContentParser parser) throws IOException {
return PARSER.apply(parser, () -> ParseFieldMatcher.STRICT).build();
}
};
}

View File

@ -64,7 +64,9 @@ public abstract class MetaDataStateFormat<T> {
public static final String STATE_DIR_NAME = "_state";
public static final String STATE_FILE_EXTENSION = ".st";
private static final String STATE_FILE_CODEC = "state";
private static final int STATE_FILE_VERSION = 0;
private static final int MIN_COMPATIBLE_STATE_FILE_VERSION = 0;
private static final int STATE_FILE_VERSION = 1;
private static final int STATE_FILE_VERSION_ES_2X_AND_BELOW = 0;
private static final int BUFFER_SIZE = 4096;
private final XContentType format;
private final String prefix;
@ -96,11 +98,10 @@ public abstract class MetaDataStateFormat<T> {
* it's target filename of the pattern <tt>{prefix}{version}.st</tt>.
*
* @param state the state object to write
* @param version the version of the state
* @param locations the locations where the state should be written to.
* @throws IOException if an IOException occurs
*/
public final void write(final T state, final long version, final Path... locations) throws IOException {
public final void write(final T state, final Path... locations) throws IOException {
if (locations == null) {
throw new IllegalArgumentException("Locations must not be null");
}
@ -116,10 +117,10 @@ public abstract class MetaDataStateFormat<T> {
final Path finalStatePath = stateLocation.resolve(fileName);
try {
final String resourceDesc = "MetaDataStateFormat.write(path=\"" + tmpStatePath + "\")";
try (OutputStreamIndexOutput out = new OutputStreamIndexOutput(resourceDesc, fileName, Files.newOutputStream(tmpStatePath), BUFFER_SIZE)) {
try (OutputStreamIndexOutput out =
new OutputStreamIndexOutput(resourceDesc, fileName, Files.newOutputStream(tmpStatePath), BUFFER_SIZE)) {
CodecUtil.writeHeader(out, STATE_FILE_CODEC, STATE_FILE_VERSION);
out.writeInt(format.index());
out.writeLong(version);
try (XContentBuilder builder = newXContentBuilder(format, new IndexOutputOutputStream(out) {
@Override
public void close() throws IOException {
@ -145,7 +146,8 @@ public abstract class MetaDataStateFormat<T> {
Path finalPath = stateLocation.resolve(fileName);
try {
Files.copy(finalStatePath, tmpPath);
Files.move(tmpPath, finalPath, StandardCopyOption.ATOMIC_MOVE); // we are on the same FileSystem / Partition here we can do an atomic move
// we are on the same FileSystem / Partition here we can do an atomic move
Files.move(tmpPath, finalPath, StandardCopyOption.ATOMIC_MOVE);
IOUtils.fsync(stateLocation, true); // we just fsync the dir here..
} finally {
Files.deleteIfExists(tmpPath);
@ -182,13 +184,18 @@ public abstract class MetaDataStateFormat<T> {
try (final IndexInput indexInput = dir.openInput(file.getFileName().toString(), IOContext.DEFAULT)) {
// We checksum the entire file before we even go and parse it. If it's corrupted we barf right here.
CodecUtil.checksumEntireFile(indexInput);
CodecUtil.checkHeader(indexInput, STATE_FILE_CODEC, STATE_FILE_VERSION, STATE_FILE_VERSION);
final int fileVersion = CodecUtil.checkHeader(indexInput, STATE_FILE_CODEC, MIN_COMPATIBLE_STATE_FILE_VERSION,
STATE_FILE_VERSION);
final XContentType xContentType = XContentType.values()[indexInput.readInt()];
if (fileVersion == STATE_FILE_VERSION_ES_2X_AND_BELOW) {
// format version 0, wrote a version that always came from the content state file and was never used
indexInput.readLong(); // version currently unused
}
long filePointer = indexInput.getFilePointer();
long contentSize = indexInput.length() - CodecUtil.footerLength() - filePointer;
try (IndexInput slice = indexInput.slice("state_xcontent", filePointer, contentSize)) {
try (XContentParser parser = XContentFactory.xContent(xContentType).createParser(new InputStreamIndexInput(slice, contentSize))) {
try (XContentParser parser = XContentFactory.xContent(xContentType).createParser(new InputStreamIndexInput(slice,
contentSize))) {
return fromXContent(parser);
}
}
@ -261,7 +268,8 @@ public abstract class MetaDataStateFormat<T> {
// now, iterate over the current versions, and find latest one
// we don't check if the stateDir is present since it could be deleted
// after the check. Also if there is a _state file and it's not a dir something is really wrong
try (DirectoryStream<Path> paths = Files.newDirectoryStream(stateDir)) { // we don't pass a glob since we need the group part for parsing
// we don't pass a glob since we need the group part for parsing
try (DirectoryStream<Path> paths = Files.newDirectoryStream(stateDir)) {
for (Path stateFile : paths) {
final Matcher matcher = stateFilePattern.matcher(stateFile.getFileName().toString());
if (matcher.matches()) {

View File

@ -125,7 +125,7 @@ public class MetaStateService extends AbstractComponent {
final Index index = indexMetaData.getIndex();
logger.trace("[{}] writing state, reason [{}]", index, reason);
try {
IndexMetaData.FORMAT.write(indexMetaData, indexMetaData.getVersion(),
IndexMetaData.FORMAT.write(indexMetaData,
nodeEnv.indexPaths(indexMetaData.getIndex()));
} catch (Exception ex) {
logger.warn("[{}]: failed to write index state", ex, index);
@ -139,7 +139,7 @@ public class MetaStateService extends AbstractComponent {
void writeGlobalState(String reason, MetaData metaData) throws Exception {
logger.trace("[_global] writing state, reason [{}]", reason);
try {
MetaData.FORMAT.write(metaData, metaData.version(), nodeEnv.nodeDataPaths());
MetaData.FORMAT.write(metaData, nodeEnv.nodeDataPaths());
} catch (Exception ex) {
logger.warn("[_global]: failed to write global state", ex);
throw new IOException("failed to write global state", ex);

View File

@ -1524,7 +1524,7 @@ public class IndexShard extends AbstractIndexShardComponent implements IndicesCl
}
logger.trace("{} writing shard state, reason [{}]", shardId, writeReason);
final ShardStateMetaData newShardStateMetadata = new ShardStateMetaData(newRouting.primary(), getIndexUUID(), newRouting.allocationId());
ShardStateMetaData.FORMAT.write(newShardStateMetadata, newShardStateMetadata.legacyVersion, shardPath().getShardStatePath());
ShardStateMetaData.FORMAT.write(newShardStateMetadata, shardPath().getShardStatePath());
} else {
logger.trace("{} skip writing shard state, has been written before", shardId);
}

View File

@ -149,6 +149,15 @@ public class Node implements Closeable {
new Setting<>("node.mode", "network", Function.identity(), Property.NodeScope);
public static final Setting<Boolean> NODE_INGEST_SETTING =
Setting.boolSetting("node.ingest", true, Property.NodeScope);
/**
* controls whether the node is allowed to persist things like metadata to disk
* Note that this does not control whether the node stores actual indices (see
* {@link #NODE_DATA_SETTING}). However, if this is false, {@link #NODE_DATA_SETTING}
* and {@link #NODE_MASTER_SETTING} must also be false.
*
*/
public static final Setting<Boolean> NODE_LOCAL_STORAGE_SETTING = Setting.boolSetting("node.local_storage", true, Property.NodeScope);
public static final Setting<String> NODE_NAME_SETTING = Setting.simpleString("node.name", Property.NodeScope);
public static final Setting<Settings> NODE_ATTRIBUTES = Setting.groupSetting("node.attr.", Property.NodeScope);
public static final Setting<String> BREAKER_TYPE_KEY = new Setting<>("indices.breaker.type", "hierarchy", (s) -> {
@ -253,7 +262,7 @@ public class Node implements Closeable {
final ClusterService clusterService = new ClusterService(settings, settingsModule.getClusterSettings(), threadPool);
clusterService.add(scriptModule.getScriptService());
resourcesToClose.add(clusterService);
final TribeService tribeService = new TribeService(settings, clusterService);
final TribeService tribeService = new TribeService(settings, clusterService, nodeEnvironment.nodeId());
resourcesToClose.add(tribeService);
NamedWriteableRegistry namedWriteableRegistry = new NamedWriteableRegistry();
ModulesBuilder modules = new ModulesBuilder();
@ -394,7 +403,7 @@ public class Node implements Closeable {
validateNodeBeforeAcceptingRequests(settings, transportService.boundAddress());
DiscoveryNode localNode = injector.getInstance(DiscoveryNodeService.class)
.buildLocalNode(transportService.boundAddress().publishAddress());
.buildLocalNode(transportService.boundAddress().publishAddress(), injector.getInstance(NodeEnvironment.class)::nodeId);
// TODO: need to find a cleaner way to start/construct a service with some initial parameters,
// playing nice with the life cycle interfaces

View File

@ -19,6 +19,7 @@
package org.elasticsearch.tribe;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.support.master.TransportMasterNodeReadAction;
import org.elasticsearch.cluster.ClusterChangedEvent;
@ -40,6 +41,7 @@ import org.elasticsearch.common.Priority;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.UUIDs;
import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.hash.MurmurHash3;
import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.common.network.NetworkService;
import org.elasticsearch.common.regex.Regex;
@ -51,6 +53,7 @@ import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.discovery.DiscoveryModule;
import org.elasticsearch.discovery.DiscoverySettings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.env.NodeEnvironment;
import org.elasticsearch.gateway.GatewayService;
import org.elasticsearch.node.Node;
import org.elasticsearch.rest.RestStatus;
@ -174,14 +177,14 @@ public class TribeService extends AbstractLifecycleComponent {
private final List<Node> nodes = new CopyOnWriteArrayList<>();
public TribeService(Settings settings, ClusterService clusterService) {
public TribeService(Settings settings, ClusterService clusterService, final String tribeNodeId) {
super(settings);
this.clusterService = clusterService;
Map<String, Settings> nodesSettings = new HashMap<>(settings.getGroups("tribe", true));
nodesSettings.remove("blocks"); // remove prefix settings that don't indicate a client
nodesSettings.remove("on_conflict"); // remove prefix settings that don't indicate a client
for (Map.Entry<String, Settings> entry : nodesSettings.entrySet()) {
Settings clientSettings = buildClientSettings(entry.getKey(), settings, entry.getValue());
Settings clientSettings = buildClientSettings(entry.getKey(), tribeNodeId, settings, entry.getValue());
nodes.add(new TribeClientNode(clientSettings));
}
@ -206,7 +209,7 @@ public class TribeService extends AbstractLifecycleComponent {
* Builds node settings for a tribe client node from the tribe node's global settings,
* combined with tribe specific settings.
*/
static Settings buildClientSettings(String tribeName, Settings globalSettings, Settings tribeSettings) {
static Settings buildClientSettings(String tribeName, String parentNodeId, Settings globalSettings, Settings tribeSettings) {
for (String tribeKey : tribeSettings.getAsMap().keySet()) {
if (tribeKey.startsWith("path.")) {
throw new IllegalArgumentException("Setting [" + tribeKey + "] not allowed in tribe client [" + tribeName + "]");
@ -236,6 +239,12 @@ public class TribeService extends AbstractLifecycleComponent {
sb.put(Node.NODE_DATA_SETTING.getKey(), false);
sb.put(Node.NODE_MASTER_SETTING.getKey(), false);
sb.put(Node.NODE_INGEST_SETTING.getKey(), false);
// node id of a tribe client node is determined by node id of parent node and tribe name
final BytesRef seedAsString = new BytesRef(parentNodeId + "/" + tribeName);
long nodeIdSeed = MurmurHash3.hash128(seedAsString.bytes, seedAsString.offset, seedAsString.length, 0, new MurmurHash3.Hash128()).h1;
sb.put(NodeEnvironment.NODE_ID_SEED_SETTING.getKey(), nodeIdSeed);
sb.put(Node.NODE_LOCAL_STORAGE_SETTING.getKey(), false);
return sb.build();
}
@ -359,14 +368,16 @@ public class TribeService extends AbstractLifecycleComponent {
}
// go over tribe nodes, and see if they need to be added
for (DiscoveryNode tribe : tribeState.nodes()) {
if (currentState.nodes().get(tribe.getId()) == null) {
if (currentState.nodes().nodeExists(tribe) == false) {
// a new node, add it, but also add the tribe name to the attributes
Map<String, String> tribeAttr = new HashMap<>(tribe.getAttributes());
tribeAttr.put(TRIBE_NAME_SETTING.getKey(), tribeName);
DiscoveryNode discoNode = new DiscoveryNode(tribe.getName(), tribe.getId(), tribe.getHostName(), tribe.getHostAddress(),
tribe.getAddress(), unmodifiableMap(tribeAttr), tribe.getRoles(), tribe.getVersion());
DiscoveryNode discoNode = new DiscoveryNode(tribe.getName(), tribe.getId(), tribe.getEphemeralId(),
tribe.getHostName(), tribe.getHostAddress(), tribe.getAddress(), unmodifiableMap(tribeAttr), tribe.getRoles(),
tribe.getVersion());
clusterStateChanged = true;
logger.info("[{}] adding node [{}]", tribeName, discoNode);
nodes.remove(tribe.getId()); // remove any existing node with the same id but different ephemeral id
nodes.put(discoNode);
}
}

View File

@ -31,7 +31,7 @@ import org.elasticsearch.cluster.routing.allocation.decider.Decision;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -65,7 +65,7 @@ public final class ClusterAllocationExplanationTests extends ESTestCase {
.numberOfShards(1)
.numberOfReplicas(1)
.build();
private DiscoveryNode node = new DiscoveryNode("node-0", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
private DiscoveryNode node = new DiscoveryNode("node-0", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
private static Decision.Multi yesDecision = new Decision.Multi();
private static Decision.Multi noDecision = new Decision.Multi();

View File

@ -26,7 +26,7 @@ import org.elasticsearch.common.UUIDs;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.collect.ImmutableOpenIntMap;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
@ -53,8 +53,8 @@ public class IndicesShardStoreResponseTests extends ESTestCase {
List<IndicesShardStoresResponse.Failure> failures = new ArrayList<>();
ImmutableOpenIntMap.Builder<List<IndicesShardStoresResponse.StoreStatus>> storeStatuses = ImmutableOpenIntMap.builder();
DiscoveryNode node1 = new DiscoveryNode("node1", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
DiscoveryNode node2 = new DiscoveryNode("node2", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
DiscoveryNode node1 = new DiscoveryNode("node1", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
DiscoveryNode node2 = new DiscoveryNode("node2", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
List<IndicesShardStoresResponse.StoreStatus> storeStatusList = new ArrayList<>();
storeStatusList.add(new IndicesShardStoresResponse.StoreStatus(node1, 3, null, IndicesShardStoresResponse.StoreStatus.AllocationStatus.PRIMARY, null));
storeStatusList.add(new IndicesShardStoresResponse.StoreStatus(node2, ShardStateMetaData.NO_VERSION, UUIDs.randomBase64UUID(), IndicesShardStoresResponse.StoreStatus.AllocationStatus.REPLICA, null));
@ -122,7 +122,7 @@ public class IndicesShardStoreResponseTests extends ESTestCase {
}
public void testStoreStatusOrdering() throws Exception {
DiscoveryNode node1 = new DiscoveryNode("node1", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
DiscoveryNode node1 = new DiscoveryNode("node1", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
List<IndicesShardStoresResponse.StoreStatus> orderedStoreStatuses = new ArrayList<>();
orderedStoreStatuses.add(new IndicesShardStoresResponse.StoreStatus(node1, ShardStateMetaData.NO_VERSION, UUIDs.randomBase64UUID(), IndicesShardStoresResponse.StoreStatus.AllocationStatus.PRIMARY, null));
orderedStoreStatuses.add(new IndicesShardStoresResponse.StoreStatus(node1, ShardStateMetaData.NO_VERSION, UUIDs.randomBase64UUID(), IndicesShardStoresResponse.StoreStatus.AllocationStatus.REPLICA, null));

View File

@ -38,7 +38,7 @@ import org.elasticsearch.cluster.routing.allocation.allocator.BalancedShardsAllo
import org.elasticsearch.cluster.routing.allocation.decider.AllocationDeciders;
import org.elasticsearch.cluster.routing.allocation.decider.MaxRetryAllocationDecider;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.index.shard.DocsStats;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.gateway.NoopGatewayAllocator;
@ -140,7 +140,7 @@ public class TransportShrinkActionTests extends ESTestCase {
}
private DiscoveryNode newNode(String nodeId) {
return new DiscoveryNode(nodeId, DummyTransportAddress.INSTANCE, emptyMap(),
return new DiscoveryNode(nodeId, LocalTransportAddress.buildUnique(), emptyMap(),
Collections.unmodifiableSet(new HashSet<>(Arrays.asList(DiscoveryNode.Role.MASTER, DiscoveryNode.Role.DATA))), Version.CURRENT);
}
}

View File

@ -33,7 +33,7 @@ import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.tasks.Task;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.VersionUtils;
@ -78,7 +78,7 @@ public class IngestProxyActionFilterTests extends ESTestCase {
if (i < ingestNodes) {
roles.add(DiscoveryNode.Role.INGEST);
}
DiscoveryNode node = new DiscoveryNode(nodeId, nodeId, DummyTransportAddress.INSTANCE, attributes, roles, VersionUtils.randomVersion(random()));
DiscoveryNode node = new DiscoveryNode(nodeId, nodeId, LocalTransportAddress.buildUnique(), attributes, roles, VersionUtils.randomVersion(random()));
builder.put(node);
if (i == totalNodes - 1) {
localNode = node;

View File

@ -49,7 +49,7 @@ import org.elasticsearch.cluster.routing.TestShardRouting;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.rest.RestStatus;
@ -247,7 +247,7 @@ public class TransportBroadcastByNodeActionTests extends ESTestCase {
}
static DiscoveryNode newNode(int nodeId) {
return new DiscoveryNode("node_" + nodeId, DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
return new DiscoveryNode("node_" + nodeId, LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
}
@AfterClass

View File

@ -37,7 +37,7 @@ import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.discovery.Discovery;
import org.elasticsearch.discovery.MasterNotDiscoveredException;
@ -89,9 +89,9 @@ public class TransportMasterNodeActionTests extends ESTestCase {
transportService = new TransportService(clusterService.getSettings(), transport, threadPool);
transportService.start();
transportService.acceptIncomingRequests();
localNode = new DiscoveryNode("local_node", DummyTransportAddress.INSTANCE, Collections.emptyMap(),
localNode = new DiscoveryNode("local_node", LocalTransportAddress.buildUnique(), Collections.emptyMap(),
Collections.singleton(DiscoveryNode.Role.MASTER), Version.CURRENT);
remoteNode = new DiscoveryNode("remote_node", DummyTransportAddress.INSTANCE, Collections.emptyMap(),
remoteNode = new DiscoveryNode("remote_node", LocalTransportAddress.buildUnique(), Collections.emptyMap(),
Collections.singleton(DiscoveryNode.Role.MASTER), Version.CURRENT);
allNodes = new DiscoveryNode[]{localNode, remoteNode};
}

View File

@ -32,7 +32,7 @@ import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.transport.CapturingTransport;
import org.elasticsearch.threadpool.TestThreadPool;
@ -236,7 +236,7 @@ public class TransportNodesActionTests extends ESTestCase {
private static DiscoveryNode newNode(int nodeId, Map<String, String> attributes, Set<DiscoveryNode.Role> roles) {
String node = "node_" + nodeId;
return new DiscoveryNode(node, node, DummyTransportAddress.INSTANCE, attributes, roles, Version.CURRENT);
return new DiscoveryNode(node, node, LocalTransportAddress.buildUnique(), attributes, roles, Version.CURRENT);
}
private static class TestTransportNodesAction

View File

@ -34,7 +34,7 @@ import org.elasticsearch.cluster.routing.ShardRoutingState;
import org.elasticsearch.cluster.routing.TestShardRouting;
import org.elasticsearch.cluster.routing.UnassignedInfo;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.index.shard.ShardId;
import java.util.Arrays;
@ -255,7 +255,7 @@ public class ClusterStateCreationUtils {
}
private static DiscoveryNode newNode(int nodeId) {
return new DiscoveryNode("node_" + nodeId, DummyTransportAddress.INSTANCE, Collections.emptyMap(),
return new DiscoveryNode("node_" + nodeId, LocalTransportAddress.buildUnique(), Collections.emptyMap(),
new HashSet<>(Arrays.asList(DiscoveryNode.Role.values())), Version.CURRENT);
}

View File

@ -122,7 +122,7 @@ public class TransportClientNodesServiceTests extends ESTestCase {
@SuppressWarnings("unchecked")
public void handleResponse(T response) {
LivenessResponse livenessResponse = new LivenessResponse(clusterName,
new DiscoveryNode(node.getName(), node.getId(), "liveness-hostname" + node.getId(),
new DiscoveryNode(node.getName(), node.getId(), node.getEphemeralId(), "liveness-hostname" + node.getId(),
"liveness-hostaddress" + node.getId(),
new LocalTransportAddress("liveness-address-" + node.getId()), node.getAttributes(), node.getRoles(),
node.getVersion()));

View File

@ -30,7 +30,7 @@ import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.cluster.routing.RoutingTable;
import org.elasticsearch.common.UUIDs;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.gateway.GatewayService;
import org.elasticsearch.index.Index;
import org.elasticsearch.test.ESTestCase;
@ -320,7 +320,8 @@ public class ClusterChangedEventTests extends ESTestCase {
// Create a new DiscoveryNode
private static DiscoveryNode newNode(final String nodeId, Set<DiscoveryNode.Role> roles) {
return new DiscoveryNode(nodeId, nodeId, DummyTransportAddress.INSTANCE, Collections.emptyMap(), roles, Version.CURRENT);
return new DiscoveryNode(nodeId, nodeId, nodeId, "host", "host_address", new LocalTransportAddress("_test_" + nodeId),
Collections.emptyMap(), roles, Version.CURRENT);
}
// Create the metadata for a cluster state.

View File

@ -53,6 +53,7 @@ import org.elasticsearch.index.Index;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.snapshots.Snapshot;
import org.elasticsearch.snapshots.SnapshotId;
import org.elasticsearch.test.ESIntegTestCase;
import java.util.Collections;
@ -191,9 +192,8 @@ public class ClusterStateDiffIT extends ESIntegTestCase {
List<String> nodeIds = randomSubsetOf(randomInt(clusterState.nodes().getNodes().size() - 1), clusterState.nodes().getNodes().keys().toArray(String.class));
for (String nodeId : nodeIds) {
if (nodeId.startsWith("node-")) {
if (randomBoolean()) {
nodes.remove(nodeId);
} else {
if (randomBoolean()) {
nodes.put(new DiscoveryNode(nodeId, new LocalTransportAddress(randomAsciiOfLength(10)), emptyMap(),
emptySet(), randomVersion(random())));
}

View File

@ -22,7 +22,7 @@ import org.elasticsearch.Version;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.test.ESTestCase;
import static java.util.Collections.emptyMap;
@ -32,8 +32,9 @@ import static org.hamcrest.Matchers.equalTo;
public class ClusterStateTests extends ESTestCase {
public void testSupersedes() {
final DiscoveryNode node1 = new DiscoveryNode("node1", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
final DiscoveryNode node2 = new DiscoveryNode("node2", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
final Version version = Version.CURRENT;
final DiscoveryNode node1 = new DiscoveryNode("node1", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), version);
final DiscoveryNode node2 = new DiscoveryNode("node2", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), version);
final DiscoveryNodes nodes = DiscoveryNodes.builder().put(node1).put(node2).build();
ClusterName name = ClusterName.CLUSTER_NAME_SETTING.getDefault(Settings.EMPTY);
ClusterState noMaster1 = ClusterState.builder(name).version(randomInt(5)).nodes(nodes).build();

View File

@ -23,8 +23,6 @@ import org.elasticsearch.Version;
import org.elasticsearch.action.admin.cluster.node.stats.NodeStats;
import org.elasticsearch.action.admin.indices.stats.CommonStats;
import org.elasticsearch.action.admin.indices.stats.ShardStats;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.node.DiscoveryNode;
@ -33,7 +31,7 @@ import org.elasticsearch.cluster.routing.ShardRoutingHelper;
import org.elasticsearch.cluster.routing.UnassignedInfo;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.index.shard.ShardPath;
@ -200,11 +198,11 @@ public class DiskUsageTests extends ESTestCase {
new FsInfo.Path("/most", "/dev/sda", 100, 90, 80),
};
List<NodeStats> nodeStats = Arrays.asList(
new NodeStats(new DiscoveryNode("node_1", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT), 0,
new NodeStats(new DiscoveryNode("node_1", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT), 0,
null,null,null,null,null,new FsInfo(0, null, node1FSInfo), null,null,null,null,null, null),
new NodeStats(new DiscoveryNode("node_2", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT), 0,
new NodeStats(new DiscoveryNode("node_2", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT), 0,
null,null,null,null,null, new FsInfo(0, null, node2FSInfo), null,null,null,null,null, null),
new NodeStats(new DiscoveryNode("node_3", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT), 0,
new NodeStats(new DiscoveryNode("node_3", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT), 0,
null,null,null,null,null, new FsInfo(0, null, node3FSInfo), null,null,null,null,null, null)
);
InternalClusterInfoService.fillDiskUsagePerNode(logger, nodeStats, newLeastAvaiableUsages, newMostAvaiableUsages);
@ -241,11 +239,11 @@ public class DiskUsageTests extends ESTestCase {
new FsInfo.Path("/least", "/dev/sda", 10, -8, 0),
};
List<NodeStats> nodeStats = Arrays.asList(
new NodeStats(new DiscoveryNode("node_1", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT), 0,
new NodeStats(new DiscoveryNode("node_1", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT), 0,
null,null,null,null,null,new FsInfo(0, null, node1FSInfo), null,null,null,null,null, null),
new NodeStats(new DiscoveryNode("node_2", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT), 0,
new NodeStats(new DiscoveryNode("node_2", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT), 0,
null,null,null,null,null, new FsInfo(0, null, node2FSInfo), null,null,null,null,null, null),
new NodeStats(new DiscoveryNode("node_3", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT), 0,
new NodeStats(new DiscoveryNode("node_3", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT), 0,
null,null,null,null,null, new FsInfo(0, null, node3FSInfo), null,null,null,null,null, null)
);
InternalClusterInfoService.fillDiskUsagePerNode(logger, nodeStats, newLeastAvailableUsages, newMostAvailableUsages);

View File

@ -26,7 +26,7 @@ import org.elasticsearch.common.component.Lifecycle;
import org.elasticsearch.common.component.LifecycleListener;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.BoundTransportAddress;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.util.concurrent.ConcurrentCollections;
import org.elasticsearch.test.ESTestCase;
@ -64,7 +64,7 @@ public class NodeConnectionsServiceTests extends ESTestCase {
List<DiscoveryNode> nodes = new ArrayList<>();
for (int i = randomIntBetween(20, 50); i > 0; i--) {
Set<DiscoveryNode.Role> roles = new HashSet<>(randomSubsetOf(Arrays.asList(DiscoveryNode.Role.values())));
nodes.add(new DiscoveryNode("node_" + i, "" + i, DummyTransportAddress.INSTANCE, Collections.emptyMap(),
nodes.add(new DiscoveryNode("node_" + i, "" + i, LocalTransportAddress.buildUnique(), Collections.emptyMap(),
roles, Version.CURRENT));
}
return nodes;

View File

@ -27,7 +27,6 @@ import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.ClusterStateTaskExecutor;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.node.DiscoveryNodeService;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.cluster.routing.GroupShardsIterator;
import org.elasticsearch.cluster.routing.IndexShardRoutingTable;
@ -41,6 +40,7 @@ import org.elasticsearch.cluster.routing.allocation.AllocationService;
import org.elasticsearch.cluster.routing.allocation.FailedRerouteAllocation;
import org.elasticsearch.cluster.routing.allocation.RoutingAllocation;
import org.elasticsearch.cluster.routing.allocation.decider.ClusterRebalanceAllocationDecider;
import org.elasticsearch.common.UUIDs;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.shard.ShardId;
@ -305,7 +305,8 @@ public class ShardFailedClusterStateTaskExecutorTests extends ESAllocationTestCa
return randomSubsetOf(1, shards.toArray(new ShardRouting[0])).get(0);
} else {
return
TestShardRouting.newShardRouting(shardRouting.shardId(), DiscoveryNodeService.generateNodeId(Settings.EMPTY), randomBoolean(), randomFrom(ShardRoutingState.values()));
TestShardRouting.newShardRouting(shardRouting.shardId(), UUIDs.randomBase64UUID(random()), randomBoolean(),
randomFrom(ShardRoutingState.values()));
}
}

View File

@ -34,7 +34,7 @@ import org.elasticsearch.cluster.routing.allocation.decider.AllocationDeciders;
import org.elasticsearch.cluster.routing.allocation.decider.MaxRetryAllocationDecider;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.indices.IndexAlreadyExistsException;
import org.elasticsearch.indices.InvalidIndexNameException;
@ -181,7 +181,7 @@ public class MetaDataCreateIndexServiceTests extends ESTestCase {
}
private DiscoveryNode newNode(String nodeId) {
return new DiscoveryNode(nodeId, DummyTransportAddress.INSTANCE, emptyMap(),
return new DiscoveryNode(nodeId, LocalTransportAddress.buildUnique(), emptyMap(),
Collections.unmodifiableSet(new HashSet<>(Arrays.asList(DiscoveryNode.Role.MASTER, DiscoveryNode.Role.DATA))), Version.CURRENT);
}

View File

@ -21,8 +21,8 @@ package org.elasticsearch.cluster.node;
import org.elasticsearch.Version;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.test.ESTestCase;
import org.junit.AfterClass;
import org.junit.BeforeClass;
@ -64,10 +64,11 @@ public class DiscoveryNodeFiltersTests extends ESTestCase {
.build();
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(OR, "xxx.", settings);
DiscoveryNode node = new DiscoveryNode("name1", "id1", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
DiscoveryNode node = new DiscoveryNode("name1", "id1", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(),
Version.CURRENT);
assertThat(filters.match(node), equalTo(true));
node = new DiscoveryNode("name2", "id2", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
node = new DiscoveryNode("name2", "id2", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
assertThat(filters.match(node), equalTo(false));
}
@ -77,10 +78,11 @@ public class DiscoveryNodeFiltersTests extends ESTestCase {
.build();
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(OR, "xxx.", settings);
DiscoveryNode node = new DiscoveryNode("name1", "id1", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
DiscoveryNode node = new DiscoveryNode("name1", "id1", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(),
Version.CURRENT);
assertThat(filters.match(node), equalTo(true));
node = new DiscoveryNode("name2", "id2", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
node = new DiscoveryNode("name2", "id2", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
assertThat(filters.match(node), equalTo(false));
}
@ -91,13 +93,14 @@ public class DiscoveryNodeFiltersTests extends ESTestCase {
.build());
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(OR, "xxx.", settings);
DiscoveryNode node = new DiscoveryNode("name1", "id1", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
final Version version = Version.CURRENT;
DiscoveryNode node = new DiscoveryNode("name1", "id1", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), version);
assertThat(filters.match(node), equalTo(true));
node = new DiscoveryNode("name2", "id2", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
node = new DiscoveryNode("name2", "id2", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), version);
assertThat(filters.match(node), equalTo(true));
node = new DiscoveryNode("name3", "id3", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
node = new DiscoveryNode("name3", "id3", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), version);
assertThat(filters.match(node), equalTo(false));
}
@ -111,7 +114,7 @@ public class DiscoveryNodeFiltersTests extends ESTestCase {
Map<String, String> attributes = new HashMap<>();
attributes.put("tag", "A");
attributes.put("group", "B");
DiscoveryNode node = new DiscoveryNode("name1", "id1", DummyTransportAddress.INSTANCE,
DiscoveryNode node = new DiscoveryNode("name1", "id1", LocalTransportAddress.buildUnique(),
attributes, emptySet(), Version.CURRENT);
assertThat(filters.match(node), equalTo(true));
@ -119,7 +122,7 @@ public class DiscoveryNodeFiltersTests extends ESTestCase {
attributes.put("tag", "A");
attributes.put("group", "B");
attributes.put("name", "X");
node = new DiscoveryNode("name2", "id2", DummyTransportAddress.INSTANCE,
node = new DiscoveryNode("name2", "id2", LocalTransportAddress.buildUnique(),
attributes, emptySet(), Version.CURRENT);
assertThat(filters.match(node), equalTo(true));
@ -127,11 +130,11 @@ public class DiscoveryNodeFiltersTests extends ESTestCase {
attributes.put("tag", "A");
attributes.put("group", "F");
attributes.put("name", "X");
node = new DiscoveryNode("name3", "id3", DummyTransportAddress.INSTANCE,
node = new DiscoveryNode("name3", "id3", LocalTransportAddress.buildUnique(),
attributes, emptySet(), Version.CURRENT);
assertThat(filters.match(node), equalTo(false));
node = new DiscoveryNode("name4", "id4", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
node = new DiscoveryNode("name4", "id4", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
assertThat(filters.match(node), equalTo(false));
}
@ -141,7 +144,8 @@ public class DiscoveryNodeFiltersTests extends ESTestCase {
.build();
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(OR, "xxx.", settings);
DiscoveryNode node = new DiscoveryNode("name1", "id1", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
DiscoveryNode node = new DiscoveryNode("name1", "id1", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(),
Version.CURRENT);
assertThat(filters.match(node), equalTo(true));
}
@ -152,7 +156,7 @@ public class DiscoveryNodeFiltersTests extends ESTestCase {
.build());
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(AND, "xxx.", settings);
DiscoveryNode node = new DiscoveryNode("", "", "", "192.1.1.54", localAddress, singletonMap("tag", "A"), emptySet(), null);
DiscoveryNode node = new DiscoveryNode("", "", "", "", "192.1.1.54", localAddress, singletonMap("tag", "A"), emptySet(), null);
assertThat(filters.match(node), equalTo(true));
}
@ -163,7 +167,7 @@ public class DiscoveryNodeFiltersTests extends ESTestCase {
.build());
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(AND, "xxx.", settings);
DiscoveryNode node = new DiscoveryNode("", "", "", "192.1.1.54", localAddress, singletonMap("tag", "A"), emptySet(), null);
DiscoveryNode node = new DiscoveryNode("", "", "", "", "192.1.1.54", localAddress, singletonMap("tag", "A"), emptySet(), null);
assertThat(filters.match(node), equalTo(false));
}
@ -174,7 +178,7 @@ public class DiscoveryNodeFiltersTests extends ESTestCase {
.build());
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(AND, "xxx.", settings);
DiscoveryNode node = new DiscoveryNode("", "", "", "192.1.1.54", localAddress, singletonMap("tag", "A"), emptySet(), null);
DiscoveryNode node = new DiscoveryNode("", "", "", "", "192.1.1.54", localAddress, singletonMap("tag", "A"), emptySet(), null);
assertThat(filters.match(node), equalTo(false));
}
@ -185,7 +189,7 @@ public class DiscoveryNodeFiltersTests extends ESTestCase {
.build());
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(OR, "xxx.", settings);
DiscoveryNode node = new DiscoveryNode("", "", "", "192.1.1.54", localAddress, singletonMap("tag", "A"), emptySet(), null);
DiscoveryNode node = new DiscoveryNode("", "", "", "", "192.1.1.54", localAddress, singletonMap("tag", "A"), emptySet(), null);
assertThat(filters.match(node), equalTo(true));
}
@ -196,7 +200,7 @@ public class DiscoveryNodeFiltersTests extends ESTestCase {
.build());
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(OR, "xxx.", settings);
DiscoveryNode node = new DiscoveryNode("", "", "", "192.1.1.54", localAddress, singletonMap("tag", "A"), emptySet(), null);
DiscoveryNode node = new DiscoveryNode("", "", "", "", "192.1.1.54", localAddress, singletonMap("tag", "A"), emptySet(), null);
assertThat(filters.match(node), equalTo(true));
}
@ -207,7 +211,7 @@ public class DiscoveryNodeFiltersTests extends ESTestCase {
.build());
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(AND, "xxx.", settings);
DiscoveryNode node = new DiscoveryNode("", "", "", "192.1.1.54", localAddress, singletonMap("tag", "A"), emptySet(), null);
DiscoveryNode node = new DiscoveryNode("", "", "", "", "192.1.1.54", localAddress, singletonMap("tag", "A"), emptySet(), null);
assertThat(filters.match(node), equalTo(true));
}
@ -218,7 +222,7 @@ public class DiscoveryNodeFiltersTests extends ESTestCase {
.build());
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(AND, "xxx.", settings);
DiscoveryNode node = new DiscoveryNode("", "", "", "192.1.1.54", localAddress, singletonMap("tag", "A"), emptySet(), null);
DiscoveryNode node = new DiscoveryNode("", "", "", "", "192.1.1.54", localAddress, singletonMap("tag", "A"), emptySet(), null);
assertThat(filters.match(node), equalTo(false));
}
@ -229,7 +233,7 @@ public class DiscoveryNodeFiltersTests extends ESTestCase {
.build());
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(OR, "xxx.", settings);
DiscoveryNode node = new DiscoveryNode("", "", "", "192.1.1.54", localAddress, singletonMap("tag", "A"), emptySet(), null);
DiscoveryNode node = new DiscoveryNode("", "", "", "", "192.1.1.54", localAddress, singletonMap("tag", "A"), emptySet(), null);
assertThat(filters.match(node), equalTo(true));
}
@ -240,7 +244,7 @@ public class DiscoveryNodeFiltersTests extends ESTestCase {
.build());
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(OR, "xxx.", settings);
DiscoveryNode node = new DiscoveryNode("", "", "", "192.1.1.54", localAddress, singletonMap("tag", "A"), emptySet(), null);
DiscoveryNode node = new DiscoveryNode("", "", "", "", "192.1.1.54", localAddress, singletonMap("tag", "A"), emptySet(), null);
assertThat(filters.match(node), equalTo(true));
}

View File

@ -19,9 +19,9 @@
package org.elasticsearch.cluster.node;
import org.elasticsearch.Version;
import org.elasticsearch.common.UUIDs;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.test.ESTestCase;
import java.util.HashMap;
@ -55,7 +55,8 @@ public class DiscoveryNodeServiceTests extends ESTestCase {
}
}
DiscoveryNodeService discoveryNodeService = new DiscoveryNodeService(builder.build());
DiscoveryNode discoveryNode = discoveryNodeService.buildLocalNode(DummyTransportAddress.INSTANCE);
DiscoveryNode discoveryNode = discoveryNodeService.buildLocalNode(LocalTransportAddress.buildUnique(),
() -> UUIDs.randomBase64UUID(random()));
assertThat(discoveryNode.getRoles(), equalTo(selectedRoles));
assertThat(discoveryNode.getAttributes(), equalTo(expectedAttributes));
}
@ -77,7 +78,8 @@ public class DiscoveryNodeServiceTests extends ESTestCase {
expectedAttributes.putAll(customAttributes);
discoveryNodeService.addCustomAttributeProvider(() -> customAttributes);
DiscoveryNode discoveryNode = discoveryNodeService.buildLocalNode(DummyTransportAddress.INSTANCE);
DiscoveryNode discoveryNode = discoveryNodeService.buildLocalNode(LocalTransportAddress.buildUnique(),
() -> UUIDs.randomBase64UUID(random()));
assertThat(discoveryNode.getAttributes(), equalTo(expectedAttributes));
}
}

View File

@ -19,8 +19,9 @@
package org.elasticsearch.cluster.node;
import com.carrotsearch.randomizedtesting.generators.RandomPicks;
import org.elasticsearch.Version;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.test.ESTestCase;
import java.util.ArrayList;
@ -30,10 +31,15 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.nullValue;
public class DiscoveryNodesTests extends ESTestCase {
@ -53,7 +59,7 @@ public class DiscoveryNodesTests extends ESTestCase {
DiscoveryNode resolvedNode = discoveryNodes.resolveNode(nodeSelector.selector);
assertThat(matchingNodeIds.size(), equalTo(1));
assertThat(resolvedNode.getId(), equalTo(matchingNodeIds.iterator().next()));
} catch(IllegalArgumentException e) {
} catch (IllegalArgumentException e) {
if (matchingNodeIds.size() == 0) {
assertThat(e.getMessage(), equalTo("failed to resolve [" + nodeSelector.selector + "], no matching nodes"));
} else if (matchingNodeIds.size() > 1) {
@ -98,26 +104,98 @@ public class DiscoveryNodesTests extends ESTestCase {
assertThat(resolvedNodesIds, equalTo(expectedNodesIds));
}
private static DiscoveryNodes buildDiscoveryNodes() {
int numNodes = randomIntBetween(1, 10);
DiscoveryNodes.Builder discoBuilder = DiscoveryNodes.builder();
public void testDeltas() {
Set<DiscoveryNode> nodesA = new HashSet<>();
nodesA.addAll(randomNodes(1 + randomInt(10)));
Set<DiscoveryNode> nodesB = new HashSet<>();
nodesB.addAll(randomNodes(1 + randomInt(5)));
for (DiscoveryNode node : randomSubsetOf(nodesA)) {
if (randomBoolean()) {
// change an attribute
Map<String, String> attrs = new HashMap<>(node.getAttributes());
attrs.put("new", "new");
node = new DiscoveryNode(node.getName(), node.getId(), node.getAddress(), attrs, node.getRoles(), node.getVersion());
}
nodesB.add(node);
}
DiscoveryNode masterA = randomBoolean() ? null : RandomPicks.randomFrom(random(), nodesA);
DiscoveryNode masterB = randomBoolean() ? null : RandomPicks.randomFrom(random(), nodesB);
DiscoveryNodes.Builder builderA = DiscoveryNodes.builder();
nodesA.stream().forEach(builderA::put);
final String masterAId = masterA == null ? null : masterA.getId();
builderA.masterNodeId(masterAId);
builderA.localNodeId(RandomPicks.randomFrom(random(), nodesA).getId());
DiscoveryNodes.Builder builderB = DiscoveryNodes.builder();
nodesB.stream().forEach(builderB::put);
final String masterBId = masterB == null ? null : masterB.getId();
builderB.masterNodeId(masterBId);
builderB.localNodeId(RandomPicks.randomFrom(random(), nodesB).getId());
final DiscoveryNodes discoNodesA = builderA.build();
final DiscoveryNodes discoNodesB = builderB.build();
logger.info("nodes A: {}", discoNodesA.prettyPrint());
logger.info("nodes B: {}", discoNodesB.prettyPrint());
DiscoveryNodes.Delta delta = discoNodesB.delta(discoNodesA);
if (masterB == null || Objects.equals(masterAId, masterBId)) {
assertFalse(delta.masterNodeChanged());
assertThat(delta.previousMasterNode(), nullValue());
assertThat(delta.newMasterNode(), nullValue());
} else {
assertTrue(delta.masterNodeChanged());
assertThat(delta.newMasterNode().getId(), equalTo(masterBId));
assertThat(delta.previousMasterNode() != null ? delta.previousMasterNode().getId() : null,
equalTo(masterAId));
}
Set<DiscoveryNode> newNodes = new HashSet<>(nodesB);
newNodes.removeAll(nodesA);
assertThat(delta.added(), equalTo(newNodes.isEmpty() == false));
assertThat(delta.addedNodes(), containsInAnyOrder(newNodes.stream().collect(Collectors.toList()).toArray()));
assertThat(delta.addedNodes().size(), equalTo(newNodes.size()));
Set<DiscoveryNode> removedNodes = new HashSet<>(nodesA);
removedNodes.removeAll(nodesB);
assertThat(delta.removed(), equalTo(removedNodes.isEmpty() == false));
assertThat(delta.removedNodes(), containsInAnyOrder(removedNodes.stream().collect(Collectors.toList()).toArray()));
assertThat(delta.removedNodes().size(), equalTo(removedNodes.size()));
}
private static AtomicInteger idGenerator = new AtomicInteger();
private static List<DiscoveryNode> randomNodes(final int numNodes) {
List<DiscoveryNode> nodesList = new ArrayList<>();
for (int i = 0; i < numNodes; i++) {
Map<String, String> attributes = new HashMap<>();
if (frequently()) {
attributes.put("custom", randomBoolean() ? "match" : randomAsciiOfLengthBetween(3, 5));
}
final DiscoveryNode node = newNode(i, attributes, new HashSet<>(randomSubsetOf(Arrays.asList(DiscoveryNode.Role.values()))));
discoBuilder = discoBuilder.put(node);
final DiscoveryNode node = newNode(idGenerator.getAndIncrement(), attributes,
new HashSet<>(randomSubsetOf(Arrays.asList(DiscoveryNode.Role.values()))));
nodesList.add(node);
}
return nodesList;
}
private static DiscoveryNodes buildDiscoveryNodes() {
int numNodes = randomIntBetween(1, 10);
DiscoveryNodes.Builder discoBuilder = DiscoveryNodes.builder();
List<DiscoveryNode> nodesList = randomNodes(numNodes);
for (DiscoveryNode node : nodesList) {
discoBuilder = discoBuilder.put(node);
}
discoBuilder.localNodeId(randomFrom(nodesList).getId());
discoBuilder.masterNodeId(randomFrom(nodesList).getId());
return discoBuilder.build();
}
private static DiscoveryNode newNode(int nodeId, Map<String, String> attributes, Set<DiscoveryNode.Role> roles) {
return new DiscoveryNode("name_" + nodeId, "node_" + nodeId, DummyTransportAddress.INSTANCE, attributes, roles, Version.CURRENT);
return new DiscoveryNode("name_" + nodeId, "node_" + nodeId, LocalTransportAddress.buildUnique(), attributes, roles,
Version.CURRENT);
}
private enum NodeSelector {
@ -152,7 +230,7 @@ public class DiscoveryNodesTests extends ESTestCase {
nodes.getIngestNodes().keysIt().forEachRemaining(ids::add);
return ids;
}
},CUSTOM_ATTRIBUTE("attr:value") {
}, CUSTOM_ATTRIBUTE("attr:value") {
@Override
Set<String> matchingNodeIds(DiscoveryNodes nodes) {
Set<String> ids = new HashSet<>();

View File

@ -25,8 +25,6 @@ import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.EmptyClusterInfoService;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.common.UUIDs;
import org.elasticsearch.snapshots.SnapshotId;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.cluster.routing.IndexRoutingTable;
@ -44,12 +42,14 @@ import org.elasticsearch.cluster.routing.allocation.decider.AllocationDeciders;
import org.elasticsearch.cluster.routing.allocation.decider.ClusterRebalanceAllocationDecider;
import org.elasticsearch.cluster.routing.allocation.decider.NodeVersionAllocationDecider;
import org.elasticsearch.cluster.routing.allocation.decider.ReplicaAfterPrimaryActiveAllocationDecider;
import org.elasticsearch.common.UUIDs;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.snapshots.Snapshot;
import org.elasticsearch.snapshots.SnapshotId;
import org.elasticsearch.test.ESAllocationTestCase;
import org.elasticsearch.test.VersionUtils;
import org.elasticsearch.test.gateway.NoopGatewayAllocator;
@ -307,11 +307,11 @@ public class NodeVersionAllocationDeciderTests extends ESAllocationTestCase {
public void testRebalanceDoesNotAllocatePrimaryAndReplicasOnDifferentVersionNodes() {
ShardId shard1 = new ShardId("test1", "_na_", 0);
ShardId shard2 = new ShardId("test2", "_na_", 0);
final DiscoveryNode newNode = new DiscoveryNode("newNode", DummyTransportAddress.INSTANCE, emptyMap(),
final DiscoveryNode newNode = new DiscoveryNode("newNode", LocalTransportAddress.buildUnique(), emptyMap(),
MASTER_DATA_ROLES, Version.CURRENT);
final DiscoveryNode oldNode1 = new DiscoveryNode("oldNode1", DummyTransportAddress.INSTANCE, emptyMap(),
final DiscoveryNode oldNode1 = new DiscoveryNode("oldNode1", LocalTransportAddress.buildUnique(), emptyMap(),
MASTER_DATA_ROLES, VersionUtils.getPreviousVersion());
final DiscoveryNode oldNode2 = new DiscoveryNode("oldNode2", DummyTransportAddress.INSTANCE, emptyMap(),
final DiscoveryNode oldNode2 = new DiscoveryNode("oldNode2", LocalTransportAddress.buildUnique(), emptyMap(),
MASTER_DATA_ROLES, VersionUtils.getPreviousVersion());
MetaData metaData = MetaData.builder()
.put(IndexMetaData.builder(shard1.getIndexName()).settings(settings(Version.CURRENT).put(Settings.EMPTY)).numberOfShards(1).numberOfReplicas(1))
@ -347,11 +347,11 @@ public class NodeVersionAllocationDeciderTests extends ESAllocationTestCase {
}
public void testRestoreDoesNotAllocateSnapshotOnOlderNodes() {
final DiscoveryNode newNode = new DiscoveryNode("newNode", DummyTransportAddress.INSTANCE, emptyMap(),
final DiscoveryNode newNode = new DiscoveryNode("newNode", LocalTransportAddress.buildUnique(), emptyMap(),
MASTER_DATA_ROLES, Version.CURRENT);
final DiscoveryNode oldNode1 = new DiscoveryNode("oldNode1", DummyTransportAddress.INSTANCE, emptyMap(),
final DiscoveryNode oldNode1 = new DiscoveryNode("oldNode1", LocalTransportAddress.buildUnique(), emptyMap(),
MASTER_DATA_ROLES, VersionUtils.getPreviousVersion());
final DiscoveryNode oldNode2 = new DiscoveryNode("oldNode2", DummyTransportAddress.INSTANCE, emptyMap(),
final DiscoveryNode oldNode2 = new DiscoveryNode("oldNode2", LocalTransportAddress.buildUnique(), emptyMap(),
MASTER_DATA_ROLES, VersionUtils.getPreviousVersion());
int numberOfShards = randomIntBetween(1, 3);

View File

@ -33,7 +33,7 @@ import org.elasticsearch.cluster.routing.allocation.decider.SameShardAllocationD
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.test.ESAllocationTestCase;
import static java.util.Collections.emptyMap;
@ -63,9 +63,9 @@ public class SameShardRoutingTests extends ESAllocationTestCase {
logger.info("--> adding two nodes with the same host");
clusterState = ClusterState.builder(clusterState).nodes(
DiscoveryNodes.builder()
.put(new DiscoveryNode("node1", "node1", "test1", "test1", DummyTransportAddress.INSTANCE, emptyMap(),
.put(new DiscoveryNode("node1", "node1", "node1", "test1", "test1", LocalTransportAddress.buildUnique(), emptyMap(),
MASTER_DATA_ROLES, Version.CURRENT))
.put(new DiscoveryNode("node2", "node2", "test1", "test1", DummyTransportAddress.INSTANCE, emptyMap(),
.put(new DiscoveryNode("node2", "node2", "node2", "test1", "test1", LocalTransportAddress.buildUnique(), emptyMap(),
MASTER_DATA_ROLES, Version.CURRENT))).build();
routingTable = strategy.reroute(clusterState, "reroute").routingTable();
clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build();
@ -82,7 +82,7 @@ public class SameShardRoutingTests extends ESAllocationTestCase {
logger.info("--> add another node, with a different host, replicas will be allocating");
clusterState = ClusterState.builder(clusterState).nodes(DiscoveryNodes.builder(clusterState.nodes())
.put(new DiscoveryNode("node3", "node3", "test2", "test2", DummyTransportAddress.INSTANCE, emptyMap(),
.put(new DiscoveryNode("node3", "node3", "node3", "test2", "test2", LocalTransportAddress.buildUnique(), emptyMap(),
MASTER_DATA_ROLES, Version.CURRENT))).build();
routingTable = strategy.reroute(clusterState, "reroute").routingTable();
clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build();

View File

@ -41,7 +41,6 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.index.Index;
@ -110,9 +109,9 @@ public class DiskThresholdDeciderUnitTests extends ESAllocationTestCase {
final Index index = metaData.index("test").getIndex();
ShardRouting test_0 = ShardRouting.newUnassigned(new ShardId(index, 0), null, true, new UnassignedInfo(UnassignedInfo.Reason.INDEX_CREATED, "foo"));
DiscoveryNode node_0 = new DiscoveryNode("node_0", DummyTransportAddress.INSTANCE, Collections.emptyMap(),
DiscoveryNode node_0 = new DiscoveryNode("node_0", LocalTransportAddress.buildUnique(), Collections.emptyMap(),
new HashSet<>(Arrays.asList(DiscoveryNode.Role.values())), Version.CURRENT);
DiscoveryNode node_1 = new DiscoveryNode("node_1", DummyTransportAddress.INSTANCE, Collections.emptyMap(),
DiscoveryNode node_1 = new DiscoveryNode("node_1", LocalTransportAddress.buildUnique(), Collections.emptyMap(),
new HashSet<>(Arrays.asList(DiscoveryNode.Role.values())), Version.CURRENT);
RoutingTable routingTable = RoutingTable.builder()
@ -149,9 +148,9 @@ public class DiskThresholdDeciderUnitTests extends ESAllocationTestCase {
DiskThresholdDecider decider = new DiskThresholdDecider(Settings.EMPTY, nss, cis, null);
ImmutableOpenMap.Builder<ShardRouting, String> shardRoutingMap = ImmutableOpenMap.builder();
DiscoveryNode node_0 = new DiscoveryNode("node_0", DummyTransportAddress.INSTANCE, Collections.emptyMap(),
DiscoveryNode node_0 = new DiscoveryNode("node_0", LocalTransportAddress.buildUnique(), Collections.emptyMap(),
new HashSet<>(Arrays.asList(DiscoveryNode.Role.values())), Version.CURRENT);
DiscoveryNode node_1 = new DiscoveryNode("node_1", DummyTransportAddress.INSTANCE, Collections.emptyMap(),
DiscoveryNode node_1 = new DiscoveryNode("node_1", LocalTransportAddress.buildUnique(), Collections.emptyMap(),
new HashSet<>(Arrays.asList(DiscoveryNode.Role.values())), Version.CURRENT);
MetaData metaData = MetaData.builder()

View File

@ -29,7 +29,7 @@ import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.cluster.routing.RoutingTable;
import org.elasticsearch.cluster.routing.allocation.AllocationService;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.test.ESAllocationTestCase;
import static java.util.Collections.emptyMap;
@ -50,7 +50,7 @@ public class ClusterStateToStringTests extends ESAllocationTestCase {
.addAsNew(metaData.index("test_idx"))
.build();
DiscoveryNodes nodes = DiscoveryNodes.builder().put(new DiscoveryNode("node_foo", DummyTransportAddress.INSTANCE,
DiscoveryNodes nodes = DiscoveryNodes.builder().put(new DiscoveryNode("node_foo", LocalTransportAddress.buildUnique(),
emptyMap(), emptySet(), Version.CURRENT)).localNodeId("node_foo").masterNodeId("node_foo").build();
ClusterState clusterState = ClusterState.builder(ClusterName.CLUSTER_NAME_SETTING.getDefault(Settings.EMPTY)).nodes(nodes)

View File

@ -37,7 +37,7 @@ import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.lease.Releasable;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.MockLogAppender;
@ -109,7 +109,7 @@ public class ClusterServiceTests extends ESTestCase {
TimedClusterService timedClusterService = new TimedClusterService(Settings.builder().put("cluster.name",
"ClusterServiceTests").build(), new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS),
threadPool);
timedClusterService.setLocalNode(new DiscoveryNode("node1", DummyTransportAddress.INSTANCE, emptyMap(),
timedClusterService.setLocalNode(new DiscoveryNode("node1", LocalTransportAddress.buildUnique(), emptyMap(),
emptySet(), Version.CURRENT));
timedClusterService.setNodeConnectionsService(new NodeConnectionsService(Settings.EMPTY, null, null) {
@Override

View File

@ -67,7 +67,7 @@ public class IndexFolderUpgraderTests extends ESTestCase {
public void testUpgradeCustomDataPath() throws IOException {
Path customPath = createTempDir();
final Settings nodeSettings = Settings.builder()
.put(NodeEnvironment.ADD_NODE_ID_TO_CUSTOM_PATH.getKey(), randomBoolean())
.put(NodeEnvironment.ADD_NODE_LOCK_ID_TO_CUSTOM_PATH.getKey(), randomBoolean())
.put(Environment.PATH_SHARED_DATA_SETTING.getKey(), customPath.toAbsolutePath().toString()).build();
try (NodeEnvironment nodeEnv = newNodeEnvironment(nodeSettings)) {
final Index index = new Index(randomAsciiOfLength(10), UUIDs.randomBase64UUID());
@ -96,7 +96,7 @@ public class IndexFolderUpgraderTests extends ESTestCase {
public void testPartialUpgradeCustomDataPath() throws IOException {
Path customPath = createTempDir();
final Settings nodeSettings = Settings.builder()
.put(NodeEnvironment.ADD_NODE_ID_TO_CUSTOM_PATH.getKey(), randomBoolean())
.put(NodeEnvironment.ADD_NODE_LOCK_ID_TO_CUSTOM_PATH.getKey(), randomBoolean())
.put(Environment.PATH_SHARED_DATA_SETTING.getKey(), customPath.toAbsolutePath().toString()).build();
try (NodeEnvironment nodeEnv = newNodeEnvironment(nodeSettings)) {
final Index index = new Index(randomAsciiOfLength(10), UUIDs.randomBase64UUID());
@ -136,7 +136,7 @@ public class IndexFolderUpgraderTests extends ESTestCase {
public void testUpgrade() throws IOException {
final Settings nodeSettings = Settings.builder()
.put(NodeEnvironment.ADD_NODE_ID_TO_CUSTOM_PATH.getKey(), randomBoolean()).build();
.put(NodeEnvironment.ADD_NODE_LOCK_ID_TO_CUSTOM_PATH.getKey(), randomBoolean()).build();
try (NodeEnvironment nodeEnv = newNodeEnvironment(nodeSettings)) {
final Index index = new Index(randomAsciiOfLength(10), UUIDs.randomBase64UUID());
Settings settings = Settings.builder()
@ -159,7 +159,7 @@ public class IndexFolderUpgraderTests extends ESTestCase {
public void testUpgradeIndices() throws IOException {
final Settings nodeSettings = Settings.builder()
.put(NodeEnvironment.ADD_NODE_ID_TO_CUSTOM_PATH.getKey(), randomBoolean()).build();
.put(NodeEnvironment.ADD_NODE_LOCK_ID_TO_CUSTOM_PATH.getKey(), randomBoolean()).build();
try (NodeEnvironment nodeEnv = newNodeEnvironment(nodeSettings)) {
Map<IndexSettings, Tuple<Integer, Integer>> indexSettingsMap = new HashMap<>();
for (int i = 0; i < randomIntBetween(2, 5); i++) {
@ -256,7 +256,7 @@ public class IndexFolderUpgraderTests extends ESTestCase {
.numberOfReplicas(0)
.build();
try (NodeEnvironment nodeEnvironment = newNodeEnvironment()) {
IndexMetaData.FORMAT.write(indexState, 1, nodeEnvironment.indexPaths(index));
IndexMetaData.FORMAT.write(indexState, nodeEnvironment.indexPaths(index));
assertFalse(IndexFolderUpgrader.needsUpgrade(index, index.getUUID()));
}
}
@ -305,7 +305,7 @@ public class IndexFolderUpgraderTests extends ESTestCase {
for (int i = 0; i < nodePaths.length; i++) {
oldIndexPaths[i] = nodePaths[i].indicesPath.resolve(indexSettings.getIndex().getName());
}
IndexMetaData.FORMAT.write(indexSettings.getIndexMetaData(), 1, oldIndexPaths);
IndexMetaData.FORMAT.write(indexSettings.getIndexMetaData(), oldIndexPaths);
for (int id = 0; id < indexSettings.getNumberOfShards(); id++) {
Path oldIndexPath = randomFrom(oldIndexPaths);
ShardId shardId = new ShardId(indexSettings.getIndex(), id);
@ -316,7 +316,7 @@ public class IndexFolderUpgraderTests extends ESTestCase {
writeShard(shardId, oldIndexPath, numIdxFiles, numTranslogFiles);
}
ShardStateMetaData state = new ShardStateMetaData(true, indexSettings.getUUID(), AllocationId.newInitializing());
ShardStateMetaData.FORMAT.write(state, 1, oldIndexPath.resolve(String.valueOf(shardId.getId())));
ShardStateMetaData.FORMAT.write(state, oldIndexPath.resolve(String.valueOf(shardId.getId())));
}
}

View File

@ -21,7 +21,7 @@ package org.elasticsearch.discovery;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.concurrent.AbstractRunnable;
import org.elasticsearch.test.ESTestCase;
@ -77,7 +77,7 @@ public class BlockingClusterStatePublishResponseHandlerTests extends ESTestCase
int nodeCount = scaledRandomIntBetween(10, 20);
DiscoveryNode[] allNodes = new DiscoveryNode[nodeCount];
for (int i = 0; i < nodeCount; i++) {
DiscoveryNode node = new DiscoveryNode("node_" + i, DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
DiscoveryNode node = new DiscoveryNode("node_" + i, LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
allNodes[i] = node;
}

View File

@ -22,7 +22,7 @@ package org.elasticsearch.discovery.zen;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.discovery.zen.elect.ElectMasterService;
import org.elasticsearch.test.ESTestCase;
@ -46,7 +46,7 @@ public class ElectMasterServiceTests extends ESTestCase {
if (randomBoolean()) {
roles.add(DiscoveryNode.Role.MASTER);
}
DiscoveryNode node = new DiscoveryNode("n_" + i, "n_" + i, DummyTransportAddress.INSTANCE, Collections.emptyMap(),
DiscoveryNode node = new DiscoveryNode("n_" + i, "n_" + i, LocalTransportAddress.buildUnique(), Collections.emptyMap(),
roles, Version.CURRENT);
nodes.add(node);
}

View File

@ -31,7 +31,6 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.concurrent.AbstractRunnable;
@ -40,6 +39,7 @@ import org.elasticsearch.discovery.DiscoverySettings;
import org.elasticsearch.discovery.zen.elect.ElectMasterService;
import org.elasticsearch.discovery.zen.membership.MembershipAction;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.VersionUtils;
import org.elasticsearch.test.junit.annotations.TestLogging;
import org.elasticsearch.threadpool.TestThreadPool;
import org.elasticsearch.threadpool.ThreadPool;
@ -49,6 +49,8 @@ import org.junit.Before;
import org.junit.BeforeClass;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -67,6 +69,7 @@ import static java.util.Collections.emptySet;
import static java.util.Collections.shuffle;
import static org.elasticsearch.test.ClusterServiceUtils.createClusterService;
import static org.elasticsearch.test.ClusterServiceUtils.setState;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
@ -203,10 +206,12 @@ public class NodeJoinControllerTests extends ESTestCase {
@Override
protected void doRun() throws Exception {
nodeJoinController.waitToBeElectedAsMaster(requiredJoins, TimeValue.timeValueHours(30), new NodeJoinController.ElectionCallback() {
nodeJoinController.waitToBeElectedAsMaster(requiredJoins, TimeValue.timeValueHours(30),
new NodeJoinController.ElectionCallback() {
@Override
public void onElectedAsMaster(ClusterState state) {
assertThat("callback called with elected as master, but state disagrees", state.nodes().isLocalNodeElectedMaster(), equalTo(true));
assertThat("callback called with elected as master, but state disagrees", state.nodes().isLocalNodeElectedMaster(),
equalTo(true));
electionFuture.markAsDone();
}
@ -251,10 +256,12 @@ public class NodeJoinControllerTests extends ESTestCase {
@Override
protected void doRun() throws Exception {
nodeJoinController.waitToBeElectedAsMaster(requiredJoins, TimeValue.timeValueHours(30), new NodeJoinController.ElectionCallback() {
nodeJoinController.waitToBeElectedAsMaster(requiredJoins, TimeValue.timeValueHours(30),
new NodeJoinController.ElectionCallback() {
@Override
public void onElectedAsMaster(ClusterState state) {
assertThat("callback called with elected as master, but state disagrees", state.nodes().isLocalNodeElectedMaster(), equalTo(true));
assertThat("callback called with elected as master, but state disagrees", state.nodes().isLocalNodeElectedMaster(),
equalTo(true));
electionFuture.markAsDone();
}
@ -403,7 +410,7 @@ public class NodeJoinControllerTests extends ESTestCase {
public void testNewClusterStateOnExistingNodeJoin() throws InterruptedException, ExecutionException {
ClusterState state = clusterService.state();
final DiscoveryNodes.Builder nodesBuilder = DiscoveryNodes.builder(state.nodes());
final DiscoveryNode other_node = new DiscoveryNode("other_node", DummyTransportAddress.INSTANCE,
final DiscoveryNode other_node = new DiscoveryNode("other_node", LocalTransportAddress.buildUnique(),
emptyMap(), emptySet(), Version.CURRENT);
nodesBuilder.put(other_node);
setState(clusterService, ClusterState.builder(state).nodes(nodesBuilder));
@ -516,6 +523,38 @@ public class NodeJoinControllerTests extends ESTestCase {
assertNodesInCurrentState(nodes);
}
public void testRejectingJoinWithSameAddressButDifferentId() throws InterruptedException, ExecutionException {
ClusterState state = clusterService.state();
final DiscoveryNode other_node = new DiscoveryNode("other_node", state.nodes().getLocalNode().getAddress(),
emptyMap(), emptySet(), Version.CURRENT);
ExecutionException e = expectThrows(ExecutionException.class, () -> joinNode(other_node));
assertThat(e.getMessage(), containsString("found existing node"));
}
public void testRejectingJoinWithSameIdButDifferentAddress() throws InterruptedException, ExecutionException {
ClusterState state = clusterService.state();
final DiscoveryNode other_node = new DiscoveryNode(state.nodes().getLocalNode().getId(),
new LocalTransportAddress(randomAsciiOfLength(20)), emptyMap(), emptySet(), Version.CURRENT);
ExecutionException e = expectThrows(ExecutionException.class, () -> joinNode(other_node));
assertThat(e.getMessage(), containsString("found existing node"));
}
public void testJoinWithSameIdSameAddressButDifferentMeta() throws InterruptedException, ExecutionException {
ClusterState state = clusterService.state();
final DiscoveryNode localNode = state.nodes().getLocalNode();
final DiscoveryNode other_node = new DiscoveryNode(
randomBoolean() ? localNode.getName() : "other_name",
localNode.getId(), localNode.getAddress(),
randomBoolean() ? localNode.getAttributes() : Collections.singletonMap("attr", "other"),
randomBoolean() ? localNode.getRoles() : new HashSet<>(randomSubsetOf(Arrays.asList(DiscoveryNode.Role.values()))),
randomBoolean() ? localNode.getVersion() : VersionUtils.randomVersion(random()));
joinNode(other_node);
assertThat(clusterService.localNode(), equalTo(other_node));
}
static class NoopAllocationService extends AllocationService {
@ -599,8 +638,8 @@ public class NodeJoinControllerTests extends ESTestCase {
* creates an object clone of node, so it will be a different object instance
*/
private DiscoveryNode cloneNode(DiscoveryNode node) {
return new DiscoveryNode(node.getName(), node.getId(), node.getHostName(), node.getHostAddress(), node.getAddress(),
node.getAttributes(), node.getRoles(), node.getVersion());
return new DiscoveryNode(node.getName(), node.getId(), node.getEphemeralId(), node.getHostName(), node.getHostAddress(),
node.getAddress(), node.getAttributes(), node.getRoles(), node.getVersion());
}
private void joinNode(final DiscoveryNode node) throws InterruptedException, ExecutionException {

View File

@ -24,8 +24,7 @@ import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.discovery.zen.ping.ZenPing;
import org.elasticsearch.test.ESTestCase;
@ -51,9 +50,9 @@ public class ZenDiscoveryUnitTests extends ESTestCase {
ClusterName clusterName = new ClusterName("abc");
DiscoveryNodes.Builder currentNodes = DiscoveryNodes.builder();
currentNodes.masterNodeId("a").put(new DiscoveryNode("a", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT));
currentNodes.masterNodeId("a").put(new DiscoveryNode("a", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT));
DiscoveryNodes.Builder newNodes = DiscoveryNodes.builder();
newNodes.masterNodeId("a").put(new DiscoveryNode("a", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT));
newNodes.masterNodeId("a").put(new DiscoveryNode("a", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT));
ClusterState.Builder currentState = ClusterState.builder(clusterName);
currentState.nodes(currentNodes);
@ -71,7 +70,7 @@ public class ZenDiscoveryUnitTests extends ESTestCase {
assertFalse("should not ignore, because new state's version is higher to current state's version", shouldIgnoreOrRejectNewClusterState(logger, currentState.build(), newState.build()));
currentNodes = DiscoveryNodes.builder();
currentNodes.masterNodeId("b").put(new DiscoveryNode("b", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT));
currentNodes.masterNodeId("b").put(new DiscoveryNode("b", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT));
;
// version isn't taken into account, so randomize it to ensure this.
if (randomBoolean()) {
@ -109,7 +108,7 @@ public class ZenDiscoveryUnitTests extends ESTestCase {
ArrayList<DiscoveryNode> allNodes = new ArrayList<>();
for (int i = randomIntBetween(10, 20); i >= 0; i--) {
Set<DiscoveryNode.Role> roles = new HashSet<>(randomSubsetOf(Arrays.asList(DiscoveryNode.Role.values())));
DiscoveryNode node = new DiscoveryNode("node_" + i, "id_" + i, DummyTransportAddress.INSTANCE, Collections.emptyMap(),
DiscoveryNode node = new DiscoveryNode("node_" + i, "id_" + i, LocalTransportAddress.buildUnique(), Collections.emptyMap(),
roles, Version.CURRENT);
responses.add(new ZenPing.PingResponse(node, randomBoolean() ? null : node, new ClusterName("test"), randomBoolean()));
allNodes.add(node);

View File

@ -23,7 +23,7 @@ import org.elasticsearch.Version;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.discovery.zen.ping.ZenPing;
import org.elasticsearch.test.ESTestCase;
@ -42,7 +42,7 @@ public class ZenPingTests extends ESTestCase {
boolean hasJoinedOncePerNode[] = new boolean[nodes.length];
ArrayList<ZenPing.PingResponse> pings = new ArrayList<>();
for (int i = 0; i < nodes.length; i++) {
nodes[i] = new DiscoveryNode("" + i, DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
nodes[i] = new DiscoveryNode("" + i, LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
}
for (int pingCount = scaledRandomIntBetween(10, nodes.length * 10); pingCount > 0; pingCount--) {

View File

@ -25,7 +25,7 @@ import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.discovery.zen.publish.PendingClusterStatesQueue.ClusterStateContext;
import org.elasticsearch.test.ESTestCase;
@ -237,7 +237,7 @@ public class PendingClusterStatesQueueTests extends ESTestCase {
ClusterState state = lastClusterStatePerMaster[masterIndex];
if (state == null) {
state = ClusterState.builder(ClusterName.CLUSTER_NAME_SETTING.getDefault(Settings.EMPTY)).nodes(DiscoveryNodes.builder()
.put(new DiscoveryNode(masters[masterIndex], DummyTransportAddress.INSTANCE,
.put(new DiscoveryNode(masters[masterIndex], LocalTransportAddress.buildUnique(),
emptyMap(), emptySet(),Version.CURRENT)).masterNodeId(masters[masterIndex]).build()
).build();
} else {

View File

@ -43,6 +43,7 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.discovery.Discovery;
import org.elasticsearch.discovery.DiscoverySettings;
import org.elasticsearch.discovery.zen.DiscoveryNodesProvider;
import org.elasticsearch.env.NodeEnvironment;
import org.elasticsearch.node.Node;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.junit.annotations.TestLogging;
@ -152,16 +153,17 @@ public class PublishClusterStateActionTests extends ESTestCase {
return createMockNode(name, settings, null);
}
public MockNode createMockNode(String name, Settings settings, @Nullable ClusterStateListener listener) throws Exception {
settings = Settings.builder()
public MockNode createMockNode(String name, final Settings basSettings, @Nullable ClusterStateListener listener) throws Exception {
final Settings settings = Settings.builder()
.put("name", name)
.put(TransportService.TRACE_LOG_INCLUDE_SETTING.getKey(), "", TransportService.TRACE_LOG_EXCLUDE_SETTING.getKey(), "NOTHING")
.put(settings)
.put(basSettings)
.build();
MockTransportService service = buildTransportService(settings);
DiscoveryNodeService discoveryNodeService = new DiscoveryNodeService(settings);
DiscoveryNode discoveryNode = discoveryNodeService.buildLocalNode(service.boundAddress().publishAddress());
DiscoveryNode discoveryNode = discoveryNodeService.buildLocalNode(service.boundAddress().publishAddress(),
() -> NodeEnvironment.generateNodeId(settings));
MockNode node = new MockNode(discoveryNode, service, listener, logger);
node.action = buildPublishClusterStateAction(settings, service, () -> node.clusterState, node);
final CountDownLatch latch = new CountDownLatch(nodes.size() * 2 + 1);

View File

@ -51,6 +51,7 @@ import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.Matchers.arrayWithSize;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.not;
@LuceneTestCase.SuppressFileSystems("ExtrasFS") // TODO: fix test to allow extras
public class NodeEnvironmentTests extends ESTestCase {
@ -389,7 +390,7 @@ public class NodeEnvironmentTests extends ESTestCase {
env.close();
NodeEnvironment env2 = newNodeEnvironment(dataPaths, "/tmp",
Settings.builder().put(NodeEnvironment.ADD_NODE_ID_TO_CUSTOM_PATH.getKey(), false).build());
Settings.builder().put(NodeEnvironment.ADD_NODE_LOCK_ID_TO_CUSTOM_PATH.getKey(), false).build());
assertThat(env2.availableShardPaths(sid), equalTo(env2.availableShardPaths(sid)));
assertThat(env2.resolveCustomLocation(s2, sid), equalTo(PathUtils.get("/tmp/foo/" + index.getUUID() + "/0")));
@ -447,6 +448,27 @@ public class NodeEnvironmentTests extends ESTestCase {
}
}
public void testPersistentNodeId() throws IOException {
String[] paths = tmpPaths();
NodeEnvironment env = newNodeEnvironment(paths, Settings.builder()
.put("node.local_storage", false)
.put("node.master", false)
.put("node.data", false)
.build());
String nodeID = env.nodeId();
env.close();
env = newNodeEnvironment(paths, Settings.EMPTY);
assertThat("previous node didn't have local storage enabled, id should change", env.nodeId(), not(equalTo(nodeID)));
nodeID = env.nodeId();
env.close();
env = newNodeEnvironment(paths, Settings.EMPTY);
assertThat(env.nodeId(), equalTo(nodeID));
env.close();
env = newNodeEnvironment(Settings.EMPTY);
assertThat(env.nodeId(), not(equalTo(nodeID)));
env.close();
}
/** Converts an array of Strings to an array of Paths, adding an additional child if specified */
private Path[] stringsToPaths(String[] strings, String additional) {
Path[] locations = new Path[strings.length];

View File

@ -24,7 +24,7 @@ import org.elasticsearch.action.support.nodes.BaseNodeResponse;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.threadpool.TestThreadPool;
@ -45,11 +45,11 @@ import static org.hamcrest.Matchers.sameInstance;
/**
*/
public class AsyncShardFetchTests extends ESTestCase {
private final DiscoveryNode node1 = new DiscoveryNode("node1", DummyTransportAddress.INSTANCE, Collections.emptyMap(),
private final DiscoveryNode node1 = new DiscoveryNode("node1", LocalTransportAddress.buildUnique(), Collections.emptyMap(),
Collections.singleton(DiscoveryNode.Role.DATA), Version.CURRENT);
private final Response response1 = new Response(node1);
private final Throwable failure1 = new Throwable("simulated failure 1");
private final DiscoveryNode node2 = new DiscoveryNode("node2", DummyTransportAddress.INSTANCE, Collections.emptyMap(),
private final DiscoveryNode node2 = new DiscoveryNode("node2", LocalTransportAddress.buildUnique(), Collections.emptyMap(),
Collections.singleton(DiscoveryNode.Role.DATA), Version.CURRENT);
private final Response response2 = new Response(node2);
private final Throwable failure2 = new Throwable("simulate failure 2");

View File

@ -346,7 +346,7 @@ public class GatewayIndexStateIT extends ESIntegTestCase {
logger.info("--> created temp data path for shadow replicas [{}]", dataPath);
logger.info("--> starting a cluster with " + numNodes + " nodes");
final Settings nodeSettings = Settings.builder()
.put("node.add_id_to_custom_path", false)
.put("node.add_lock_id_to_custom_path", false)
.put(Environment.PATH_SHARED_DATA_SETTING.getKey(), dataPath.toString())
.put("index.store.fs.fs_lock", randomFrom("native", "simple"))
.build();
@ -426,7 +426,7 @@ public class GatewayIndexStateIT extends ESIntegTestCase {
// this one is not validated ahead of time and breaks allocation
.put("index.analysis.filter.myCollator.type", "icu_collation")
).build();
IndexMetaData.FORMAT.write(brokenMeta, brokenMeta.getVersion(), services.indexPaths(brokenMeta.getIndex()));
IndexMetaData.FORMAT.write(brokenMeta, services.indexPaths(brokenMeta.getIndex()));
}
internalCluster().fullRestart();
// ensureGreen(closedIndex) waits for the index to show up in the metadata
@ -483,7 +483,7 @@ public class GatewayIndexStateIT extends ESIntegTestCase {
for (NodeEnvironment services : internalCluster().getInstances(NodeEnvironment.class)) {
IndexMetaData brokenMeta = IndexMetaData.builder(metaData).settings(metaData.getSettings()
.filter((s) -> "index.analysis.analyzer.test.tokenizer".equals(s) == false)).build();
IndexMetaData.FORMAT.write(brokenMeta, brokenMeta.getVersion(), services.indexPaths(brokenMeta.getIndex()));
IndexMetaData.FORMAT.write(brokenMeta, services.indexPaths(brokenMeta.getIndex()));
}
internalCluster().fullRestart();
// ensureGreen(closedIndex) waits for the index to show up in the metadata
@ -521,7 +521,7 @@ public class GatewayIndexStateIT extends ESIntegTestCase {
MetaData brokenMeta = MetaData.builder(metaData).persistentSettings(Settings.builder()
.put(metaData.persistentSettings()).put("this.is.unknown", true)
.put(ElectMasterService.DISCOVERY_ZEN_MINIMUM_MASTER_NODES_SETTING.getKey(), "broken").build()).build();
MetaData.FORMAT.write(brokenMeta, metaData.version(), nodeEnv.nodeDataPaths());
MetaData.FORMAT.write(brokenMeta, nodeEnv.nodeDataPaths());
}
internalCluster().fullRestart();
ensureYellow("test"); // wait for state recovery

View File

@ -104,7 +104,7 @@ public class MetaDataStateFormatTests extends ESTestCase {
Format format = new Format(randomFrom(XContentType.values()), "foo-");
DummyState state = new DummyState(randomRealisticUnicodeOfCodepointLengthBetween(1, 1000), randomInt(), randomLong(), randomDouble(), randomBoolean());
int version = between(0, Integer.MAX_VALUE/2);
format.write(state, version, dirs);
format.write(state, dirs);
for (Path file : dirs) {
Path[] list = content("*", file);
assertEquals(list.length, 1);
@ -119,7 +119,7 @@ public class MetaDataStateFormatTests extends ESTestCase {
}
final int version2 = between(version, Integer.MAX_VALUE);
DummyState state2 = new DummyState(randomRealisticUnicodeOfCodepointLengthBetween(1, 1000), randomInt(), randomLong(), randomDouble(), randomBoolean());
format.write(state2, version2, dirs);
format.write(state2, dirs);
for (Path file : dirs) {
Path[] list = content("*", file);
@ -146,7 +146,7 @@ public class MetaDataStateFormatTests extends ESTestCase {
Format format = new Format(randomFrom(XContentType.values()), "foo-");
DummyState state = new DummyState(randomRealisticUnicodeOfCodepointLengthBetween(1, 1000), randomInt(), randomLong(), randomDouble(), randomBoolean());
int version = between(0, Integer.MAX_VALUE/2);
format.write(state, version, dirs);
format.write(state, dirs);
for (Path file : dirs) {
Path[] list = content("*", file);
assertEquals(list.length, 1);
@ -170,7 +170,7 @@ public class MetaDataStateFormatTests extends ESTestCase {
Format format = new Format(randomFrom(XContentType.values()), "foo-");
DummyState state = new DummyState(randomRealisticUnicodeOfCodepointLengthBetween(1, 1000), randomInt(), randomLong(), randomDouble(), randomBoolean());
int version = between(0, Integer.MAX_VALUE/2);
format.write(state, version, dirs);
format.write(state, dirs);
for (Path file : dirs) {
Path[] list = content("*", file);
assertEquals(list.length, 1);
@ -261,7 +261,7 @@ public class MetaDataStateFormatTests extends ESTestCase {
}
}
for (int j = numLegacy; j < numStates; j++) {
format.write(meta.get(j), j, dirs[i]);
format.write(meta.get(j), dirs[i]);
if (randomBoolean() && (j < numStates - 1 || dirs.length > 0 && i != 0)) { // corrupt a file that we do not necessarily need here....
Path file = dirs[i].resolve(MetaDataStateFormat.STATE_DIR_NAME).resolve("global-" + j + ".st");
corruptedFiles.add(file);

View File

@ -94,7 +94,7 @@ public class IndexWithShadowReplicasIT extends ESIntegTestCase {
private Settings nodeSettings(String dataPath) {
return Settings.builder()
.put(NodeEnvironment.ADD_NODE_ID_TO_CUSTOM_PATH.getKey(), false)
.put(NodeEnvironment.ADD_NODE_LOCK_ID_TO_CUSTOM_PATH.getKey(), false)
.put(Environment.PATH_SHARED_DATA_SETTING.getKey(), dataPath)
.put(FsDirectoryService.INDEX_LOCK_FACTOR_SETTING.getKey(), randomFrom("native", "simple"))
.build();
@ -454,7 +454,7 @@ public class IndexWithShadowReplicasIT extends ESIntegTestCase {
public void testPrimaryRelocationWhereRecoveryFails() throws Exception {
Path dataPath = createTempDir();
Settings nodeSettings = Settings.builder()
.put("node.add_id_to_custom_path", false)
.put("node.add_lock_id_to_custom_path", false)
.put(Environment.PATH_SHARED_DATA_SETTING.getKey(), dataPath)
.build();

View File

@ -46,7 +46,7 @@ import org.elasticsearch.cluster.routing.TestShardRouting;
import org.elasticsearch.common.collect.Iterators;
import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.common.unit.ByteSizeUnit;
import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.env.NodeEnvironment;
@ -198,7 +198,7 @@ public abstract class ESIndexLevelReplicationTestCase extends ESTestCase {
}
private DiscoveryNode getDiscoveryNode(String id) {
return new DiscoveryNode(id, id, DummyTransportAddress.INSTANCE, Collections.emptyMap(),
return new DiscoveryNode(id, id, LocalTransportAddress.buildUnique(), Collections.emptyMap(),
Collections.singleton(DiscoveryNode.Role.DATA), Version.CURRENT);
}

View File

@ -69,7 +69,7 @@ import org.elasticsearch.common.lease.Releasable;
import org.elasticsearch.common.lease.Releasables;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.common.unit.ByteSizeUnit;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -463,7 +463,7 @@ public class IndexShardTests extends ESSingleNodeTestCase {
public static void write(ShardStateMetaData shardStateMetaData,
Path... shardPaths) throws IOException {
ShardStateMetaData.FORMAT.write(shardStateMetaData, shardStateMetaData.legacyVersion, shardPaths);
ShardStateMetaData.FORMAT.write(shardStateMetaData, shardPaths);
}
public void testDurableFlagHasEffect() {
@ -1036,7 +1036,7 @@ public class IndexShardTests extends ESSingleNodeTestCase {
routing = ShardRoutingHelper.reinit(routing);
IndexShard newShard = test.createShard(routing);
newShard.updateRoutingEntry(routing);
DiscoveryNode localNode = new DiscoveryNode("foo", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
DiscoveryNode localNode = new DiscoveryNode("foo", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
newShard.markAsRecovering("store", new RecoveryState(newShard.shardId(), routing.primary(), RecoveryState.Type.STORE, localNode, localNode));
assertTrue(newShard.recoverFromStore());
assertEquals(translogOps, newShard.recoveryState().getTranslog().recoveredOperations());
@ -1063,7 +1063,7 @@ public class IndexShardTests extends ESSingleNodeTestCase {
routing = ShardRoutingHelper.reinit(routing, UnassignedInfo.Reason.INDEX_CREATED);
IndexShard newShard = test.createShard(routing);
newShard.updateRoutingEntry(routing);
DiscoveryNode localNode = new DiscoveryNode("foo", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
DiscoveryNode localNode = new DiscoveryNode("foo", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
newShard.markAsRecovering("store", new RecoveryState(newShard.shardId(), routing.primary(), RecoveryState.Type.STORE, localNode,
localNode));
assertTrue(newShard.recoverFromStore());
@ -1080,7 +1080,7 @@ public class IndexShardTests extends ESSingleNodeTestCase {
createIndex("test");
ensureGreen();
IndicesService indicesService = getInstanceFromNode(IndicesService.class);
DiscoveryNode localNode = new DiscoveryNode("foo", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
DiscoveryNode localNode = new DiscoveryNode("foo", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
IndexService test = indicesService.indexService(resolveIndex("test"));
final IndexShard shard = test.getShardOrNull(0);
@ -1176,7 +1176,7 @@ public class IndexShardTests extends ESSingleNodeTestCase {
Store targetStore = test_target_shard.store();
test_target_shard.updateRoutingEntry(routing);
DiscoveryNode localNode = new DiscoveryNode("foo", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
DiscoveryNode localNode = new DiscoveryNode("foo", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
test_target_shard.markAsRecovering("store", new RecoveryState(routing.shardId(), routing.primary(), RecoveryState.Type.SNAPSHOT, routing.restoreSource(), localNode));
assertTrue(test_target_shard.restoreFromRepository(new IndexShardRepository() {
@Override
@ -1460,7 +1460,7 @@ public class IndexShardTests extends ESSingleNodeTestCase {
}
public static final IndexShard recoverShard(IndexShard newShard) throws IOException {
DiscoveryNode localNode = new DiscoveryNode("foo", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
DiscoveryNode localNode = new DiscoveryNode("foo", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
newShard.markAsRecovering("store", new RecoveryState(newShard.shardId(), newShard.routingEntry().primary(), RecoveryState.Type.STORE, localNode, localNode));
assertTrue(newShard.recoverFromStore());
newShard.updateRoutingEntry(newShard.routingEntry().moveToStarted());
@ -1500,7 +1500,7 @@ public class IndexShardTests extends ESSingleNodeTestCase {
ShardRouting routing = getInitializingShardRouting(shard.routingEntry());
test.removeShard(0, "b/c britta says so");
IndexShard newShard = test.createShard(routing);
DiscoveryNode localNode = new DiscoveryNode("foo", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
DiscoveryNode localNode = new DiscoveryNode("foo", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
newShard.markAsRecovering("for testing", new RecoveryState(newShard.shardId(), routing.primary(), RecoveryState.Type.REPLICA, localNode, localNode));
List<Translog.Operation> operations = new ArrayList<>();
operations.add(new Translog.Index("testtype", "1", BytesReference.toBytes(jsonBuilder().startObject().field("foo", "bar").endObject().bytes())));
@ -1528,7 +1528,7 @@ public class IndexShardTests extends ESSingleNodeTestCase {
test.removeShard(0, "b/c britta says so");
IndexShard newShard = test.createShard(routing);
newShard.shardRouting = routing;
DiscoveryNode localNode = new DiscoveryNode("foo", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
DiscoveryNode localNode = new DiscoveryNode("foo", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
newShard.markAsRecovering("for testing", new RecoveryState(newShard.shardId(), routing.primary(), RecoveryState.Type.REPLICA, localNode, localNode));
// Shard is still inactive since we haven't started recovering yet
assertFalse(newShard.isActive());
@ -1556,7 +1556,7 @@ public class IndexShardTests extends ESSingleNodeTestCase {
ShardRouting routing = getInitializingShardRouting(shard.routingEntry());
test.removeShard(0, "b/c britta says so");
IndexShard newShard = test.createShard(routing);
DiscoveryNode localNode = new DiscoveryNode("foo", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
DiscoveryNode localNode = new DiscoveryNode("foo", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
newShard.markAsRecovering("for testing", new RecoveryState(newShard.shardId(), routing.primary(), RecoveryState.Type.REPLICA, localNode, localNode));
// Shard is still inactive since we haven't started recovering yet
assertFalse(newShard.isActive());
@ -1591,7 +1591,7 @@ public class IndexShardTests extends ESSingleNodeTestCase {
IndexShard shard = test.getShardOrNull(0);
ShardRouting routing = ShardRoutingHelper.initWithSameId(shard.routingEntry());
test.removeShard(0, "b/c simon says so");
DiscoveryNode localNode = new DiscoveryNode("foo", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
DiscoveryNode localNode = new DiscoveryNode("foo", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
{
final IndexShard newShard = test.createShard(routing);
newShard.updateRoutingEntry(routing);

View File

@ -45,7 +45,7 @@ public class ShardPathTests extends ESTestCase {
ShardId shardId = new ShardId("foo", "0xDEADBEEF", 0);
Path[] paths = env.availableShardPaths(shardId);
Path path = randomFrom(paths);
ShardStateMetaData.FORMAT.write(new ShardStateMetaData(2, true, "0xDEADBEEF", AllocationId.newInitializing()), 2, path);
ShardStateMetaData.FORMAT.write(new ShardStateMetaData(2, true, "0xDEADBEEF", AllocationId.newInitializing()), path);
ShardPath shardPath = ShardPath.loadShardPath(logger, env, shardId, IndexSettingsModule.newIndexSettings(shardId.getIndex(), settings));
assertEquals(path, shardPath.getDataPath());
assertEquals("0xDEADBEEF", shardPath.getShardId().getIndex().getUUID());
@ -65,7 +65,7 @@ public class ShardPathTests extends ESTestCase {
Path[] paths = env.availableShardPaths(shardId);
assumeTrue("This test tests multi data.path but we only got one", paths.length > 1);
int id = randomIntBetween(1, 10);
ShardStateMetaData.FORMAT.write(new ShardStateMetaData(id, true, indexUUID, AllocationId.newInitializing()), id, paths);
ShardStateMetaData.FORMAT.write(new ShardStateMetaData(id, true, indexUUID, AllocationId.newInitializing()), paths);
ShardPath.loadShardPath(logger, env, shardId, IndexSettingsModule.newIndexSettings(shardId.getIndex(), settings));
fail("Expected IllegalStateException");
} catch (IllegalStateException e) {
@ -82,7 +82,7 @@ public class ShardPathTests extends ESTestCase {
Path[] paths = env.availableShardPaths(shardId);
Path path = randomFrom(paths);
int id = randomIntBetween(1, 10);
ShardStateMetaData.FORMAT.write(new ShardStateMetaData(id, true, "0xDEADBEEF", AllocationId.newInitializing()), id, path);
ShardStateMetaData.FORMAT.write(new ShardStateMetaData(id, true, "0xDEADBEEF", AllocationId.newInitializing()), path);
ShardPath.loadShardPath(logger, env, shardId, IndexSettingsModule.newIndexSettings(shardId.getIndex(), settings));
fail("Expected IllegalStateException");
} catch (IllegalStateException e) {
@ -124,7 +124,7 @@ public class ShardPathTests extends ESTestCase {
final boolean includeNodeId = randomBoolean();
indexSettings = indexSettingsBuilder.put(IndexMetaData.SETTING_DATA_PATH, "custom").build();
nodeSettings = Settings.builder().put(Environment.PATH_SHARED_DATA_SETTING.getKey(), path.toAbsolutePath().toAbsolutePath())
.put(NodeEnvironment.ADD_NODE_ID_TO_CUSTOM_PATH.getKey(), includeNodeId).build();
.put(NodeEnvironment.ADD_NODE_LOCK_ID_TO_CUSTOM_PATH.getKey(), includeNodeId).build();
if (includeNodeId) {
customPath = path.resolve("custom").resolve("0");
} else {
@ -139,7 +139,7 @@ public class ShardPathTests extends ESTestCase {
ShardId shardId = new ShardId("foo", indexUUID, 0);
Path[] paths = env.availableShardPaths(shardId);
Path path = randomFrom(paths);
ShardStateMetaData.FORMAT.write(new ShardStateMetaData(2, true, indexUUID, AllocationId.newInitializing()), 2, path);
ShardStateMetaData.FORMAT.write(new ShardStateMetaData(2, true, indexUUID, AllocationId.newInitializing()), path);
ShardPath shardPath = ShardPath.loadShardPath(logger, env, shardId, IndexSettingsModule.newIndexSettings(shardId.getIndex(), indexSettings));
boolean found = false;
for (Path p : env.nodeDataPaths()) {

View File

@ -22,9 +22,8 @@ import org.elasticsearch.Version;
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeResponse;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.routing.ShardRouting;
import org.elasticsearch.cluster.routing.ShardRoutingHelper;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.common.unit.ByteSizeUnit;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.index.IndexService;
@ -448,7 +447,7 @@ public class IndexingMemoryControllerTests extends ESSingleNodeTestCase {
try {
assertEquals(0, imc.availableShards().size());
ShardRouting routing = newShard.routingEntry();
DiscoveryNode localNode = new DiscoveryNode("foo", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
DiscoveryNode localNode = new DiscoveryNode("foo", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
newShard.markAsRecovering("store", new RecoveryState(newShard.shardId(), routing.primary(), RecoveryState.Type.STORE, localNode, localNode));
assertEquals(1, imc.availableShards().size());

View File

@ -25,7 +25,7 @@ import org.elasticsearch.cluster.routing.ShardRouting;
import org.elasticsearch.cluster.routing.ShardRoutingHelper;
import org.elasticsearch.cluster.routing.UnassignedInfo;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.NodeServicesProvider;
@ -103,7 +103,7 @@ public class IndicesLifecycleListenerSingleNodeTests extends ESSingleNodeTestCas
newRouting = ShardRoutingHelper.initialize(newRouting, nodeId);
IndexShard shard = index.createShard(newRouting);
shard.updateRoutingEntry(newRouting);
final DiscoveryNode localNode = new DiscoveryNode("foo", DummyTransportAddress.INSTANCE,
final DiscoveryNode localNode = new DiscoveryNode("foo", LocalTransportAddress.buildUnique(),
emptyMap(), emptySet(), Version.CURRENT);
shard.markAsRecovering("store", new RecoveryState(shard.shardId(), newRouting.primary(), RecoveryState.Type.SNAPSHOT, newRouting.restoreSource(), localNode));
shard.recoverFromStore();

View File

@ -37,7 +37,7 @@ import org.elasticsearch.cluster.routing.ShardRouting;
import org.elasticsearch.cluster.routing.allocation.FailedRerouteAllocation.FailedShard;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.indices.recovery.RecoveryTargetService;
import org.elasticsearch.repositories.RepositoriesService;
@ -123,7 +123,7 @@ public class IndicesClusterStateServiceRandomUpdatesTests extends AbstractIndice
for (Iterator<Entry<DiscoveryNode, IndicesClusterStateService>> it = clusterStateServiceMap.entrySet().iterator(); it.hasNext(); ) {
DiscoveryNode node = it.next().getKey();
if (state.nodes().nodeExists(node.getId()) == false) {
if (state.nodes().nodeExists(node) == false) {
it.remove();
}
}
@ -254,7 +254,7 @@ public class IndicesClusterStateServiceRandomUpdatesTests extends AbstractIndice
for (DiscoveryNode.Role mustHaveRole : mustHaveRoles) {
roles.add(mustHaveRole);
}
return new DiscoveryNode("node_" + randomAsciiOfLength(8), DummyTransportAddress.INSTANCE, Collections.emptyMap(), roles,
return new DiscoveryNode("node_" + randomAsciiOfLength(8), LocalTransportAddress.buildUnique(), Collections.emptyMap(), roles,
Version.CURRENT);
}

View File

@ -38,7 +38,7 @@ import org.elasticsearch.common.io.FileSystemUtils;
import org.elasticsearch.common.lucene.store.IndexOutputOutputStream;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.index.store.DirectoryService;
@ -69,8 +69,8 @@ public class RecoverySourceHandlerTests extends ESTestCase {
put("indices.recovery.concurrent_small_file_streams", 1).build();
final RecoverySettings recoverySettings = new RecoverySettings(settings, service);
StartRecoveryRequest request = new StartRecoveryRequest(shardId,
new DiscoveryNode("b", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT),
new DiscoveryNode("b", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT),
new DiscoveryNode("b", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT),
new DiscoveryNode("b", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT),
null, RecoveryState.Type.STORE, randomLong());
Store store = newStore(createTempDir());
RecoverySourceHandler handler = new RecoverySourceHandler(null, null, request, recoverySettings.getChunkSize().bytesAsInt(),
@ -119,8 +119,8 @@ public class RecoverySourceHandlerTests extends ESTestCase {
put("indices.recovery.concurrent_small_file_streams", 1).build();
final RecoverySettings recoverySettings = new RecoverySettings(settings, service);
StartRecoveryRequest request = new StartRecoveryRequest(shardId,
new DiscoveryNode("b", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT),
new DiscoveryNode("b", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT),
new DiscoveryNode("b", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT),
new DiscoveryNode("b", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT),
null, RecoveryState.Type.STORE, randomLong());
Path tempDir = createTempDir();
Store store = newStore(tempDir, false);
@ -182,8 +182,8 @@ public class RecoverySourceHandlerTests extends ESTestCase {
put("indices.recovery.concurrent_small_file_streams", 1).build();
final RecoverySettings recoverySettings = new RecoverySettings(settings, service);
StartRecoveryRequest request = new StartRecoveryRequest(shardId,
new DiscoveryNode("b", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT),
new DiscoveryNode("b", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT),
new DiscoveryNode("b", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT),
new DiscoveryNode("b", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT),
null, RecoveryState.Type.STORE, randomLong());
Path tempDir = createTempDir();
Store store = newStore(tempDir, false);

View File

@ -24,7 +24,7 @@ import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.Streamable;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.indices.recovery.RecoveryState.File;
import org.elasticsearch.indices.recovery.RecoveryState.Index;
@ -339,7 +339,8 @@ public class RecoveryTargetTests extends ESTestCase {
}
public void testStageSequenceEnforcement() {
final DiscoveryNode discoveryNode = new DiscoveryNode("1", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
final DiscoveryNode discoveryNode = new DiscoveryNode("1", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(),
Version.CURRENT);
Stage[] stages = Stage.values();
int i = randomIntBetween(0, stages.length - 1);
int j;

View File

@ -42,7 +42,7 @@ import org.elasticsearch.cluster.routing.allocation.decider.AllocationDeciders;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.discovery.DiscoveryModule;
import org.elasticsearch.discovery.DiscoverySettings;
@ -126,7 +126,7 @@ public class RareClusterStateIT extends ESIntegTestCase {
// inject a node
ClusterState.Builder builder = ClusterState.builder(currentState);
builder.nodes(DiscoveryNodes.builder(currentState.nodes()).put(new DiscoveryNode("_non_existent",
DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT)));
LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT)));
// open index
final IndexMetaData indexMetaData = IndexMetaData.builder(currentState.metaData().index(index)).state(IndexMetaData.State.OPEN).build();

View File

@ -35,7 +35,6 @@ import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.indices.IndexTemplateAlreadyExistsException;
import org.elasticsearch.indices.InvalidAliasNameException;
import org.elasticsearch.indices.InvalidIndexNameException;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.test.ESIntegTestCase;

View File

@ -21,10 +21,8 @@ package org.elasticsearch.ingest;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.ingest.ProcessorsRegistry;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.threadpool.TestThreadPool;
import org.junit.Before;
import java.util.ArrayList;

View File

@ -259,7 +259,7 @@ public class PipelineStoreTests extends ESTestCase {
store.validatePipeline(ingestInfos, putRequest);
fail("exception expected");
} catch (IllegalArgumentException e) {
assertThat(e.getMessage(), equalTo("Processor type [remove] is not installed on node [{_node_id2}{local}{local[_id]}]"));
assertThat(e.getMessage(), equalTo("Processor type [remove] is not installed on node [" + node2 + "]"));
}
ingestInfos.put(node2, new IngestInfo(Arrays.asList(new ProcessorInfo("set"), new ProcessorInfo("remove"))));

View File

@ -28,7 +28,7 @@ import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.BoundTransportAddress;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.xcontent.ToXContent;
@ -117,7 +117,7 @@ public class NodeInfoStreamingTests extends ESTestCase {
private NodeInfo createNodeInfo() {
Build build = Build.CURRENT;
DiscoveryNode node = new DiscoveryNode("test_node", DummyTransportAddress.INSTANCE,
DiscoveryNode node = new DiscoveryNode("test_node", LocalTransportAddress.buildUnique(),
emptyMap(), emptySet(), VersionUtils.randomVersion(random()));
Map<String, String> serviceAttributes = new HashMap<>();
serviceAttributes.put("test", "attribute");
@ -129,7 +129,7 @@ public class NodeInfoStreamingTests extends ESTestCase {
threadPoolInfos.add(new ThreadPool.Info("test_threadpool", ThreadPool.ThreadPoolType.FIXED, 5));
ThreadPoolInfo threadPoolInfo = new ThreadPoolInfo(threadPoolInfos);
Map<String, BoundTransportAddress> profileAddresses = new HashMap<>();
BoundTransportAddress dummyBoundTransportAddress = new BoundTransportAddress(new TransportAddress[]{DummyTransportAddress.INSTANCE}, DummyTransportAddress.INSTANCE);
BoundTransportAddress dummyBoundTransportAddress = new BoundTransportAddress(new TransportAddress[]{LocalTransportAddress.buildUnique()}, LocalTransportAddress.buildUnique());
profileAddresses.put("test_address", dummyBoundTransportAddress);
TransportInfo transport = new TransportInfo(dummyBoundTransportAddress, profileAddresses);
HttpInfo htttpInfo = new HttpInfo(dummyBoundTransportAddress, randomLong());

View File

@ -24,9 +24,9 @@ import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.EsExecutors;
import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
import org.elasticsearch.test.ESIntegTestCase.Scope;
import org.elasticsearch.test.ESIntegTestCase;
import java.util.List;

View File

@ -22,7 +22,7 @@ import org.elasticsearch.Version;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.shard.IndexShard;
import org.elasticsearch.index.shard.ShardId;
@ -30,16 +30,13 @@ import org.elasticsearch.indices.IndicesService;
import org.elasticsearch.indices.recovery.RecoveriesCollection;
import org.elasticsearch.indices.recovery.RecoveryFailedException;
import org.elasticsearch.indices.recovery.RecoveryState;
import org.elasticsearch.indices.recovery.RecoveryTarget;
import org.elasticsearch.indices.recovery.RecoveryTargetService;
import org.elasticsearch.test.ESSingleNodeTestCase;
import org.elasticsearch.threadpool.ThreadPool;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import static java.util.Collections.emptyMap;
import static java.util.Collections.emptySet;
@ -135,7 +132,8 @@ public class RecoveriesCollectionTests extends ESSingleNodeTestCase {
long startRecovery(RecoveriesCollection collection, RecoveryTargetService.RecoveryListener listener, TimeValue timeValue) {
IndicesService indexServices = getInstanceFromNode(IndicesService.class);
IndexShard indexShard = indexServices.indexServiceSafe(resolveIndex("test")).getShardOrNull(0);
final DiscoveryNode sourceNode = new DiscoveryNode("id", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT);
final DiscoveryNode sourceNode = new DiscoveryNode("id", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(),
Version.CURRENT);
return collection.startRecovery(indexShard, sourceNode, listener, timeValue);
}
}

View File

@ -27,7 +27,7 @@ public class TribeServiceTests extends ESTestCase {
Settings globalSettings = Settings.builder()
.put("node.name", "nodename")
.put("path.home", "some/path").build();
Settings clientSettings = TribeService.buildClientSettings("tribe1", globalSettings, Settings.EMPTY);
Settings clientSettings = TribeService.buildClientSettings("tribe1", "parent_id", globalSettings, Settings.EMPTY);
assertEquals("some/path", clientSettings.get("path.home"));
assertEquals("nodename/tribe1", clientSettings.get("node.name"));
assertEquals("tribe1", clientSettings.get("tribe.name"));
@ -35,7 +35,9 @@ public class TribeServiceTests extends ESTestCase {
assertEquals("false", clientSettings.get("node.master"));
assertEquals("false", clientSettings.get("node.data"));
assertEquals("false", clientSettings.get("node.ingest"));
assertEquals(7, clientSettings.getAsMap().size());
assertEquals("false", clientSettings.get("node.local_storage"));
assertEquals("3707202549613653169", clientSettings.get("node.id.seed")); // should be fixed by the parent id and tribe name
assertEquals(9, clientSettings.getAsMap().size());
}
public void testEnvironmentSettings() {
@ -45,7 +47,7 @@ public class TribeServiceTests extends ESTestCase {
.put("path.conf", "conf/path")
.put("path.scripts", "scripts/path")
.put("path.logs", "logs/path").build();
Settings clientSettings = TribeService.buildClientSettings("tribe1", globalSettings, Settings.EMPTY);
Settings clientSettings = TribeService.buildClientSettings("tribe1", "parent_id", globalSettings, Settings.EMPTY);
assertEquals("some/path", clientSettings.get("path.home"));
assertEquals("conf/path", clientSettings.get("path.conf"));
assertEquals("scripts/path", clientSettings.get("path.scripts"));
@ -54,7 +56,7 @@ public class TribeServiceTests extends ESTestCase {
Settings tribeSettings = Settings.builder()
.put("path.home", "alternate/path").build();
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> {
TribeService.buildClientSettings("tribe1", globalSettings, tribeSettings);
TribeService.buildClientSettings("tribe1", "parent_id", globalSettings, tribeSettings);
});
assertTrue(e.getMessage(), e.getMessage().contains("Setting [path.home] not allowed in tribe client"));
}
@ -69,7 +71,7 @@ public class TribeServiceTests extends ESTestCase {
.put("transport.host", "3.3.3.3")
.put("transport.bind_host", "4.4.4.4")
.put("transport.publish_host", "5.5.5.5").build();
Settings clientSettings = TribeService.buildClientSettings("tribe1", globalSettings, Settings.EMPTY);
Settings clientSettings = TribeService.buildClientSettings("tribe1", "parent_id", globalSettings, Settings.EMPTY);
assertEquals("0.0.0.0", clientSettings.get("network.host"));
assertEquals("1.1.1.1", clientSettings.get("network.bind_host"));
assertEquals("2.2.2.2", clientSettings.get("network.publish_host"));
@ -85,7 +87,7 @@ public class TribeServiceTests extends ESTestCase {
.put("transport.host", "6.6.6.6")
.put("transport.bind_host", "7.7.7.7")
.put("transport.publish_host", "8.8.8.8").build();
clientSettings = TribeService.buildClientSettings("tribe1", globalSettings, tribeSettings);
clientSettings = TribeService.buildClientSettings("tribe1", "parent_id", globalSettings, tribeSettings);
assertEquals("3.3.3.3", clientSettings.get("network.host"));
assertEquals("4.4.4.4", clientSettings.get("network.bind_host"));
assertEquals("5.5.5.5", clientSettings.get("network.publish_host"));

View File

@ -10,12 +10,12 @@ index.
In order to fully utilize the `index.data_path` and `index.shadow_replicas`
settings, you need to allow Elasticsearch to use the same data directory for
multiple instances by setting `node.add_id_to_custom_path` to false in
multiple instances by setting `node.add_lock_id_to_custom_path` to false in
elasticsearch.yml:
[source,yaml]
--------------------------------------------------
node.add_id_to_custom_path: false
node.add_lock_id_to_custom_path: false
--------------------------------------------------
You will also need to indicate to the security manager where the custom indices
@ -114,7 +114,7 @@ settings API:
These are non-dynamic settings that need to be configured in `elasticsearch.yml`
`node.add_id_to_custom_path`::
`node.add_lock_id_to_custom_path`::
Boolean setting indicating whether Elasticsearch should append the node's
ordinal to the custom data path. For example, if this is enabled and a path
of "/tmp/foo" is used, the first locally-running node will use "/tmp/foo/0",

View File

@ -23,3 +23,9 @@ behavior will be removed.
If you are using a multi-cluster setup with both instances of Elasticsearch
pointing to the same data path, you will need to add the cluster name to the
data path so that different clusters do not overwrite data.
==== Local files
Prior to 5.0, nodes that were marked with both `node.data: false` and `node.master: false` (or the now removed `node.client: true`)
didn't write any files or folder to disk. 5.x added persistent node ids, requiring nodes to store that information. As such, all
node types will write a small state file to their data folders.

View File

@ -26,6 +26,8 @@ should be used instead.
The `name` setting has been removed and is replaced by `node.name`. Usage of
`-Dname=some_node_name` is not supported anymore.
The `node.add_id_to_custom_path` was renamed to `add_lock_id_to_custom_path`.
==== Node attribute settings
Node level attributes used for allocation filtering, forced awareness or other node identification / grouping

View File

@ -23,10 +23,10 @@ import org.apache.lucene.util.IOUtils;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodeService;
import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.env.NodeEnvironment;
import org.elasticsearch.node.Node;
import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.test.ESTestCase;
@ -65,14 +65,14 @@ public class TribeUnitTests extends ESTestCase {
.put(baseSettings)
.put("cluster.name", "tribe1")
.put("node.name", "tribe1_node")
.put(DiscoveryNodeService.NODE_ID_SEED_SETTING.getKey(), random().nextLong())
.put(NodeEnvironment.NODE_ID_SEED_SETTING.getKey(), random().nextLong())
.build()).start();
tribe2 = new TribeClientNode(
Settings.builder()
.put(baseSettings)
.put("cluster.name", "tribe2")
.put("node.name", "tribe2_node")
.put(DiscoveryNodeService.NODE_ID_SEED_SETTING.getKey(), random().nextLong())
.put(NodeEnvironment.NODE_ID_SEED_SETTING.getKey(), random().nextLong())
.build()).start();
}

View File

@ -1,5 +1,5 @@
cluster.name: tribe_node_cluster
tribe.t1.cluster.name: tribe1
tribe.t2.cluster.name: tribe2
tribe.t1.node_id.seed: 1
tribe.t2.node_id.seed: 2
tribe.t1.node.id.seed: 1
tribe.t2.node.id.seed: 2

View File

@ -32,7 +32,7 @@ import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.monitor.fs.FsInfo;
import org.elasticsearch.plugins.Plugin;
@ -67,7 +67,7 @@ public class MockInternalClusterInfoService extends InternalClusterInfoService {
usage.getTotalBytes(), usage.getFreeBytes(), usage.getFreeBytes());
paths[0] = path;
FsInfo fsInfo = new FsInfo(System.currentTimeMillis(), null, paths);
return new NodeStats(new DiscoveryNode(nodeName, DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT),
return new NodeStats(new DiscoveryNode(nodeName, LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT),
System.currentTimeMillis(),
null, null, null, null, null,
fsInfo,

View File

@ -29,7 +29,7 @@ import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.threadpool.ThreadPool;
import java.util.Arrays;
@ -45,7 +45,7 @@ public class ClusterServiceUtils {
ClusterService clusterService = new ClusterService(Settings.builder().put("cluster.name", "ClusterServiceTests").build(),
new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS),
threadPool);
clusterService.setLocalNode(new DiscoveryNode("node", DummyTransportAddress.INSTANCE, Collections.emptyMap(),
clusterService.setLocalNode(new DiscoveryNode("node", LocalTransportAddress.buildUnique(), Collections.emptyMap(),
new HashSet<>(Arrays.asList(DiscoveryNode.Role.values())),Version.CURRENT));
clusterService.setNodeConnectionsService(new NodeConnectionsService(Settings.EMPTY, null, null) {
@Override

View File

@ -42,7 +42,7 @@ import org.elasticsearch.cluster.routing.allocation.decider.SameShardAllocationD
import org.elasticsearch.common.Randomness;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.gateway.AsyncShardFetch;
import org.elasticsearch.gateway.GatewayAllocator;
import org.elasticsearch.gateway.ReplicaShardAllocator;
@ -133,19 +133,19 @@ public abstract class ESAllocationTestCase extends ESTestCase {
}
protected static DiscoveryNode newNode(String nodeName, String nodeId, Map<String, String> attributes) {
return new DiscoveryNode(nodeName, nodeId, DummyTransportAddress.INSTANCE, attributes, MASTER_DATA_ROLES, Version.CURRENT);
return new DiscoveryNode(nodeName, nodeId, LocalTransportAddress.buildUnique(), attributes, MASTER_DATA_ROLES, Version.CURRENT);
}
protected static DiscoveryNode newNode(String nodeId, Map<String, String> attributes) {
return new DiscoveryNode(nodeId, DummyTransportAddress.INSTANCE, attributes, MASTER_DATA_ROLES, Version.CURRENT);
return new DiscoveryNode(nodeId, LocalTransportAddress.buildUnique(), attributes, MASTER_DATA_ROLES, Version.CURRENT);
}
protected static DiscoveryNode newNode(String nodeId, Set<DiscoveryNode.Role> roles) {
return new DiscoveryNode(nodeId, DummyTransportAddress.INSTANCE, emptyMap(), roles, Version.CURRENT);
return new DiscoveryNode(nodeId, LocalTransportAddress.buildUnique(), emptyMap(), roles, Version.CURRENT);
}
protected static DiscoveryNode newNode(String nodeId, Version version) {
return new DiscoveryNode(nodeId, DummyTransportAddress.INSTANCE, emptyMap(), MASTER_DATA_ROLES, version);
return new DiscoveryNode(nodeId, LocalTransportAddress.buildUnique(), emptyMap(), MASTER_DATA_ROLES, version);
}
protected static ClusterState startRandomInitializingShard(ClusterState clusterState, AllocationService strategy) {

View File

@ -40,7 +40,6 @@ import org.elasticsearch.cluster.action.index.MappingUpdatedAction;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNode.Role;
import org.elasticsearch.cluster.node.DiscoveryNodeService;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.cluster.routing.OperationRouting;
import org.elasticsearch.cluster.routing.ShardRouting;
@ -606,7 +605,7 @@ public final class InternalTestCluster extends TestCluster {
.put(Environment.PATH_HOME_SETTING.getKey(), baseDir) // allow overriding path.home
.put(settings)
.put("node.name", name)
.put(DiscoveryNodeService.NODE_ID_SEED_SETTING.getKey(), seed)
.put(NodeEnvironment.NODE_ID_SEED_SETTING.getKey(), seed)
.build();
MockNode node = new MockNode(finalSettings, plugins);
return new NodeAndClient(name, node, nodeId);
@ -898,8 +897,8 @@ public final class InternalTestCluster extends TestCluster {
}
private void createNewNode(final Settings newSettings) {
final long newIdSeed = DiscoveryNodeService.NODE_ID_SEED_SETTING.get(node.settings()) + 1; // use a new seed to make sure we have new node id
Settings finalSettings = Settings.builder().put(node.settings()).put(newSettings).put(DiscoveryNodeService.NODE_ID_SEED_SETTING.getKey(), newIdSeed).build();
final long newIdSeed = NodeEnvironment.NODE_ID_SEED_SETTING.get(node.settings()) + 1; // use a new seed to make sure we have new node id
Settings finalSettings = Settings.builder().put(node.settings()).put(newSettings).put(NodeEnvironment.NODE_ID_SEED_SETTING.getKey(), newIdSeed).build();
Collection<Class<? extends Plugin>> plugins = node.getPlugins();
node = new MockNode(finalSettings, plugins);
markNodeDataDirsAsNotEligableForWipe(node);
@ -1393,7 +1392,6 @@ public final class InternalTestCluster extends TestCluster {
// delete data folders now, before we start other nodes that may claim it
nodeAndClient.clearDataIfNeeded(callback);
DiscoveryNode discoveryNode = getInstanceFromNode(ClusterService.class, nodeAndClient.node()).localNode();
nodesRoleOrder[nodeAndClient.nodeAndClientId()] = discoveryNode.getRoles();
nodesByRoles.computeIfAbsent(discoveryNode.getRoles(), k -> new ArrayList<>()).add(nodeAndClient);

View File

@ -178,7 +178,7 @@ public class InternalTestClusterTests extends ESTestCase {
int maxNumDataNodes = 2;
final String clusterName1 = "shared1";
NodeConfigurationSource nodeConfigurationSource = NodeConfigurationSource.EMPTY;
int numClientNodes = 0;
int numClientNodes = randomIntBetween(0, 2);
boolean enableHttpPipelining = randomBoolean();
String nodePrefix = "test";
Path baseDir = createTempDir();
@ -218,8 +218,7 @@ public class InternalTestClusterTests extends ESTestCase {
assertFileNotExists(testMarker); // a new unknown node used this path, it should be cleaned
assertFileExists(stableTestMarker); // but leaving the structure of existing, reused nodes
for (String name: cluster.getNodeNames()) {
assertThat("data paths for " + name + " changed", getNodePaths(cluster, name),
equalTo(shardNodePaths.get(name)));
assertThat("data paths for " + name + " changed", getNodePaths(cluster, name), equalTo(shardNodePaths.get(name)));
}
cluster.beforeTest(random(), 0.0);