Search in sources :

Example 91 with ClusterState

use of org.elasticsearch.cluster.ClusterState in project elasticsearch by elastic.

the class TaskResultsService method storeResult.

public void storeResult(TaskResult taskResult, ActionListener<Void> listener) {
    ClusterState state = clusterService.state();
    if (state.routingTable().hasIndex(TASK_INDEX) == false) {
        CreateIndexRequest createIndexRequest = new CreateIndexRequest();
        createIndexRequest.settings(taskResultIndexSettings());
        createIndexRequest.index(TASK_INDEX);
        createIndexRequest.mapping(TASK_TYPE, taskResultIndexMapping(), XContentType.JSON);
        createIndexRequest.cause("auto(task api)");
        createIndexAction.execute(null, createIndexRequest, new ActionListener<CreateIndexResponse>() {

            @Override
            public void onResponse(CreateIndexResponse result) {
                doStoreResult(taskResult, listener);
            }

            @Override
            public void onFailure(Exception e) {
                if (ExceptionsHelper.unwrapCause(e) instanceof ResourceAlreadyExistsException) {
                    // we have the index, do it
                    try {
                        doStoreResult(taskResult, listener);
                    } catch (Exception inner) {
                        inner.addSuppressed(e);
                        listener.onFailure(inner);
                    }
                } else {
                    listener.onFailure(e);
                }
            }
        });
    } else {
        IndexMetaData metaData = state.getMetaData().index(TASK_INDEX);
        if (metaData.getMappings().containsKey(TASK_TYPE) == false) {
            // The index already exists but doesn't have our mapping
            client.admin().indices().preparePutMapping(TASK_INDEX).setType(TASK_TYPE).setSource(taskResultIndexMapping(), XContentType.JSON).execute(new ActionListener<PutMappingResponse>() {

                @Override
                public void onResponse(PutMappingResponse putMappingResponse) {
                    doStoreResult(taskResult, listener);
                }

                @Override
                public void onFailure(Exception e) {
                    listener.onFailure(e);
                }
            });
        } else {
            doStoreResult(taskResult, listener);
        }
    }
}
Also used : ClusterState(org.elasticsearch.cluster.ClusterState) ResourceAlreadyExistsException(org.elasticsearch.ResourceAlreadyExistsException) PutMappingResponse(org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse) CreateIndexRequest(org.elasticsearch.action.admin.indices.create.CreateIndexRequest) CreateIndexResponse(org.elasticsearch.action.admin.indices.create.CreateIndexResponse) ElasticsearchException(org.elasticsearch.ElasticsearchException) ResourceAlreadyExistsException(org.elasticsearch.ResourceAlreadyExistsException) IOException(java.io.IOException) IndexMetaData(org.elasticsearch.cluster.metadata.IndexMetaData)

Example 92 with ClusterState

use of org.elasticsearch.cluster.ClusterState in project elasticsearch by elastic.

the class SnapshotsService method deleteSnapshot.

/**
     * Deletes snapshot from repository.
     * <p>
     * If the snapshot is still running cancels the snapshot first and then deletes it from the repository.
     *
     * @param snapshot snapshot
     * @param listener listener
     * @param repositoryStateId the unique id for the state of the repository
     */
