Search in sources :

Example 1 with RemoteClusterService

use of org.opensearch.transport.RemoteClusterService in project OpenSearch by opensearch-project.

the class TransportSearchActionTests method testCollectSearchShards.

public void testCollectSearchShards() throws Exception {
    int numClusters = randomIntBetween(2, 10);
    DiscoveryNode[] nodes = new DiscoveryNode[numClusters];
    Map<String, OriginalIndices> remoteIndicesByCluster = new HashMap<>();
    Settings.Builder builder = Settings.builder();
    MockTransportService[] mockTransportServices = startTransport(numClusters, nodes, remoteIndicesByCluster, builder);
    Settings settings = builder.build();
    try (MockTransportService service = MockTransportService.createNewService(settings, Version.CURRENT, threadPool, null)) {
        service.start();
        service.acceptIncomingRequests();
        RemoteClusterService remoteClusterService = service.getRemoteClusterService();
        {
            final CountDownLatch latch = new CountDownLatch(1);
            AtomicReference<Map<String, ClusterSearchShardsResponse>> response = new AtomicReference<>();
            AtomicInteger skippedClusters = new AtomicInteger();
            TransportSearchAction.collectSearchShards(IndicesOptions.lenientExpandOpen(), null, null, skippedClusters, remoteIndicesByCluster, remoteClusterService, threadPool, new LatchedActionListener<>(ActionListener.wrap(response::set, e -> fail("no failures expected")), latch));
            awaitLatch(latch, 5, TimeUnit.SECONDS);
            assertEquals(0, skippedClusters.get());
            assertNotNull(response.get());
            Map<String, ClusterSearchShardsResponse> map = response.get();
            assertEquals(numClusters, map.size());
            for (int i = 0; i < numClusters; i++) {
                String clusterAlias = "remote" + i;
                assertTrue(map.containsKey(clusterAlias));
                ClusterSearchShardsResponse shardsResponse = map.get(clusterAlias);
                assertEquals(1, shardsResponse.getNodes().length);
            }
        }
        {
            final CountDownLatch latch = new CountDownLatch(1);
            AtomicReference<Exception> failure = new AtomicReference<>();
            AtomicInteger skippedClusters = new AtomicInteger(0);
            TransportSearchAction.collectSearchShards(IndicesOptions.lenientExpandOpen(), "index_not_found", null, skippedClusters, remoteIndicesByCluster, remoteClusterService, threadPool, new LatchedActionListener<>(ActionListener.wrap(r -> fail("no response expected"), failure::set), latch));
            awaitLatch(latch, 5, TimeUnit.SECONDS);
            assertEquals(0, skippedClusters.get());
            assertNotNull(failure.get());
            assertThat(failure.get(), instanceOf(RemoteTransportException.class));
            RemoteTransportException remoteTransportException = (RemoteTransportException) failure.get();
            assertEquals(RestStatus.NOT_FOUND, remoteTransportException.status());
        }
        int numDisconnectedClusters = randomIntBetween(1, numClusters);
        Set<DiscoveryNode> disconnectedNodes = new HashSet<>(numDisconnectedClusters);
        Set<Integer> disconnectedNodesIndices = new HashSet<>(numDisconnectedClusters);
        while (disconnectedNodes.size() < numDisconnectedClusters) {
            int i = randomIntBetween(0, numClusters - 1);
            if (disconnectedNodes.add(nodes[i])) {
                assertTrue(disconnectedNodesIndices.add(i));
            }
        }
        CountDownLatch disconnectedLatch = new CountDownLatch(numDisconnectedClusters);
        RemoteClusterServiceTests.addConnectionListener(remoteClusterService, new TransportConnectionListener() {

            @Override
            public void onNodeDisconnected(DiscoveryNode node, Transport.Connection connection) {
                if (disconnectedNodes.remove(node)) {
                    disconnectedLatch.countDown();
                }
            }
        });
        for (DiscoveryNode disconnectedNode : disconnectedNodes) {
            service.addFailToSendNoConnectRule(disconnectedNode.getAddress());
        }
        {
            final CountDownLatch latch = new CountDownLatch(1);
            AtomicInteger skippedClusters = new AtomicInteger(0);
            AtomicReference<Exception> failure = new AtomicReference<>();
            TransportSearchAction.collectSearchShards(IndicesOptions.lenientExpandOpen(), null, null, skippedClusters, remoteIndicesByCluster, remoteClusterService, threadPool, new LatchedActionListener<>(ActionListener.wrap(r -> fail("no response expected"), failure::set), latch));
            awaitLatch(latch, 5, TimeUnit.SECONDS);
            assertEquals(0, skippedClusters.get());
            assertNotNull(failure.get());
            assertThat(failure.get(), instanceOf(RemoteTransportException.class));
            assertThat(failure.get().getMessage(), containsString("error while communicating with remote cluster ["));
            assertThat(failure.get().getCause(), instanceOf(NodeDisconnectedException.class));
        }
        // setting skip_unavailable to true for all the disconnected clusters will make the request succeed again
        for (int i : disconnectedNodesIndices) {
            RemoteClusterServiceTests.updateSkipUnavailable(remoteClusterService, "remote" + i, true);
        }
        {
            final CountDownLatch latch = new CountDownLatch(1);
            AtomicInteger skippedClusters = new AtomicInteger(0);
            AtomicReference<Map<String, ClusterSearchShardsResponse>> response = new AtomicReference<>();
            TransportSearchAction.collectSearchShards(IndicesOptions.lenientExpandOpen(), null, null, skippedClusters, remoteIndicesByCluster, remoteClusterService, threadPool, new LatchedActionListener<>(ActionListener.wrap(response::set, e -> fail("no failures expected")), latch));
            awaitLatch(latch, 5, TimeUnit.SECONDS);
            assertNotNull(response.get());
            Map<String, ClusterSearchShardsResponse> map = response.get();
            assertEquals(numClusters - disconnectedNodesIndices.size(), map.size());
            assertEquals(skippedClusters.get(), disconnectedNodesIndices.size());
            for (int i = 0; i < numClusters; i++) {
                String clusterAlias = "remote" + i;
                if (disconnectedNodesIndices.contains(i)) {
                    assertFalse(map.containsKey(clusterAlias));
                } else {
                    assertNotNull(map.get(clusterAlias));
                }
            }
        }
        // give transport service enough time to realize that the node is down, and to notify the connection listeners
        // so that RemoteClusterConnection is left with no connected nodes, hence it will retry connecting next
        assertTrue(disconnectedLatch.await(5, TimeUnit.SECONDS));
        service.clearAllRules();
        if (randomBoolean()) {
            for (int i : disconnectedNodesIndices) {
                if (randomBoolean()) {
                    RemoteClusterServiceTests.updateSkipUnavailable(remoteClusterService, "remote" + i, true);
                }
            }
        }
        {
            final CountDownLatch latch = new CountDownLatch(1);
            AtomicInteger skippedClusters = new AtomicInteger(0);
            AtomicReference<Map<String, ClusterSearchShardsResponse>> response = new AtomicReference<>();
            TransportSearchAction.collectSearchShards(IndicesOptions.lenientExpandOpen(), null, null, skippedClusters, remoteIndicesByCluster, remoteClusterService, threadPool, new LatchedActionListener<>(ActionListener.wrap(response::set, e -> fail("no failures expected")), latch));
            awaitLatch(latch, 5, TimeUnit.SECONDS);
            assertEquals(0, skippedClusters.get());
            assertNotNull(response.get());
            Map<String, ClusterSearchShardsResponse> map = response.get();
            assertEquals(numClusters, map.size());
            for (int i = 0; i < numClusters; i++) {
                String clusterAlias = "remote" + i;
                assertTrue(map.containsKey(clusterAlias));
                assertNotNull(map.get(clusterAlias));
            }
        }
        assertEquals(0, service.getConnectionManager().size());
    } finally {
        for (MockTransportService mockTransportService : mockTransportServices) {
            mockTransportService.close();
        }
    }
}
Also used : ClusterSearchShardsResponse(org.opensearch.action.admin.cluster.shards.ClusterSearchShardsResponse) Arrays(java.util.Arrays) SearchContext(org.opensearch.search.internal.SearchContext) BiFunction(java.util.function.BiFunction) TestThreadPool(org.opensearch.threadpool.TestThreadPool) SortBuilders(org.opensearch.search.sort.SortBuilders) Version(org.opensearch.Version) ClusterSearchShardsResponse(org.opensearch.action.admin.cluster.shards.ClusterSearchShardsResponse) CoreMatchers.startsWith(org.hamcrest.CoreMatchers.startsWith) Strings(org.opensearch.common.Strings) Transport(org.opensearch.transport.Transport) CoreMatchers.instanceOf(org.hamcrest.CoreMatchers.instanceOf) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) LatchedActionListener(org.opensearch.action.LatchedActionListener) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) InternalAggregations(org.opensearch.search.aggregations.InternalAggregations) AliasFilter(org.opensearch.search.internal.AliasFilter) Map(java.util.Map) ActionListener(org.opensearch.action.ActionListener) Scroll(org.opensearch.search.Scroll) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) OpenSearchAssertions.awaitLatch(org.opensearch.test.hamcrest.OpenSearchAssertions.awaitLatch) InternalAggregationTestCase.emptyReduceContextBuilder(org.opensearch.test.InternalAggregationTestCase.emptyReduceContextBuilder) Index(org.opensearch.index.Index) SearchHit(org.opensearch.search.SearchHit) OpenSearchTestCase(org.opensearch.test.OpenSearchTestCase) RemoteTransportException(org.opensearch.transport.RemoteTransportException) TransportRequestOptions(org.opensearch.transport.TransportRequestOptions) InnerHitBuilder(org.opensearch.index.query.InnerHitBuilder) Set(java.util.Set) Settings(org.opensearch.common.settings.Settings) RestStatus(org.opensearch.rest.RestStatus) TransportService(org.opensearch.transport.TransportService) OriginalIndices(org.opensearch.action.OriginalIndices) Tuple(org.opensearch.common.collect.Tuple) TransportAddress(org.opensearch.common.transport.TransportAddress) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) NodeDisconnectedException(org.opensearch.transport.NodeDisconnectedException) SearchSourceBuilder(org.opensearch.search.builder.SearchSourceBuilder) CollapseBuilder(org.opensearch.search.collapse.CollapseBuilder) TermsQueryBuilder(org.opensearch.index.query.TermsQueryBuilder) InternalAggregation(org.opensearch.search.aggregations.InternalAggregation) TransportException(org.opensearch.transport.TransportException) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) RemoteClusterServiceTests(org.opensearch.transport.RemoteClusterServiceTests) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) ThreadPool(org.opensearch.threadpool.ThreadPool) GroupShardsIteratorTests(org.opensearch.cluster.routing.GroupShardsIteratorTests) HashMap(java.util.HashMap) SearchHits(org.opensearch.search.SearchHits) IndicesOptions(org.opensearch.action.support.IndicesOptions) MockTransportService(org.opensearch.test.transport.MockTransportService) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ClusterState(org.opensearch.cluster.ClusterState) ShardRoutingState(org.opensearch.cluster.routing.ShardRoutingState) ClusterBlocks(org.opensearch.cluster.block.ClusterBlocks) QueryBuilders(org.opensearch.index.query.QueryBuilders) SetOnce(org.apache.lucene.util.SetOnce) RemoteClusterService(org.opensearch.transport.RemoteClusterService) TransportRequest(org.opensearch.transport.TransportRequest) TransportConnectionListener(org.opensearch.transport.TransportConnectionListener) InternalSearchResponse(org.opensearch.search.internal.InternalSearchResponse) ClusterSearchShardsGroup(org.opensearch.action.admin.cluster.shards.ClusterSearchShardsGroup) TotalHits(org.apache.lucene.search.TotalHits) ShardRouting(org.opensearch.cluster.routing.ShardRouting) ShardId(org.opensearch.index.shard.ShardId) TimeUnit(java.util.concurrent.TimeUnit) GroupShardsIterator(org.opensearch.cluster.routing.GroupShardsIterator) TestShardRouting(org.opensearch.cluster.routing.TestShardRouting) SearchShardTarget(org.opensearch.search.SearchShardTarget) RemoteClusterConnectionTests(org.opensearch.transport.RemoteClusterConnectionTests) ClusterName(org.opensearch.cluster.ClusterName) OriginalIndicesTests(org.opensearch.action.OriginalIndicesTests) MatchAllQueryBuilder(org.opensearch.index.query.MatchAllQueryBuilder) Collections(java.util.Collections) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) MockTransportService(org.opensearch.test.transport.MockTransportService) HashMap(java.util.HashMap) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) TransportConnectionListener(org.opensearch.transport.TransportConnectionListener) LatchedActionListener(org.opensearch.action.LatchedActionListener) Settings(org.opensearch.common.settings.Settings) HashSet(java.util.HashSet) RemoteTransportException(org.opensearch.transport.RemoteTransportException) RemoteClusterService(org.opensearch.transport.RemoteClusterService) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Transport(org.opensearch.transport.Transport) Map(java.util.Map) HashMap(java.util.HashMap) OriginalIndices(org.opensearch.action.OriginalIndices)

