diff --git a/legacy/src/main/java/org/opensearch/sql/legacy/plugin/OpenSearchSQLPluginConfig.java b/legacy/src/main/java/org/opensearch/sql/legacy/plugin/OpenSearchSQLPluginConfig.java index 91b3a58925..b396d896b0 100644 --- a/legacy/src/main/java/org/opensearch/sql/legacy/plugin/OpenSearchSQLPluginConfig.java +++ b/legacy/src/main/java/org/opensearch/sql/legacy/plugin/OpenSearchSQLPluginConfig.java @@ -7,7 +7,6 @@ package org.opensearch.sql.legacy.plugin; import org.opensearch.client.node.NodeClient; -import org.opensearch.cluster.service.ClusterService; import org.opensearch.sql.common.setting.Settings; import org.opensearch.sql.executor.ExecutionEngine; import org.opensearch.sql.expression.config.ExpressionConfig; @@ -34,8 +33,6 @@ @Configuration @Import({ExpressionConfig.class}) public class OpenSearchSQLPluginConfig { - @Autowired - private ClusterService clusterService; @Autowired private NodeClient nodeClient; @@ -48,7 +45,7 @@ public class OpenSearchSQLPluginConfig { @Bean public OpenSearchClient client() { - return new OpenSearchNodeClient(clusterService, nodeClient); + return new OpenSearchNodeClient(nodeClient); } @Bean diff --git a/opensearch/src/main/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClient.java b/opensearch/src/main/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClient.java index db35f3580c..80a2fb8604 100644 --- a/opensearch/src/main/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClient.java +++ b/opensearch/src/main/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClient.java @@ -9,7 +9,7 @@ import com.carrotsearch.hppc.cursors.ObjectObjectCursor; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import java.io.IOException; +import com.google.common.collect.Streams; import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -18,24 +18,17 @@ import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.apache.logging.log4j.ThreadContext; import org.opensearch.action.admin.indices.get.GetIndexResponse; -import org.opensearch.action.support.IndicesOptions; +import org.opensearch.action.admin.indices.mapping.get.GetMappingsResponse; +import org.opensearch.action.admin.indices.settings.get.GetSettingsResponse; import org.opensearch.client.node.NodeClient; -import org.opensearch.cluster.ClusterState; import org.opensearch.cluster.metadata.AliasMetadata; -import org.opensearch.cluster.metadata.IndexMetadata; import org.opensearch.cluster.metadata.IndexNameExpressionResolver; -import org.opensearch.cluster.metadata.MappingMetadata; -import org.opensearch.cluster.service.ClusterService; -import org.opensearch.common.collect.ImmutableOpenMap; import org.opensearch.common.settings.Settings; -import org.opensearch.common.unit.TimeValue; import org.opensearch.index.IndexSettings; import org.opensearch.sql.opensearch.mapping.IndexMapping; import org.opensearch.sql.opensearch.request.OpenSearchRequest; import org.opensearch.sql.opensearch.response.OpenSearchResponse; -import org.opensearch.threadpool.ThreadPool; /** OpenSearch connection by node client. */ public class OpenSearchNodeClient implements OpenSearchClient { @@ -43,23 +36,16 @@ public class OpenSearchNodeClient implements OpenSearchClient { public static final Function> ALL_FIELDS = (anyIndex -> (anyField -> true)); - /** Current cluster state on local node. */ - private final ClusterService clusterService; - /** Node client provided by OpenSearch container. */ private final NodeClient client; /** Index name expression resolver to get concrete index name. */ private final IndexNameExpressionResolver resolver; - private static final String SQL_WORKER_THREAD_POOL_NAME = "sql-worker"; - /** * Constructor of ElasticsearchNodeClient. */ - public OpenSearchNodeClient(ClusterService clusterService, - NodeClient client) { - this.clusterService = clusterService; + public OpenSearchNodeClient(NodeClient client) { this.client = client; this.resolver = new IndexNameExpressionResolver(client.threadPool().getThreadContext()); } @@ -78,14 +64,16 @@ public OpenSearchNodeClient(ClusterService clusterService, @Override public Map getIndexMappings(String... indexExpression) { try { - ClusterState state = clusterService.state(); - String[] concreteIndices = resolveIndexExpression(state, indexExpression); - - return populateIndexMappings( - state.metadata().findMappings(concreteIndices, ALL_FIELDS)); - } catch (IOException e) { + GetMappingsResponse mappingsResponse = client.admin().indices() + .prepareGetMappings(indexExpression) + .setLocal(true) + .get(); + return Streams.stream(mappingsResponse.mappings().iterator()) + .collect(Collectors.toMap(cursor -> cursor.key, + cursor -> new IndexMapping(cursor.value))); + } catch (Exception e) { throw new IllegalStateException( - "Failed to read mapping in cluster state for index pattern [" + indexExpression + "]", e); + "Failed to read mapping for index pattern [" + indexExpression + "]", e); } } @@ -97,19 +85,24 @@ public Map getIndexMappings(String... indexExpression) { */ @Override public Map getIndexMaxResultWindows(String... indexExpression) { - ClusterState state = clusterService.state(); - ImmutableOpenMap indicesMetadata = state.metadata().getIndices(); - String[] concreteIndices = resolveIndexExpression(state, indexExpression); - - ImmutableMap.Builder result = ImmutableMap.builder(); - for (String index : concreteIndices) { - Settings settings = indicesMetadata.get(index).getSettings(); - Integer maxResultWindow = settings.getAsInt("index.max_result_window", - IndexSettings.MAX_RESULT_WINDOW_SETTING.getDefault(settings)); - result.put(index, maxResultWindow); + try { + GetSettingsResponse settingsResponse = + client.admin().indices().prepareGetSettings(indexExpression).setLocal(true).get(); + ImmutableMap.Builder result = ImmutableMap.builder(); + for (ObjectObjectCursor indexToSetting : + settingsResponse.getIndexToSettings()) { + Settings settings = indexToSetting.value; + result.put( + indexToSetting.key, + settings.getAsInt( + IndexSettings.MAX_RESULT_WINDOW_SETTING.getKey(), + IndexSettings.MAX_RESULT_WINDOW_SETTING.getDefault(settings))); + } + return result.build(); + } catch (Exception e) { + throw new IllegalStateException( + "Failed to read setting for index pattern [" + indexExpression + "]", e); } - - return result.build(); } /** @@ -149,9 +142,8 @@ public List indices() { */ @Override public Map meta() { - final ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); - builder.put(META_CLUSTER_NAME, clusterService.getClusterName().value()); - return builder.build(); + return ImmutableMap.of(META_CLUSTER_NAME, + client.settings().get("cluster.name", "opensearch")); } @Override @@ -161,40 +153,12 @@ public void cleanup(OpenSearchRequest request) { @Override public void schedule(Runnable task) { - ThreadPool threadPool = client.threadPool(); - threadPool.schedule( - withCurrentContext(task), - new TimeValue(0), - SQL_WORKER_THREAD_POOL_NAME - ); + // at that time, task already running the sql-worker ThreadPool. + task.run(); } @Override public NodeClient getNodeClient() { return client; } - - private String[] resolveIndexExpression(ClusterState state, String[] indices) { - return resolver.concreteIndexNames(state, IndicesOptions.strictExpandOpen(), true, indices); - } - - private Map populateIndexMappings( - ImmutableOpenMap indexMappings) { - - ImmutableMap.Builder result = ImmutableMap.builder(); - for (ObjectObjectCursor cursor: - indexMappings) { - result.put(cursor.key, new IndexMapping(cursor.value)); - } - return result.build(); - } - - /** Copy from LogUtils. */ - private static Runnable withCurrentContext(final Runnable task) { - final Map currentContext = ThreadContext.getImmutableContext(); - return () -> { - ThreadContext.putAll(currentContext); - task.run(); - }; - } } diff --git a/opensearch/src/test/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClientTest.java b/opensearch/src/test/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClientTest.java index 8fdb93427b..ad26d792ed 100644 --- a/opensearch/src/test/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClientTest.java +++ b/opensearch/src/test/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClientTest.java @@ -12,8 +12,9 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Answers.RETURNS_DEEP_STUBS; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.any; -import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -22,12 +23,10 @@ import com.google.common.base.Charsets; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSortedMap; import com.google.common.io.Resources; import java.io.IOException; import java.net.URL; import java.util.Arrays; -import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -40,24 +39,21 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.opensearch.action.admin.indices.get.GetIndexResponse; +import org.opensearch.action.admin.indices.mapping.get.GetMappingsResponse; +import org.opensearch.action.admin.indices.settings.get.GetSettingsResponse; import org.opensearch.action.search.ClearScrollRequestBuilder; import org.opensearch.action.search.SearchResponse; import org.opensearch.client.node.NodeClient; -import org.opensearch.cluster.ClusterName; -import org.opensearch.cluster.ClusterState; import org.opensearch.cluster.metadata.AliasMetadata; -import org.opensearch.cluster.metadata.IndexAbstraction; import org.opensearch.cluster.metadata.IndexMetadata; import org.opensearch.cluster.metadata.MappingMetadata; -import org.opensearch.cluster.metadata.Metadata; -import org.opensearch.cluster.service.ClusterService; import org.opensearch.common.collect.ImmutableOpenMap; +import org.opensearch.common.settings.Settings; import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.common.xcontent.DeprecationHandler; import org.opensearch.common.xcontent.NamedXContentRegistry; import org.opensearch.common.xcontent.XContentParser; import org.opensearch.common.xcontent.XContentType; -import org.opensearch.index.IndexNotFoundException; import org.opensearch.search.SearchHit; import org.opensearch.search.SearchHits; import org.opensearch.sql.data.model.ExprIntegerValue; @@ -67,7 +63,6 @@ import org.opensearch.sql.opensearch.mapping.IndexMapping; import org.opensearch.sql.opensearch.request.OpenSearchScrollRequest; import org.opensearch.sql.opensearch.response.OpenSearchResponse; -import org.opensearch.threadpool.ThreadPool; @ExtendWith(MockitoExtension.class) class OpenSearchNodeClientTest { @@ -139,8 +134,8 @@ public void getIndexMappingsWithEmptyMapping() { @Test public void getIndexMappingsWithIOException() { String indexName = "test"; - ClusterService clusterService = mockClusterService(indexName, new IOException()); - OpenSearchNodeClient client = new OpenSearchNodeClient(clusterService, nodeClient); + when(nodeClient.admin().indices()).thenThrow(RuntimeException.class); + OpenSearchNodeClient client = new OpenSearchNodeClient(nodeClient); assertThrows(IllegalStateException.class, () -> client.getIndexMappings(indexName)); } @@ -148,18 +143,17 @@ public void getIndexMappingsWithIOException() { @Test public void getIndexMappingsWithNonExistIndex() { OpenSearchNodeClient client = - new OpenSearchNodeClient(mockClusterService("test"), nodeClient); - - assertThrows(IndexNotFoundException.class, () -> client.getIndexMappings("non_exist_index")); + new OpenSearchNodeClient(mockNodeClient("test")); + assertTrue(client.getIndexMappings("non_exist_index").isEmpty()); } @Test public void getIndexMaxResultWindows() throws IOException { URL url = Resources.getResource(TEST_MAPPING_SETTINGS_FILE); - String mappings = Resources.toString(url, Charsets.UTF_8); + String indexMetadata = Resources.toString(url, Charsets.UTF_8); String indexName = "accounts"; - ClusterService clusterService = mockClusterServiceForSettings(indexName, mappings); - OpenSearchNodeClient client = new OpenSearchNodeClient(clusterService, nodeClient); + OpenSearchNodeClient client = + new OpenSearchNodeClient(mockNodeClientSettings(indexName, indexMetadata)); Map indexMaxResultWindows = client.getIndexMaxResultWindows(indexName); assertEquals(1, indexMaxResultWindows.size()); @@ -171,10 +165,10 @@ public void getIndexMaxResultWindows() throws IOException { @Test public void getIndexMaxResultWindowsWithDefaultSettings() throws IOException { URL url = Resources.getResource(TEST_MAPPING_FILE); - String mappings = Resources.toString(url, Charsets.UTF_8); + String indexMetadata = Resources.toString(url, Charsets.UTF_8); String indexName = "accounts"; - ClusterService clusterService = mockClusterServiceForSettings(indexName, mappings); - OpenSearchNodeClient client = new OpenSearchNodeClient(clusterService, nodeClient); + OpenSearchNodeClient client = + new OpenSearchNodeClient(mockNodeClientSettings(indexName, indexMetadata)); Map indexMaxResultWindows = client.getIndexMaxResultWindows(indexName); assertEquals(1, indexMaxResultWindows.size()); @@ -183,6 +177,15 @@ public void getIndexMaxResultWindowsWithDefaultSettings() throws IOException { assertEquals(10000, indexMaxResultWindow); } + @Test + public void getIndexMaxResultWindowsWithIOException() { + String indexName = "test"; + when(nodeClient.admin().indices()).thenThrow(RuntimeException.class); + OpenSearchNodeClient client = new OpenSearchNodeClient(nodeClient); + + assertThrows(IllegalStateException.class, () -> client.getIndexMaxResultWindows(indexName)); + } + /** Jacoco enforce this constant lambda be tested. */ @Test public void testAllFieldsPredicate() { @@ -192,7 +195,7 @@ public void testAllFieldsPredicate() { @Test public void search() { OpenSearchNodeClient client = - new OpenSearchNodeClient(mock(ClusterService.class), nodeClient); + new OpenSearchNodeClient(nodeClient); // Mock first scroll request SearchResponse searchResponse = mock(SearchResponse.class); @@ -230,23 +233,12 @@ public void search() { @Test void schedule() { - ThreadPool threadPool = mock(ThreadPool.class); - when(nodeClient.threadPool()).thenReturn(threadPool); - when(threadPool.getThreadContext()).thenReturn(threadContext); - - doAnswer( - invocation -> { - Runnable task = invocation.getArgument(0); - task.run(); - return null; - }) - .when(threadPool) - .schedule(any(), any(), any()); - - OpenSearchNodeClient client = - new OpenSearchNodeClient(mock(ClusterService.class), nodeClient); + OpenSearchNodeClient client = new OpenSearchNodeClient(nodeClient); AtomicBoolean isRun = new AtomicBoolean(false); - client.schedule(() -> isRun.set(true)); + client.schedule( + () -> { + isRun.set(true); + }); assertTrue(isRun.get()); } @@ -257,8 +249,7 @@ void cleanup() { when(requestBuilder.addScrollId(any())).thenReturn(requestBuilder); when(requestBuilder.get()).thenReturn(null); - OpenSearchNodeClient client = - new OpenSearchNodeClient(mock(ClusterService.class), nodeClient); + OpenSearchNodeClient client = new OpenSearchNodeClient(nodeClient); OpenSearchScrollRequest request = new OpenSearchScrollRequest("test", factory); request.setScrollId("scroll123"); client.cleanup(request); @@ -272,8 +263,7 @@ void cleanup() { @Test void cleanupWithoutScrollId() { - OpenSearchNodeClient client = - new OpenSearchNodeClient(mock(ClusterService.class), nodeClient); + OpenSearchNodeClient client = new OpenSearchNodeClient(nodeClient); OpenSearchScrollRequest request = new OpenSearchScrollRequest("test", factory); client.cleanup(request); @@ -294,122 +284,80 @@ void getIndices() { when(indexResponse.getIndices()).thenReturn(new String[] {"index"}); when(indexResponse.aliases()).thenReturn(openMap); - OpenSearchNodeClient client = - new OpenSearchNodeClient(mock(ClusterService.class), nodeClient); + OpenSearchNodeClient client = new OpenSearchNodeClient(nodeClient); final List indices = client.indices(); assertEquals(2, indices.size()); } @Test void meta() { - ClusterName clusterName = mock(ClusterName.class); - ClusterService mockService = mock(ClusterService.class); - when(clusterName.value()).thenReturn("cluster-name"); - when(mockService.getClusterName()).thenReturn(clusterName); + Settings settings = mock(Settings.class); + when(nodeClient.settings()).thenReturn(settings); + when(settings.get(anyString(), anyString())).thenReturn("cluster-name"); - OpenSearchNodeClient client = - new OpenSearchNodeClient(mockService, nodeClient); + OpenSearchNodeClient client = new OpenSearchNodeClient(nodeClient); final Map meta = client.meta(); assertEquals("cluster-name", meta.get(META_CLUSTER_NAME)); } @Test void ml() { - OpenSearchNodeClient client = new OpenSearchNodeClient(mock(ClusterService.class), nodeClient); + OpenSearchNodeClient client = new OpenSearchNodeClient(nodeClient); assertNotNull(client.getNodeClient()); } private OpenSearchNodeClient mockClient(String indexName, String mappings) { - ClusterService clusterService = mockClusterService(indexName, mappings); - return new OpenSearchNodeClient(clusterService, nodeClient); + mockNodeClientIndicesMappings(indexName, mappings); + return new OpenSearchNodeClient(nodeClient); } - /** Mock getAliasAndIndexLookup() only for index name resolve test. */ - public ClusterService mockClusterService(String indexName) { - ClusterService mockService = mock(ClusterService.class); - ClusterState mockState = mock(ClusterState.class); - Metadata mockMetaData = mock(Metadata.class); - - when(mockService.state()).thenReturn(mockState); - when(mockState.metadata()).thenReturn(mockMetaData); - when(mockMetaData.getIndicesLookup()) - .thenReturn(ImmutableSortedMap.of(indexName, mock(IndexAbstraction.class))); - return mockService; - } - - public ClusterService mockClusterService(String indexName, String mappings) { - ClusterService mockService = mock(ClusterService.class); - ClusterState mockState = mock(ClusterState.class); - Metadata mockMetaData = mock(Metadata.class); - - when(mockService.state()).thenReturn(mockState); - when(mockState.metadata()).thenReturn(mockMetaData); + public void mockNodeClientIndicesMappings(String indexName, String mappings) { + GetMappingsResponse mockResponse = mock(GetMappingsResponse.class); + MappingMetadata emptyMapping = mock(MappingMetadata.class); + when(nodeClient.admin().indices() + .prepareGetMappings(any()) + .setLocal(anyBoolean()) + .get()).thenReturn(mockResponse); try { - ImmutableOpenMap.Builder builder = - ImmutableOpenMap.builder(); - MappingMetadata metadata; + ImmutableOpenMap metadata; if (mappings.isEmpty()) { - metadata = MappingMetadata.EMPTY_MAPPINGS; + when(emptyMapping.getSourceAsMap()).thenReturn(ImmutableMap.of()); + metadata = + new ImmutableOpenMap.Builder() + .fPut(indexName, emptyMapping) + .build(); } else { - metadata = IndexMetadata.fromXContent(createParser(mappings)).mapping(); + metadata = new ImmutableOpenMap.Builder().fPut(indexName, + IndexMetadata.fromXContent(createParser(mappings)).mapping()).build(); } - - - builder.put(indexName, metadata); - when(mockMetaData.findMappings(any(), any())).thenReturn(builder.build()); - - // IndexNameExpressionResolver use this method to check if index exists. If not, - // IndexNotFoundException is thrown. - when(mockMetaData.getIndicesLookup()) - .thenReturn(ImmutableSortedMap.of(indexName, mock(IndexAbstraction.class))); + when(mockResponse.mappings()).thenReturn(metadata); } catch (IOException e) { - throw new IllegalStateException("Failed to mock cluster service", e); + throw new IllegalStateException("Failed to mock node client", e); } - return mockService; } - public ClusterService mockClusterService(String indexName, Throwable t) { - ClusterService mockService = mock(ClusterService.class); - ClusterState mockState = mock(ClusterState.class); - Metadata mockMetaData = mock(Metadata.class); - - when(mockService.state()).thenReturn(mockState); - when(mockState.metadata()).thenReturn(mockMetaData); - try { - when(mockMetaData.findMappings(any(), any())).thenThrow(t); - when(mockMetaData.getIndicesLookup()) - .thenReturn(ImmutableSortedMap.of(indexName, mock(IndexAbstraction.class))); - } catch (IOException e) { - throw new IllegalStateException("Failed to mock cluster service", e); - } - return mockService; + public NodeClient mockNodeClient(String indexName) { + GetMappingsResponse mockResponse = mock(GetMappingsResponse.class); + when(nodeClient.admin().indices() + .prepareGetMappings(any()) + .setLocal(anyBoolean()) + .get()).thenReturn(mockResponse); + when(mockResponse.mappings()).thenReturn(ImmutableOpenMap.of()); + return nodeClient; } - public ClusterService mockClusterServiceForSettings(String indexName, String mappings) { - ClusterService mockService = mock(ClusterService.class); - ClusterState mockState = mock(ClusterState.class); - Metadata mockMetaData = mock(Metadata.class); - - when(mockService.state()).thenReturn(mockState); - when(mockState.metadata()).thenReturn(mockMetaData); - try { - ImmutableOpenMap.Builder indexBuilder = - ImmutableOpenMap.builder(); - IndexMetadata indexMetadata = IndexMetadata.fromXContent(createParser(mappings)); - - indexBuilder.put(indexName, indexMetadata); - when(mockMetaData.getIndices()).thenReturn(indexBuilder.build()); - - // IndexNameExpressionResolver use this method to check if index exists. If not, - // IndexNotFoundException is thrown. - IndexAbstraction indexAbstraction = mock(IndexAbstraction.class); - when(indexAbstraction.getIndices()).thenReturn(Collections.singletonList(indexMetadata)); - when(mockMetaData.getIndicesLookup()) - .thenReturn(ImmutableSortedMap.of(indexName, indexAbstraction)); - } catch (IOException e) { - throw new IllegalStateException("Failed to mock cluster service", e); - } - return mockService; + private NodeClient mockNodeClientSettings(String indexName, String indexMetadata) + throws IOException { + GetSettingsResponse mockResponse = mock(GetSettingsResponse.class); + when(nodeClient.admin().indices().prepareGetSettings(any()).setLocal(anyBoolean()).get()) + .thenReturn(mockResponse); + ImmutableOpenMap metadata = + new ImmutableOpenMap.Builder() + .fPut(indexName, IndexMetadata.fromXContent(createParser(indexMetadata)).getSettings()) + .build(); + + when(mockResponse.getIndexToSettings()).thenReturn(metadata); + return nodeClient; } private XContentParser createParser(String mappings) throws IOException { diff --git a/plugin/src/main/java/org/opensearch/sql/plugin/rest/OpenSearchPluginConfig.java b/plugin/src/main/java/org/opensearch/sql/plugin/rest/OpenSearchPluginConfig.java index c1b860877b..6d8dbf50bc 100644 --- a/plugin/src/main/java/org/opensearch/sql/plugin/rest/OpenSearchPluginConfig.java +++ b/plugin/src/main/java/org/opensearch/sql/plugin/rest/OpenSearchPluginConfig.java @@ -7,7 +7,6 @@ package org.opensearch.sql.plugin.rest; import org.opensearch.client.node.NodeClient; -import org.opensearch.cluster.service.ClusterService; import org.opensearch.sql.common.setting.Settings; import org.opensearch.sql.executor.ExecutionEngine; import org.opensearch.sql.monitor.ResourceMonitor; @@ -31,9 +30,6 @@ @Configuration public class OpenSearchPluginConfig { - @Autowired - private ClusterService clusterService; - @Autowired private NodeClient nodeClient; @@ -42,7 +38,7 @@ public class OpenSearchPluginConfig { @Bean public OpenSearchClient client() { - return new OpenSearchNodeClient(clusterService, nodeClient); + return new OpenSearchNodeClient(nodeClient); } @Bean