Search in sources :

Example 66 with KeyValueTimestamp

use of org.apache.kafka.streams.KeyValueTimestamp in project kafka by apache.

the class SuppressScenarioTest method shouldWorkBeforeGroupBy.

@Test
public void shouldWorkBeforeGroupBy() {
    final StreamsBuilder builder = new StreamsBuilder();
    builder.table("topic", Consumed.with(Serdes.String(), Serdes.String())).suppress(untilTimeLimit(ofMillis(10), unbounded())).groupBy(KeyValue::pair, Grouped.with(Serdes.String(), Serdes.String())).count().toStream().to("output", Produced.with(Serdes.String(), Serdes.Long()));
    try (final TopologyTestDriver driver = new TopologyTestDriver(builder.build(), config)) {
        final TestInputTopic<String, String> inputTopic = driver.createInputTopic("topic", STRING_SERIALIZER, STRING_SERIALIZER);
        inputTopic.pipeInput("A", "a", 0L);
        inputTopic.pipeInput("tick", "tick", 10L);
        verify(drainProducerRecords(driver, "output", STRING_DESERIALIZER, LONG_DESERIALIZER), singletonList(new KeyValueTimestamp<>("A", 1L, 0L)));
    }
}
Also used : StreamsBuilder(org.apache.kafka.streams.StreamsBuilder) TopologyTestDriver(org.apache.kafka.streams.TopologyTestDriver) KeyValueTimestamp(org.apache.kafka.streams.KeyValueTimestamp) Test(org.junit.Test)

Example 67 with KeyValueTimestamp

use of org.apache.kafka.streams.KeyValueTimestamp in project kafka by apache.

the class SuppressScenarioTest method shouldSupportFinalResultsForTimeWindows.

@Test
public void shouldSupportFinalResultsForTimeWindows() {
    final StreamsBuilder builder = new StreamsBuilder();
    final KTable<Windowed<String>, Long> valueCounts = builder.stream("input", Consumed.with(STRING_SERDE, STRING_SERDE)).groupBy((String k, String v) -> k, Grouped.with(STRING_SERDE, STRING_SERDE)).windowedBy(TimeWindows.of(ofMillis(2L)).grace(ofMillis(1L))).count(Materialized.<String, Long, WindowStore<Bytes, byte[]>>as("counts").withCachingDisabled());
    valueCounts.suppress(untilWindowCloses(unbounded())).toStream().map((final Windowed<String> k, final Long v) -> new KeyValue<>(k.toString(), v)).to("output-suppressed", Produced.with(STRING_SERDE, Serdes.Long()));
    valueCounts.toStream().map((final Windowed<String> k, final Long v) -> new KeyValue<>(k.toString(), v)).to("output-raw", Produced.with(STRING_SERDE, Serdes.Long()));
    final Topology topology = builder.build();
    System.out.println(topology.describe());
    try (final TopologyTestDriver driver = new TopologyTestDriver(topology, config)) {
        final TestInputTopic<String, String> inputTopic = driver.createInputTopic("input", STRING_SERIALIZER, STRING_SERIALIZER);
        inputTopic.pipeInput("k1", "v1", 0L);
        inputTopic.pipeInput("k1", "v1", 1L);
        inputTopic.pipeInput("k1", "v1", 2L);
        inputTopic.pipeInput("k1", "v1", 1L);
        inputTopic.pipeInput("k1", "v1", 0L);
        inputTopic.pipeInput("k1", "v1", 5L);
        // note this last record gets dropped because it is out of the grace period
        inputTopic.pipeInput("k1", "v1", 0L);
        verify(drainProducerRecords(driver, "output-raw", STRING_DESERIALIZER, LONG_DESERIALIZER), asList(new KeyValueTimestamp<>("[k1@0/2]", 1L, 0L), new KeyValueTimestamp<>("[k1@0/2]", 2L, 1L), new KeyValueTimestamp<>("[k1@2/4]", 1L, 2L), new KeyValueTimestamp<>("[k1@0/2]", 3L, 1L), new KeyValueTimestamp<>("[k1@0/2]", 4L, 1L), new KeyValueTimestamp<>("[k1@4/6]", 1L, 5L)));
        verify(drainProducerRecords(driver, "output-suppressed", STRING_DESERIALIZER, LONG_DESERIALIZER), asList(new KeyValueTimestamp<>("[k1@0/2]", 4L, 1L), new KeyValueTimestamp<>("[k1@2/4]", 1L, 2L)));
    }
}
Also used : StreamsBuilder(org.apache.kafka.streams.StreamsBuilder) Windowed(org.apache.kafka.streams.kstream.Windowed) WindowStore(org.apache.kafka.streams.state.WindowStore) KeyValue(org.apache.kafka.streams.KeyValue) TopologyTestDriver(org.apache.kafka.streams.TopologyTestDriver) Topology(org.apache.kafka.streams.Topology) KeyValueTimestamp(org.apache.kafka.streams.KeyValueTimestamp) Test(org.junit.Test)

