Serialize can contain data with roles (#64324)

This commit internalizes whether or not a role represents the ability to
contain data. In the future, this will let us remove the compatibility
role notion.
This commit is contained in:
Jason Tedor 2020-10-29 20:40:31 -04:00
parent b1ba274157
commit 1126ba4df8
No known key found for this signature in database
GPG Key ID: FA89F05560F16BC5
5 changed files with 72 additions and 51 deletions

View File

@ -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

View File

@ -59,6 +59,17 @@ public abstract class DiscoveryNodeRole implements Comparable<DiscoveryNodeRole>
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<DiscoveryNodeRole>
}
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<Boolean> 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>
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<DiscoveryNodeRole>
return "DiscoveryNodeRole{" +
"roleName='" + roleName + '\'' +
", roleNameAbbreviation='" + roleNameAbbreviation + '\'' +
", canContainData=" + canContainData +
(isKnownRole ? "" : ", isKnownRole=false") +
'}';
}
@ -133,7 +149,7 @@ public abstract class DiscoveryNodeRole implements Comparable<DiscoveryNodeRole>
/**
* 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<Boolean> legacySetting() {
@ -141,10 +157,6 @@ public abstract class DiscoveryNodeRole implements Comparable<DiscoveryNodeRole>
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<DiscoveryNodeRole>
*
* @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

View File

@ -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());
}

View File

@ -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<Boolean> 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"));

View File

@ -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;