/** * Asynchronously produce messages with String keys and sequential Integer values, and write them to the cluster. * * @param topic the name of the topic to which the messages should be written; may not be null * @param messageCount the number of messages to produce; must be positive * @param initialValue the first integer value to produce * @param completionCallback the function to be called when the producer is completed; may be null */ public void produceIntegers(String topic, int messageCount, int initialValue, Runnable completionCallback) { AtomicLong counter = new AtomicLong(initialValue); produceIntegers(messageCount, completionCallback, () -> { long i = counter.incrementAndGet(); String keyAndValue = Long.toString(i); return new ProducerRecord<String, Integer>(topic, keyAndValue, Integer.valueOf((int) i)); }); }
@Test @SkipLongRunning public void shouldStartClusterAndAllowProducersAndConsumersToUseIt() throws Exception { Testing.Debug.enable(); final String topicName = "topicA"; final CountDownLatch completion = new CountDownLatch(2); final int numMessages = 100; final AtomicLong messagesRead = new AtomicLong(0); // Start a cluster and create a topic ... cluster.addBrokers(1).startup(); cluster.createTopics(topicName); // Consume messages asynchronously ... Stopwatch sw = Stopwatch.reusable().start(); cluster.useTo().consumeIntegers(topicName, numMessages, 10, TimeUnit.SECONDS, completion::countDown, (key, value) -> { messagesRead.incrementAndGet(); return true; }); // Produce some messages asynchronously ... cluster.useTo().produceIntegers(topicName, numMessages, 1, completion::countDown); // Wait for both to complete ... if (completion.await(10, TimeUnit.SECONDS)) { sw.stop(); Testing.debug("Both consumer and producer completed normally in " + sw.durations()); } else { Testing.debug("Consumer and/or producer did not completed normally"); } assertThat(messagesRead.get()).isEqualTo(numMessages); }