Example 68 with KeyValueTimestamp

use of org.apache.kafka.streams.KeyValueTimestamp in project kafka by apache.

the class SuppressScenarioTest method shouldSuppressIntermediateEventsWithTimeLimit.

@Test
public void shouldSuppressIntermediateEventsWithTimeLimit() {
    final StreamsBuilder builder = new StreamsBuilder();
    final KTable<String, Long> valueCounts = builder.table("input", Consumed.with(STRING_SERDE, STRING_SERDE), Materialized.<String, String, KeyValueStore<Bytes, byte[]>>with(STRING_SERDE, STRING_SERDE).withCachingDisabled().withLoggingDisabled()).groupBy((k, v) -> new KeyValue<>(v, k), Grouped.with(STRING_SERDE, STRING_SERDE)).count();
    valueCounts.suppress(untilTimeLimit(ofMillis(2L), unbounded())).toStream().to("output-suppressed", Produced.with(STRING_SERDE, Serdes.Long()));
    valueCounts.toStream().to("output-raw", Produced.with(STRING_SERDE, Serdes.Long()));
    final Topology topology = builder.build();
    try (final TopologyTestDriver driver = new TopologyTestDriver(topology, config)) {
        final TestInputTopic<String, String> inputTopic = driver.createInputTopic("input", STRING_SERIALIZER, STRING_SERIALIZER);
        inputTopic.pipeInput("k1", "v1", 0L);
        inputTopic.pipeInput("k1", "v2", 1L);
        inputTopic.pipeInput("k2", "v1", 2L);
        verify(drainProducerRecords(driver, "output-raw", STRING_DESERIALIZER, LONG_DESERIALIZER), asList(new KeyValueTimestamp<>("v1", 1L, 0L), new KeyValueTimestamp<>("v1", 0L, 1L), new KeyValueTimestamp<>("v2", 1L, 1L), new KeyValueTimestamp<>("v1", 1L, 2L)));
        verify(drainProducerRecords(driver, "output-suppressed", STRING_DESERIALIZER, LONG_DESERIALIZER), singletonList(new KeyValueTimestamp<>("v1", 1L, 2L)));
        // inserting a dummy "tick" record just to advance stream time
        inputTopic.pipeInput("tick", "tick", 3L);
        verify(drainProducerRecords(driver, "output-raw", STRING_DESERIALIZER, LONG_DESERIALIZER), singletonList(new KeyValueTimestamp<>("tick", 1L, 3L)));
        // the stream time is now 3, so it's time to emit this record
        verify(drainProducerRecords(driver, "output-suppressed", STRING_DESERIALIZER, LONG_DESERIALIZER), singletonList(new KeyValueTimestamp<>("v2", 1L, 1L)));
        inputTopic.pipeInput("tick", "tock", 4L);
        verify(drainProducerRecords(driver, "output-raw", STRING_DESERIALIZER, LONG_DESERIALIZER), asList(new KeyValueTimestamp<>("tick", 0L, 4L), new KeyValueTimestamp<>("tock", 1L, 4L)));
        // tick is still buffered, since it was first inserted at time 3, and it is only time 4 right now.
        verify(drainProducerRecords(driver, "output-suppressed", STRING_DESERIALIZER, LONG_DESERIALIZER), emptyList());
    }
}
Also used : StreamsBuilder(org.apache.kafka.streams.StreamsBuilder) Produced(org.apache.kafka.streams.kstream.Produced) Collections.singletonList(java.util.Collections.singletonList) StringDeserializer(org.apache.kafka.common.serialization.StringDeserializer) Serde(org.apache.kafka.common.serialization.Serde) Arrays.asList(java.util.Arrays.asList) KeyValueStore(org.apache.kafka.streams.state.KeyValueStore) Duration(java.time.Duration) BufferConfig.maxRecords(org.apache.kafka.streams.kstream.Suppressed.BufferConfig.maxRecords) Serdes(org.apache.kafka.common.serialization.Serdes) StringSerializer(org.apache.kafka.common.serialization.StringSerializer) TestRecord(org.apache.kafka.streams.test.TestRecord) TestUtils(org.apache.kafka.test.TestUtils) Collections.emptyList(java.util.Collections.emptyList) KeyValue(org.apache.kafka.streams.KeyValue) LongDeserializer(org.apache.kafka.common.serialization.LongDeserializer) Bytes(org.apache.kafka.common.utils.Bytes) List(java.util.List) Materialized(org.apache.kafka.streams.kstream.Materialized) ZERO(java.time.Duration.ZERO) Duration.ofMillis(java.time.Duration.ofMillis) Topology(org.apache.kafka.streams.Topology) StreamsConfig(org.apache.kafka.streams.StreamsConfig) KGroupedStream(org.apache.kafka.streams.kstream.KGroupedStream) SessionWindows(org.apache.kafka.streams.kstream.SessionWindows) BufferConfig.unbounded(org.apache.kafka.streams.kstream.Suppressed.BufferConfig.unbounded) CoreMatchers.equalTo(org.hamcrest.CoreMatchers.equalTo) KStream(org.apache.kafka.streams.kstream.KStream) BufferConfig.maxBytes(org.apache.kafka.streams.kstream.Suppressed.BufferConfig.maxBytes) WindowStore(org.apache.kafka.streams.state.WindowStore) Suppressed.untilWindowCloses(org.apache.kafka.streams.kstream.Suppressed.untilWindowCloses) Windowed(org.apache.kafka.streams.kstream.Windowed) Named(org.apache.kafka.streams.kstream.Named) Deserializer(org.apache.kafka.common.serialization.Deserializer) SessionStore(org.apache.kafka.streams.state.SessionStore) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Utils(org.apache.kafka.common.utils.Utils) TopologyTestDriver(org.apache.kafka.streams.TopologyTestDriver) StreamsBuilder(org.apache.kafka.streams.StreamsBuilder) KTable(org.apache.kafka.streams.kstream.KTable) Properties(java.util.Properties) Iterator(java.util.Iterator) Consumed(org.apache.kafka.streams.kstream.Consumed) Suppressed(org.apache.kafka.streams.kstream.Suppressed) Test(org.junit.Test) KeyValueTimestamp(org.apache.kafka.streams.KeyValueTimestamp) Grouped(org.apache.kafka.streams.kstream.Grouped) SlidingWindows(org.apache.kafka.streams.kstream.SlidingWindows) TimeWindows(org.apache.kafka.streams.kstream.TimeWindows) TestInputTopic(org.apache.kafka.streams.TestInputTopic) Comparator(java.util.Comparator) Suppressed.untilTimeLimit(org.apache.kafka.streams.kstream.Suppressed.untilTimeLimit) Bytes(org.apache.kafka.common.utils.Bytes) BufferConfig.maxBytes(org.apache.kafka.streams.kstream.Suppressed.BufferConfig.maxBytes) KeyValue(org.apache.kafka.streams.KeyValue) TopologyTestDriver(org.apache.kafka.streams.TopologyTestDriver) Topology(org.apache.kafka.streams.Topology) KeyValueTimestamp(org.apache.kafka.streams.KeyValueTimestamp) Test(org.junit.Test)

