diff --git a/server/src/main/java/org/elasticsearch/cluster/node/DiscoveryNode.java b/server/src/main/java/org/elasticsearch/cluster/node/DiscoveryNode.java index 02563f095ee..b984c5c5dcd 100644 --- a/server/src/main/java/org/elasticsearch/cluster/node/DiscoveryNode.java +++ b/server/src/main/java/org/elasticsearch/cluster/node/DiscoveryNode.java @@ -276,9 +276,15 @@ public class DiscoveryNode implements Writeable, ToXContentFragment { for (int i = 0; i < rolesSize; i++) { final String roleName = in.readString(); final String roleNameAbbreviation = in.readString(); + final boolean canContainData; + if (in.getVersion().onOrAfter(Version.V_7_10_0)) { + canContainData = in.readBoolean(); + } else { + canContainData = roleName.equals(DiscoveryNodeRole.DATA_ROLE.roleName()); + } final DiscoveryNodeRole role = roleMap.get(roleName); if (role == null) { - roles.add(new DiscoveryNodeRole.UnknownRole(roleName, roleNameAbbreviation)); + roles.add(new DiscoveryNodeRole.UnknownRole(roleName, roleNameAbbreviation, canContainData)); } else { assert roleName.equals(role.roleName()) : "role name [" + roleName + "] does not match role [" + role.roleName() + "]"; assert roleNameAbbreviation.equals(role.roleNameAbbreviation()) @@ -328,6 +334,9 @@ public class DiscoveryNode implements Writeable, ToXContentFragment { final DiscoveryNodeRole compatibleRole = role.getCompatibilityRole(out.getVersion()); out.writeString(compatibleRole.roleName()); out.writeString(compatibleRole.roleNameAbbreviation()); + if (out.getVersion().onOrAfter(Version.V_7_10_0)) { + out.writeBoolean(compatibleRole.canContainData()); + } } } else { // an old node will only understand legacy roles since pluggable roles is a new concept diff --git a/server/src/main/java/org/elasticsearch/cluster/node/DiscoveryNodeRole.java b/server/src/main/java/org/elasticsearch/cluster/node/DiscoveryNodeRole.java index 92667749d76..02a40a10655 100644 --- a/server/src/main/java/org/elasticsearch/cluster/node/DiscoveryNodeRole.java +++ b/server/src/main/java/org/elasticsearch/cluster/node/DiscoveryNodeRole.java @@ -59,6 +59,17 @@ public abstract class DiscoveryNodeRole implements Comparable return roleNameAbbreviation; } + private final boolean canContainData; + + /** + * Indicates whether a node with this role can contain data. + * + * @return true if a node with this role can contain data, otherwise false + */ + public final boolean canContainData() { + return canContainData; + } + private final boolean isKnownRole; /** @@ -73,24 +84,27 @@ public abstract class DiscoveryNodeRole implements Comparable } protected DiscoveryNodeRole(final String roleName, final String roleNameAbbreviation) { - this(true, roleName, roleNameAbbreviation); + this(roleName, roleNameAbbreviation, false); } - private DiscoveryNodeRole(final boolean isKnownRole, final String roleName, final String roleNameAbbreviation) { + protected DiscoveryNodeRole(final String roleName, final String roleNameAbbreviation, final boolean canContainData) { + this(true, roleName, roleNameAbbreviation, canContainData); + } + + private DiscoveryNodeRole( + final boolean isKnownRole, + final String roleName, + final String roleNameAbbreviation, + final boolean canContainData + ) { this.isKnownRole = isKnownRole; this.roleName = Objects.requireNonNull(roleName); this.roleNameAbbreviation = Objects.requireNonNull(roleNameAbbreviation); + this.canContainData = canContainData; } public abstract Setting legacySetting(); - /** - * Indicates whether a node with the given role can contain data. Defaults to false and can be overridden - */ - public boolean canContainData() { - return false; - } - /** * When serializing a {@link DiscoveryNodeRole}, the role may not be available to nodes of * previous versions, where the role had not yet been added. This method allows overriding @@ -108,12 +122,13 @@ public abstract class DiscoveryNodeRole implements Comparable DiscoveryNodeRole that = (DiscoveryNodeRole) o; return roleName.equals(that.roleName) && roleNameAbbreviation.equals(that.roleNameAbbreviation) && + canContainData == that.canContainData && isKnownRole == that.isKnownRole; } @Override public final int hashCode() { - return Objects.hash(isKnownRole, roleName(), roleNameAbbreviation()); + return Objects.hash(isKnownRole, roleName(), roleNameAbbreviation(), canContainData()); } @Override @@ -126,6 +141,7 @@ public abstract class DiscoveryNodeRole implements Comparable return "DiscoveryNodeRole{" + "roleName='" + roleName + '\'' + ", roleNameAbbreviation='" + roleNameAbbreviation + '\'' + + ", canContainData=" + canContainData + (isKnownRole ? "" : ", isKnownRole=false") + '}'; } @@ -133,7 +149,7 @@ public abstract class DiscoveryNodeRole implements Comparable /** * Represents the role for a data node. */ - public static final DiscoveryNodeRole DATA_ROLE = new DiscoveryNodeRole("data", "d") { + public static final DiscoveryNodeRole DATA_ROLE = new DiscoveryNodeRole("data", "d", true) { @Override public Setting legacySetting() { @@ -141,10 +157,6 @@ public abstract class DiscoveryNodeRole implements Comparable return Setting.boolSetting("node.data", true, Property.Deprecated, Property.NodeScope); } - @Override - public boolean canContainData() { - return true; - } }; /** @@ -214,9 +226,10 @@ public abstract class DiscoveryNodeRole implements Comparable * * @param roleName the role name * @param roleNameAbbreviation the role name abbreviation + * @param canContainData whether or not nodes with the role can contain data */ - UnknownRole(final String roleName, final String roleNameAbbreviation) { - super(false, roleName, roleNameAbbreviation); + UnknownRole(final String roleName, final String roleNameAbbreviation, final boolean canContainData) { + super(false, roleName, roleNameAbbreviation, canContainData); } @Override diff --git a/server/src/test/java/org/elasticsearch/cluster/node/DiscoveryNodeRoleTests.java b/server/src/test/java/org/elasticsearch/cluster/node/DiscoveryNodeRoleTests.java index 41e36f0a6cf..81c93e3398a 100644 --- a/server/src/test/java/org/elasticsearch/cluster/node/DiscoveryNodeRoleTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/node/DiscoveryNodeRoleTests.java @@ -78,13 +78,27 @@ public class DiscoveryNodeRoleTests extends ESTestCase { } public void testDiscoveryNodeRoleEqualsHashCode() { - EqualsHashCodeTestUtils.checkEqualsAndHashCode(new DiscoveryNodeRole.UnknownRole(randomAlphaOfLength(10), randomAlphaOfLength(1)), - r -> new DiscoveryNodeRole.UnknownRole(r.roleName(), r.roleNameAbbreviation()), + EqualsHashCodeTestUtils.checkEqualsAndHashCode( + new DiscoveryNodeRole.UnknownRole(randomAlphaOfLength(10), randomAlphaOfLength(1), randomBoolean()), + r -> new DiscoveryNodeRole.UnknownRole(r.roleName(), r.roleNameAbbreviation(), r.canContainData()), r -> { - if (randomBoolean()) { - return new DiscoveryNodeRole.UnknownRole(randomAlphaOfLength(21 - r.roleName().length()), r.roleNameAbbreviation()); - } else { - return new DiscoveryNodeRole.UnknownRole(r.roleName(), randomAlphaOfLength(3 - r.roleNameAbbreviation().length())); + final int value = randomIntBetween(0, 2); + switch (value) { + case 0: + return new DiscoveryNodeRole.UnknownRole( + randomAlphaOfLength(21 - r.roleName().length()), + r.roleNameAbbreviation(), + r.canContainData() + ); + case 1: + return new DiscoveryNodeRole.UnknownRole( + r.roleName(), + randomAlphaOfLength(3 - r.roleNameAbbreviation().length()), + r.canContainData()); + case 2: + return new DiscoveryNodeRole.UnknownRole(r.roleName(), r.roleNameAbbreviation(), r.canContainData() == false); + default: + throw new AssertionError("unexpected value [" + value + "] not between 0 and 2"); } }); @@ -92,8 +106,11 @@ public class DiscoveryNodeRoleTests extends ESTestCase { public void testUnknownRoleIsDistinctFromKnownRoles() { for (DiscoveryNodeRole buildInRole : DiscoveryNodeRole.BUILT_IN_ROLES) { - final DiscoveryNodeRole.UnknownRole unknownDataRole - = new DiscoveryNodeRole.UnknownRole(buildInRole.roleName(), buildInRole.roleNameAbbreviation()); + final DiscoveryNodeRole.UnknownRole unknownDataRole = new DiscoveryNodeRole.UnknownRole( + buildInRole.roleName(), + buildInRole.roleNameAbbreviation(), + buildInRole.canContainData() + ); assertNotEquals(buildInRole, unknownDataRole); assertNotEquals(buildInRole.toString(), unknownDataRole.toString()); } diff --git a/server/src/test/java/org/elasticsearch/cluster/node/DiscoveryNodeTests.java b/server/src/test/java/org/elasticsearch/cluster/node/DiscoveryNodeTests.java index a935f2d6f43..16e161f087a 100644 --- a/server/src/test/java/org/elasticsearch/cluster/node/DiscoveryNodeTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/node/DiscoveryNodeTests.java @@ -95,7 +95,7 @@ public class DiscoveryNodeTests extends ESTestCase { InetAddress inetAddress = InetAddress.getByAddress("name1", new byte[] { (byte) 192, (byte) 168, (byte) 0, (byte) 1}); TransportAddress transportAddress = new TransportAddress(inetAddress, randomIntBetween(0, 65535)); - DiscoveryNodeRole customRole = new DiscoveryNodeRole("custom_role", "z") { + DiscoveryNodeRole customRole = new DiscoveryNodeRole("custom_role", "z", true) { @Override public Setting legacySetting() { return null; @@ -120,6 +120,7 @@ public class DiscoveryNodeTests extends ESTestCase { node.writeTo(streamOutput); StreamInput in = StreamInput.wrap(streamOutput.bytes().toBytesRef().bytes); + in.setVersion(Version.CURRENT); DiscoveryNode serialized = new DiscoveryNode(in); assertThat(serialized.getRoles().stream().map(DiscoveryNodeRole::roleName).collect(Collectors.joining()), equalTo("custom_role")); @@ -131,6 +132,7 @@ public class DiscoveryNodeTests extends ESTestCase { node.writeTo(streamOutput); StreamInput in = StreamInput.wrap(streamOutput.bytes().toBytesRef().bytes); + in.setVersion(Version.V_7_10_0); DiscoveryNode serialized = new DiscoveryNode(in); assertThat(serialized.getRoles().stream().map(DiscoveryNodeRole::roleName).collect(Collectors.joining()), equalTo("data")); diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/DataTier.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/DataTier.java index d99a8e1deeb..fa274d51c1b 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/DataTier.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/DataTier.java @@ -66,7 +66,7 @@ public class DataTier { return false; } - public static DiscoveryNodeRole DATA_CONTENT_NODE_ROLE = new DiscoveryNodeRole("data_content", "s") { + public static DiscoveryNodeRole DATA_CONTENT_NODE_ROLE = new DiscoveryNodeRole("data_content", "s", true) { @Override public boolean isEnabledByDefault(final Settings settings) { return DiscoveryNode.hasRole(settings, DiscoveryNodeRole.DATA_ROLE); @@ -85,18 +85,13 @@ public class DataTier { ); } - @Override - public boolean canContainData() { - return true; - } - @Override public DiscoveryNodeRole getCompatibilityRole(Version nodeVersion) { return nodeVersion.before(Version.V_7_10_0) ? DiscoveryNodeRole.DATA_ROLE : this; } }; - public static DiscoveryNodeRole DATA_HOT_NODE_ROLE = new DiscoveryNodeRole("data_hot", "h") { + public static DiscoveryNodeRole DATA_HOT_NODE_ROLE = new DiscoveryNodeRole("data_hot", "h", true) { @Override public boolean isEnabledByDefault(final Settings settings) { return DiscoveryNode.hasRole(settings, DiscoveryNodeRole.DATA_ROLE); @@ -115,18 +110,13 @@ public class DataTier { ); } - @Override - public boolean canContainData() { - return true; - } - @Override public DiscoveryNodeRole getCompatibilityRole(Version nodeVersion) { return nodeVersion.before(Version.V_7_10_0) ? DiscoveryNodeRole.DATA_ROLE : this; } }; - public static DiscoveryNodeRole DATA_WARM_NODE_ROLE = new DiscoveryNodeRole("data_warm", "w") { + public static DiscoveryNodeRole DATA_WARM_NODE_ROLE = new DiscoveryNodeRole("data_warm", "w", true) { @Override public boolean isEnabledByDefault(final Settings settings) { return DiscoveryNode.hasRole(settings, DiscoveryNodeRole.DATA_ROLE); @@ -145,18 +135,13 @@ public class DataTier { ); } - @Override - public boolean canContainData() { - return true; - } - @Override public DiscoveryNodeRole getCompatibilityRole(Version nodeVersion) { return nodeVersion.before(Version.V_7_10_0) ? DiscoveryNodeRole.DATA_ROLE : this; } }; - public static DiscoveryNodeRole DATA_COLD_NODE_ROLE = new DiscoveryNodeRole("data_cold", "c") { + public static DiscoveryNodeRole DATA_COLD_NODE_ROLE = new DiscoveryNodeRole("data_cold", "c", true) { @Override public boolean isEnabledByDefault(final Settings settings) { return DiscoveryNode.hasRole(settings, DiscoveryNodeRole.DATA_ROLE); @@ -175,11 +160,6 @@ public class DataTier { ); } - @Override - public boolean canContainData() { - return true; - } - @Override public DiscoveryNodeRole getCompatibilityRole(Version nodeVersion) { return nodeVersion.before(Version.V_7_10_0) ? DiscoveryNodeRole.DATA_ROLE : this;