private void deleteSnapshot(final Snapshot snapshot, final DeleteSnapshotListener listener, final long repositoryStateId, final boolean immediatePriority) {
    Priority priority = immediatePriority ? Priority.IMMEDIATE : Priority.NORMAL;
    clusterService.submitStateUpdateTask("delete snapshot", new ClusterStateUpdateTask(priority) {

        boolean waitForSnapshot = false;

        @Override
        public ClusterState execute(ClusterState currentState) throws Exception {
            SnapshotDeletionsInProgress deletionsInProgress = currentState.custom(SnapshotDeletionsInProgress.TYPE);
            if (deletionsInProgress != null && deletionsInProgress.hasDeletionsInProgress()) {
                throw new ConcurrentSnapshotExecutionException(snapshot, "cannot delete - another snapshot is currently being deleted");
            }
            RestoreInProgress restoreInProgress = currentState.custom(RestoreInProgress.TYPE);
            if (restoreInProgress != null) {
                // and the files the restore depends on would all be gone
                if (restoreInProgress.entries().isEmpty() == false) {
                    throw new ConcurrentSnapshotExecutionException(snapshot, "cannot delete snapshot during a restore");
                }
            }
            ClusterState.Builder clusterStateBuilder = ClusterState.builder(currentState);
            SnapshotsInProgress snapshots = currentState.custom(SnapshotsInProgress.TYPE);
            SnapshotsInProgress.Entry snapshotEntry = snapshots != null ? snapshots.snapshot(snapshot) : null;
            if (snapshotEntry == null) {
                // This snapshot is not running - delete
                if (snapshots != null && !snapshots.entries().isEmpty()) {
                    // However other snapshots are running - cannot continue
                    throw new ConcurrentSnapshotExecutionException(snapshot, "another snapshot is currently running cannot delete");
                }
                // add the snapshot deletion to the cluster state
                SnapshotDeletionsInProgress.Entry entry = new SnapshotDeletionsInProgress.Entry(snapshot, System.currentTimeMillis(), repositoryStateId);
                if (deletionsInProgress != null) {
                    deletionsInProgress = deletionsInProgress.withAddedEntry(entry);
                } else {
                    deletionsInProgress = SnapshotDeletionsInProgress.newInstance(entry);
                }
                clusterStateBuilder.putCustom(SnapshotDeletionsInProgress.TYPE, deletionsInProgress);
            } else {
                // This snapshot is currently running - stopping shards first
                waitForSnapshot = true;
                ImmutableOpenMap<ShardId, ShardSnapshotStatus> shards;
                if (snapshotEntry.state() == State.STARTED && snapshotEntry.shards() != null) {
                    // snapshot is currently running - stop started shards
                    ImmutableOpenMap.Builder<ShardId, ShardSnapshotStatus> shardsBuilder = ImmutableOpenMap.builder();
                    for (ObjectObjectCursor<ShardId, ShardSnapshotStatus> shardEntry : snapshotEntry.shards()) {
                        ShardSnapshotStatus status = shardEntry.value;
                        if (!status.state().completed()) {
                            shardsBuilder.put(shardEntry.key, new ShardSnapshotStatus(status.nodeId(), State.ABORTED));
                        } else {
                            shardsBuilder.put(shardEntry.key, status);
                        }
                    }
                    shards = shardsBuilder.build();
                } else if (snapshotEntry.state() == State.INIT) {
                    // snapshot hasn't started yet - end it
                    shards = snapshotEntry.shards();
                    endSnapshot(snapshotEntry);
                } else {
                    boolean hasUncompletedShards = false;
                    // Cleanup in case a node gone missing and snapshot wasn't updated for some reason
                    for (ObjectCursor<ShardSnapshotStatus> shardStatus : snapshotEntry.shards().values()) {
                        // Check if we still have shard running on existing nodes
                        if (shardStatus.value.state().completed() == false && shardStatus.value.nodeId() != null && currentState.nodes().get(shardStatus.value.nodeId()) != null) {
                            hasUncompletedShards = true;
                            break;
                        }
                    }
                    if (hasUncompletedShards) {
                        // snapshot is being finalized - wait for shards to complete finalization process
                        logger.debug("trying to delete completed snapshot - should wait for shards to finalize on all nodes");
                        return currentState;
                    } else {
                        // no shards to wait for - finish the snapshot
                        logger.debug("trying to delete completed snapshot with no finalizing shards - can delete immediately");
                        shards = snapshotEntry.shards();
                        endSnapshot(snapshotEntry);
                    }
                }
                SnapshotsInProgress.Entry newSnapshot = new SnapshotsInProgress.Entry(snapshotEntry, State.ABORTED, shards);
                snapshots = new SnapshotsInProgress(newSnapshot);
                clusterStateBuilder.putCustom(SnapshotsInProgress.TYPE, snapshots);
            }
            return clusterStateBuilder.build();
        }

        @Override
        public void onFailure(String source, Exception e) {
            listener.onFailure(e);
        }

        @Override
        public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) {
            if (waitForSnapshot) {
                logger.trace("adding snapshot completion listener to wait for deleted snapshot to finish");
                addListener(new SnapshotCompletionListener() {

                    @Override
                    public void onSnapshotCompletion(Snapshot completedSnapshot, SnapshotInfo snapshotInfo) {
                        if (completedSnapshot.equals(snapshot)) {
                            logger.trace("deleted snapshot completed - deleting files");
                            removeListener(this);
                            threadPool.executor(ThreadPool.Names.SNAPSHOT).execute(() -> deleteSnapshot(completedSnapshot.getRepository(), completedSnapshot.getSnapshotId().getName(), listener, true));
                        }
                    }

                    @Override
                    public void onSnapshotFailure(Snapshot failedSnapshot, Exception e) {
                        if (failedSnapshot.equals(snapshot)) {
                            logger.trace("deleted snapshot failed - deleting files", e);
                            removeListener(this);
                            threadPool.executor(ThreadPool.Names.SNAPSHOT).execute(() -> deleteSnapshot(failedSnapshot.getRepository(), failedSnapshot.getSnapshotId().getName(), listener, true));
                        }
                    }
                });
            } else {
                logger.trace("deleted snapshot is not running - deleting files");
                deleteSnapshotFromRepository(snapshot, listener, repositoryStateId);
            }
        }
    });
}
Also used : ClusterState(org.elasticsearch.cluster.ClusterState) Priority(org.elasticsearch.common.Priority) ClusterStateUpdateTask(org.elasticsearch.cluster.ClusterStateUpdateTask) ImmutableOpenMap(org.elasticsearch.common.collect.ImmutableOpenMap) RepositoryMissingException(org.elasticsearch.repositories.RepositoryMissingException) IOException(java.io.IOException) SnapshotDeletionsInProgress(org.elasticsearch.cluster.SnapshotDeletionsInProgress) RestoreInProgress(org.elasticsearch.cluster.RestoreInProgress) SnapshotsInProgress(org.elasticsearch.cluster.SnapshotsInProgress) ShardSnapshotStatus(org.elasticsearch.cluster.SnapshotsInProgress.ShardSnapshotStatus) IndexShardSnapshotStatus(org.elasticsearch.index.snapshots.IndexShardSnapshotStatus) ObjectObjectCursor(com.carrotsearch.hppc.cursors.ObjectObjectCursor)

Example 93 with ClusterState

use of org.elasticsearch.cluster.ClusterState in project elasticsearch by elastic.

the class SnapshotsService method beginSnapshot.

/**
     * Starts snapshot.
     * <p>
     * Creates snapshot in repository and updates snapshot metadata record with list of shards that needs to be processed.
     *
     * @param clusterState               cluster state
     * @param snapshot                   snapshot meta data
     * @param partial                    allow partial snapshots
     * @param userCreateSnapshotListener listener
     */
private void beginSnapshot(final ClusterState clusterState, final SnapshotsInProgress.Entry snapshot, final boolean partial, final CreateSnapshotListener userCreateSnapshotListener) {
    boolean snapshotCreated = false;
    try {
        Repository repository = repositoriesService.repository(snapshot.snapshot().getRepository());
        MetaData metaData = clusterState.metaData();
        if (!snapshot.includeGlobalState()) {
            // Remove global state from the cluster state
            MetaData.Builder builder = MetaData.builder();
            for (IndexId index : snapshot.indices()) {
                builder.put(metaData.index(index.getName()), false);
            }
            metaData = builder.build();
        }
        repository.initializeSnapshot(snapshot.snapshot().getSnapshotId(), snapshot.indices(), metaData);
        snapshotCreated = true;
        if (snapshot.indices().isEmpty()) {
            // No indices in this snapshot - we are done
            userCreateSnapshotListener.onResponse();
            endSnapshot(snapshot);
            return;
        }
        clusterService.submitStateUpdateTask("update_snapshot [" + snapshot.snapshot() + "]", new ClusterStateUpdateTask() {

            boolean accepted = false;

            SnapshotsInProgress.Entry updatedSnapshot;

            String failure = null;

            @Override
            public ClusterState execute(ClusterState currentState) {
                SnapshotsInProgress snapshots = currentState.custom(SnapshotsInProgress.TYPE);
                List<SnapshotsInProgress.Entry> entries = new ArrayList<>();
                for (SnapshotsInProgress.Entry entry : snapshots.entries()) {
                    if (entry.snapshot().equals(snapshot.snapshot())) {
                        // Replace the snapshot that was just created
                        ImmutableOpenMap<ShardId, SnapshotsInProgress.ShardSnapshotStatus> shards = shards(currentState, entry.indices());
                        if (!partial) {
                            Tuple<Set<String>, Set<String>> indicesWithMissingShards = indicesWithMissingShards(shards, currentState.metaData());
                            Set<String> missing = indicesWithMissingShards.v1();
                            Set<String> closed = indicesWithMissingShards.v2();
                            if (missing.isEmpty() == false || closed.isEmpty() == false) {
                                StringBuilder failureMessage = new StringBuilder();
                                updatedSnapshot = new SnapshotsInProgress.Entry(entry, State.FAILED, shards);
                                entries.add(updatedSnapshot);
                                if (missing.isEmpty() == false) {
                                    failureMessage.append("Indices don't have primary shards ");
                                    failureMessage.append(missing);
                                }
                                if (closed.isEmpty() == false) {
                                    if (failureMessage.length() > 0) {
                                        failureMessage.append("; ");
                                    }
                                    failureMessage.append("Indices are closed ");
                                    failureMessage.append(closed);
                                }
                                failure = failureMessage.toString();
                                continue;
                            }
                        }
                        updatedSnapshot = new SnapshotsInProgress.Entry(entry, State.STARTED, shards);
                        entries.add(updatedSnapshot);
                        if (!completed(shards.values())) {
                            accepted = true;
                        }
                    } else {
                        entries.add(entry);
                    }
                }
                return ClusterState.builder(currentState).putCustom(SnapshotsInProgress.TYPE, new SnapshotsInProgress(Collections.unmodifiableList(entries))).build();
            }

            @Override
            public void onFailure(String source, Exception e) {
                logger.warn((Supplier<?>) () -> new ParameterizedMessage("[{}] failed to create snapshot", snapshot.snapshot().getSnapshotId()), e);
                removeSnapshotFromClusterState(snapshot.snapshot(), null, e, new CleanupAfterErrorListener(snapshot, true, userCreateSnapshotListener, e));
            }

            @Override
            public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) {
                // The userCreateSnapshotListener.onResponse() notifies caller that the snapshot was accepted
                // for processing. If client wants to wait for the snapshot completion, it can register snapshot
                // completion listener in this method. For the snapshot completion to work properly, the snapshot
                // should still exist when listener is registered.
                userCreateSnapshotListener.onResponse();
                // go ahead and continue working on this snapshot rather then end here.
                if (!accepted && updatedSnapshot != null) {
                    endSnapshot(updatedSnapshot, failure);
                }
            }
        });
    } catch (Exception e) {
        logger.warn((Supplier<?>) () -> new ParameterizedMessage("failed to create snapshot [{}]", snapshot.snapshot().getSnapshotId()), e);
        removeSnapshotFromClusterState(snapshot.snapshot(), null, e, new CleanupAfterErrorListener(snapshot, snapshotCreated, userCreateSnapshotListener, e));
    }
}
Also used : IndexId(org.elasticsearch.repositories.IndexId) ClusterState(org.elasticsearch.cluster.ClusterState) Set(java.util.Set) HashSet(java.util.HashSet) ClusterStateUpdateTask(org.elasticsearch.cluster.ClusterStateUpdateTask) ImmutableOpenMap(org.elasticsearch.common.collect.ImmutableOpenMap) RepositoryMissingException(org.elasticsearch.repositories.RepositoryMissingException) IOException(java.io.IOException) Repository(org.elasticsearch.repositories.Repository) MetaData(org.elasticsearch.cluster.metadata.MetaData) IndexMetaData(org.elasticsearch.cluster.metadata.IndexMetaData) RepositoriesMetaData(org.elasticsearch.cluster.metadata.RepositoriesMetaData) SnapshotsInProgress(org.elasticsearch.cluster.SnapshotsInProgress) List(java.util.List) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) Supplier(org.apache.logging.log4j.util.Supplier) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) Tuple(org.elasticsearch.common.collect.Tuple)

Example 94 with ClusterState

use of org.elasticsearch.cluster.ClusterState in project elasticsearch by elastic.

the class MainActionTests method testMainActionClusterAvailable.

public void testMainActionClusterAvailable() {
    final ClusterService clusterService = mock(ClusterService.class);
    final ClusterName clusterName = new ClusterName("elasticsearch");
    final Settings settings = Settings.builder().put("node.name", "my-node").build();
    final boolean available = randomBoolean();
    ClusterBlocks blocks;
    if (available) {
        if (randomBoolean()) {
            blocks = ClusterBlocks.EMPTY_CLUSTER_BLOCK;
        } else {
            blocks = ClusterBlocks.builder().addGlobalBlock(new ClusterBlock(randomIntBetween(1, 16), "test global block 400", randomBoolean(), randomBoolean(), RestStatus.BAD_REQUEST, ClusterBlockLevel.ALL)).build();
        }
    } else {
        blocks = ClusterBlocks.builder().addGlobalBlock(new ClusterBlock(randomIntBetween(1, 16), "test global block 503", randomBoolean(), randomBoolean(), RestStatus.SERVICE_UNAVAILABLE, ClusterBlockLevel.ALL)).build();
    }
    ClusterState state = ClusterState.builder(clusterName).blocks(blocks).build();
    when(clusterService.state()).thenReturn(state);
    TransportService transportService = new TransportService(Settings.EMPTY, null, null, TransportService.NOOP_TRANSPORT_INTERCEPTOR, x -> null, null);
    TransportMainAction action = new TransportMainAction(settings, mock(ThreadPool.class), transportService, mock(ActionFilters.class), mock(IndexNameExpressionResolver.class), clusterService);
    AtomicReference<MainResponse> responseRef = new AtomicReference<>();
    action.doExecute(new MainRequest(), new ActionListener<MainResponse>() {

        @Override
        public void onResponse(MainResponse mainResponse) {
            responseRef.set(mainResponse);
        }

        @Override
        public void onFailure(Exception e) {
            logger.error("unexpected error", e);
        }
    });
    assertNotNull(responseRef.get());
    assertEquals(available, responseRef.get().isAvailable());
    verify(clusterService, times(1)).state();
}
Also used : ClusterState(org.elasticsearch.cluster.ClusterState) ClusterBlocks(org.elasticsearch.cluster.block.ClusterBlocks) ThreadPool(org.elasticsearch.threadpool.ThreadPool) AtomicReference(java.util.concurrent.atomic.AtomicReference) ActionFilters(org.elasticsearch.action.support.ActionFilters) IOException(java.io.IOException) ClusterBlock(org.elasticsearch.cluster.block.ClusterBlock) ClusterService(org.elasticsearch.cluster.service.ClusterService) TransportService(org.elasticsearch.transport.TransportService) ClusterName(org.elasticsearch.cluster.ClusterName) IndexNameExpressionResolver(org.elasticsearch.cluster.metadata.IndexNameExpressionResolver) Settings(org.elasticsearch.common.settings.Settings)