Example 2 with RemoteClusterService

use of org.opensearch.transport.RemoteClusterService in project OpenSearch by opensearch-project.

the class TransportSearchActionTests method testProcessRemoteShards.

public void testProcessRemoteShards() {
    try (TransportService transportService = MockTransportService.createNewService(Settings.EMPTY, Version.CURRENT, threadPool, null)) {
        RemoteClusterService service = transportService.getRemoteClusterService();
        assertFalse(service.isCrossClusterSearchEnabled());
        Map<String, ClusterSearchShardsResponse> searchShardsResponseMap = new HashMap<>();
        DiscoveryNode[] nodes = new DiscoveryNode[] { new DiscoveryNode("node1", buildNewFakeTransportAddress(), Version.CURRENT), new DiscoveryNode("node2", buildNewFakeTransportAddress(), Version.CURRENT) };
        Map<String, AliasFilter> indicesAndAliases = new HashMap<>();
        indicesAndAliases.put("foo", new AliasFilter(new TermsQueryBuilder("foo", "bar"), "some_alias_for_foo", "some_other_foo_alias"));
        indicesAndAliases.put("bar", new AliasFilter(new MatchAllQueryBuilder(), Strings.EMPTY_ARRAY));
        ClusterSearchShardsGroup[] groups = new ClusterSearchShardsGroup[] { new ClusterSearchShardsGroup(new ShardId("foo", "foo_id", 0), new ShardRouting[] { TestShardRouting.newShardRouting("foo", 0, "node1", true, ShardRoutingState.STARTED), TestShardRouting.newShardRouting("foo", 0, "node2", false, ShardRoutingState.STARTED) }), new ClusterSearchShardsGroup(new ShardId("foo", "foo_id", 1), new ShardRouting[] { TestShardRouting.newShardRouting("foo", 0, "node1", true, ShardRoutingState.STARTED), TestShardRouting.newShardRouting("foo", 1, "node2", false, ShardRoutingState.STARTED) }), new ClusterSearchShardsGroup(new ShardId("bar", "bar_id", 0), new ShardRouting[] { TestShardRouting.newShardRouting("bar", 0, "node2", true, ShardRoutingState.STARTED), TestShardRouting.newShardRouting("bar", 0, "node1", false, ShardRoutingState.STARTED) }) };
        searchShardsResponseMap.put("test_cluster_1", new ClusterSearchShardsResponse(groups, nodes, indicesAndAliases));
        DiscoveryNode[] nodes2 = new DiscoveryNode[] { new DiscoveryNode("node3", buildNewFakeTransportAddress(), Version.CURRENT) };
        ClusterSearchShardsGroup[] groups2 = new ClusterSearchShardsGroup[] { new ClusterSearchShardsGroup(new ShardId("xyz", "xyz_id", 0), new ShardRouting[] { TestShardRouting.newShardRouting("xyz", 0, "node3", true, ShardRoutingState.STARTED) }) };
        Map<String, AliasFilter> filter = new HashMap<>();
        filter.put("xyz", new AliasFilter(null, "some_alias_for_xyz"));
        searchShardsResponseMap.put("test_cluster_2", new ClusterSearchShardsResponse(groups2, nodes2, filter));
        Map<String, OriginalIndices> remoteIndicesByCluster = new HashMap<>();
        remoteIndicesByCluster.put("test_cluster_1", new OriginalIndices(new String[] { "fo*", "ba*" }, SearchRequest.DEFAULT_INDICES_OPTIONS));
        remoteIndicesByCluster.put("test_cluster_2", new OriginalIndices(new String[] { "x*" }, SearchRequest.DEFAULT_INDICES_OPTIONS));
        Map<String, AliasFilter> remoteAliases = TransportSearchAction.getRemoteAliasFilters(searchShardsResponseMap);
        List<SearchShardIterator> iteratorList = TransportSearchAction.getRemoteShardsIterator(searchShardsResponseMap, remoteIndicesByCluster, remoteAliases);
        assertEquals(4, iteratorList.size());
        for (SearchShardIterator iterator : iteratorList) {
            if (iterator.shardId().getIndexName().endsWith("foo")) {
                assertArrayEquals(new String[] { "some_alias_for_foo", "some_other_foo_alias" }, iterator.getOriginalIndices().indices());
                assertTrue(iterator.shardId().getId() == 0 || iterator.shardId().getId() == 1);
                assertEquals("test_cluster_1", iterator.getClusterAlias());
                assertEquals("foo", iterator.shardId().getIndexName());
                SearchShardTarget shard = iterator.nextOrNull();
                assertNotNull(shard);
                assertEquals(shard.getShardId().getIndexName(), "foo");
                shard = iterator.nextOrNull();
                assertNotNull(shard);
                assertEquals(shard.getShardId().getIndexName(), "foo");
                assertNull(iterator.nextOrNull());
            } else if (iterator.shardId().getIndexName().endsWith("bar")) {
                assertArrayEquals(new String[] { "bar" }, iterator.getOriginalIndices().indices());
                assertEquals(0, iterator.shardId().getId());
                assertEquals("test_cluster_1", iterator.getClusterAlias());
                assertEquals("bar", iterator.shardId().getIndexName());
                SearchShardTarget shard = iterator.nextOrNull();
                assertNotNull(shard);
                assertEquals(shard.getShardId().getIndexName(), "bar");
                shard = iterator.nextOrNull();
                assertNotNull(shard);
                assertEquals(shard.getShardId().getIndexName(), "bar");
                assertNull(iterator.nextOrNull());
            } else if (iterator.shardId().getIndexName().endsWith("xyz")) {
                assertArrayEquals(new String[] { "some_alias_for_xyz" }, iterator.getOriginalIndices().indices());
                assertEquals(0, iterator.shardId().getId());
                assertEquals("xyz", iterator.shardId().getIndexName());
                assertEquals("test_cluster_2", iterator.getClusterAlias());
                SearchShardTarget shard = iterator.nextOrNull();
                assertNotNull(shard);
                assertEquals(shard.getShardId().getIndexName(), "xyz");
                assertNull(iterator.nextOrNull());
            }
        }
        assertEquals(3, remoteAliases.size());
        assertTrue(remoteAliases.toString(), remoteAliases.containsKey("foo_id"));
        assertTrue(remoteAliases.toString(), remoteAliases.containsKey("bar_id"));
        assertTrue(remoteAliases.toString(), remoteAliases.containsKey("xyz_id"));
        assertEquals(new TermsQueryBuilder("foo", "bar"), remoteAliases.get("foo_id").getQueryBuilder());
        assertEquals(new MatchAllQueryBuilder(), remoteAliases.get("bar_id").getQueryBuilder());
        assertNull(remoteAliases.get("xyz_id").getQueryBuilder());
    }
}
Also used : ClusterSearchShardsResponse(org.opensearch.action.admin.cluster.shards.ClusterSearchShardsResponse) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) AliasFilter(org.opensearch.search.internal.AliasFilter) HashMap(java.util.HashMap) RemoteClusterService(org.opensearch.transport.RemoteClusterService) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) ClusterSearchShardsGroup(org.opensearch.action.admin.cluster.shards.ClusterSearchShardsGroup) ShardId(org.opensearch.index.shard.ShardId) TransportService(org.opensearch.transport.TransportService) MockTransportService(org.opensearch.test.transport.MockTransportService) TermsQueryBuilder(org.opensearch.index.query.TermsQueryBuilder) SearchShardTarget(org.opensearch.search.SearchShardTarget) OriginalIndices(org.opensearch.action.OriginalIndices) MatchAllQueryBuilder(org.opensearch.index.query.MatchAllQueryBuilder)

