org.opensearch.cluster.node.DiscoveryNodeRole Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of opensearch Show documentation
Show all versions of opensearch Show documentation
OpenSearch subproject :server
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/
/*
* 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.
*/
/*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/
package org.opensearch.cluster.node;
import org.opensearch.LegacyESVersion;
import org.opensearch.Version;
import org.opensearch.common.Booleans;
import org.opensearch.common.annotation.PublicApi;
import org.opensearch.common.logging.DeprecationLogger;
import org.opensearch.common.settings.Setting;
import org.opensearch.common.settings.Setting.Property;
import org.opensearch.common.settings.Settings;
import org.opensearch.transport.RemoteClusterService;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.SortedSet;
import java.util.TreeSet;
/**
* Represents a node role.
*
* @opensearch.api
*/
@PublicApi(since = "1.0.0")
public abstract class DiscoveryNodeRole implements Comparable {
private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(DiscoveryNodeRole.class);
public static final String MASTER_ROLE_DEPRECATION_MESSAGE =
"Assigning [master] role in setting [node.roles] is deprecated. To promote inclusive language, please use [cluster_manager] role instead.";
private final String roleName;
/**
* The name of the role.
*
* @return the role name
*/
public final String roleName() {
return roleName;
}
private final String roleNameAbbreviation;
/**
* The abbreviation of the name of the role. This is used in the cat nodes API to display an abbreviated version of the name of the
* role.
*
* @return the role name abbreviation
*/
public final String roleNameAbbreviation() {
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;
private final boolean isDynamicRole;
/**
* Whether this role is known by this node, or is an {@link DiscoveryNodeRole.UnknownRole}.
*/
public final boolean isKnownRole() {
return isKnownRole;
}
public final boolean isDynamicRole() {
return isDynamicRole;
}
public boolean isEnabledByDefault(final Settings settings) {
return legacySetting() != null && legacySetting().get(settings);
}
protected DiscoveryNodeRole(final String roleName, final String roleNameAbbreviation) {
this(roleName, roleNameAbbreviation, false);
}
protected DiscoveryNodeRole(final String roleName, final String roleNameAbbreviation, final boolean canContainData) {
this(true, false, roleName, roleNameAbbreviation, canContainData);
}
private DiscoveryNodeRole(
final boolean isKnownRole,
final boolean isDynamicRole,
final String roleName,
final String roleNameAbbreviation,
final boolean canContainData
) {
this.isKnownRole = isKnownRole;
this.isDynamicRole = isDynamicRole;
// As we are supporting dynamic role, should make role name case-insensitive to avoid confusion of role name like "Data"/"DATA"
this.roleName = Objects.requireNonNull(roleName).toLowerCase(Locale.ROOT);
this.roleNameAbbreviation = Objects.requireNonNull(roleNameAbbreviation).toLowerCase(Locale.ROOT);
this.canContainData = canContainData;
}
public abstract Setting legacySetting();
/**
* 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
* the role that should be serialized when communicating to versions prior to the introduction
* of the discovery node role.
*/
public DiscoveryNodeRole getCompatibilityRole(Version nodeVersion) {
return this;
}
/**
* Validate the role is compatible with the other roles in the list, when assigning the list of roles to a node.
* An {@link IllegalArgumentException} is expected to be thrown, if the role can't coexist with the other roles.
* @param roles a {@link List} of {@link DiscoveryNodeRole} that a node is going to have
*/
public void validateRole(List roles) {};
@Override
public final boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DiscoveryNodeRole that = (DiscoveryNodeRole) o;
return roleName.equals(that.roleName)
&& roleNameAbbreviation.equals(that.roleNameAbbreviation)
&& canContainData == that.canContainData
&& isKnownRole == that.isKnownRole
&& isDynamicRole == that.isDynamicRole;
}
@Override
public final int hashCode() {
return Objects.hash(isKnownRole, isDynamicRole, roleName(), roleNameAbbreviation(), canContainData());
}
@Override
public final int compareTo(final DiscoveryNodeRole o) {
return roleName.compareTo(o.roleName);
}
@Override
public final String toString() {
return "DiscoveryNodeRole{"
+ "roleName='"
+ roleName
+ '\''
+ ", roleNameAbbreviation='"
+ roleNameAbbreviation
+ '\''
+ ", canContainData="
+ canContainData
+ (isKnownRole ? "" : ", isKnownRole=false")
+ (isDynamicRole ? "" : ", isDynamicRole=false")
+ '}';
}
/**
* Represents the role for a data node.
*/
public static final DiscoveryNodeRole DATA_ROLE = new DiscoveryNodeRole("data", "d", true) {
@Override
public Setting legacySetting() {
// copy the setting here so we can mark it private in org.opensearch.node.Node
return Setting.boolSetting("node.data", true, Property.Deprecated, Property.NodeScope);
}
};
/**
* Represents the role for an ingest node.
*/
public static final DiscoveryNodeRole INGEST_ROLE = new DiscoveryNodeRole("ingest", "i") {
@Override
public Setting legacySetting() {
// copy the setting here so we can mark it private in org.opensearch.node.Node
return Setting.boolSetting("node.ingest", true, Property.Deprecated, Property.NodeScope);
}
};
/**
* Represents the role for a cluster-manager-eligible node.
* @deprecated As of 2.0, because promoting inclusive language, replaced by {@link #CLUSTER_MANAGER_ROLE}
*/
@Deprecated
public static final DiscoveryNodeRole MASTER_ROLE = new DiscoveryNodeRole("master", "m") {
@Override
public Setting legacySetting() {
// copy the setting here so we can mark it private in org.opensearch.node.Node
// As of 2.0, set the default value to 'false', so that MASTER_ROLE isn't added as a default value of NODE_ROLES_SETTING
return Setting.boolSetting("node.master", false, Property.Deprecated, Property.NodeScope);
}
@Override
public void validateRole(List roles) {
deprecationLogger.deprecate("node_role_master", MASTER_ROLE_DEPRECATION_MESSAGE);
}
};
/**
* Represents the role for a cluster-manager-eligible node.
*/
public static final DiscoveryNodeRole CLUSTER_MANAGER_ROLE = new DiscoveryNodeRole("cluster_manager", "m") {
@Override
public Setting legacySetting() {
// 'cluster_manager' role should not configure legacy setting since deprecated 'master' role is supported till OS 2.x
return null;
}
@Override
public DiscoveryNodeRole getCompatibilityRole(Version nodeVersion) {
if (nodeVersion.onOrAfter(Version.V_2_0_0)) {
return this;
} else {
return DiscoveryNodeRole.MASTER_ROLE;
}
}
@Override
public void validateRole(List roles) {
if (roles.contains(DiscoveryNodeRole.MASTER_ROLE)) {
throw new IllegalArgumentException(
String.format(
Locale.ROOT,
"The two roles [%s, %s] can not be assigned together to a node. %s",
DiscoveryNodeRole.MASTER_ROLE.roleName(),
DiscoveryNodeRole.CLUSTER_MANAGER_ROLE.roleName(),
MASTER_ROLE_DEPRECATION_MESSAGE
)
);
}
}
@Override
public boolean isEnabledByDefault(final Settings settings) {
return Booleans.isBoolean(settings.get("node.master")) == false;
}
};
public static final DiscoveryNodeRole REMOTE_CLUSTER_CLIENT_ROLE = new DiscoveryNodeRole("remote_cluster_client", "r") {
@Override
public Setting legacySetting() {
// copy the setting here so we can mark it private in org.opensearch.node.Node
return Setting.boolSetting(
"node.remote_cluster_client",
RemoteClusterService.ENABLE_REMOTE_CLUSTERS,
Property.Deprecated,
Property.NodeScope
);
}
};
/**
* Represents the role for a search node, which is dedicated to provide search capability.
*/
public static final DiscoveryNodeRole SEARCH_ROLE = new DiscoveryNodeRole("search", "s", true) {
@Override
public Setting legacySetting() {
// search role is added in 2.4 so doesn't need to configure legacy setting
return null;
}
};
/**
* The built-in node roles.
*/
public static SortedSet BUILT_IN_ROLES = Collections.unmodifiableSortedSet(
new TreeSet<>(Arrays.asList(DATA_ROLE, INGEST_ROLE, CLUSTER_MANAGER_ROLE, REMOTE_CLUSTER_CLIENT_ROLE, SEARCH_ROLE))
);
/**
* The version that {@link #REMOTE_CLUSTER_CLIENT_ROLE} is introduced. Nodes before this version do not have that role even
* they can connect to remote clusters.
*/
public static final Version REMOTE_CLUSTER_CLIENT_ROLE_VERSION = LegacyESVersion.fromString("7.8.0");
static SortedSet LEGACY_ROLES = Collections.unmodifiableSortedSet(
new TreeSet<>(Arrays.asList(DATA_ROLE, INGEST_ROLE, MASTER_ROLE))
);
/**
* Represents an unknown role. This can occur if a newer version adds a role that an older version does not know about, or a newer
* version removes a role that an older version knows about.
*/
static class UnknownRole extends DiscoveryNodeRole {
/**
* Construct an unknown role with the specified role name and role name abbreviation.
*
* @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, final boolean canContainData) {
super(false, false, roleName, roleNameAbbreviation, canContainData);
}
@Override
public Setting legacySetting() {
// since this setting is not registered, it will always return false when testing if the local node has the role
assert false;
return Setting.boolSetting("node. " + roleName(), false, Setting.Property.NodeScope);
}
}
/**
* Represents a dynamic role. This can occur if a custom role that not in {@link DiscoveryNodeRole#BUILT_IN_ROLES} added for a node.
* Some plugin can support extension function with dynamic roles. For example, ML plugin may run machine learning tasks on nodes
* with "ml" dynamic role.
*/
static class DynamicRole extends DiscoveryNodeRole {
/**
* Construct a dynamic role with the specified role name and role name abbreviation.
*
* @param roleName the role name
* @param roleNameAbbreviation the role name abbreviation
* @param canContainData whether or not nodes with the role can contain data
*/
DynamicRole(final String roleName, final String roleNameAbbreviation, final boolean canContainData) {
super(false, true, roleName, roleNameAbbreviation, canContainData);
}
@Override
public Setting legacySetting() {
// return null as dynamic role has no legacy setting
return null;
}
}
/**
* Check if the role is {@link #CLUSTER_MANAGER_ROLE} or {@link #MASTER_ROLE}.
* @deprecated As of 2.0, because promoting inclusive language. MASTER_ROLE is deprecated.
* @return true if the node role is{@link #CLUSTER_MANAGER_ROLE} or {@link #MASTER_ROLE}
*/
@Deprecated
public boolean isClusterManager() {
return this.equals(DiscoveryNodeRole.CLUSTER_MANAGER_ROLE) || this.equals(DiscoveryNodeRole.MASTER_ROLE);
}
}