diff --git a/changelog/unreleased/pr-19170.toml b/changelog/unreleased/pr-19170.toml new file mode 100644 index 0000000000..363a2e53c9 --- /dev/null +++ b/changelog/unreleased/pr-19170.toml @@ -0,0 +1,5 @@ +type = "fixed" +message = "Remove datanode leader flag. It's neither needed nor used." + +issues = ["18861"] +pulls = ["19170"] diff --git a/data-node/src/main/java/org/graylog/datanode/bindings/PeriodicalBindings.java b/data-node/src/main/java/org/graylog/datanode/bindings/PeriodicalBindings.java index 92cde4c866..84b8e00712 100644 --- a/data-node/src/main/java/org/graylog/datanode/bindings/PeriodicalBindings.java +++ b/data-node/src/main/java/org/graylog/datanode/bindings/PeriodicalBindings.java @@ -19,7 +19,6 @@ package org.graylog.datanode.bindings; import com.google.inject.AbstractModule; import com.google.inject.multibindings.Multibinder; import org.graylog.datanode.bootstrap.preflight.DataNodeConfigurationPeriodical; -import org.graylog.datanode.periodicals.ClusterManagerDiscovery; import org.graylog.datanode.periodicals.MetricsCollector; import org.graylog.datanode.periodicals.NodePingPeriodical; import org.graylog.datanode.periodicals.OpensearchNodeHeartbeat; @@ -34,7 +33,6 @@ public class PeriodicalBindings extends AbstractModule { periodicalBinder.addBinding().to(ClusterEventPeriodical.class); periodicalBinder.addBinding().to(ClusterEventCleanupPeriodical.class); periodicalBinder.addBinding().to(OpensearchNodeHeartbeat.class); - periodicalBinder.addBinding().to(ClusterManagerDiscovery.class); // periodicalBinder.addBinding().to(UserSessionTerminationPeriodical.class); periodicalBinder.addBinding().to(NodePingPeriodical.class); periodicalBinder.addBinding().to(DataNodeConfigurationPeriodical.class); diff --git a/data-node/src/main/java/org/graylog/datanode/commands/Server.java b/data-node/src/main/java/org/graylog/datanode/commands/Server.java index fe2635bf45..042e207640 100644 --- a/data-node/src/main/java/org/graylog/datanode/commands/Server.java +++ b/data-node/src/main/java/org/graylog/datanode/commands/Server.java @@ -139,7 +139,6 @@ public class Server extends ServerBootstrap { // always set leader to "false" on startup and let the NodePingPeriodical take care of it later nodeService.registerServer(DataNodeDto.Builder.builder() .setId(nodeId.getNodeId()) - .setLeader(false) .setTransportAddress(configuration.getHttpPublishUri().toString()) .setHostname(Tools.getLocalCanonicalHostname()) .setDataNodeStatus(DataNodeStatus.STARTING) diff --git a/data-node/src/main/java/org/graylog/datanode/opensearch/OpensearchInfo.java b/data-node/src/main/java/org/graylog/datanode/opensearch/OpensearchInfo.java index 275d973126..e9fdf14df9 100644 --- a/data-node/src/main/java/org/graylog/datanode/opensearch/OpensearchInfo.java +++ b/data-node/src/main/java/org/graylog/datanode/opensearch/OpensearchInfo.java @@ -19,6 +19,6 @@ package org.graylog.datanode.opensearch; import org.graylog.datanode.opensearch.statemachine.OpensearchState; import org.graylog.datanode.process.ProcessInformation; -public record OpensearchInfo(String nodeName, OpensearchState state, boolean isLeaderNode, String restBaseUrl, +public record OpensearchInfo(String nodeName, OpensearchState state, String restBaseUrl, ProcessInformation process) { } diff --git a/data-node/src/main/java/org/graylog/datanode/opensearch/OpensearchProcess.java b/data-node/src/main/java/org/graylog/datanode/opensearch/OpensearchProcess.java index 5430962103..8818633a98 100644 --- a/data-node/src/main/java/org/graylog/datanode/opensearch/OpensearchProcess.java +++ b/data-node/src/main/java/org/graylog/datanode/opensearch/OpensearchProcess.java @@ -34,9 +34,6 @@ public interface OpensearchProcess extends ManagableProcess restClient(); Optional openSearchClient(); - - boolean isLeaderNode(); - void setLeaderNode(boolean isManagerNode); List stdOutLogs(); List stdErrLogs(); diff --git a/data-node/src/main/java/org/graylog/datanode/opensearch/OpensearchProcessImpl.java b/data-node/src/main/java/org/graylog/datanode/opensearch/OpensearchProcessImpl.java index 89e0d369f8..8e75ea6fe4 100644 --- a/data-node/src/main/java/org/graylog/datanode/opensearch/OpensearchProcessImpl.java +++ b/data-node/src/main/java/org/graylog/datanode/opensearch/OpensearchProcessImpl.java @@ -70,7 +70,6 @@ class OpensearchProcessImpl implements OpensearchProcess, ProcessListener { private final DatanodeConfiguration datanodeConfiguration; - private boolean isLeaderNode; private OpensearchCommandLineProcess commandLineProcess; private final Queue stdout; @@ -116,7 +115,7 @@ class OpensearchProcessImpl implements OpensearchProcess, ProcessListener { } public OpensearchInfo processInfo() { - return new OpensearchInfo(configuration.getDatanodeNodeName(), processState.getState(), isLeaderNode, getOpensearchBaseUrl().toString(), commandLineProcess != null ? commandLineProcess.processInfo() : ProcessInformation.empty()); + return new OpensearchInfo(configuration.getDatanodeNodeName(), processState.getState(), getOpensearchBaseUrl().toString(), commandLineProcess != null ? commandLineProcess.processInfo() : ProcessInformation.empty()); } @Override @@ -156,15 +155,6 @@ class OpensearchProcessImpl implements OpensearchProcess, ProcessListener { this.processState.getTracerAggregator().addTracer((StateMachineTracer) stateMachineTracer); } - public void setLeaderNode(boolean isLeaderNode) { - this.isLeaderNode = isLeaderNode; - } - - @Override - public boolean isLeaderNode() { - return isLeaderNode; - } - public boolean isInState(OpensearchState expectedState) { return this.processState.getState().equals(expectedState); } diff --git a/data-node/src/main/java/org/graylog/datanode/periodicals/ClusterManagerDiscovery.java b/data-node/src/main/java/org/graylog/datanode/periodicals/ClusterManagerDiscovery.java deleted file mode 100644 index d95912db9d..0000000000 --- a/data-node/src/main/java/org/graylog/datanode/periodicals/ClusterManagerDiscovery.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2020 Graylog, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * . - */ -package org.graylog.datanode.periodicals; - -import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; -import org.graylog.datanode.Configuration; -import org.graylog.datanode.configuration.DatanodeConfiguration; -import org.graylog.datanode.opensearch.OpensearchProcess; -import org.graylog.datanode.opensearch.statemachine.OpensearchState; -import org.graylog.shaded.opensearch2.org.opensearch.client.Request; -import org.graylog.shaded.opensearch2.org.opensearch.client.Response; -import org.graylog.shaded.opensearch2.org.opensearch.client.RestHighLevelClient; -import org.graylog2.plugin.periodical.Periodical; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.Optional; - -@Singleton -public class ClusterManagerDiscovery extends Periodical { - - private static final Logger LOG = LoggerFactory.getLogger(ClusterManagerDiscovery.class); - private final DatanodeConfiguration datanodeConfiguration; - private final OpensearchProcess managedOpenSearch; - private final ObjectMapper objectMapper; - private final Configuration configuration; - - @Inject - public ClusterManagerDiscovery(DatanodeConfiguration datanodeConfiguration, OpensearchProcess managedOpenSearch, ObjectMapper objectMapper, Configuration configuration) { - this.datanodeConfiguration = datanodeConfiguration; - this.managedOpenSearch = managedOpenSearch; - this.objectMapper = objectMapper; - this.configuration = configuration; - } - - @Override - // This method is "synchronized" because we are also calling it directly in AutomaticLeaderElectionService - public synchronized void doRun() { - if (managedOpenSearch.isInState(OpensearchState.AVAILABLE)) { - final Boolean isManagerNode = getClusterStateResponse(managedOpenSearch) - .map(r -> r.nodes().get(r.clusterManagerNode())) - .map(managerNode -> configuration.getDatanodeNodeName().equals(managerNode.name())) - .orElse(false); - managedOpenSearch.setLeaderNode(isManagerNode); - } - } - - - private Optional getClusterStateResponse(OpensearchProcess process) { - return process.restClient().flatMap(this::requestClusterState); - } - - private Optional requestClusterState(RestHighLevelClient client) { - try { - final Response response = client.getLowLevelClient().performRequest(new Request("GET", "_cluster/state/")); - final ClusterStateResponse state = objectMapper.readValue(response.getEntity().getContent(), ClusterStateResponse.class); - return Optional.of(state); - } catch (IOException e) { - LOG.warn("Failed to obtain cluster state response", e); - return Optional.empty(); - } - } - - @Override - protected Logger getLogger() { - return LOG; - } - - @Override - public boolean runsForever() { - return false; - } - - @Override - public boolean stopOnGracefulShutdown() { - return false; - } - - @Override - public boolean leaderOnly() { - return false; - } - - @Override - public boolean startOnThisNode() { - return true; - } - - @Override - public boolean isDaemon() { - return true; - } - - @Override - public int getInitialDelaySeconds() { - return 0; - } - - @Override - public int getPeriodSeconds() { - return 10; - } -} diff --git a/data-node/src/main/java/org/graylog/datanode/periodicals/MetricsCollector.java b/data-node/src/main/java/org/graylog/datanode/periodicals/MetricsCollector.java index ff52bcf1d4..2dece553fc 100644 --- a/data-node/src/main/java/org/graylog/datanode/periodicals/MetricsCollector.java +++ b/data-node/src/main/java/org/graylog/datanode/periodicals/MetricsCollector.java @@ -21,9 +21,9 @@ import com.google.common.collect.ImmutableMap; import jakarta.annotation.Nonnull; import jakarta.inject.Inject; import org.graylog.datanode.Configuration; -import org.graylog.datanode.opensearch.OpensearchProcess; import org.graylog.datanode.metrics.ClusterStatMetricsCollector; import org.graylog.datanode.metrics.NodeMetricsCollector; +import org.graylog.datanode.opensearch.OpensearchProcess; import org.graylog.datanode.opensearch.statemachine.OpensearchState; import org.graylog.shaded.opensearch2.org.joda.time.DateTime; import org.graylog.shaded.opensearch2.org.joda.time.DateTimeZone; @@ -31,7 +31,9 @@ import org.graylog.shaded.opensearch2.org.opensearch.action.index.IndexRequest; import org.graylog.shaded.opensearch2.org.opensearch.action.index.IndexResponse; import org.graylog.shaded.opensearch2.org.opensearch.action.search.SearchRequest; import org.graylog.shaded.opensearch2.org.opensearch.action.search.SearchResponse; +import org.graylog.shaded.opensearch2.org.opensearch.client.Request; import org.graylog.shaded.opensearch2.org.opensearch.client.RequestOptions; +import org.graylog.shaded.opensearch2.org.opensearch.client.Response; import org.graylog.shaded.opensearch2.org.opensearch.client.RestHighLevelClient; import org.graylog.shaded.opensearch2.org.opensearch.core.action.ActionListener; import org.graylog.shaded.opensearch2.org.opensearch.index.query.QueryBuilders; @@ -50,6 +52,7 @@ import java.lang.management.MemoryUsage; import java.util.HashMap; import java.util.Map; import java.util.Objects; +import java.util.Optional; public class MetricsCollector extends Periodical { @@ -59,7 +62,6 @@ public class MetricsCollector extends Periodical { private NodeMetricsCollector nodeStatMetricsCollector; private ClusterStatMetricsCollector clusterStatMetricsCollector; private final ObjectMapper objectMapper; - private boolean isLeader; @Inject public MetricsCollector(OpensearchProcess process, Configuration configuration, ObjectMapper objectMapper) { @@ -110,8 +112,6 @@ public class MetricsCollector extends Periodical { process.restClient().ifPresent(client -> { this.nodeStatMetricsCollector = new NodeMetricsCollector(client, objectMapper); this.clusterStatMetricsCollector = new ClusterStatMetricsCollector(client, objectMapper); - this.isLeader = process.isLeaderNode(); - final IndexRequest indexRequest = new IndexRequest(configuration.getMetricsStream()); Map metrics = new HashMap(); metrics.put(configuration.getMetricsTimestamp(), new DateTime(DateTimeZone.UTC)); @@ -122,17 +122,36 @@ public class MetricsCollector extends Periodical { indexRequest.source(metrics); indexDocument(client, indexRequest); - if (isLeader) { + if (isManagerNode(process)) { metrics = new HashMap<>(clusterStatMetricsCollector.getClusterMetrics(getPreviousMetricsForCluster(client))); metrics.put(configuration.getMetricsTimestamp(), new DateTime(DateTimeZone.UTC)); indexRequest.source(metrics); indexDocument(client, indexRequest); } - }); } } + public boolean isManagerNode(OpensearchProcess process) { + return process.restClient() + .flatMap(this::requestClusterState) + .map(r -> r.nodes().get(r.clusterManagerNode())) + .map(managerNode -> configuration.getDatanodeNodeName().equals(managerNode.name())) + .orElse(false); + } + + + private Optional requestClusterState(RestHighLevelClient client) { + try { + final Response response = client.getLowLevelClient().performRequest(new Request("GET", "_cluster/state/")); + final ClusterStateResponse state = objectMapper.readValue(response.getEntity().getContent(), ClusterStateResponse.class); + return Optional.of(state); + } catch (IOException e) { + LOG.warn("Failed to obtain cluster state response", e); + return Optional.empty(); + } + } + private void addJvmMetrics(Map metrics) { MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean(); metrics.put("dn_heap_usage", calcUsage(memoryMXBean.getHeapMemoryUsage())); diff --git a/data-node/src/main/java/org/graylog/datanode/periodicals/NodePingPeriodical.java b/data-node/src/main/java/org/graylog/datanode/periodicals/NodePingPeriodical.java index 9a43082aee..b72ae8dbf3 100644 --- a/data-node/src/main/java/org/graylog/datanode/periodicals/NodePingPeriodical.java +++ b/data-node/src/main/java/org/graylog/datanode/periodicals/NodePingPeriodical.java @@ -40,7 +40,6 @@ public class NodePingPeriodical extends Periodical { private final Supplier opensearchBaseUri; private final Supplier opensearchClusterUri; private final Supplier datanodeRestApiUri; - private final Supplier isLeader; private final Configuration configuration; private final Supplier processState; @@ -54,7 +53,6 @@ public class NodePingPeriodical extends Periodical { managedOpenSearch::getOpensearchBaseUrl, managedOpenSearch::getOpensearchClusterUrl, managedOpenSearch::getDatanodeRestApiUrl, - managedOpenSearch::isLeaderNode, () -> managedOpenSearch.processInfo().state() ); } @@ -66,7 +64,6 @@ public class NodePingPeriodical extends Periodical { Supplier opensearchBaseUri, Supplier opensearchClusterUri, Supplier datanodeRestApiUri, - Supplier isLeader, Supplier processState ) { this.nodeService = nodeService; @@ -74,7 +71,6 @@ public class NodePingPeriodical extends Periodical { this.opensearchBaseUri = opensearchBaseUri; this.opensearchClusterUri = opensearchClusterUri; this.datanodeRestApiUri = datanodeRestApiUri; - this.isLeader = isLeader; this.configuration = configuration; this.processState = processState; } @@ -124,7 +120,6 @@ public class NodePingPeriodical extends Periodical { public void doRun() { final DataNodeDto dto = DataNodeDto.Builder.builder() .setId(nodeId.getNodeId()) - .setLeader(isLeader.get()) .setTransportAddress(opensearchBaseUri.get().toString()) .setClusterAddress(opensearchClusterUri.get()) .setDataNodeStatus(processState.get().getDataNodeStatus()) @@ -139,7 +134,6 @@ public class NodePingPeriodical extends Periodical { private void registerServer() { final boolean registrationSucceeded = nodeService.registerServer(DataNodeDto.Builder.builder() .setId(nodeId.getNodeId()) - .setLeader(isLeader.get()) .setTransportAddress(opensearchBaseUri.get().toString()) .setClusterAddress(opensearchClusterUri.get()) .setHostname(configuration.getHostname()) diff --git a/data-node/src/test/java/org/graylog/datanode/periodicals/NodePingPeriodicalTest.java b/data-node/src/test/java/org/graylog/datanode/periodicals/NodePingPeriodicalTest.java index 5077b52695..eeb52cc135 100644 --- a/data-node/src/test/java/org/graylog/datanode/periodicals/NodePingPeriodicalTest.java +++ b/data-node/src/test/java/org/graylog/datanode/periodicals/NodePingPeriodicalTest.java @@ -30,7 +30,7 @@ import java.net.URI; class NodePingPeriodicalTest { @Test - void doRun() throws NodeNotFoundException { + void doRun() { final SimpleNodeId nodeID = new SimpleNodeId("5ca1ab1e-0000-4000-a000-000000000000"); final URI uri = URI.create("http://localhost:9200"); @@ -49,7 +49,6 @@ class NodePingPeriodicalTest { () -> uri, () -> cluster, () -> datanodeRestApi, - () -> true, () -> OpensearchState.AVAILABLE ); @@ -57,7 +56,6 @@ class NodePingPeriodicalTest { Mockito.verify(nodeService).ping(Mockito.eq(DataNodeDto.Builder.builder() .setId(nodeID.getNodeId()) - .setLeader(true) .setTransportAddress(uri.toString()) .setClusterAddress(cluster) .setRestApiAddress(datanodeRestApi) diff --git a/full-backend-tests/src/test/java/org/graylog/datanode/DatanodeOpensearchProxyIT.java b/full-backend-tests/src/test/java/org/graylog/datanode/DatanodeOpensearchProxyIT.java index 21c48272cc..4f206102b8 100644 --- a/full-backend-tests/src/test/java/org/graylog/datanode/DatanodeOpensearchProxyIT.java +++ b/full-backend-tests/src/test/java/org/graylog/datanode/DatanodeOpensearchProxyIT.java @@ -44,8 +44,7 @@ public class DatanodeOpensearchProxyIT { @ContainerMatrixTest void testProxyPlaintextGet() throws ExecutionException, RetryException { - apis.datanodeProxy().waitForLeader(); - final ValidatableResponse response = apis.get("/datanodes/leader/opensearch/_cat/indices", 200); + final ValidatableResponse response = apis.get("/datanodes/any/opensearch/_cat/indices", 200); final String responseBody = response.extract().body().asString(); Assertions.assertThat(responseBody).contains(".ds-gl-datanode-metrics").contains("graylog_0").contains("gl-system-events_0"); } diff --git a/graylog2-server/src/main/java/org/graylog2/cluster/nodes/DataNodeDto.java b/graylog2-server/src/main/java/org/graylog2/cluster/nodes/DataNodeDto.java index 106016e21f..6dbf21b601 100644 --- a/graylog2-server/src/main/java/org/graylog2/cluster/nodes/DataNodeDto.java +++ b/graylog2-server/src/main/java/org/graylog2/cluster/nodes/DataNodeDto.java @@ -85,7 +85,8 @@ public abstract class DataNodeDto extends NodeDto { @JsonCreator public static Builder builder() { - return new AutoValue_DataNodeDto.Builder(); + return new AutoValue_DataNodeDto.Builder() + .setLeader(false); // TODO: completely remove the leader property from this DTO } @JsonProperty("cluster_address") diff --git a/graylog2-server/src/main/java/org/graylog2/cluster/nodes/ServerNodeDto.java b/graylog2-server/src/main/java/org/graylog2/cluster/nodes/ServerNodeDto.java index 050857d14c..63404beb86 100644 --- a/graylog2-server/src/main/java/org/graylog2/cluster/nodes/ServerNodeDto.java +++ b/graylog2-server/src/main/java/org/graylog2/cluster/nodes/ServerNodeDto.java @@ -18,6 +18,7 @@ package org.graylog2.cluster.nodes; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.google.auto.value.AutoValue; @@ -42,5 +43,4 @@ public abstract class ServerNodeDto extends NodeDto { public abstract ServerNodeDto build(); } - } diff --git a/graylog2-server/src/main/java/org/graylog2/rest/resources/datanodes/DatanodeResolver.java b/graylog2-server/src/main/java/org/graylog2/rest/resources/datanodes/DatanodeResolver.java index 3934d8c2e7..285ef5d8e4 100644 --- a/graylog2-server/src/main/java/org/graylog2/rest/resources/datanodes/DatanodeResolver.java +++ b/graylog2-server/src/main/java/org/graylog2/rest/resources/datanodes/DatanodeResolver.java @@ -19,8 +19,9 @@ package org.graylog2.rest.resources.datanodes; import jakarta.inject.Inject; import jakarta.inject.Singleton; import org.graylog2.cluster.nodes.DataNodeDto; -import org.graylog2.cluster.nodes.NodeDto; import org.graylog2.cluster.nodes.NodeService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.Collection; import java.util.Locale; @@ -30,6 +31,8 @@ import java.util.Optional; @Singleton public class DatanodeResolver { + private static final Logger LOG = LoggerFactory.getLogger(DatanodeResolver.class); + public static final String LEADER_KEYWORD = "leader"; public static final String ANY_NODE_KEYWORD = "any"; public static final String ALL_NODES_KEYWORD = "all"; @@ -50,7 +53,8 @@ public class DatanodeResolver { private Optional findByKeyword(Collection datanodes, String hostname) { if (hostname != null && hostname.trim().toLowerCase(Locale.ROOT).equals(LEADER_KEYWORD)) { - return datanodes.stream().filter(NodeDto::isLeader).findFirst(); + LOG.warn("Leader keyword not supported as datanode selector. Please use any or an actual hostname as selector. Falling back to any datanode."); + return findByKeyword(datanodes, "any"); } else if (hostname != null && hostname.trim().toLowerCase(Locale.ROOT).equals(ANY_NODE_KEYWORD)) { return datanodes.stream().findFirst(); } else { diff --git a/graylog2-server/src/test/java/org/graylog/testing/completebackend/apis/DatanodeProxy.java b/graylog2-server/src/test/java/org/graylog/testing/completebackend/apis/DatanodeProxy.java deleted file mode 100644 index c4ec6aa0c8..0000000000 --- a/graylog2-server/src/test/java/org/graylog/testing/completebackend/apis/DatanodeProxy.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2020 Graylog, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * . - */ -package org.graylog.testing.completebackend.apis; - -import com.github.rholder.retry.Attempt; -import com.github.rholder.retry.RetryException; -import com.github.rholder.retry.RetryListener; -import com.github.rholder.retry.RetryerBuilder; -import com.github.rholder.retry.StopStrategies; -import com.github.rholder.retry.WaitStrategies; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; - -public class DatanodeProxy { - - private static final Logger LOG = LoggerFactory.getLogger(DatanodeProxy.class); - private final GraylogApis graylogApis; - - public DatanodeProxy(GraylogApis graylogApis) { - this.graylogApis = graylogApis; - } - - /** - * A datanode becomes leader if the underlying opensearch node becomes leader. This may take a while during the - * startup. Our periodical checks the leader status every 10s, so in this interval there should appear one leader - * for sure. - */ - public void waitForLeader() throws ExecutionException, RetryException { - RetryerBuilder.newBuilder() - .retryIfResult(r -> !isAnyLeader(r)) - .withRetryListener(new RetryListener() { - @Override - public void onRetry(Attempt attempt) { - LOG.info("Waiting for one datanode to become leader, attempt {}", attempt.getAttemptNumber()); - } - }) - .withWaitStrategy(WaitStrategies.fixedWait(1, TimeUnit.SECONDS)) - .withStopStrategy(StopStrategies.stopAfterAttempt(60)) - .build() - .call(() -> graylogApis.system().datanodes()); - } - - private boolean isAnyLeader(GraylogApiResponse r) { - List isLeader = r.properJSONPath().read("elements.*.is_leader"); - return isLeader.stream().anyMatch(leader -> leader); - } -} diff --git a/graylog2-server/src/test/java/org/graylog/testing/completebackend/apis/GraylogApis.java b/graylog2-server/src/test/java/org/graylog/testing/completebackend/apis/GraylogApis.java index 1b9f4f0ec5..f7c9661cf4 100644 --- a/graylog2-server/src/test/java/org/graylog/testing/completebackend/apis/GraylogApis.java +++ b/graylog2-server/src/test/java/org/graylog/testing/completebackend/apis/GraylogApis.java @@ -53,7 +53,6 @@ public class GraylogApis implements GraylogRestApi { private final SystemApi system; private final EventNotifications eventNotifications; private final EventDefinitions eventDefinitions; - private final DatanodeProxy datanodeProxy; public GraylogApis(GraylogBackend backend) { this.backend = backend; @@ -68,7 +67,6 @@ public class GraylogApis implements GraylogRestApi { this.system = new SystemApi(this); this.eventNotifications = new EventNotifications(this); this.eventDefinitions = new EventDefinitions(this); - this.datanodeProxy = new DatanodeProxy(this); } public RequestSpecification requestSpecification() { @@ -134,10 +132,6 @@ public class GraylogApis implements GraylogRestApi { return eventDefinitions; } - public DatanodeProxy datanodeProxy() { - return datanodeProxy; - } - protected RequestSpecification prefix(final Users.User user) { return given() .config(withGraylogBackendFailureConfig())