All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.streamthoughts.azkarra.api.streams.KafkaStreamsContainer Maven / Gradle / Ivy

There is a newer version: 0.9.2
Show newest version
/*
 * Copyright 2019-2020 StreamThoughts.
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.streamthoughts.azkarra.api.streams;

import io.streamthoughts.azkarra.api.config.Conf;
import io.streamthoughts.azkarra.api.events.EventStream;
import io.streamthoughts.azkarra.api.events.reactive.EventStreamPublisher;
import io.streamthoughts.azkarra.api.model.Metric;
import io.streamthoughts.azkarra.api.model.MetricGroup;
import io.streamthoughts.azkarra.api.model.StreamsTopologyGraph;
import io.streamthoughts.azkarra.api.model.TimestampedValue;
import io.streamthoughts.azkarra.api.monad.Tuple;
import io.streamthoughts.azkarra.api.query.QueryableKafkaStreams;
import io.streamthoughts.azkarra.api.streams.consumer.ConsumerGroupOffsets;
import io.streamthoughts.azkarra.api.streams.store.LocalStatePartitionsInfo;
import io.streamthoughts.azkarra.api.streams.topology.TopologyMetadata;
import io.streamthoughts.azkarra.api.util.Endpoint;
import org.apache.kafka.clients.admin.AdminClient;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.common.serialization.Serde;
import org.apache.kafka.streams.KafkaStreams;
import org.apache.kafka.streams.StreamsConfig;
import org.apache.kafka.streams.Topology;
import org.apache.kafka.streams.TopologyDescription;
import org.apache.kafka.streams.processor.ThreadMetadata;

import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;

/**
 * A {@code KafkaStreamsContainer} is used to encapsulate and to manipulate a {@link KafkaStreams} instance
 * that can be running either locally or remotely.
 */
public interface KafkaStreamsContainer extends QueryableKafkaStreams {

    /**
     * Restarts this container.
     */
    void restart();

    /**
     * Closes this {@link KafkaStreams} instance.
     */
    default void close(final Duration timeout) {
        close(false, timeout);
    }

    /**
     * Closes this {@link KafkaStreams} instance and wait up to the timeout for the streams to be closed.
     *
     * A {@code timeout} of 0 means to return immediately (i.e {@code Duration.ZERO}
     *
     * @param cleanUp flag to clean up the local streams states.
     * @param timeout the duration to wait for the streams to shutdown.
     *
     */
    void close(final boolean cleanUp, final Duration timeout);

    /**
     * Gets the current state of the streams container.
     *
     * @return  a {@link TimestampedValue} instance.
     */
    TimestampedValue state();

    /**
     * Gets the local thread metadata.
     *
     * @return  a set of {@link ThreadMetadata} instance.
     */
    Set threadMetadata();

    /**
     * Gets the started epoch-time in milliseconds.
     *
     * @return  a unix epoch-time in milliseconds.
     */
    long startedSince();

    /**
     * Gets the configuration for this {@link KafkaStreams} instance.
     *
     * @return a {@link Conf} instance.
     */
    Conf streamsConfig();

    /**
     * Gets the id for this container.
     *
     * @return  a string container id.
     */
    String containerId();

    /**
     * Gets configured {@link StreamsConfig#APPLICATION_ID_CONFIG} for this {@link KafkaStreams} instance.
     *
     * @return  a string {@code application.id}
     */
    String applicationId();

    /**
     * Gets the endpoint configured for this {@link KafkaStreams} instance.
     *
     * @see StreamsConfig#APPLICATION_SERVER_CONFIG
     *
     * @return  an optional {@link Endpoint}
     */
    Optional endpoint();

    /**
     * Gets the last observed exception thrown the {@link KafkaStreams} instance.
     *
     * @return a {@link Throwable} instance.
     */
    Optional exception();

    /**
     * Gets the {@link TopologyMetadata} about the topology runs by this {@link KafkaStreams} instance.
     *
     * @return  a {@link TopologyMetadata} instance.
     */
    TopologyMetadata topologyMetadata();

    /**
     * Gets the {@link StreamsTopologyGraph} for this {@link KafkaStreams} instance.
     *
     * @return  a new {@link TopologyDescription} instance.
     */
    StreamsTopologyGraph topologyGraph();

    /**
     * Gets all {@link Metric}s for this {@link KafkaStreams} instance.
     *
     * @see KafkaStreams#metrics()
     *
     * @return  a {@code Set} of {@link Metric}.
     */
    default Set metrics() {
        return metrics(KafkaMetricFilter.all());
    }

    /**
     * Gets all {@link Metric}s for this {@link KafkaStreams} instance matching the specified {@link KafkaMetricFilter}.
     *
     * @see KafkaStreams#metrics()
     *
     * @param   filter the {@link KafkaMetricFilter} to be used.
     * @return         a {@code Set} of {@link Metric}.
     */
    Set metrics(final KafkaMetricFilter filter);