Example 69 with KeyValueTimestamp

use of org.apache.kafka.streams.KeyValueTimestamp in project kafka by apache.

the class EOSUncleanShutdownIntegrationTest method shouldWorkWithUncleanShutdownWipeOutStateStore.

@Test
public void shouldWorkWithUncleanShutdownWipeOutStateStore() throws InterruptedException {
    final String appId = "shouldWorkWithUncleanShutdownWipeOutStateStore";
    STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appId);
    STREAMS_CONFIG.put(StreamsConfig.PROCESSING_GUARANTEE_CONFIG, eosConfig);
    final String input = "input-topic";
    cleanStateBeforeTest(CLUSTER, input);
    final StreamsBuilder builder = new StreamsBuilder();
    final KStream<String, String> inputStream = builder.stream(input);
    final AtomicInteger recordCount = new AtomicInteger(0);
    final KTable<String, String> valueCounts = inputStream.groupByKey().aggregate(() -> "()", (key, value, aggregate) -> aggregate + ",(" + key + ": " + value + ")", Materialized.as("aggregated_value"));
    valueCounts.toStream().peek((key, value) -> {
        if (recordCount.incrementAndGet() >= RECORD_TOTAL) {
            throw new IllegalStateException("Crash on the " + RECORD_TOTAL + " record");
        }
    });
    final Properties producerConfig = mkProperties(mkMap(mkEntry(ProducerConfig.CLIENT_ID_CONFIG, "anything"), mkEntry(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, ((Serializer<String>) STRING_SERIALIZER).getClass().getName()), mkEntry(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, ((Serializer<String>) STRING_SERIALIZER).getClass().getName()), mkEntry(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, CLUSTER.bootstrapServers())));
    final KafkaStreams driver = new KafkaStreams(builder.build(), STREAMS_CONFIG);
    driver.cleanUp();
    driver.start();
    // Task's StateDir
    final File taskStateDir = new File(String.join("/", TEST_FOLDER.getRoot().getPath(), appId, "0_0"));
    final File taskCheckpointFile = new File(taskStateDir, ".checkpoint");
    try {
        IntegrationTestUtils.produceSynchronously(producerConfig, false, input, Optional.empty(), singletonList(new KeyValueTimestamp<>("k1", "v1", 0L)));
        // wait until the first request is processed and some files are created in it
        TestUtils.waitForCondition(() -> taskStateDir.exists() && taskStateDir.isDirectory() && taskStateDir.list().length > 0, "Failed awaiting CreateTopics first request failure");
        IntegrationTestUtils.produceSynchronously(producerConfig, false, input, Optional.empty(), asList(new KeyValueTimestamp<>("k2", "v2", 1L), new KeyValueTimestamp<>("k3", "v3", 2L)));
        TestUtils.waitForCondition(() -> recordCount.get() == RECORD_TOTAL, "Expected " + RECORD_TOTAL + " records processed but only got " + recordCount.get());
    } finally {
        TestUtils.waitForCondition(() -> driver.state().equals(State.ERROR), "Expected ERROR state but driver is on " + driver.state());
        driver.close();
        // Although there is an uncaught exception,
        // case 1: the state directory is cleaned up without any problems.
        // case 2: The state directory is not cleaned up, for it does not include any checkpoint file.
        // case 3: The state directory is not cleaned up, for it includes a checkpoint file but it is empty.
        assertTrue(!taskStateDir.exists() || (taskStateDir.exists() && taskStateDir.list().length > 0 && !taskCheckpointFile.exists()) || (taskCheckpointFile.exists() && taskCheckpointFile.length() == 0L));
        quietlyCleanStateAfterTest(CLUSTER, driver);
    }
}
Also used : StreamsBuilder(org.apache.kafka.streams.StreamsBuilder) KafkaStreams(org.apache.kafka.streams.KafkaStreams) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Utils.mkProperties(org.apache.kafka.common.utils.Utils.mkProperties) Properties(java.util.Properties) File(java.io.File) KeyValueTimestamp(org.apache.kafka.streams.KeyValueTimestamp) StringSerializer(org.apache.kafka.common.serialization.StringSerializer) Serializer(org.apache.kafka.common.serialization.Serializer) IntegrationTest(org.apache.kafka.test.IntegrationTest) Test(org.junit.Test) IntegrationTestUtils.cleanStateBeforeTest(org.apache.kafka.streams.integration.utils.IntegrationTestUtils.cleanStateBeforeTest) IntegrationTestUtils.quietlyCleanStateAfterTest(org.apache.kafka.streams.integration.utils.IntegrationTestUtils.quietlyCleanStateAfterTest)