Example 3 with RemoteClusterService

use of org.opensearch.transport.RemoteClusterService in project OpenSearch by opensearch-project.

the class TransportSearchActionTests method testCCSRemoteReduceMergeFails.

public void testCCSRemoteReduceMergeFails() throws Exception {
    int numClusters = randomIntBetween(2, 10);
    DiscoveryNode[] nodes = new DiscoveryNode[numClusters];
    Map<String, OriginalIndices> remoteIndicesByCluster = new HashMap<>();
    Settings.Builder builder = Settings.builder();
    MockTransportService[] mockTransportServices = startTransport(numClusters, nodes, remoteIndicesByCluster, builder);
    Settings settings = builder.build();
    boolean local = randomBoolean();
    OriginalIndices localIndices = local ? new OriginalIndices(new String[] { "index" }, SearchRequest.DEFAULT_INDICES_OPTIONS) : null;
    TransportSearchAction.SearchTimeProvider timeProvider = new TransportSearchAction.SearchTimeProvider(0, 0, () -> 0);
    Function<Boolean, InternalAggregation.ReduceContext> reduceContext = finalReduce -> null;
    try (MockTransportService service = MockTransportService.createNewService(settings, Version.CURRENT, threadPool, null)) {
        service.start();
        service.acceptIncomingRequests();
        RemoteClusterService remoteClusterService = service.getRemoteClusterService();
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.preference("null_target");
        final CountDownLatch latch = new CountDownLatch(1);
        SetOnce<Tuple<SearchRequest, ActionListener<SearchResponse>>> setOnce = new SetOnce<>();
        AtomicReference<Exception> failure = new AtomicReference<>();
        LatchedActionListener<SearchResponse> listener = new LatchedActionListener<>(ActionListener.wrap(r -> fail("no response expected"), failure::set), latch);
        TransportSearchAction.ccsRemoteReduce(searchRequest, localIndices, remoteIndicesByCluster, timeProvider, emptyReduceContextBuilder(), remoteClusterService, threadPool, listener, (r, l) -> setOnce.set(Tuple.tuple(r, l)));
        if (localIndices == null) {
            assertNull(setOnce.get());
        } else {
            Tuple<SearchRequest, ActionListener<SearchResponse>> tuple = setOnce.get();
            assertEquals("", tuple.v1().getLocalClusterAlias());
            assertThat(tuple.v2(), instanceOf(TransportSearchAction.CCSActionListener.class));
            tuple.v2().onResponse(emptySearchResponse());
        }
        awaitLatch(latch, 5, TimeUnit.SECONDS);
        assertNotNull(failure.get());
        // the intention here is not to test that we throw NPE, rather to trigger a situation that makes
        // SearchResponseMerger#getMergedResponse fail unexpectedly and verify that the listener is properly notified with the NPE
        assertThat(failure.get(), instanceOf(NullPointerException.class));
        assertEquals(0, service.getConnectionManager().size());
    } finally {
        for (MockTransportService mockTransportService : mockTransportServices) {
            mockTransportService.close();
        }
    }
}
Also used : Arrays(java.util.Arrays) SearchContext(org.opensearch.search.internal.SearchContext) BiFunction(java.util.function.BiFunction) TestThreadPool(org.opensearch.threadpool.TestThreadPool) SortBuilders(org.opensearch.search.sort.SortBuilders) Version(org.opensearch.Version) ClusterSearchShardsResponse(org.opensearch.action.admin.cluster.shards.ClusterSearchShardsResponse) CoreMatchers.startsWith(org.hamcrest.CoreMatchers.startsWith) Strings(org.opensearch.common.Strings) Transport(org.opensearch.transport.Transport) CoreMatchers.instanceOf(org.hamcrest.CoreMatchers.instanceOf) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) LatchedActionListener(org.opensearch.action.LatchedActionListener) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) InternalAggregations(org.opensearch.search.aggregations.InternalAggregations) AliasFilter(org.opensearch.search.internal.AliasFilter) Map(java.util.Map) ActionListener(org.opensearch.action.ActionListener) Scroll(org.opensearch.search.Scroll) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) OpenSearchAssertions.awaitLatch(org.opensearch.test.hamcrest.OpenSearchAssertions.awaitLatch) InternalAggregationTestCase.emptyReduceContextBuilder(org.opensearch.test.InternalAggregationTestCase.emptyReduceContextBuilder) Index(org.opensearch.index.Index) SearchHit(org.opensearch.search.SearchHit) OpenSearchTestCase(org.opensearch.test.OpenSearchTestCase) RemoteTransportException(org.opensearch.transport.RemoteTransportException) TransportRequestOptions(org.opensearch.transport.TransportRequestOptions) InnerHitBuilder(org.opensearch.index.query.InnerHitBuilder) Set(java.util.Set) Settings(org.opensearch.common.settings.Settings) RestStatus(org.opensearch.rest.RestStatus) TransportService(org.opensearch.transport.TransportService) OriginalIndices(org.opensearch.action.OriginalIndices) Tuple(org.opensearch.common.collect.Tuple) TransportAddress(org.opensearch.common.transport.TransportAddress) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) NodeDisconnectedException(org.opensearch.transport.NodeDisconnectedException) SearchSourceBuilder(org.opensearch.search.builder.SearchSourceBuilder) CollapseBuilder(org.opensearch.search.collapse.CollapseBuilder) TermsQueryBuilder(org.opensearch.index.query.TermsQueryBuilder) InternalAggregation(org.opensearch.search.aggregations.InternalAggregation) TransportException(org.opensearch.transport.TransportException) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) RemoteClusterServiceTests(org.opensearch.transport.RemoteClusterServiceTests) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) ThreadPool(org.opensearch.threadpool.ThreadPool) GroupShardsIteratorTests(org.opensearch.cluster.routing.GroupShardsIteratorTests) HashMap(java.util.HashMap) SearchHits(org.opensearch.search.SearchHits) IndicesOptions(org.opensearch.action.support.IndicesOptions) MockTransportService(org.opensearch.test.transport.MockTransportService) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ClusterState(org.opensearch.cluster.ClusterState) ShardRoutingState(org.opensearch.cluster.routing.ShardRoutingState) ClusterBlocks(org.opensearch.cluster.block.ClusterBlocks) QueryBuilders(org.opensearch.index.query.QueryBuilders) SetOnce(org.apache.lucene.util.SetOnce) RemoteClusterService(org.opensearch.transport.RemoteClusterService) TransportRequest(org.opensearch.transport.TransportRequest) TransportConnectionListener(org.opensearch.transport.TransportConnectionListener) InternalSearchResponse(org.opensearch.search.internal.InternalSearchResponse) ClusterSearchShardsGroup(org.opensearch.action.admin.cluster.shards.ClusterSearchShardsGroup) TotalHits(org.apache.lucene.search.TotalHits) ShardRouting(org.opensearch.cluster.routing.ShardRouting) ShardId(org.opensearch.index.shard.ShardId) TimeUnit(java.util.concurrent.TimeUnit) GroupShardsIterator(org.opensearch.cluster.routing.GroupShardsIterator) TestShardRouting(org.opensearch.cluster.routing.TestShardRouting) SearchShardTarget(org.opensearch.search.SearchShardTarget) RemoteClusterConnectionTests(org.opensearch.transport.RemoteClusterConnectionTests) ClusterName(org.opensearch.cluster.ClusterName) OriginalIndicesTests(org.opensearch.action.OriginalIndicesTests) MatchAllQueryBuilder(org.opensearch.index.query.MatchAllQueryBuilder) Collections(java.util.Collections) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) MockTransportService(org.opensearch.test.transport.MockTransportService) HashMap(java.util.HashMap) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) LatchedActionListener(org.opensearch.action.LatchedActionListener) Settings(org.opensearch.common.settings.Settings) SetOnce(org.apache.lucene.util.SetOnce) RemoteClusterService(org.opensearch.transport.RemoteClusterService) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) RemoteTransportException(org.opensearch.transport.RemoteTransportException) NodeDisconnectedException(org.opensearch.transport.NodeDisconnectedException) TransportException(org.opensearch.transport.TransportException) InternalSearchResponse(org.opensearch.search.internal.InternalSearchResponse) LatchedActionListener(org.opensearch.action.LatchedActionListener) ActionListener(org.opensearch.action.ActionListener) OriginalIndices(org.opensearch.action.OriginalIndices) Tuple(org.opensearch.common.collect.Tuple)