    /**
     * Gets the offsets for the topic/partitions assigned to this {@link KafkaStreams} instance.
     * If the {@link KafkaStreams} instance is not running then no offsets will be computed.
     *
     * @return  the {@link ConsumerGroupOffsets}.
     */
    ConsumerGroupOffsets offsets();

    /**
     * Gets the default {@link Serde} configured for key.
     *
     * @return  a optional {@link Serde} instance.
     */
    Optional defaultKeySerde();

    /**
     * Checks if the {@link KafkaStreams} is either RUNNING or REBALANCING.
     *
     * @return {@code false} if no {@link KafkaStreams} is initialized.
     */
    boolean isRunning() ;

    /**
     * Returns the wrapped {@link KafkaStreams} instance.
     *
     * This method can throw an {@link UnsupportedOperationException} if the {@link KafkaStreamsContainer}
     * implementation doesn't manage the {@link KafkaStreams} locally.
     *
     * @return  the {@link KafkaStreams}.
     */
    default KafkaStreams getKafkaStreams() {
        throw new UnsupportedOperationException();
    }
   /**
     * Returns the wrapped {@link Topology} instance.
     *
     * This method can throw an {@link UnsupportedOperationException} if the {@link KafkaStreamsContainer}
     * implementation doesn't manage the {@link KafkaStreams} locally.
     *
     * @return  the {@link Topology} instance.
     */
    default Topology getTopology() {
        throw new UnsupportedOperationException();
    }

    /**
     * Checks whether the given {@link Endpoint} is the same as this container.
     *
     * @param endpoint  the {@link Endpoint} to verify.
     * @return          {@code true} if the given host
     */
    boolean checkEndpoint(final Endpoint endpoint);

    /**
     * Gets the partition restoration and lag for all local state store.
     *
     * @see KafkaStreams#allLocalStorePartitionLags().
     * @return the list of {@link LocalStatePartitionsInfo}.
     */
    List allLocalStorePartitionInfos();

    /**
     * Describes the local {@code KafkaStreams} instance.
     *
     * @return  the {@link KafkaStreamsInstance} instance.
     */
    KafkaStreamsInstance describe();

    /**
     * Creates a new {@link Producer} instance using the same configs that the Kafka Streams instance.
     *
     * @param overrides the producer configs to overrides.
     */
    Producer createNewProducer(final Map overrides);

    /**
     * Gets a shared {@link AdminClient} instance for this {@link KafkaStreams} instance.
     *
     * @return a {@link AdminClient} instance.
     */
    AdminClient getAdminClient();

    /**
     * Gets a new {@link EventStreamPublisher} for the given event-tye.
     *
     * @param eventType the {@link EventStream} type.
     * @return          a new {@link EventStreamPublisher} instance.
     */
     EventStreamPublisher getEventStreamPublisherForType(final String eventType);

    /**
     * Registers a new {@link EventStream} to this container.
     *
     * @param eventStream   the {@link EventStream} to register.
     * @param    the record key-type.
     * @param    the record value-type.
     */
     void registerEventStream(final EventStream eventStream);

    /**
     * Gets the set of registered event streams.
     *
     * @return  the {@link Set} of event-streams.
     */
    Set listRegisteredEventStreamTypes();

    /**
     * Register a watcher to be notified of {@link KafkaStreams.State} change event.
     *
     * @param watcher   the {@link StateChangeWatcher} to be registered.
     */
    void addStateChangeWatcher(final StateChangeWatcher watcher);

    /**
     * Watch a {@link KafkaStreams} instance for {@link KafkaStreams.State} change.
     *
     * By default, a {@link StateChangeWatcher} is one time called, i.e. once it is triggered,
     * it has to re-register itself to watch for further changes.
     */
    interface StateChangeWatcher {

        /**
         * Should this watcher be called for the given {@link State}.
         *
         * @param newState  the new state of the {@link KafkaStreams} instance.
         * @return          {@code true} if this watcher must be called, {@code false} otherwise.
         */
        default boolean accept(final State newState) {
            return true;
        }

        /**
         * Called when state changes. This method should not be blocking.
         *
         * @param event the {@link StateChangeEvent}
         */
        void onChange(final StateChangeEvent event);
    }

    /**
     * A {@code KafkaMetricFilter} can be used to only get specific metrics.
     */
    interface KafkaMetricFilter extends Predicate> {

        static KafkaMetricFilter of(final Predicate> predicate) {
            return predicate::test;
        }

        static KafkaMetricFilter all() {
            return candidate -> true;
        }

        static KafkaMetricFilter filterByGroup(final String groupName) {
            return candidate -> candidate.left().equals(groupName);
        }

        static KafkaMetricFilter filterByGroupAndMetricName(final String groupName, final String metricName) {
            return candidate -> candidate.left().equals(groupName) && candidate.right().name().equals(metricName);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy