Search in sources :

Example 1 with Evolving

use of org.apache.kafka.common.annotation.InterfaceStability.Evolving in project kafka by apache.

the class KafkaStreams method query.

/**
 * Run an interactive query against a state store.
 * <p>
 * This method allows callers outside of the Streams runtime to access the internal state of
 * stateful processors. See https://kafka.apache.org/documentation/streams/developer-guide/interactive-queries.html
 * for more information.
 *
 * @param <R> The result type specified by the query.
 * @throws StreamsNotStartedException If Streams has not yet been started. Just call {@link
 *                                    KafkaStreams#start()} and then retry this call.
 * @throws StreamsStoppedException    If Streams is in a terminal state like PENDING_SHUTDOWN,
 *                                    NOT_RUNNING, PENDING_ERROR, or ERROR. The caller should
 *                                    discover a new instance to query.
 * @throws UnknownStateStoreException If the specified store name does not exist in the
 *                                    topology.
 */
@Evolving
public <R> StateQueryResult<R> query(final StateQueryRequest<R> request) {
    final String storeName = request.getStoreName();
    if (!topologyMetadata.hasStore(storeName)) {
        throw new UnknownStateStoreException("Cannot get state store " + storeName + " because no such store is registered in the topology.");
    }
    if (state().hasNotStarted()) {
        throw new StreamsNotStartedException("KafkaStreams has not been started, you can retry after calling start().");
    }
    if (state().isShuttingDown() || state.hasCompletedShutdown()) {
        throw new StreamsStoppedException("KafkaStreams has been stopped (" + state + ")." + " This instance can no longer serve queries.");
    }
    final StateQueryResult<R> result = new StateQueryResult<>();
    final Map<String, StateStore> globalStateStores = topologyMetadata.globalStateStores();
    if (globalStateStores.containsKey(storeName)) {
        // See KAFKA-13523
        result.setGlobalResult(QueryResult.forFailure(FailureReason.UNKNOWN_QUERY_TYPE, "Global stores do not yet support the KafkaStreams#query API. Use KafkaStreams#store instead."));
    } else {
        for (final StreamThread thread : threads) {
            final Map<TaskId, Task> tasks = thread.allTasks();
            for (final Entry<TaskId, Task> entry : tasks.entrySet()) {
                final TaskId taskId = entry.getKey();
                final int partition = taskId.partition();
                if (request.isAllPartitions() || request.getPartitions().contains(partition)) {
                    final Task task = entry.getValue();
                    final StateStore store = task.getStore(storeName);
                    if (store != null) {
                        final StreamThread.State state = thread.state();
                        final boolean active = task.isActive();
                        if (request.isRequireActive() && (state != StreamThread.State.RUNNING || !active)) {
                            result.addResult(partition, QueryResult.forFailure(FailureReason.NOT_ACTIVE, "Query requires a running active task," + " but partition was in state " + state + " and was " + (active ? "active" : "not active") + "."));
                        } else {
                            final QueryResult<R> r = store.query(request.getQuery(), request.isRequireActive() ? PositionBound.unbounded() : request.getPositionBound(), new QueryConfig(request.executionInfoEnabled()));
                            result.addResult(partition, r);
                        }
                        // we can return right away.
                        if (!request.isAllPartitions() && result.getPartitionResults().keySet().containsAll(request.getPartitions())) {
                            return result;
                        }
                    }
                }
            }
        }
    }
    if (!request.isAllPartitions()) {
        for (final Integer partition : request.getPartitions()) {
            if (!result.getPartitionResults().containsKey(partition)) {
                result.addResult(partition, QueryResult.forFailure(FailureReason.NOT_PRESENT, "The requested partition was not present at the time of the query."));
            }
        }
    }
    return result;
}
Also used : State(org.apache.kafka.streams.processor.internals.GlobalStreamThread.State) Task(org.apache.kafka.streams.processor.internals.Task) TaskId(org.apache.kafka.streams.processor.TaskId) QueryConfig(org.apache.kafka.streams.query.QueryConfig) GlobalStreamThread(org.apache.kafka.streams.processor.internals.GlobalStreamThread) StreamThread(org.apache.kafka.streams.processor.internals.StreamThread) StateStore(org.apache.kafka.streams.processor.StateStore) StreamsNotStartedException(org.apache.kafka.streams.errors.StreamsNotStartedException) StreamsStoppedException(org.apache.kafka.streams.errors.StreamsStoppedException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) UnknownStateStoreException(org.apache.kafka.streams.errors.UnknownStateStoreException) StateQueryResult(org.apache.kafka.streams.query.StateQueryResult) Evolving(org.apache.kafka.common.annotation.InterfaceStability.Evolving)

Aggregations

AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 Evolving (org.apache.kafka.common.annotation.InterfaceStability.Evolving)1 StreamsNotStartedException (org.apache.kafka.streams.errors.StreamsNotStartedException)1 StreamsStoppedException (org.apache.kafka.streams.errors.StreamsStoppedException)1 UnknownStateStoreException (org.apache.kafka.streams.errors.UnknownStateStoreException)1 StateStore (org.apache.kafka.streams.processor.StateStore)1 TaskId (org.apache.kafka.streams.processor.TaskId)1 GlobalStreamThread (org.apache.kafka.streams.processor.internals.GlobalStreamThread)1 State (org.apache.kafka.streams.processor.internals.GlobalStreamThread.State)1 StreamThread (org.apache.kafka.streams.processor.internals.StreamThread)1 Task (org.apache.kafka.streams.processor.internals.Task)1 QueryConfig (org.apache.kafka.streams.query.QueryConfig)1 StateQueryResult (org.apache.kafka.streams.query.StateQueryResult)1