Search in sources :

Example 31 with DiscoveryNode

use of org.elasticsearch.cluster.node.DiscoveryNode in project elasticsearch by elastic.

the class IndicesClusterStateServiceRandomUpdatesTests method randomlyUpdateClusterState.

public ClusterState randomlyUpdateClusterState(ClusterState state, Map<DiscoveryNode, IndicesClusterStateService> clusterStateServiceMap, Supplier<MockIndicesService> indicesServiceSupplier) {
    // randomly create new indices (until we have 200 max)
    for (int i = 0; i < randomInt(5); i++) {
        if (state.metaData().indices().size() > 200) {
            break;
        }
        String name = "index_" + randomAsciiOfLength(15).toLowerCase(Locale.ROOT);
        Settings.Builder settingsBuilder = Settings.builder().put(SETTING_NUMBER_OF_SHARDS, randomIntBetween(1, 3)).put(SETTING_NUMBER_OF_REPLICAS, randomInt(2));
        if (randomBoolean()) {
            settingsBuilder.put(IndexMetaData.SETTING_SHADOW_REPLICAS, true).put(IndexMetaData.SETTING_SHARED_FILESYSTEM, true);
        }
        CreateIndexRequest request = new CreateIndexRequest(name, settingsBuilder.build()).waitForActiveShards(ActiveShardCount.NONE);
        state = cluster.createIndex(state, request);
        assertTrue(state.metaData().hasIndex(name));
    }
    // randomly delete indices
    Set<String> indicesToDelete = new HashSet<>();
    int numberOfIndicesToDelete = randomInt(Math.min(2, state.metaData().indices().size()));
    for (String index : randomSubsetOf(numberOfIndicesToDelete, state.metaData().indices().keys().toArray(String.class))) {
        indicesToDelete.add(state.metaData().index(index).getIndex().getName());
    }
    if (indicesToDelete.isEmpty() == false) {
        DeleteIndexRequest deleteRequest = new DeleteIndexRequest(indicesToDelete.toArray(new String[indicesToDelete.size()]));
        state = cluster.deleteIndices(state, deleteRequest);
        for (String index : indicesToDelete) {
            assertFalse(state.metaData().hasIndex(index));
        }
    }
    // randomly close indices
    int numberOfIndicesToClose = randomInt(Math.min(1, state.metaData().indices().size()));
    for (String index : randomSubsetOf(numberOfIndicesToClose, state.metaData().indices().keys().toArray(String.class))) {
        CloseIndexRequest closeIndexRequest = new CloseIndexRequest(state.metaData().index(index).getIndex().getName());
        state = cluster.closeIndices(state, closeIndexRequest);
    }
    // randomly open indices
    int numberOfIndicesToOpen = randomInt(Math.min(1, state.metaData().indices().size()));
    for (String index : randomSubsetOf(numberOfIndicesToOpen, state.metaData().indices().keys().toArray(String.class))) {
        OpenIndexRequest openIndexRequest = new OpenIndexRequest(state.metaData().index(index).getIndex().getName());
        state = cluster.openIndices(state, openIndexRequest);
    }
    // randomly update settings
    Set<String> indicesToUpdate = new HashSet<>();
    boolean containsClosedIndex = false;
    int numberOfIndicesToUpdate = randomInt(Math.min(2, state.metaData().indices().size()));
    for (String index : randomSubsetOf(numberOfIndicesToUpdate, state.metaData().indices().keys().toArray(String.class))) {
        indicesToUpdate.add(state.metaData().index(index).getIndex().getName());
        if (state.metaData().index(index).getState() == IndexMetaData.State.CLOSE) {
            containsClosedIndex = true;
        }
    }
    if (indicesToUpdate.isEmpty() == false) {
        UpdateSettingsRequest updateSettingsRequest = new UpdateSettingsRequest(indicesToUpdate.toArray(new String[indicesToUpdate.size()]));
        Settings.Builder settings = Settings.builder();
        if (containsClosedIndex == false) {
            settings.put(SETTING_NUMBER_OF_REPLICAS, randomInt(2));
        }
        settings.put("index.refresh_interval", randomIntBetween(1, 5) + "s");
        updateSettingsRequest.settings(settings.build());
        state = cluster.updateSettings(state, updateSettingsRequest);
    }
    // randomly reroute
    if (rarely()) {
        state = cluster.reroute(state, new ClusterRerouteRequest());
    }
    // randomly start and fail allocated shards
    List<ShardRouting> startedShards = new ArrayList<>();
    List<FailedShard> failedShards = new ArrayList<>();
    for (DiscoveryNode node : state.nodes()) {
        IndicesClusterStateService indicesClusterStateService = clusterStateServiceMap.get(node);
        MockIndicesService indicesService = (MockIndicesService) indicesClusterStateService.indicesService;
        for (MockIndexService indexService : indicesService) {
            for (MockIndexShard indexShard : indexService) {
                ShardRouting persistedShardRouting = indexShard.routingEntry();
                if (persistedShardRouting.initializing() && randomBoolean()) {
                    startedShards.add(persistedShardRouting);
                } else if (rarely()) {
                    failedShards.add(new FailedShard(persistedShardRouting, "fake shard failure", new Exception()));
                }
            }
        }
    }
    state = cluster.applyFailedShards(state, failedShards);
    state = cluster.applyStartedShards(state, startedShards);
    // randomly add and remove nodes (except current master)
    if (rarely()) {
        if (randomBoolean()) {
            // add node
            if (state.nodes().getSize() < 10) {
                DiscoveryNodes newNodes = DiscoveryNodes.builder(state.nodes()).add(createNode()).build();
                state = ClusterState.builder(state).nodes(newNodes).build();
                // always reroute after node leave
                state = cluster.reroute(state, new ClusterRerouteRequest());
                updateNodes(state, clusterStateServiceMap, indicesServiceSupplier);
            }
        } else {
            // remove node
            if (state.nodes().getDataNodes().size() > 3) {
                DiscoveryNode discoveryNode = randomFrom(state.nodes().getNodes().values().toArray(DiscoveryNode.class));
                if (discoveryNode.equals(state.nodes().getMasterNode()) == false) {
                    DiscoveryNodes newNodes = DiscoveryNodes.builder(state.nodes()).remove(discoveryNode.getId()).build();
                    state = ClusterState.builder(state).nodes(newNodes).build();
                    state = cluster.deassociateDeadNodes(state, true, "removed and added a node");
                    updateNodes(state, clusterStateServiceMap, indicesServiceSupplier);
                }
                if (randomBoolean()) {
                    // and add it back
                    DiscoveryNodes newNodes = DiscoveryNodes.builder(state.nodes()).add(discoveryNode).build();
                    state = ClusterState.builder(state).nodes(newNodes).build();
                    state = cluster.reroute(state, new ClusterRerouteRequest());
                    updateNodes(state, clusterStateServiceMap, indicesServiceSupplier);
                }
            }
        }
    }
    return state;
}
Also used : DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) UpdateSettingsRequest(org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest) ArrayList(java.util.ArrayList) DeleteIndexRequest(org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest) ClusterRerouteRequest(org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteRequest) Settings(org.elasticsearch.common.settings.Settings) DiscoveryNodes(org.elasticsearch.cluster.node.DiscoveryNodes) HashSet(java.util.HashSet) OpenIndexRequest(org.elasticsearch.action.admin.indices.open.OpenIndexRequest) FailedShard(org.elasticsearch.cluster.routing.allocation.FailedShard) CloseIndexRequest(org.elasticsearch.action.admin.indices.close.CloseIndexRequest) CreateIndexRequest(org.elasticsearch.action.admin.indices.create.CreateIndexRequest) ShardRouting(org.elasticsearch.cluster.routing.ShardRouting)