Example 70 with KeyValueTimestamp

use of org.apache.kafka.streams.KeyValueTimestamp in project kafka by apache.

the class CachingInMemorySessionStoreTest method shouldNotForwardChangedValuesDuringFlushWhenSendOldValuesDisabled.

@Test
public void shouldNotForwardChangedValuesDuringFlushWhenSendOldValuesDisabled() {
    final Windowed<Bytes> a = new Windowed<>(keyA, new SessionWindow(0, 0));
    final Windowed<String> aDeserialized = new Windowed<>("a", new SessionWindow(0, 0));
    final CacheFlushListenerStub<Windowed<String>, String> flushListener = new CacheFlushListenerStub<>(new SessionWindowedDeserializer<>(new StringDeserializer()), new StringDeserializer());
    cachingStore.setFlushListener(flushListener, false);
    cachingStore.put(a, "1".getBytes());
    cachingStore.flush();
    cachingStore.put(a, "2".getBytes());
    cachingStore.flush();
    cachingStore.remove(a);
    cachingStore.flush();
    assertEquals(asList(new KeyValueTimestamp<>(aDeserialized, new Change<>("1", null), DEFAULT_TIMESTAMP), new KeyValueTimestamp<>(aDeserialized, new Change<>("2", null), DEFAULT_TIMESTAMP), new KeyValueTimestamp<>(aDeserialized, new Change<>(null, null), DEFAULT_TIMESTAMP)), flushListener.forwarded);
    flushListener.forwarded.clear();
    cachingStore.put(a, "1".getBytes());
    cachingStore.put(a, "2".getBytes());
    cachingStore.remove(a);
    cachingStore.flush();
    assertEquals(Collections.emptyList(), flushListener.forwarded);
    flushListener.forwarded.clear();
}
Also used : Windowed(org.apache.kafka.streams.kstream.Windowed) Bytes(org.apache.kafka.common.utils.Bytes) StringDeserializer(org.apache.kafka.common.serialization.StringDeserializer) SessionWindow(org.apache.kafka.streams.kstream.internals.SessionWindow) KeyValueTimestamp(org.apache.kafka.streams.KeyValueTimestamp) Test(org.junit.Test)