Example 95 with ClusterState

use of org.elasticsearch.cluster.ClusterState in project elasticsearch by elastic.

the class ActiveShardCountTests method testEnoughShardsActiveZero.

public void testEnoughShardsActiveZero() {
    final String indexName = "test-idx";
    final int numberOfShards = randomIntBetween(1, 5);
    final int numberOfReplicas = randomIntBetween(4, 7);
    final ActiveShardCount waitForActiveShards = ActiveShardCount.NONE;
    ClusterState clusterState = initializeWithNewIndex(indexName, numberOfShards, numberOfReplicas);
    assertTrue(waitForActiveShards.enoughShardsActive(clusterState, indexName));
    clusterState = startPrimaries(clusterState, indexName);
    assertTrue(waitForActiveShards.enoughShardsActive(clusterState, indexName));
    clusterState = startAllShards(clusterState, indexName);
    assertTrue(waitForActiveShards.enoughShardsActive(clusterState, indexName));
}
Also used : ClusterState(org.elasticsearch.cluster.ClusterState)

Aggregations

ClusterState (org.elasticsearch.cluster.ClusterState)564 IndexMetaData (org.elasticsearch.cluster.metadata.IndexMetaData)211 MetaData (org.elasticsearch.cluster.metadata.MetaData)179 RoutingTable (org.elasticsearch.cluster.routing.RoutingTable)150 ShardRouting (org.elasticsearch.cluster.routing.ShardRouting)123 Settings (org.elasticsearch.common.settings.Settings)100 DiscoveryNode (org.elasticsearch.cluster.node.DiscoveryNode)85 ClusterName (org.elasticsearch.cluster.ClusterName)82 DiscoveryNodes (org.elasticsearch.cluster.node.DiscoveryNodes)75 Matchers.containsString (org.hamcrest.Matchers.containsString)72 IndexShardRoutingTable (org.elasticsearch.cluster.routing.IndexShardRoutingTable)62 ShardId (org.elasticsearch.index.shard.ShardId)61 RoutingNodes (org.elasticsearch.cluster.routing.RoutingNodes)59 ArrayList (java.util.ArrayList)57 IOException (java.io.IOException)55 Index (org.elasticsearch.index.Index)53 ClusterSettings (org.elasticsearch.common.settings.ClusterSettings)49 CountDownLatch (java.util.concurrent.CountDownLatch)47 HashSet (java.util.HashSet)45 List (java.util.List)45