Search in sources :

Example 1 with Empty

use of org.opensearch.transport.TransportResponse.Empty in project OpenSearch by opensearch-project.

the class JoinHelper method sendJoinRequest.

public void sendJoinRequest(DiscoveryNode destination, long term, Optional<Join> optionalJoin, Runnable onCompletion) {
    assert destination.isMasterNode() : "trying to join master-ineligible " + destination;
    final StatusInfo statusInfo = nodeHealthService.getHealth();
    if (statusInfo.getStatus() == UNHEALTHY) {
        logger.debug("dropping join request to [{}]: [{}]", destination, statusInfo.getInfo());
        return;
    }
    final JoinRequest joinRequest = new JoinRequest(transportService.getLocalNode(), term, optionalJoin);
    final Tuple<DiscoveryNode, JoinRequest> dedupKey = Tuple.tuple(destination, joinRequest);
    if (pendingOutgoingJoins.add(dedupKey)) {
        logger.debug("attempting to join {} with {}", destination, joinRequest);
        transportService.sendRequest(destination, JOIN_ACTION_NAME, joinRequest, TransportRequestOptions.EMPTY, new TransportResponseHandler<Empty>() {

            @Override
            public Empty read(StreamInput in) {
                return Empty.INSTANCE;
            }

            @Override
            public void handleResponse(Empty response) {
                pendingOutgoingJoins.remove(dedupKey);
                logger.debug("successfully joined {} with {}", destination, joinRequest);
                lastFailedJoinAttempt.set(null);
                onCompletion.run();
            }

            @Override
            public void handleException(TransportException exp) {
                pendingOutgoingJoins.remove(dedupKey);
                logger.info(() -> new ParameterizedMessage("failed to join {} with {}", destination, joinRequest), exp);
                FailedJoinAttempt attempt = new FailedJoinAttempt(destination, joinRequest, exp);
                attempt.logNow();
                lastFailedJoinAttempt.set(attempt);
                onCompletion.run();
            }

            @Override
            public String executor() {
                return Names.SAME;
            }
        });
    } else {
        logger.debug("already attempting to join {} with request {}, not sending request", destination, joinRequest);
    }
}
Also used : DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) Empty(org.opensearch.transport.TransportResponse.Empty) StatusInfo(org.opensearch.monitor.StatusInfo) StreamInput(org.opensearch.common.io.stream.StreamInput) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) TransportException(org.opensearch.transport.TransportException)

Example 2 with Empty

use of org.opensearch.transport.TransportResponse.Empty in project OpenSearch by opensearch-project.

the class FollowersCheckerTests method testFailureCounterResetsOnSuccess.

public void testFailureCounterResetsOnSuccess() {
    final Settings settings = randomSettings();
    final int retryCount = FOLLOWER_CHECK_RETRY_COUNT_SETTING.get(settings);
    final int maxRecoveries = randomIntBetween(3, 10);
    // passes just enough checks to keep it alive, up to maxRecoveries, and then fails completely
    testBehaviourOfFailingNode(settings, new Supplier<Empty>() {

        private int checkIndex;

        private int recoveries;

        @Override
        public Empty get() {
            checkIndex++;
            if (checkIndex % retryCount == 0 && recoveries < maxRecoveries) {
                recoveries++;
                return Empty.INSTANCE;
            }
            throw new OpenSearchException("simulated exception");
        }
    }, "followers check retry count exceeded", (FOLLOWER_CHECK_RETRY_COUNT_SETTING.get(settings) * (maxRecoveries + 1) - 1) * FOLLOWER_CHECK_INTERVAL_SETTING.get(settings).millis(), () -> new StatusInfo(HEALTHY, "healthy-info"));
}
Also used : Empty(org.opensearch.transport.TransportResponse.Empty) StatusInfo(org.opensearch.monitor.StatusInfo) OpenSearchException(org.opensearch.OpenSearchException) Settings(org.opensearch.common.settings.Settings)

Example 3 with Empty

use of org.opensearch.transport.TransportResponse.Empty in project OpenSearch by opensearch-project.

the class RestBuilderListenerTests method testXContentBuilderClosedInBuildResponse.

public void testXContentBuilderClosedInBuildResponse() throws Exception {
    AtomicReference<XContentBuilder> builderAtomicReference = new AtomicReference<>();
    RestBuilderListener<TransportResponse.Empty> builderListener = new RestBuilderListener<Empty>(new FakeRestChannel(new FakeRestRequest(), randomBoolean(), 1)) {

        @Override
        public RestResponse buildResponse(Empty empty, XContentBuilder builder) throws Exception {
            builderAtomicReference.set(builder);
            builder.close();
            return new BytesRestResponse(RestStatus.OK, BytesRestResponse.TEXT_CONTENT_TYPE, BytesArray.EMPTY);
        }
    };
    builderListener.buildResponse(Empty.INSTANCE);
    assertNotNull(builderAtomicReference.get());
    assertTrue(builderAtomicReference.get().generator().isClosed());
}
Also used : Empty(org.opensearch.transport.TransportResponse.Empty) BytesRestResponse(org.opensearch.rest.BytesRestResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) FakeRestChannel(org.opensearch.test.rest.FakeRestChannel) FakeRestRequest(org.opensearch.test.rest.FakeRestRequest) XContentBuilder(org.opensearch.common.xcontent.XContentBuilder)

Example 4 with Empty

use of org.opensearch.transport.TransportResponse.Empty in project OpenSearch by opensearch-project.

the class RestBuilderListenerTests method testXContentBuilderNotClosedInBuildResponseAssertionsEnabled.

public void testXContentBuilderNotClosedInBuildResponseAssertionsEnabled() throws Exception {
    assumeTrue("tests are not being run with assertions", RestBuilderListener.class.desiredAssertionStatus());
    RestBuilderListener<TransportResponse.Empty> builderListener = new RestBuilderListener<Empty>(new FakeRestChannel(new FakeRestRequest(), randomBoolean(), 1)) {

        @Override
        public RestResponse buildResponse(Empty empty, XContentBuilder builder) throws Exception {
            return new BytesRestResponse(RestStatus.OK, BytesRestResponse.TEXT_CONTENT_TYPE, BytesArray.EMPTY);
        }
    };
    AssertionError error = expectThrows(AssertionError.class, () -> builderListener.buildResponse(Empty.INSTANCE));
    assertEquals("callers should ensure the XContentBuilder is closed themselves", error.getMessage());
}
Also used : Empty(org.opensearch.transport.TransportResponse.Empty) BytesRestResponse(org.opensearch.rest.BytesRestResponse) FakeRestChannel(org.opensearch.test.rest.FakeRestChannel) FakeRestRequest(org.opensearch.test.rest.FakeRestRequest) XContentBuilder(org.opensearch.common.xcontent.XContentBuilder)

Example 5 with Empty

use of org.opensearch.transport.TransportResponse.Empty in project OpenSearch by opensearch-project.

the class FollowersCheckerTests method testBehaviourOfFailingNode.

private void testBehaviourOfFailingNode(Settings testSettings, Supplier<TransportResponse.Empty> responder, String failureReason, long expectedFailureTime, NodeHealthService nodeHealthService) {
    final DiscoveryNode localNode = new DiscoveryNode("local-node", buildNewFakeTransportAddress(), Version.CURRENT);
    final DiscoveryNode otherNode = new DiscoveryNode("other-node", buildNewFakeTransportAddress(), Version.CURRENT);
    final Settings settings = Settings.builder().put(NODE_NAME_SETTING.getKey(), localNode.getName()).put(testSettings).build();
    final DeterministicTaskQueue deterministicTaskQueue = new DeterministicTaskQueue(settings, random());
    final MockTransport mockTransport = new MockTransport() {

        @Override
        protected void onSendRequest(long requestId, String action, TransportRequest request, DiscoveryNode node) {
            assertNotEquals(node, localNode);
            deterministicTaskQueue.scheduleNow(new Runnable() {

                @Override
                public void run() {
                    if (node.equals(otherNode) == false) {
                        // other nodes are ok
                        handleResponse(requestId, Empty.INSTANCE);
                        return;
                    }
                    try {
                        final Empty response = responder.get();
                        if (response != null) {
                            handleResponse(requestId, response);
                        }
                    } catch (Exception e) {
                        handleRemoteError(requestId, e);
                    }
                }

                @Override
                public String toString() {
                    return "sending response to [" + action + "][" + requestId + "] from " + node;
                }
            });
        }
    };
    final TransportService transportService = mockTransport.createTransportService(settings, deterministicTaskQueue.getThreadPool(), TransportService.NOOP_TRANSPORT_INTERCEPTOR, boundTransportAddress -> localNode, null, emptySet());
    transportService.start();
    transportService.acceptIncomingRequests();
    final AtomicBoolean nodeFailed = new AtomicBoolean();
    final FollowersChecker followersChecker = new FollowersChecker(settings, transportService, fcr -> {
        assert false : fcr;
    }, (node, reason) -> {
        assertTrue(nodeFailed.compareAndSet(false, true));
        assertThat(reason, equalTo(failureReason));
    }, nodeHealthService);
    DiscoveryNodes discoveryNodes = DiscoveryNodes.builder().add(localNode).add(otherNode).localNodeId(localNode.getId()).build();
    followersChecker.setCurrentNodes(discoveryNodes);
    while (nodeFailed.get() == false) {
        if (deterministicTaskQueue.hasRunnableTasks() == false) {
            deterministicTaskQueue.advanceTime();
        }
        deterministicTaskQueue.runAllRunnableTasks();
    }
    assertThat(deterministicTaskQueue.getCurrentTimeMillis(), equalTo(expectedFailureTime));
    assertThat(followersChecker.getFaultyNodes(), contains(otherNode));
    deterministicTaskQueue.runAllTasks();
    // add another node and see that it schedules checks for this new node but keeps on considering the old one faulty
    final DiscoveryNode otherNode2 = new DiscoveryNode("other-node-2", buildNewFakeTransportAddress(), Version.CURRENT);
    discoveryNodes = DiscoveryNodes.builder(discoveryNodes).add(otherNode2).build();
    followersChecker.setCurrentNodes(discoveryNodes);
    deterministicTaskQueue.runAllRunnableTasks();
    deterministicTaskQueue.advanceTime();
    deterministicTaskQueue.runAllRunnableTasks();
    assertThat(followersChecker.getFaultyNodes(), contains(otherNode));
    // remove the faulty node and see that it is removed
    discoveryNodes = DiscoveryNodes.builder(discoveryNodes).remove(otherNode).build();
    followersChecker.setCurrentNodes(discoveryNodes);
    assertThat(followersChecker.getFaultyNodes(), empty());
    deterministicTaskQueue.runAllRunnableTasks();
    deterministicTaskQueue.advanceTime();
    deterministicTaskQueue.runAllRunnableTasks();
    // remove the working node and see that everything eventually stops
    discoveryNodes = DiscoveryNodes.builder(discoveryNodes).remove(otherNode2).build();
    followersChecker.setCurrentNodes(discoveryNodes);
    deterministicTaskQueue.runAllTasks();
    // add back the faulty node afresh and see that it fails again
    discoveryNodes = DiscoveryNodes.builder(discoveryNodes).add(otherNode).build();
    followersChecker.setCurrentNodes(discoveryNodes);
    nodeFailed.set(false);
    assertThat(followersChecker.getFaultyNodes(), empty());
    deterministicTaskQueue.runAllTasksInTimeOrder();
    assertTrue(nodeFailed.get());
    assertThat(followersChecker.getFaultyNodes(), contains(otherNode));
}
Also used : DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) TransportRequest(org.opensearch.transport.TransportRequest) OpenSearchException(org.opensearch.OpenSearchException) ConnectTransportException(org.opensearch.transport.ConnectTransportException) TransportException(org.opensearch.transport.TransportException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Empty(org.opensearch.transport.TransportResponse.Empty) TransportService(org.opensearch.transport.TransportService) MockTransport(org.opensearch.test.transport.MockTransport) Settings(org.opensearch.common.settings.Settings) DiscoveryNodes(org.opensearch.cluster.node.DiscoveryNodes)

Aggregations

Empty (org.opensearch.transport.TransportResponse.Empty)6 XContentBuilder (org.opensearch.common.xcontent.XContentBuilder)3 BytesRestResponse (org.opensearch.rest.BytesRestResponse)3 FakeRestChannel (org.opensearch.test.rest.FakeRestChannel)3 FakeRestRequest (org.opensearch.test.rest.FakeRestRequest)3 AtomicReference (java.util.concurrent.atomic.AtomicReference)2 OpenSearchException (org.opensearch.OpenSearchException)2 DiscoveryNode (org.opensearch.cluster.node.DiscoveryNode)2 Settings (org.opensearch.common.settings.Settings)2 StatusInfo (org.opensearch.monitor.StatusInfo)2 TransportException (org.opensearch.transport.TransportException)2 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 ParameterizedMessage (org.apache.logging.log4j.message.ParameterizedMessage)1 DiscoveryNodes (org.opensearch.cluster.node.DiscoveryNodes)1 StreamInput (org.opensearch.common.io.stream.StreamInput)1 MockTransport (org.opensearch.test.transport.MockTransport)1 ConnectTransportException (org.opensearch.transport.ConnectTransportException)1 TransportRequest (org.opensearch.transport.TransportRequest)1 TransportService (org.opensearch.transport.TransportService)1