Example 4 with RemoteClusterService

use of org.opensearch.transport.RemoteClusterService in project OpenSearch by opensearch-project.

the class TransportSearchAction method executeRequest.

private void executeRequest(Task task, SearchRequest searchRequest, SearchAsyncActionProvider searchAsyncActionProvider, ActionListener<SearchResponse> listener) {
    final long relativeStartNanos = System.nanoTime();
    final SearchTimeProvider timeProvider = new SearchTimeProvider(searchRequest.getOrCreateAbsoluteStartMillis(), relativeStartNanos, System::nanoTime);
    ActionListener<SearchSourceBuilder> rewriteListener = ActionListener.wrap(source -> {
        if (source != searchRequest.source()) {
            // only set it if it changed - we don't allow null values to be set but it might be already null. this way we catch
            // situations when source is rewritten to null due to a bug
            searchRequest.source(source);
        }
        final ClusterState clusterState = clusterService.state();
        final SearchContextId searchContext;
        final Map<String, OriginalIndices> remoteClusterIndices;
        if (searchRequest.pointInTimeBuilder() != null) {
            searchContext = SearchContextId.decode(namedWriteableRegistry, searchRequest.pointInTimeBuilder().getId());
            remoteClusterIndices = getIndicesFromSearchContexts(searchContext, searchRequest.indicesOptions());
        } else {
            searchContext = null;
            remoteClusterIndices = remoteClusterService.groupIndices(searchRequest.indicesOptions(), searchRequest.indices(), idx -> indexNameExpressionResolver.hasIndexAbstraction(idx, clusterState));
        }
        OriginalIndices localIndices = remoteClusterIndices.remove(RemoteClusterAware.LOCAL_CLUSTER_GROUP_KEY);
        if (remoteClusterIndices.isEmpty()) {
            executeLocalSearch(task, timeProvider, searchRequest, localIndices, clusterState, listener, searchContext, searchAsyncActionProvider);
        } else {
            if (shouldMinimizeRoundtrips(searchRequest)) {
                ccsRemoteReduce(searchRequest, localIndices, remoteClusterIndices, timeProvider, searchService.aggReduceContextBuilder(searchRequest), remoteClusterService, threadPool, listener, (r, l) -> executeLocalSearch(task, timeProvider, r, localIndices, clusterState, l, searchContext, searchAsyncActionProvider));
            } else {
                AtomicInteger skippedClusters = new AtomicInteger(0);
                collectSearchShards(searchRequest.indicesOptions(), searchRequest.preference(), searchRequest.routing(), skippedClusters, remoteClusterIndices, remoteClusterService, threadPool, ActionListener.wrap(searchShardsResponses -> {
                    final BiFunction<String, String, DiscoveryNode> clusterNodeLookup = getRemoteClusterNodeLookup(searchShardsResponses);
                    final Map<String, AliasFilter> remoteAliasFilters;
                    final List<SearchShardIterator> remoteShardIterators;
                    if (searchContext != null) {
                        remoteAliasFilters = searchContext.aliasFilter();
                        remoteShardIterators = getRemoteShardsIteratorFromPointInTime(searchShardsResponses, searchContext, searchRequest.pointInTimeBuilder().getKeepAlive(), remoteClusterIndices);
                    } else {
                        remoteAliasFilters = getRemoteAliasFilters(searchShardsResponses);
                        remoteShardIterators = getRemoteShardsIterator(searchShardsResponses, remoteClusterIndices, remoteAliasFilters);
                    }
                    int localClusters = localIndices == null ? 0 : 1;
                    int totalClusters = remoteClusterIndices.size() + localClusters;
                    int successfulClusters = searchShardsResponses.size() + localClusters;
                    executeSearch((SearchTask) task, timeProvider, searchRequest, localIndices, remoteShardIterators, clusterNodeLookup, clusterState, remoteAliasFilters, listener, new SearchResponse.Clusters(totalClusters, successfulClusters, skippedClusters.get()), searchContext, searchAsyncActionProvider);
                }, listener::onFailure));
            }
        }
    }, listener::onFailure);
    if (searchRequest.source() == null) {
        rewriteListener.onResponse(searchRequest.source());
    } else {
        Rewriteable.rewriteAndFetch(searchRequest.source(), searchService.getRewriteContext(timeProvider::getAbsoluteStartMillis), rewriteListener);
    }
}
Also used : RemoteClusterAware(org.opensearch.transport.RemoteClusterAware) Arrays(java.util.Arrays) LongSupplier(java.util.function.LongSupplier) CountDown(org.opensearch.common.util.concurrent.CountDown) ProfileShardResult(org.opensearch.search.profile.ProfileShardResult) SearchContext(org.opensearch.search.internal.SearchContext) BiFunction(java.util.function.BiFunction) ClusterSearchShardsResponse(org.opensearch.action.admin.cluster.shards.ClusterSearchShardsResponse) CircuitBreaker(org.opensearch.common.breaker.CircuitBreaker) DFS_QUERY_THEN_FETCH(org.opensearch.action.search.SearchType.DFS_QUERY_THEN_FETCH) Strings(org.opensearch.common.Strings) Transport(org.opensearch.transport.Transport) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) QUERY_THEN_FETCH(org.opensearch.action.search.SearchType.QUERY_THEN_FETCH) Property(org.opensearch.common.settings.Setting.Property) InternalAggregations(org.opensearch.search.aggregations.InternalAggregations) AliasFilter(org.opensearch.search.internal.AliasFilter) Map(java.util.Map) Inject(org.opensearch.common.inject.Inject) ActionListener(org.opensearch.action.ActionListener) CancellableTask(org.opensearch.tasks.CancellableTask) Client(org.opensearch.client.Client) TimeValue(org.opensearch.common.unit.TimeValue) NodeClient(org.opensearch.client.node.NodeClient) Index(org.opensearch.index.Index) RemoteTransportException(org.opensearch.transport.RemoteTransportException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ClusterBlockException(org.opensearch.cluster.block.ClusterBlockException) Set(java.util.Set) Task(org.opensearch.tasks.Task) TransportService(org.opensearch.transport.TransportService) Collectors(java.util.stream.Collectors) OriginalIndices(org.opensearch.action.OriginalIndices) Nullable(org.opensearch.common.Nullable) ActionFilters(org.opensearch.action.support.ActionFilters) OperationRouting(org.opensearch.cluster.routing.OperationRouting) List(java.util.List) SearchPhaseResult(org.opensearch.search.SearchPhaseResult) SearchSourceBuilder(org.opensearch.search.builder.SearchSourceBuilder) InternalAggregation(org.opensearch.search.aggregations.InternalAggregation) IndexNameExpressionResolver(org.opensearch.cluster.metadata.IndexNameExpressionResolver) SearchProfileShardResults(org.opensearch.search.profile.SearchProfileShardResults) DiscoveryNodes(org.opensearch.cluster.node.DiscoveryNodes) HandledTransportAction(org.opensearch.action.support.HandledTransportAction) FieldSortBuilder.hasPrimaryFieldSort(org.opensearch.search.sort.FieldSortBuilder.hasPrimaryFieldSort) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) ShardIterator(org.opensearch.cluster.routing.ShardIterator) ThreadPool(org.opensearch.threadpool.ThreadPool) HashMap(java.util.HashMap) IndicesOptions(org.opensearch.action.support.IndicesOptions) Writeable(org.opensearch.common.io.stream.Writeable) TimeoutTaskCancellationUtility(org.opensearch.action.support.TimeoutTaskCancellationUtility) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) NamedWriteableRegistry(org.opensearch.common.io.stream.NamedWriteableRegistry) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ClusterState(org.opensearch.cluster.ClusterState) BiConsumer(java.util.function.BiConsumer) StreamSupport(java.util.stream.StreamSupport) SearchService(org.opensearch.search.SearchService) TASKS_ORIGIN(org.opensearch.action.admin.cluster.node.tasks.get.GetTaskAction.TASKS_ORIGIN) Setting(org.opensearch.common.settings.Setting) RemoteClusterService(org.opensearch.transport.RemoteClusterService) Executor(java.util.concurrent.Executor) ClusterBlockLevel(org.opensearch.cluster.block.ClusterBlockLevel) Rewriteable(org.opensearch.index.query.Rewriteable) TaskId(org.opensearch.tasks.TaskId) InternalSearchResponse(org.opensearch.search.internal.InternalSearchResponse) ClusterSearchShardsGroup(org.opensearch.action.admin.cluster.shards.ClusterSearchShardsGroup) ClusterSearchShardsRequest(org.opensearch.action.admin.cluster.shards.ClusterSearchShardsRequest) ShardId(org.opensearch.index.shard.ShardId) TimeUnit(java.util.concurrent.TimeUnit) GroupShardsIterator(org.opensearch.cluster.routing.GroupShardsIterator) AtomicArray(org.opensearch.common.util.concurrent.AtomicArray) SearchShardTarget(org.opensearch.search.SearchShardTarget) CancelTasksRequest(org.opensearch.action.admin.cluster.node.tasks.cancel.CancelTasksRequest) CircuitBreakerService(org.opensearch.indices.breaker.CircuitBreakerService) ClusterService(org.opensearch.cluster.service.ClusterService) Collections(java.util.Collections) OriginSettingClient(org.opensearch.client.OriginSettingClient) ClusterState(org.opensearch.cluster.ClusterState) SearchSourceBuilder(org.opensearch.search.builder.SearchSourceBuilder) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) BiFunction(java.util.function.BiFunction) List(java.util.List) ArrayList(java.util.ArrayList) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) OriginalIndices(org.opensearch.action.OriginalIndices)

Example 5 with RemoteClusterService

use of org.opensearch.transport.RemoteClusterService in project OpenSearch by opensearch-project.

the class SearchScrollAsyncAction method collectNodesAndRun.

/**
 * This method collects nodes from the remote clusters asynchronously if any of the scroll IDs references a remote cluster.
 * Otherwise the action listener will be invoked immediately with a function based on the given discovery nodes.
 */
static void collectNodesAndRun(final Iterable<SearchContextIdForNode> scrollIds, DiscoveryNodes nodes, SearchTransportService searchTransportService, ActionListener<BiFunction<String, String, DiscoveryNode>> listener) {
    Set<String> clusters = new HashSet<>();
    for (SearchContextIdForNode target : scrollIds) {
        if (target.getClusterAlias() != null) {
            clusters.add(target.getClusterAlias());
        }
    }
    if (clusters.isEmpty()) {
        // no remote clusters
        listener.onResponse((cluster, node) -> nodes.get(node));
    } else {
        RemoteClusterService remoteClusterService = searchTransportService.getRemoteClusterService();
        remoteClusterService.collectNodes(clusters, ActionListener.map(listener, nodeFunction -> (clusterAlias, node) -> clusterAlias == null ? nodes.get(node) : nodeFunction.apply(clusterAlias, node)));
    }
}
Also used : DiscoveryNodes(org.opensearch.cluster.node.DiscoveryNodes) Arrays(java.util.Arrays) RemoteClusterService(org.opensearch.transport.RemoteClusterService) CountDown(org.opensearch.common.util.concurrent.CountDown) ShardSearchContextId(org.opensearch.search.internal.ShardSearchContextId) BiFunction(java.util.function.BiFunction) Set(java.util.Set) IOException(java.io.IOException) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) InternalSearchResponse(org.opensearch.search.internal.InternalSearchResponse) Supplier(java.util.function.Supplier) Nullable(org.opensearch.common.Nullable) ArrayList(java.util.ArrayList) Transport(org.opensearch.transport.Transport) HashSet(java.util.HashSet) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) List(java.util.List) Logger(org.apache.logging.log4j.Logger) AtomicArray(org.opensearch.common.util.concurrent.AtomicArray) SearchShardTarget(org.opensearch.search.SearchShardTarget) InternalScrollSearchRequest(org.opensearch.search.internal.InternalScrollSearchRequest) SearchPhaseResult(org.opensearch.search.SearchPhaseResult) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ActionListener(org.opensearch.action.ActionListener) RemoteClusterService(org.opensearch.transport.RemoteClusterService) HashSet(java.util.HashSet)

Aggregations

DiscoveryNode (org.opensearch.cluster.node.DiscoveryNode)6 SearchShardTarget (org.opensearch.search.SearchShardTarget)6 RemoteClusterService (org.opensearch.transport.RemoteClusterService)6 ArrayList (java.util.ArrayList)5 Arrays (java.util.Arrays)5 HashMap (java.util.HashMap)5 HashSet (java.util.HashSet)5 List (java.util.List)5 Set (java.util.Set)5 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)5 BiFunction (java.util.function.BiFunction)5 ActionListener (org.opensearch.action.ActionListener)5 OriginalIndices (org.opensearch.action.OriginalIndices)5 ClusterSearchShardsGroup (org.opensearch.action.admin.cluster.shards.ClusterSearchShardsGroup)5 ClusterSearchShardsResponse (org.opensearch.action.admin.cluster.shards.ClusterSearchShardsResponse)5 ShardId (org.opensearch.index.shard.ShardId)5 AliasFilter (org.opensearch.search.internal.AliasFilter)5 Collections (java.util.Collections)4 Map (java.util.Map)4 TimeUnit (java.util.concurrent.TimeUnit)4