Search in sources :

Example 1 with UnknownStateStoreException

use of org.apache.kafka.streams.errors.UnknownStateStoreException 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)

Example 2 with UnknownStateStoreException

use of org.apache.kafka.streams.errors.UnknownStateStoreException in project kafka by apache.

the class JoinStoreIntegrationTest method providingAJoinStoreNameShouldNotMakeTheJoinResultQueriable.

@Test
public void providingAJoinStoreNameShouldNotMakeTheJoinResultQueriable() throws InterruptedException {
    STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-no-store-access");
    final StreamsBuilder builder = new StreamsBuilder();
    final KStream<String, Integer> left = builder.stream(INPUT_TOPIC_LEFT, Consumed.with(Serdes.String(), Serdes.Integer()));
    final KStream<String, Integer> right = builder.stream(INPUT_TOPIC_RIGHT, Consumed.with(Serdes.String(), Serdes.Integer()));
    final CountDownLatch latch = new CountDownLatch(1);
    left.join(right, Integer::sum, JoinWindows.of(ofMillis(100)), StreamJoined.with(Serdes.String(), Serdes.Integer(), Serdes.Integer()).withStoreName("join-store"));
    try (final KafkaStreams kafkaStreams = new KafkaStreams(builder.build(), STREAMS_CONFIG)) {
        kafkaStreams.setStateListener((newState, oldState) -> {
            if (newState == KafkaStreams.State.RUNNING) {
                latch.countDown();
            }
        });
        kafkaStreams.start();
        latch.await();
        final UnknownStateStoreException exception = assertThrows(UnknownStateStoreException.class, () -> kafkaStreams.store(fromNameAndType("join-store", keyValueStore())));
        assertThat(exception.getMessage(), is("Cannot get state store join-store because no such store is registered in the topology."));
    }
}
Also used : StreamsBuilder(org.apache.kafka.streams.StreamsBuilder) KafkaStreams(org.apache.kafka.streams.KafkaStreams) UnknownStateStoreException(org.apache.kafka.streams.errors.UnknownStateStoreException) CountDownLatch(java.util.concurrent.CountDownLatch) IntegrationTest(org.apache.kafka.test.IntegrationTest) Test(org.junit.Test)

Example 3 with UnknownStateStoreException

use of org.apache.kafka.streams.errors.UnknownStateStoreException in project kafka by apache.

the class QueryableStateIntegrationTest method shouldRejectNonExistentStoreName.

@Test
public void shouldRejectNonExistentStoreName() throws InterruptedException {
    final String uniqueTestName = safeUniqueTestName(getClass(), testName);
    final String input = uniqueTestName + "-input";
    final String storeName = uniqueTestName + "-input-table";
    final StreamsBuilder builder = new StreamsBuilder();
    builder.table(input, Materialized.<String, String, KeyValueStore<Bytes, byte[]>>as(storeName).withKeySerde(Serdes.String()).withValueSerde(Serdes.String()));
    final Properties properties = mkProperties(mkMap(mkEntry(StreamsConfig.APPLICATION_ID_CONFIG, safeUniqueTestName(getClass(), testName)), mkEntry(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, CLUSTER.bootstrapServers())));
    CLUSTER.createTopic(input);
    try (final KafkaStreams streams = getRunningStreams(properties, builder, true)) {
        final ReadOnlyKeyValueStore<String, String> store = streams.store(fromNameAndType(storeName, keyValueStore()));
        assertThat(store, Matchers.notNullValue());
        final UnknownStateStoreException exception = assertThrows(UnknownStateStoreException.class, () -> streams.store(fromNameAndType("no-table", keyValueStore())));
        assertThat(exception.getMessage(), is("Cannot get state store no-table because no such store is registered in the topology."));
    }
}
Also used : StreamsBuilder(org.apache.kafka.streams.StreamsBuilder) Bytes(org.apache.kafka.common.utils.Bytes) KafkaStreams(org.apache.kafka.streams.KafkaStreams) UnknownStateStoreException(org.apache.kafka.streams.errors.UnknownStateStoreException) Utils.mkProperties(org.apache.kafka.common.utils.Utils.mkProperties) Properties(java.util.Properties) KafkaStreamsTest(org.apache.kafka.streams.KafkaStreamsTest) Test(org.junit.Test) IntegrationTest(org.apache.kafka.test.IntegrationTest)

Aggregations

UnknownStateStoreException (org.apache.kafka.streams.errors.UnknownStateStoreException)3 KafkaStreams (org.apache.kafka.streams.KafkaStreams)2 StreamsBuilder (org.apache.kafka.streams.StreamsBuilder)2 IntegrationTest (org.apache.kafka.test.IntegrationTest)2 Test (org.junit.Test)2 Properties (java.util.Properties)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 Evolving (org.apache.kafka.common.annotation.InterfaceStability.Evolving)1 Bytes (org.apache.kafka.common.utils.Bytes)1 Utils.mkProperties (org.apache.kafka.common.utils.Utils.mkProperties)1 KafkaStreamsTest (org.apache.kafka.streams.KafkaStreamsTest)1 StreamsNotStartedException (org.apache.kafka.streams.errors.StreamsNotStartedException)1 StreamsStoppedException (org.apache.kafka.streams.errors.StreamsStoppedException)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