Aggregations

KeyValueTimestamp (org.apache.kafka.streams.KeyValueTimestamp)71 Test (org.junit.Test)65 StreamsBuilder (org.apache.kafka.streams.StreamsBuilder)46 TopologyTestDriver (org.apache.kafka.streams.TopologyTestDriver)44 StringSerializer (org.apache.kafka.common.serialization.StringSerializer)36 Properties (java.util.Properties)26 Windowed (org.apache.kafka.streams.kstream.Windowed)22 Serdes (org.apache.kafka.common.serialization.Serdes)21 IntegrationTest (org.apache.kafka.test.IntegrationTest)20 StringDeserializer (org.apache.kafka.common.serialization.StringDeserializer)19 KeyValue (org.apache.kafka.streams.KeyValue)19 Consumed (org.apache.kafka.streams.kstream.Consumed)17 IntegerSerializer (org.apache.kafka.common.serialization.IntegerSerializer)16 MockApiProcessorSupplier (org.apache.kafka.test.MockApiProcessorSupplier)16 Bytes (org.apache.kafka.common.utils.Bytes)15 KStream (org.apache.kafka.streams.kstream.KStream)14 Duration (java.time.Duration)13 KafkaStreams (org.apache.kafka.streams.KafkaStreams)13 TestInputTopic (org.apache.kafka.streams.TestInputTopic)13 Utils.mkProperties (org.apache.kafka.common.utils.Utils.mkProperties)12