Search in sources :

Example 61 with IndexResponse

use of org.elasticsearch.action.index.IndexResponse in project elasticsearch by elastic.

the class TasksIT method testCanFetchIndexStatus.

/**
     * Very basic "is it plugged in" style test that indexes a document and makes sure that you can fetch the status of the process. The
     * goal here is to verify that the large moving parts that make fetching task status work fit together rather than to verify any
     * particular status results from indexing. For that, look at {@link TransportReplicationActionTests}. We intentionally don't use the
     * task recording mechanism used in other places in this test so we can make sure that the status fetching works properly over the wire.
     */
public void testCanFetchIndexStatus() throws Exception {
    // First latch waits for the task to start, second on blocks it from finishing.
    CountDownLatch taskRegistered = new CountDownLatch(1);
    CountDownLatch letTaskFinish = new CountDownLatch(1);
    Thread index = null;
    try {
        for (TransportService transportService : internalCluster().getInstances(TransportService.class)) {
            ((MockTaskManager) transportService.getTaskManager()).addListener(new MockTaskManagerListener() {

                @Override
                public void onTaskRegistered(Task task) {
                    if (task.getAction().startsWith(IndexAction.NAME)) {
                        taskRegistered.countDown();
                        logger.debug("Blocking [{}] starting", task);
                        try {
                            assertTrue(letTaskFinish.await(10, TimeUnit.SECONDS));
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }

                @Override
                public void onTaskUnregistered(Task task) {
                }

                @Override
                public void waitForTaskCompletion(Task task) {
                }
            });
        }
        // Need to run the task in a separate thread because node client's .execute() is blocked by our task listener
        index = new Thread(() -> {
            IndexResponse indexResponse = client().prepareIndex("test", "test").setSource("test", "test").get();
            assertArrayEquals(ReplicationResponse.EMPTY, indexResponse.getShardInfo().getFailures());
        });
        index.start();
        // waiting for at least one task to be registered
        assertTrue(taskRegistered.await(10, TimeUnit.SECONDS));
        ListTasksResponse listResponse = client().admin().cluster().prepareListTasks().setActions("indices:data/write/index*").setDetailed(true).get();
        assertThat(listResponse.getTasks(), not(empty()));
        for (TaskInfo task : listResponse.getTasks()) {
            assertNotNull(task.getStatus());
            GetTaskResponse getResponse = client().admin().cluster().prepareGetTask(task.getTaskId()).get();
            assertFalse("task should still be running", getResponse.getTask().isCompleted());
            TaskInfo fetchedWithGet = getResponse.getTask().getTask();
            assertEquals(task.getId(), fetchedWithGet.getId());
            assertEquals(task.getType(), fetchedWithGet.getType());
            assertEquals(task.getAction(), fetchedWithGet.getAction());
            assertEquals(task.getDescription(), fetchedWithGet.getDescription());
            assertEquals(task.getStatus(), fetchedWithGet.getStatus());
            assertEquals(task.getStartTime(), fetchedWithGet.getStartTime());
            assertThat(fetchedWithGet.getRunningTimeNanos(), greaterThanOrEqualTo(task.getRunningTimeNanos()));
            assertEquals(task.isCancellable(), fetchedWithGet.isCancellable());
            assertEquals(task.getParentTaskId(), fetchedWithGet.getParentTaskId());
        }
    } finally {
        letTaskFinish.countDown();
        if (index != null) {
            index.join();
        }
        assertBusy(() -> {
            assertEquals(emptyList(), client().admin().cluster().prepareListTasks().setActions("indices:data/write/index*").get().getTasks());
        });
    }
}
Also used : Task(org.elasticsearch.tasks.Task) MockTaskManagerListener(org.elasticsearch.test.tasks.MockTaskManagerListener) GetTaskResponse(org.elasticsearch.action.admin.cluster.node.tasks.get.GetTaskResponse) CountDownLatch(java.util.concurrent.CountDownLatch) ListTasksResponse(org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksResponse) MockTaskManager(org.elasticsearch.test.tasks.MockTaskManager) TaskInfo(org.elasticsearch.tasks.TaskInfo) SearchTransportService(org.elasticsearch.action.search.SearchTransportService) MockTransportService(org.elasticsearch.test.transport.MockTransportService) TransportService(org.elasticsearch.transport.TransportService) IndexResponse(org.elasticsearch.action.index.IndexResponse)

Example 62 with IndexResponse

use of org.elasticsearch.action.index.IndexResponse in project elasticsearch by elastic.

the class TransportBulkActionIngestTests method testSingleItemBulkActionIngestForward.

public void testSingleItemBulkActionIngestForward() throws Exception {
    localIngest = false;
    IndexRequest indexRequest = new IndexRequest("index", "type", "id");
    indexRequest.source(Collections.emptyMap());
    indexRequest.setPipeline("testpipeline");
    IndexResponse indexResponse = mock(IndexResponse.class);
    AtomicBoolean responseCalled = new AtomicBoolean(false);
    ActionListener<IndexResponse> listener = ActionListener.wrap(response -> {
        responseCalled.set(true);
        assertSame(indexResponse, response);
    }, e -> {
        throw new AssertionError(e);
    });
    singleItemBulkWriteAction.execute(null, indexRequest, listener);
    // should not have executed ingest locally
    verify(executionService, never()).executeBulkRequest(any(), any(), any());
    // but instead should have sent to a remote node with the transport service
    ArgumentCaptor<DiscoveryNode> node = ArgumentCaptor.forClass(DiscoveryNode.class);
    verify(transportService).sendRequest(node.capture(), eq(BulkAction.NAME), any(), remoteResponseHandler.capture());
    // make sure we used one of the nodes
    boolean usedNode1 = node.getValue() == remoteNode1;
    if (usedNode1 == false) {
        assertSame(remoteNode2, node.getValue());
    }
    // no local index execution
    assertFalse(action.isExecuted);
    // listener not called yet
    assertFalse(responseCalled.get());
    BulkItemResponse itemResponse = new BulkItemResponse(0, DocWriteRequest.OpType.CREATE, indexResponse);
    BulkItemResponse[] bulkItemResponses = new BulkItemResponse[1];
    bulkItemResponses[0] = itemResponse;
    // call the listener for the remote node
    remoteResponseHandler.getValue().handleResponse(new BulkResponse(bulkItemResponses, 0));
    // now the listener we passed should have been delegated to by the remote listener
    assertTrue(responseCalled.get());
    // still no local index execution
    assertFalse(action.isExecuted);
    // now make sure ingest nodes are rotated through with a subsequent request
    reset(transportService);
    singleItemBulkWriteAction.execute(null, indexRequest, listener);
    verify(transportService).sendRequest(node.capture(), eq(BulkAction.NAME), any(), remoteResponseHandler.capture());
    if (usedNode1) {
        assertSame(remoteNode2, node.getValue());
    } else {
        assertSame(remoteNode1, node.getValue());
    }
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) IndexResponse(org.elasticsearch.action.index.IndexResponse) IndexRequest(org.elasticsearch.action.index.IndexRequest)

Example 63 with IndexResponse

use of org.elasticsearch.action.index.IndexResponse in project elasticsearch by elastic.

the class TransportShardBulkActionTests method testUpdateReplicaRequestWithSuccess.

public void testUpdateReplicaRequestWithSuccess() throws Exception {
    DocWriteRequest writeRequest = new IndexRequest("index", "type", "id").source(Requests.INDEX_CONTENT_TYPE, "field", "value");
    BulkItemRequest replicaRequest = new BulkItemRequest(0, writeRequest);
    boolean created = randomBoolean();
    Translog.Location resultLocation = new Translog.Location(42, 42, 42);
    Engine.IndexResult indexResult = new FakeResult(1, 1, created, resultLocation);
    DocWriteResponse indexResponse = new IndexResponse(shardId, "index", "id", 1, 1, created);
    BulkItemResultHolder goodResults = new BulkItemResultHolder(indexResponse, indexResult, replicaRequest);
    Translog.Location originalLocation = new Translog.Location(21, 21, 21);
    BulkItemRequest[] items = new BulkItemRequest[0];
    BulkShardRequest bulkShardRequest = new BulkShardRequest(shardId, RefreshPolicy.NONE, items);
    Translog.Location newLocation = TransportShardBulkAction.updateReplicaRequest(goodResults, DocWriteRequest.OpType.INDEX, originalLocation, bulkShardRequest);
    BulkItemResponse primaryResponse = replicaRequest.getPrimaryResponse();
    // Check that the translog is successfully advanced
    assertThat(newLocation, equalTo(resultLocation));
    // Since this was not a conflict failure, the primary response
    // should be filled out with the failure information
    assertThat(primaryResponse.getItemId(), equalTo(0));
    assertThat(primaryResponse.getId(), equalTo("id"));
    assertThat(primaryResponse.getOpType(), equalTo(DocWriteRequest.OpType.INDEX));
    DocWriteResponse response = primaryResponse.getResponse();
    assertThat(response.status(), equalTo(created ? RestStatus.CREATED : RestStatus.OK));
}
Also used : DocWriteResponse(org.elasticsearch.action.DocWriteResponse) IndexRequest(org.elasticsearch.action.index.IndexRequest) Translog(org.elasticsearch.index.translog.Translog) IndexResponse(org.elasticsearch.action.index.IndexResponse) DocWriteRequest(org.elasticsearch.action.DocWriteRequest) Engine(org.elasticsearch.index.engine.Engine)

Example 64 with IndexResponse

use of org.elasticsearch.action.index.IndexResponse in project elasticsearch by elastic.

the class IndexingMasterFailoverIT method testMasterFailoverDuringIndexingWithMappingChanges.

/**
     * Indexing operations which entail mapping changes require a blocking request to the master node to update the mapping.
     * If the master node is being disrupted or if it cannot commit cluster state changes, it needs to retry within timeout limits.
     * This retry logic is implemented in TransportMasterNodeAction and tested by the following master failover scenario.
     */
public void testMasterFailoverDuringIndexingWithMappingChanges() throws Throwable {
    logger.info("--> start 4 nodes, 3 master, 1 data");
    final Settings sharedSettings = Settings.builder().put(FaultDetection.PING_TIMEOUT_SETTING.getKey(), // for hitting simulated network failures quickly
    "1s").put(FaultDetection.PING_RETRIES_SETTING.getKey(), // for hitting simulated network failures quickly
    "1").put("discovery.zen.join_timeout", // still long to induce failures but to long so test won't time out
    "10s").put(DiscoverySettings.PUBLISH_TIMEOUT_SETTING.getKey(), // <-- for hitting simulated network failures quickly
    "1s").put(ElectMasterService.DISCOVERY_ZEN_MINIMUM_MASTER_NODES_SETTING.getKey(), 2).build();
    internalCluster().startMasterOnlyNodes(3, sharedSettings);
    String dataNode = internalCluster().startDataOnlyNode(sharedSettings);
    logger.info("--> wait for all nodes to join the cluster");
    ensureStableCluster(4);
    // We index data with mapping changes into cluster and have master failover at same time
    client().admin().indices().prepareCreate("myindex").setSettings(Settings.builder().put("index.number_of_shards", 1).put("index.number_of_replicas", 0)).get();
    ensureGreen("myindex");
    final CyclicBarrier barrier = new CyclicBarrier(2);
    Thread indexingThread = new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                barrier.await();
            } catch (InterruptedException e) {
                logger.warn("Barrier interrupted", e);
                return;
            } catch (BrokenBarrierException e) {
                logger.warn("Broken barrier", e);
                return;
            }
            for (int i = 0; i < 10; i++) {
                // index data with mapping changes
                IndexResponse response = client(dataNode).prepareIndex("myindex", "mytype").setSource("field_" + i, "val").get();
                assertEquals(DocWriteResponse.Result.CREATED, response.getResult());
            }
        }
    });
    indexingThread.setName("indexingThread");
    indexingThread.start();
    barrier.await();
    // interrupt communication between master and other nodes in cluster
    String master = internalCluster().getMasterName();
    Set<String> otherNodes = new HashSet<>(Arrays.asList(internalCluster().getNodeNames()));
    otherNodes.remove(master);
    NetworkDisruption partition = new NetworkDisruption(new TwoPartitions(Collections.singleton(master), otherNodes), new NetworkDisconnect());
    internalCluster().setDisruptionScheme(partition);
    logger.info("--> disrupting network");
    partition.startDisrupting();
    logger.info("--> waiting for new master to be elected");
    ensureStableCluster(3, dataNode);
    partition.stopDisrupting();
    logger.info("--> waiting to heal");
    ensureStableCluster(4);
    indexingThread.join();
    ensureGreen("myindex");
    refresh();
    assertThat(client().prepareSearch("myindex").get().getHits().getTotalHits(), equalTo(10L));
}
Also used : BrokenBarrierException(java.util.concurrent.BrokenBarrierException) TwoPartitions(org.elasticsearch.test.disruption.NetworkDisruption.TwoPartitions) NetworkDisconnect(org.elasticsearch.test.disruption.NetworkDisruption.NetworkDisconnect) CyclicBarrier(java.util.concurrent.CyclicBarrier) IndexResponse(org.elasticsearch.action.index.IndexResponse) NetworkDisruption(org.elasticsearch.test.disruption.NetworkDisruption) DiscoverySettings(org.elasticsearch.discovery.DiscoverySettings) Settings(org.elasticsearch.common.settings.Settings) HashSet(java.util.HashSet)

Example 65 with IndexResponse

use of org.elasticsearch.action.index.IndexResponse in project elasticsearch by elastic.

the class DiscoveryWithServiceDisruptionsIT method testAckedIndexing.

/**
     * Test that we do not loose document whose indexing request was successful, under a randomly selected disruption scheme
     * We also collect &amp; report the type of indexing failures that occur.
     * <p>
     * This test is a superset of tests run in the Jepsen test suite, with the exception of versioned updates
     */
@TestLogging("_root:DEBUG,org.elasticsearch.action.bulk:TRACE,org.elasticsearch.action.get:TRACE,discovery:TRACE," + "org.elasticsearch.cluster.service:TRACE,org.elasticsearch.indices.recovery:TRACE," + "org.elasticsearch.indices.cluster:TRACE,org.elasticsearch.index.shard:TRACE")
public void testAckedIndexing() throws Exception {
    final int seconds = !(TEST_NIGHTLY && rarely()) ? 1 : 5;
    final String timeout = seconds + "s";
    final List<String> nodes = startCluster(rarely() ? 5 : 3);
    assertAcked(prepareCreate("test").setSettings(Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1 + randomInt(2)).put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, randomInt(2)).put(IndexSettings.INDEX_SEQ_NO_CHECKPOINT_SYNC_INTERVAL.getKey(), randomBoolean() ? "5s" : "200ms")));
    ensureGreen();
    ServiceDisruptionScheme disruptionScheme = addRandomDisruptionScheme();
    logger.info("disruption scheme [{}] added", disruptionScheme);
    // id -> node sent.
    final ConcurrentHashMap<String, String> ackedDocs = new ConcurrentHashMap<>();
    final AtomicBoolean stop = new AtomicBoolean(false);
    List<Thread> indexers = new ArrayList<>(nodes.size());
    List<Semaphore> semaphores = new ArrayList<>(nodes.size());
    final AtomicInteger idGenerator = new AtomicInteger(0);
    final AtomicReference<CountDownLatch> countDownLatchRef = new AtomicReference<>();
    final List<Exception> exceptedExceptions = Collections.synchronizedList(new ArrayList<Exception>());
    logger.info("starting indexers");
    try {
        for (final String node : nodes) {
            final Semaphore semaphore = new Semaphore(0);
            semaphores.add(semaphore);
            final Client client = client(node);
            final String name = "indexer_" + indexers.size();
            final int numPrimaries = getNumShards("test").numPrimaries;
            Thread thread = new Thread(() -> {
                while (!stop.get()) {
                    String id = null;
                    try {
                        if (!semaphore.tryAcquire(10, TimeUnit.SECONDS)) {
                            continue;
                        }
                        logger.info("[{}] Acquired semaphore and it has {} permits left", name, semaphore.availablePermits());
                        try {
                            id = Integer.toString(idGenerator.incrementAndGet());
                            int shard = Math.floorMod(Murmur3HashFunction.hash(id), numPrimaries);
                            logger.trace("[{}] indexing id [{}] through node [{}] targeting shard [{}]", name, id, node, shard);
                            IndexResponse response = client.prepareIndex("test", "type", id).setSource("{}", XContentType.JSON).setTimeout(timeout).get(timeout);
                            assertEquals(DocWriteResponse.Result.CREATED, response.getResult());
                            ackedDocs.put(id, node);
                            logger.trace("[{}] indexed id [{}] through node [{}]", name, id, node);
                        } catch (ElasticsearchException e) {
                            exceptedExceptions.add(e);
                            final String docId = id;
                            logger.trace((Supplier<?>) () -> new ParameterizedMessage("[{}] failed id [{}] through node [{}]", name, docId, node), e);
                        } finally {
                            countDownLatchRef.get().countDown();
                            logger.trace("[{}] decreased counter : {}", name, countDownLatchRef.get().getCount());
                        }
                    } catch (InterruptedException e) {
                    // fine - semaphore interrupt
                    } catch (AssertionError | Exception e) {
                        logger.info((Supplier<?>) () -> new ParameterizedMessage("unexpected exception in background thread of [{}]", node), e);
                    }
                }
            });
            thread.setName(name);
            thread.start();
            indexers.add(thread);
        }
        int docsPerIndexer = randomInt(3);
        logger.info("indexing {} docs per indexer before partition", docsPerIndexer);
        countDownLatchRef.set(new CountDownLatch(docsPerIndexer * indexers.size()));
        for (Semaphore semaphore : semaphores) {
            semaphore.release(docsPerIndexer);
        }
        assertTrue(countDownLatchRef.get().await(1, TimeUnit.MINUTES));
        for (int iter = 1 + randomInt(2); iter > 0; iter--) {
            logger.info("starting disruptions & indexing (iteration [{}])", iter);
            disruptionScheme.startDisrupting();
            docsPerIndexer = 1 + randomInt(5);
            logger.info("indexing {} docs per indexer during partition", docsPerIndexer);
            countDownLatchRef.set(new CountDownLatch(docsPerIndexer * indexers.size()));
            Collections.shuffle(semaphores, random());
            for (Semaphore semaphore : semaphores) {
                assertThat(semaphore.availablePermits(), equalTo(0));
                semaphore.release(docsPerIndexer);
            }
            logger.info("waiting for indexing requests to complete");
            assertTrue(countDownLatchRef.get().await(docsPerIndexer * seconds * 1000 + 2000, TimeUnit.MILLISECONDS));
            logger.info("stopping disruption");
            disruptionScheme.stopDisrupting();
            for (String node : internalCluster().getNodeNames()) {
                ensureStableCluster(nodes.size(), TimeValue.timeValueMillis(disruptionScheme.expectedTimeToHeal().millis() + DISRUPTION_HEALING_OVERHEAD.millis()), true, node);
            }
            ensureGreen("test");
            logger.info("validating successful docs");
            assertBusy(() -> {
                for (String node : nodes) {
                    try {
                        logger.debug("validating through node [{}] ([{}] acked docs)", node, ackedDocs.size());
                        for (String id : ackedDocs.keySet()) {
                            assertTrue("doc [" + id + "] indexed via node [" + ackedDocs.get(id) + "] not found", client(node).prepareGet("test", "type", id).setPreference("_local").get().isExists());
                        }
                    } catch (AssertionError | NoShardAvailableActionException e) {
                        throw new AssertionError(e.getMessage() + " (checked via node [" + node + "]", e);
                    }
                }
            }, 30, TimeUnit.SECONDS);
            logger.info("done validating (iteration [{}])", iter);
        }
    } finally {
        if (exceptedExceptions.size() > 0) {
            StringBuilder sb = new StringBuilder();
            for (Exception e : exceptedExceptions) {
                sb.append("\n").append(e.getMessage());
            }
            logger.debug("Indexing exceptions during disruption: {}", sb);
        }
        logger.info("shutting down indexers");
        stop.set(true);
        for (Thread indexer : indexers) {
            indexer.interrupt();
            indexer.join(60000);
        }
    }
}
Also used : ArrayList(java.util.ArrayList) ServiceDisruptionScheme(org.elasticsearch.test.disruption.ServiceDisruptionScheme) Semaphore(java.util.concurrent.Semaphore) ElasticsearchException(org.elasticsearch.ElasticsearchException) Supplier(org.apache.logging.log4j.util.Supplier) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Client(org.elasticsearch.client.Client) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) ElasticsearchException(org.elasticsearch.ElasticsearchException) CorruptIndexException(org.apache.lucene.index.CorruptIndexException) NoShardAvailableActionException(org.elasticsearch.action.NoShardAvailableActionException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) NoShardAvailableActionException(org.elasticsearch.action.NoShardAvailableActionException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) IndexResponse(org.elasticsearch.action.index.IndexResponse) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) TestLogging(org.elasticsearch.test.junit.annotations.TestLogging)

Aggregations

IndexResponse (org.elasticsearch.action.index.IndexResponse)103 Test (org.junit.Test)26 SearchResponse (org.elasticsearch.action.search.SearchResponse)18 IOException (java.io.IOException)15 CreateIndexResponse (org.elasticsearch.action.admin.indices.create.CreateIndexResponse)15 HashMap (java.util.HashMap)13 DeleteResponse (org.elasticsearch.action.delete.DeleteResponse)13 IndexRequest (org.elasticsearch.action.index.IndexRequest)13 ElasticsearchException (org.elasticsearch.ElasticsearchException)11 CountDownLatch (java.util.concurrent.CountDownLatch)10 XContentBuilder (org.elasticsearch.common.xcontent.XContentBuilder)8 BulkResponse (org.elasticsearch.action.bulk.BulkResponse)7 Settings (org.elasticsearch.common.settings.Settings)7 ArrayList (java.util.ArrayList)6 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)6 DeleteIndexResponse (org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse)6 ExecutionException (java.util.concurrent.ExecutionException)5 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)5 AtomicReference (java.util.concurrent.atomic.AtomicReference)5 BulkItemResponse (org.elasticsearch.action.bulk.BulkItemResponse)5