Example 32 with DiscoveryNode

use of org.elasticsearch.cluster.node.DiscoveryNode in project elasticsearch by elastic.

the class IndicesClusterStateServiceRandomUpdatesTests method testRandomClusterStateUpdates.

public void testRandomClusterStateUpdates() {
    // we have an IndicesClusterStateService per node in the cluster
    final Map<DiscoveryNode, IndicesClusterStateService> clusterStateServiceMap = new HashMap<>();
    ClusterState state = randomInitialClusterState(clusterStateServiceMap, MockIndicesService::new);
    // each of the following iterations represents a new cluster state update processed on all nodes
    for (int i = 0; i < 30; i++) {
        logger.info("Iteration {}", i);
        final ClusterState previousState = state;
        // calculate new cluster state
        for (int j = 0; j < randomInt(3); j++) {
            // multiple iterations to simulate batching of cluster states
            try {
                state = randomlyUpdateClusterState(state, clusterStateServiceMap, MockIndicesService::new);
            } catch (AssertionError error) {
                ClusterState finalState = state;
                logger.error((org.apache.logging.log4j.util.Supplier<?>) () -> new ParameterizedMessage("failed to random change state. last good state: \n{}", finalState), error);
                throw error;
            }
        }
        // apply cluster state to nodes (incl. master)
        for (DiscoveryNode node : state.nodes()) {
            IndicesClusterStateService indicesClusterStateService = clusterStateServiceMap.get(node);
            ClusterState localState = adaptClusterStateToLocalNode(state, node);
            ClusterState previousLocalState = adaptClusterStateToLocalNode(previousState, node);
            final ClusterChangedEvent event = new ClusterChangedEvent("simulated change " + i, localState, previousLocalState);
            try {
                indicesClusterStateService.applyClusterState(event);
            } catch (AssertionError error) {
                logger.error((org.apache.logging.log4j.util.Supplier<?>) () -> new ParameterizedMessage("failed to apply change on [{}].\n ***  Previous state ***\n{}\n ***  New state ***\n{}", node, event.previousState(), event.state()), error);
                throw error;
            }
            // check that cluster state has been properly applied to node
            assertClusterStateMatchesNodeState(localState, indicesClusterStateService);
        }
    }
    // TODO: check if we can go to green by starting all shards and finishing all iterations
    logger.info("Final cluster state: {}", state);
}
Also used : ClusterState(org.elasticsearch.cluster.ClusterState) DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) HashMap(java.util.HashMap) ClusterChangedEvent(org.elasticsearch.cluster.ClusterChangedEvent) Supplier(java.util.function.Supplier) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage)

Example 33 with DiscoveryNode

use of org.elasticsearch.cluster.node.DiscoveryNode in project elasticsearch by elastic.

the class IndicesClusterStateServiceRandomUpdatesTests method updateNodes.

private void updateNodes(ClusterState state, Map<DiscoveryNode, IndicesClusterStateService> clusterStateServiceMap, Supplier<MockIndicesService> indicesServiceSupplier) {
    for (DiscoveryNode node : state.nodes()) {
        clusterStateServiceMap.computeIfAbsent(node, discoveryNode -> {
            IndicesClusterStateService ics = createIndicesClusterStateService(discoveryNode, indicesServiceSupplier);
            ics.start();
            return ics;
        });
    }
    for (Iterator<Entry<DiscoveryNode, IndicesClusterStateService>> it = clusterStateServiceMap.entrySet().iterator(); it.hasNext(); ) {
        DiscoveryNode node = it.next().getKey();
        if (state.nodes().nodeExists(node) == false) {
            it.remove();
        }
    }
}
Also used : DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) Entry(java.util.Map.Entry)

Example 34 with DiscoveryNode

use of org.elasticsearch.cluster.node.DiscoveryNode in project elasticsearch by elastic.

the class RecoverySourceHandlerTests method testHandleExceptinoOnSendSendFiles.

public void testHandleExceptinoOnSendSendFiles() throws Throwable {
    Settings settings = Settings.builder().put("indices.recovery.concurrent_streams", 1).put("indices.recovery.concurrent_small_file_streams", 1).build();
    final RecoverySettings recoverySettings = new RecoverySettings(settings, service);
    final StartRecoveryRequest request = new StartRecoveryRequest(shardId, new DiscoveryNode("b", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT), new DiscoveryNode("b", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT), null, randomBoolean(), randomNonNegativeLong(), randomBoolean() ? SequenceNumbersService.UNASSIGNED_SEQ_NO : 0L);
    Path tempDir = createTempDir();
    Store store = newStore(tempDir, false);
    AtomicBoolean failedEngine = new AtomicBoolean(false);
    RecoverySourceHandler handler = new RecoverySourceHandler(null, null, request, () -> 0L, e -> () -> {
    }, recoverySettings.getChunkSize().bytesAsInt(), Settings.EMPTY) {

        @Override
        protected void failEngine(IOException cause) {
            assertFalse(failedEngine.get());
            failedEngine.set(true);
        }
    };
    Directory dir = store.directory();
    RandomIndexWriter writer = new RandomIndexWriter(random(), dir, newIndexWriterConfig());
    int numDocs = randomIntBetween(10, 100);
    for (int i = 0; i < numDocs; i++) {
        Document document = new Document();
        document.add(new StringField("id", Integer.toString(i), Field.Store.YES));
        document.add(newField("field", randomUnicodeOfCodepointLengthBetween(1, 10), TextField.TYPE_STORED));
        writer.addDocument(document);
    }
    writer.commit();
    writer.close();
    Store.MetadataSnapshot metadata = store.getMetadata(null);
    List<StoreFileMetaData> metas = new ArrayList<>();
    for (StoreFileMetaData md : metadata) {
        metas.add(md);
    }
    final boolean throwCorruptedIndexException = randomBoolean();
    Store targetStore = newStore(createTempDir(), false);
    try {
        handler.sendFiles(store, metas.toArray(new StoreFileMetaData[0]), (md) -> {
            if (throwCorruptedIndexException) {
                throw new RuntimeException(new CorruptIndexException("foo", "bar"));
            } else {
                throw new RuntimeException("boom");
            }
        });
        fail("exception index");
    } catch (RuntimeException ex) {
        assertNull(ExceptionsHelper.unwrapCorruption(ex));
        if (throwCorruptedIndexException) {
            assertEquals(ex.getMessage(), "[File corruption occurred on recovery but checksums are ok]");
        } else {
            assertEquals(ex.getMessage(), "boom");
        }
    } catch (CorruptIndexException ex) {
        fail("not expected here");
    }
    assertFalse(failedEngine.get());
    IOUtils.close(store, targetStore);
}
Also used : Path(java.nio.file.Path) DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) ArrayList(java.util.ArrayList) Store(org.elasticsearch.index.store.Store) CorruptIndexException(org.apache.lucene.index.CorruptIndexException) IOException(java.io.IOException) Document(org.apache.lucene.document.Document) ParsedDocument(org.elasticsearch.index.mapper.ParsedDocument) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) StoreFileMetaData(org.elasticsearch.index.store.StoreFileMetaData) StringField(org.apache.lucene.document.StringField) Settings(org.elasticsearch.common.settings.Settings) IndexSettings(org.elasticsearch.index.IndexSettings) ClusterSettings(org.elasticsearch.common.settings.ClusterSettings) RandomIndexWriter(org.apache.lucene.index.RandomIndexWriter) Directory(org.apache.lucene.store.Directory)

Example 35 with DiscoveryNode

use of org.elasticsearch.cluster.node.DiscoveryNode in project elasticsearch by elastic.

the class RecoveryStatusTests method testRenameTempFiles.

public void testRenameTempFiles() throws IOException {
    IndexService service = createIndex("foo");
    IndexShard indexShard = service.getShardOrNull(0);
    DiscoveryNode node = new DiscoveryNode("foo", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT);
    RecoveryTarget status = new RecoveryTarget(indexShard, node, new PeerRecoveryTargetService.RecoveryListener() {

        @Override
        public void onRecoveryDone(RecoveryState state) {
        }

        @Override
        public void onRecoveryFailure(RecoveryState state, RecoveryFailedException e, boolean sendShardFailure) {
        }
    }, version -> {
    });
    try (IndexOutput indexOutput = status.openAndPutIndexOutput("foo.bar", new StoreFileMetaData("foo.bar", 8 + CodecUtil.footerLength(), "9z51nw"), status.store())) {
        indexOutput.writeInt(1);
        IndexOutput openIndexOutput = status.getOpenIndexOutput("foo.bar");
        assertSame(openIndexOutput, indexOutput);
        openIndexOutput.writeInt(1);
        CodecUtil.writeFooter(indexOutput);
    }
    try {
        status.openAndPutIndexOutput("foo.bar", new StoreFileMetaData("foo.bar", 8 + CodecUtil.footerLength(), "9z51nw"), status.store());
        fail("file foo.bar is already opened and registered");
    } catch (IllegalStateException ex) {
        assertEquals("output for file [foo.bar] has already been created", ex.getMessage());
    // all well = it's already registered
    }
    status.removeOpenIndexOutputs("foo.bar");
    Set<String> strings = Sets.newHashSet(status.store().directory().listAll());
    String expectedFile = null;
    for (String file : strings) {
        if (Pattern.compile("recovery[.][\\w-]+[.]foo[.]bar").matcher(file).matches()) {
            expectedFile = file;
            break;
        }
    }
    assertNotNull(expectedFile);
    // we have to close it here otherwise rename fails since the write.lock is held by the engine
    indexShard.close("foo", false);
    status.renameAllTempFiles();
    strings = Sets.newHashSet(status.store().directory().listAll());
    assertTrue(strings.toString(), strings.contains("foo.bar"));
    assertFalse(strings.toString(), strings.contains(expectedFile));
    // we must fail the recovery because marking it as done will try to move the shard to POST_RECOVERY, which will fail because it's started
    status.fail(new RecoveryFailedException(status.state(), "end of test. OK.", null), false);
}
Also used : DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) IndexService(org.elasticsearch.index.IndexService) IndexShard(org.elasticsearch.index.shard.IndexShard) IndexOutput(org.apache.lucene.store.IndexOutput) StoreFileMetaData(org.elasticsearch.index.store.StoreFileMetaData)

Aggregations

DiscoveryNode (org.elasticsearch.cluster.node.DiscoveryNode)352 ClusterState (org.elasticsearch.cluster.ClusterState)83 ArrayList (java.util.ArrayList)82 Settings (org.elasticsearch.common.settings.Settings)79 DiscoveryNodes (org.elasticsearch.cluster.node.DiscoveryNodes)74 IOException (java.io.IOException)69 ShardRouting (org.elasticsearch.cluster.routing.ShardRouting)52 HashMap (java.util.HashMap)45 ShardId (org.elasticsearch.index.shard.ShardId)45 HashSet (java.util.HashSet)43 List (java.util.List)41 TransportAddress (org.elasticsearch.common.transport.TransportAddress)41 CountDownLatch (java.util.concurrent.CountDownLatch)39 MockTransportService (org.elasticsearch.test.transport.MockTransportService)39 IndexMetaData (org.elasticsearch.cluster.metadata.IndexMetaData)37 Map (java.util.Map)35 ExecutionException (java.util.concurrent.ExecutionException)35 Version (org.elasticsearch.Version)35 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)31 ClusterName (org.elasticsearch.cluster.ClusterName)30