Fix parsing of missing watermark settings. (#18624)

* Fix parsing of missing watermark settings.

* Adding license header.
This commit is contained in:
Dennis Oelkers
2024-03-14 14:52:43 +01:00
committed by GitHub
parent e6df421cc9
commit e9783e4d88
2 changed files with 205 additions and 0 deletions

View File

@@ -162,11 +162,17 @@ public class ClusterAdapterOS2 implements ClusterAdapter {
var current = settings.get(firstKey).toJson();
for (String curKey : keyPath.subList(1, keyPath.size() - 1)) {
if (current == null) {
return null;
}
current = current.asJsonObject().get(curKey);
}
final var lastKey = keyPath.get(keyPath.size() - 1);
if (current == null) {
return null;
}
return current.asJsonObject().getString(lastKey, null);
}

View File

@@ -0,0 +1,199 @@
/*
* 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
* <http://www.mongodb.com/licensing/server-side-public-license>.
*/
package org.graylog.storage.opensearch2;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.joschi.jadconfig.util.Duration;
import jakarta.json.Json;
import org.graylog.shaded.opensearch2.org.opensearch.client.RestHighLevelClient;
import org.graylog2.indexer.cluster.ClusterAdapter;
import org.graylog2.indexer.cluster.health.ClusterAllocationDiskSettings;
import org.graylog2.indexer.cluster.health.ClusterAllocationDiskSettingsFactory;
import org.graylog2.shared.bindings.providers.ObjectMapperProvider;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.stubbing.OngoingStubbing;
import org.opensearch.client.RestClient;
import org.opensearch.client.json.JsonData;
import org.opensearch.client.opensearch.cluster.GetClusterSettingsResponse;
import java.io.IOException;
import java.util.Map;
import java.util.function.Function;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
class ClusterAdapterOS2Test {
private static final ObjectMapper objectMapper = new ObjectMapperProvider().get();
private static final Map<String, JsonData> ENABLED_RESPONSE = Map.of("cluster", m(
Map.of("routing",
Map.of("allocation",
Map.of("disk",
Map.of(
"threshold_enabled", "true",
"watermark", Map.of(
"flood_stage", "95%",
"high", "90%",
"low", "85%",
"enable_for_single_data_node", "false"
)
))))
));
private static final Map<String, JsonData> DISABLED_RESPONSE = Map.of("cluster", m(
Map.of("routing",
Map.of("allocation",
Map.of("disk",
Map.of(
"threshold_enabled", "false"
))))
));
public static final ClusterAllocationDiskSettings ENABLED_RESULT = ClusterAllocationDiskSettingsFactory.create(
true,
"85%",
"90%",
"95%"
);
public static final ClusterAllocationDiskSettings DISABLED_RESULT = ClusterAllocationDiskSettingsFactory.create(false, null, null, null);
private org.opensearch.client.opensearch.OpenSearchClient opensearchClient;
private ClusterAdapter clusterAdapter;
@BeforeEach
void setup() {
this.opensearchClient = mock(org.opensearch.client.opensearch.OpenSearchClient.class, RETURNS_DEEP_STUBS);
final var client = new OpenSearchClient(mock(RestHighLevelClient.class), opensearchClient, mock(RestClient.class), objectMapper);
this.clusterAdapter = new ClusterAdapterOS2(client, Duration.seconds(30), new PlainJsonApi(objectMapper, client));
}
@Test
void enabledWatermarkSettingsFromDefaults() throws IOException {
final var response = new GetClusterSettingsResponse.Builder()
.persistent(Map.of())
.transient_(Map.of())
.defaults(ENABLED_RESPONSE)
.build();
whenClusterSettings().thenReturn(response);
final var result = clusterAdapter.clusterAllocationDiskSettings();
assertThat(result).isEqualTo(ENABLED_RESULT);
}
@Test
void enabledWatermarkSettingsFromPersisted() throws IOException {
final var response = new GetClusterSettingsResponse.Builder()
.persistent(ENABLED_RESPONSE)
.transient_(Map.of())
.defaults(Map.of())
.build();
whenClusterSettings().thenReturn(response);
final var result = clusterAdapter.clusterAllocationDiskSettings();
assertThat(result).isEqualTo(ENABLED_RESULT);
}
@Test
void enabledWatermarkSettingsFromTransient() throws IOException {
final var response = new GetClusterSettingsResponse.Builder()
.persistent(Map.of())
.transient_(ENABLED_RESPONSE)
.defaults(Map.of())
.build();
whenClusterSettings().thenReturn(response);
final var result = clusterAdapter.clusterAllocationDiskSettings();
assertThat(result).isEqualTo(ENABLED_RESULT);
}
@Test
void disabledWatermarkSettingsFromDefaults() throws IOException {
final var response = new GetClusterSettingsResponse.Builder()
.persistent(Map.of())
.transient_(Map.of())
.defaults(DISABLED_RESPONSE)
.build();
whenClusterSettings().thenReturn(response);
final var result = clusterAdapter.clusterAllocationDiskSettings();
assertThat(result).isEqualTo(DISABLED_RESULT);
}
@Test
void disabledWatermarkSettingsFromPersisted() throws IOException {
final var response = new GetClusterSettingsResponse.Builder()
.persistent(DISABLED_RESPONSE)
.transient_(Map.of())
.defaults(Map.of())
.build();
whenClusterSettings().thenReturn(response);
final var result = clusterAdapter.clusterAllocationDiskSettings();
assertThat(result).isEqualTo(DISABLED_RESULT);
}
@Test
void disabledWatermarkSettingsFromTransient() throws IOException {
final var response = new GetClusterSettingsResponse.Builder()
.persistent(Map.of())
.transient_(DISABLED_RESPONSE)
.defaults(Map.of())
.build();
whenClusterSettings().thenReturn(response);
final var result = clusterAdapter.clusterAllocationDiskSettings();
assertThat(result).isEqualTo(DISABLED_RESULT);
}
@Test
void missingWatermarkSettings() throws IOException {
final var response = new GetClusterSettingsResponse.Builder()
.persistent(Map.of())
.transient_(Map.of())
.defaults(Map.of("cluster", JsonData.of(Json.createObjectBuilder(
Map.of("routing",
Map.of("allocation", Map.of()))).build()
)))
.build();
whenClusterSettings().thenReturn(response);
final var result = clusterAdapter.clusterAllocationDiskSettings();
assertThat(result).isEqualTo(DISABLED_RESULT);
}
private static JsonData m(Map<String, ?> response) {
return JsonData.of(Json.createObjectBuilder(response).build());
}
private OngoingStubbing<GetClusterSettingsResponse> whenClusterSettings() throws IOException {
return when(opensearchClient.cluster().getSettings(any(Function.class)));
}
}