Search in sources :

Example 1 with Consumer

use of org.apache.pulsar.client.api.Consumer in project incubator-pulsar by apache.

the class TopicsConsumerImplTest method testAsyncConsumer.

@Test(timeOut = testTimeout)
public void testAsyncConsumer() throws Exception {
    String key = "TopicsConsumerAsyncTest";
    final String subscriptionName = "my-ex-subscription-" + key;
    final String messagePredicate = "my-message-" + key + "-";
    final int totalMessages = 30;
    final String topicName1 = "persistent://prop/use/ns-abc/topic-1-" + key;
    final String topicName2 = "persistent://prop/use/ns-abc/topic-2-" + key;
    final String topicName3 = "persistent://prop/use/ns-abc/topic-3-" + key;
    List<String> topicNames = Lists.newArrayList(topicName1, topicName2, topicName3);
    admin.properties().createProperty("prop", new PropertyAdmin());
    admin.persistentTopics().createPartitionedTopic(topicName2, 2);
    admin.persistentTopics().createPartitionedTopic(topicName3, 3);
    // 1. producer connect
    Producer<byte[]> producer1 = pulsarClient.newProducer().topic(topicName1).create();
    Producer<byte[]> producer2 = pulsarClient.newProducer().topic(topicName2).messageRoutingMode(org.apache.pulsar.client.api.MessageRoutingMode.RoundRobinPartition).create();
    Producer<byte[]> producer3 = pulsarClient.newProducer().topic(topicName3).messageRoutingMode(org.apache.pulsar.client.api.MessageRoutingMode.RoundRobinPartition).create();
    // 2. Create consumer
    Consumer<byte[]> consumer = pulsarClient.newConsumer().topics(topicNames).subscriptionName(subscriptionName).subscriptionType(SubscriptionType.Shared).ackTimeout(ackTimeOutMillis, TimeUnit.MILLISECONDS).receiverQueueSize(4).subscribe();
    assertTrue(consumer instanceof TopicsConsumerImpl);
    // Asynchronously produce messages
    List<Future<MessageId>> futures = Lists.newArrayList();
    for (int i = 0; i < totalMessages / 3; i++) {
        futures.add(producer1.sendAsync((messagePredicate + "producer1-" + i).getBytes()));
        futures.add(producer2.sendAsync((messagePredicate + "producer2-" + i).getBytes()));
        futures.add(producer3.sendAsync((messagePredicate + "producer3-" + i).getBytes()));
    }
    log.info("Waiting for async publish to complete : {}", futures.size());
    for (Future<MessageId> future : futures) {
        future.get();
    }
    log.info("start async consume");
    CountDownLatch latch = new CountDownLatch(totalMessages);
    ExecutorService executor = Executors.newFixedThreadPool(1);
    executor.execute(() -> IntStream.range(0, totalMessages).forEach(index -> consumer.receiveAsync().thenAccept(msg -> {
        assertTrue(msg instanceof TopicMessageImpl);
        try {
            consumer.acknowledge(msg);
        } catch (PulsarClientException e1) {
            fail("message acknowledge failed", e1);
        }
        latch.countDown();
        log.info("receive index: {}, latch countDown: {}", index, latch.getCount());
    }).exceptionally(ex -> {
        log.warn("receive index: {}, failed receive message {}", index, ex.getMessage());
        ex.printStackTrace();
        return null;
    })));
    latch.await();
    log.info("success latch wait");
    consumer.unsubscribe();
    consumer.close();
    producer1.close();
    producer2.close();
    producer3.close();
}
Also used : IntStream(java.util.stream.IntStream) Producer(org.apache.pulsar.client.api.Producer) LoggerFactory(org.slf4j.LoggerFactory) Assert.assertEquals(org.testng.Assert.assertEquals) CompletableFuture(java.util.concurrent.CompletableFuture) Test(org.testng.annotations.Test) Message(org.apache.pulsar.client.api.Message) AfterMethod(org.testng.annotations.AfterMethod) HashSet(java.util.HashSet) Future(java.util.concurrent.Future) Lists(com.google.common.collect.Lists) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) ExecutorService(java.util.concurrent.ExecutorService) PropertyAdmin(org.apache.pulsar.common.policies.data.PropertyAdmin) Logger(org.slf4j.Logger) Assert.fail(org.testng.Assert.fail) BeforeMethod(org.testng.annotations.BeforeMethod) SubscriptionType(org.apache.pulsar.client.api.SubscriptionType) Executors(java.util.concurrent.Executors) TimeUnit(java.util.concurrent.TimeUnit) CountDownLatch(java.util.concurrent.CountDownLatch) Consumer(org.apache.pulsar.client.api.Consumer) List(java.util.List) MessageId(org.apache.pulsar.client.api.MessageId) Assert.assertTrue(org.testng.Assert.assertTrue) ProducerConsumerBase(org.apache.pulsar.client.api.ProducerConsumerBase) CountDownLatch(java.util.concurrent.CountDownLatch) PropertyAdmin(org.apache.pulsar.common.policies.data.PropertyAdmin) ExecutorService(java.util.concurrent.ExecutorService) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) CompletableFuture(java.util.concurrent.CompletableFuture) Future(java.util.concurrent.Future) MessageId(org.apache.pulsar.client.api.MessageId) Test(org.testng.annotations.Test)

Example 2 with Consumer

use of org.apache.pulsar.client.api.Consumer in project incubator-pulsar by apache.

the class CompactionTest method testFirstMessageRetained.

@Test
public void testFirstMessageRetained() throws Exception {
    String topic = "persistent://my-property/use/my-ns/my-topic1";
    // subscribe before sending anything, so that we get all messages
    pulsarClient.newConsumer().topic(topic).subscriptionName("sub1").readCompacted(true).subscribe().close();
    try (Producer producer = pulsarClient.createProducer(topic)) {
        producer.sendAsync(MessageBuilder.create().setKey("key1").setContent("my-message-1".getBytes()).build());
        producer.sendAsync(MessageBuilder.create().setKey("key2").setContent("my-message-2".getBytes()).build());
        producer.sendAsync(MessageBuilder.create().setKey("key2").setContent("my-message-3".getBytes()).build()).get();
    }
    // Read messages before compaction to get ids
    List<Message> messages = new ArrayList<>();
    try (Consumer consumer = pulsarClient.newConsumer().topic(topic).subscriptionName("sub1").readCompacted(true).subscribe()) {
        messages.add(consumer.receive());
        messages.add(consumer.receive());
        messages.add(consumer.receive());
    }
    // compact the topic
    Compactor compactor = new TwoPhaseCompactor(conf, pulsarClient, bk, compactionScheduler);
    compactor.compact(topic).get();
    // Check that messages after compaction have same ids
    try (Consumer consumer = pulsarClient.newConsumer().topic(topic).subscriptionName("sub1").readCompacted(true).subscribe()) {
        Message message1 = consumer.receive();
        Assert.assertEquals(message1.getKey(), "key1");
        Assert.assertEquals(new String(message1.getData()), "my-message-1");
        Assert.assertEquals(message1.getMessageId(), messages.get(0).getMessageId());
        Message message2 = consumer.receive();
        Assert.assertEquals(message2.getKey(), "key2");
        Assert.assertEquals(new String(message2.getData()), "my-message-3");
        Assert.assertEquals(message2.getMessageId(), messages.get(2).getMessageId());
    }
}
Also used : Producer(org.apache.pulsar.client.api.Producer) Message(org.apache.pulsar.client.api.Message) Consumer(org.apache.pulsar.client.api.Consumer) ArrayList(java.util.ArrayList) Test(org.testng.annotations.Test) MockedPulsarServiceBaseTest(org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest)

Example 3 with Consumer

use of org.apache.pulsar.client.api.Consumer in project incubator-pulsar by apache.

the class CompactionTest method testBatchMessageIdsDontChange.

@Test
public void testBatchMessageIdsDontChange() throws Exception {
    String topic = "persistent://my-property/use/my-ns/my-topic1";
    // subscribe before sending anything, so that we get all messages
    pulsarClient.newConsumer().topic(topic).subscriptionName("sub1").readCompacted(true).subscribe().close();
    try (Producer producer = pulsarClient.newProducer().topic(topic).maxPendingMessages(3).enableBatching(true).batchingMaxMessages(3).batchingMaxPublishDelay(1, TimeUnit.HOURS).create()) {
        producer.sendAsync(MessageBuilder.create().setKey("key1").setContent("my-message-1".getBytes()).build());
        producer.sendAsync(MessageBuilder.create().setKey("key2").setContent("my-message-2".getBytes()).build());
        producer.sendAsync(MessageBuilder.create().setKey("key2").setContent("my-message-3".getBytes()).build()).get();
    }
    // Read messages before compaction to get ids
    List<Message> messages = new ArrayList<>();
    try (Consumer consumer = pulsarClient.newConsumer().topic(topic).subscriptionName("sub1").readCompacted(true).subscribe()) {
        messages.add(consumer.receive());
        messages.add(consumer.receive());
        messages.add(consumer.receive());
    }
    // Ensure all messages are in same batch
    Assert.assertEquals(((BatchMessageIdImpl) messages.get(0).getMessageId()).getLedgerId(), ((BatchMessageIdImpl) messages.get(1).getMessageId()).getLedgerId());
    Assert.assertEquals(((BatchMessageIdImpl) messages.get(0).getMessageId()).getLedgerId(), ((BatchMessageIdImpl) messages.get(2).getMessageId()).getLedgerId());
    Assert.assertEquals(((BatchMessageIdImpl) messages.get(0).getMessageId()).getEntryId(), ((BatchMessageIdImpl) messages.get(1).getMessageId()).getEntryId());
    Assert.assertEquals(((BatchMessageIdImpl) messages.get(0).getMessageId()).getEntryId(), ((BatchMessageIdImpl) messages.get(2).getMessageId()).getEntryId());
    // compact the topic
    Compactor compactor = new TwoPhaseCompactor(conf, pulsarClient, bk, compactionScheduler);
    compactor.compact(topic).get();
    // Check that messages after compaction have same ids
    try (Consumer consumer = pulsarClient.newConsumer().topic(topic).subscriptionName("sub1").readCompacted(true).subscribe()) {
        Message message1 = consumer.receive();
        Assert.assertEquals(message1.getKey(), "key1");
        Assert.assertEquals(new String(message1.getData()), "my-message-1");
        Assert.assertEquals(message1.getMessageId(), messages.get(0).getMessageId());
        Message message2 = consumer.receive();
        Assert.assertEquals(message2.getKey(), "key2");
        Assert.assertEquals(new String(message2.getData()), "my-message-3");
        Assert.assertEquals(message2.getMessageId(), messages.get(2).getMessageId());
    }
}
Also used : Producer(org.apache.pulsar.client.api.Producer) Message(org.apache.pulsar.client.api.Message) Consumer(org.apache.pulsar.client.api.Consumer) ArrayList(java.util.ArrayList) Test(org.testng.annotations.Test) MockedPulsarServiceBaseTest(org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest)

Example 4 with Consumer

use of org.apache.pulsar.client.api.Consumer in project incubator-pulsar by apache.

the class PersistentTopicE2ETest method testConcurrentConsumerThreads.

// some race conditions needs to be handled
// disabling the test for now to not block commit jobs
@Test(enabled = false)
public void testConcurrentConsumerThreads() throws Exception {
    // test concurrent consumer threads on same consumerId
    final String topicName = "persistent://prop/use/ns-abc/topic3";
    final String subName = "sub3";
    final int recvQueueSize = 100;
    final int numConsumersThreads = 10;
    ExecutorService executor = Executors.newCachedThreadPool();
    final CyclicBarrier barrier = new CyclicBarrier(numConsumersThreads + 1);
    for (int i = 0; i < numConsumersThreads; i++) {
        executor.submit(new Callable<Void>() {

            @Override
            public Void call() throws Exception {
                barrier.await();
                Consumer<byte[]> consumer = pulsarClient.newConsumer().topic(topicName).subscriptionName(subName).receiverQueueSize(recvQueueSize).subscribe();
                for (int i = 0; i < recvQueueSize / numConsumersThreads; i++) {
                    Message<byte[]> msg = consumer.receive();
                    consumer.acknowledge(msg);
                }
                return null;
            }
        });
    }
    Producer<byte[]> producer = pulsarClient.newProducer().topic(topicName).create();
    for (int i = 0; i < recvQueueSize * numConsumersThreads; i++) {
        String message = "my-message-" + i;
        producer.send(message.getBytes());
    }
    barrier.await();
    Thread.sleep(ASYNC_EVENT_COMPLETION_WAIT);
    PersistentTopic topicRef = (PersistentTopic) pulsar.getBrokerService().getTopicReference(topicName);
    PersistentSubscription subRef = topicRef.getSubscription(subName);
    // 1. cumulatively all threads drain the backlog
    assertEquals(subRef.getNumberOfEntriesInBacklog(), 0);
    // 2. flow control works the same as single consumer single thread
    Thread.sleep(ASYNC_EVENT_COMPLETION_WAIT);
    assertEquals(getAvailablePermits(subRef), recvQueueSize);
    executor.shutdown();
}
Also used : Message(org.apache.pulsar.client.api.Message) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) ProducerBusyException(org.apache.pulsar.client.api.PulsarClientException.ProducerBusyException) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) CyclicBarrier(java.util.concurrent.CyclicBarrier) Consumer(org.apache.pulsar.client.api.Consumer) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) ExecutorService(java.util.concurrent.ExecutorService) Test(org.testng.annotations.Test)

Example 5 with Consumer

use of org.apache.pulsar.client.api.Consumer in project incubator-pulsar by apache.

the class V1_ProducerConsumerTest method testBlockUnackedConsumerRedeliverySpecificMessagesProduceWithPause.

/**
 * It verifies that redelivery-of-specific messages: that redelivers all those messages even when consumer gets
 * blocked due to unacked messsages
 *
 * Usecase: produce message with 10ms interval: so, consumer can consume only 10 messages without acking
 *
 * @throws Exception
 */
@Test
public void testBlockUnackedConsumerRedeliverySpecificMessagesProduceWithPause() throws Exception {
    log.info("-- Starting {} test --", methodName);
    int unAckedMessages = pulsar.getConfiguration().getMaxUnackedMessagesPerConsumer();
    try {
        final int unAckedMessagesBufferSize = 10;
        final int receiverQueueSize = 20;
        final int totalProducedMsgs = 20;
        pulsar.getConfiguration().setMaxUnackedMessagesPerConsumer(unAckedMessagesBufferSize);
        ConsumerConfiguration conf = new ConsumerConfiguration();
        conf.setReceiverQueueSize(receiverQueueSize);
        conf.setSubscriptionType(SubscriptionType.Shared);
        ConsumerImpl consumer = (ConsumerImpl) pulsarClient.subscribe("persistent://my-property/use/my-ns/unacked-topic", "subscriber-1", conf);
        ProducerConfiguration producerConf = new ProducerConfiguration();
        Producer producer = pulsarClient.createProducer("persistent://my-property/use/my-ns/unacked-topic", producerConf);
        // (1) Produced Messages
        for (int i = 0; i < totalProducedMsgs; i++) {
            String message = "my-message-" + i;
            producer.send(message.getBytes());
            Thread.sleep(10);
        }
        // (2) try to consume messages: but will be able to consume number of messages = unAckedMessagesBufferSize
        Message msg = null;
        List<Message> messages1 = Lists.newArrayList();
        for (int i = 0; i < totalProducedMsgs; i++) {
            msg = consumer.receive(1, TimeUnit.SECONDS);
            if (msg != null) {
                messages1.add(msg);
                log.info("Received message: " + new String(msg.getData()));
            } else {
                break;
            }
        }
        // client should not receive all produced messages and should be blocked due to unack-messages
        assertEquals(messages1.size(), unAckedMessagesBufferSize);
        Set<MessageIdImpl> redeliveryMessages = messages1.stream().map(m -> {
            return (MessageIdImpl) m.getMessageId();
        }).collect(Collectors.toSet());
        // (3) redeliver all consumed messages
        consumer.redeliverUnacknowledgedMessages(Sets.newHashSet(redeliveryMessages));
        Thread.sleep(1000);
        Set<MessageIdImpl> messages2 = Sets.newHashSet();
        for (int i = 0; i < totalProducedMsgs; i++) {
            msg = consumer.receive(1, TimeUnit.SECONDS);
            if (msg != null) {
                messages2.add((MessageIdImpl) msg.getMessageId());
                log.info("Received message: " + new String(msg.getData()));
            } else {
                break;
            }
        }
        assertEquals(messages1.size(), messages2.size());
        // (4) Verify: redelivered all previous unacked-consumed messages
        messages2.removeAll(redeliveryMessages);
        assertEquals(messages2.size(), 0);
        producer.close();
        consumer.close();
        log.info("-- Exiting {} test --", methodName);
    } catch (Exception e) {
        fail();
    } finally {
        pulsar.getConfiguration().setMaxUnackedMessagesPerConsumer(unAckedMessages);
    }
}
Also used : Producer(org.apache.pulsar.client.api.Producer) LoggerFactory(org.slf4j.LoggerFactory) Test(org.testng.annotations.Test) AfterMethod(org.testng.annotations.AfterMethod) Future(java.util.concurrent.Future) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) EncryptionKeyInfo(org.apache.pulsar.client.api.EncryptionKeyInfo) Assert.assertFalse(org.testng.Assert.assertFalse) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) PulsarDecoder(org.apache.pulsar.common.api.PulsarDecoder) Assert.assertNotEquals(org.testng.Assert.assertNotEquals) CyclicBarrier(java.util.concurrent.CyclicBarrier) ConsumerImpl(org.apache.pulsar.client.impl.ConsumerImpl) MessageBuilder(org.apache.pulsar.client.api.MessageBuilder) CompressionType(org.apache.pulsar.client.api.CompressionType) Mockito.atLeastOnce(org.mockito.Mockito.atLeastOnce) BeforeMethod(org.testng.annotations.BeforeMethod) Set(java.util.Set) UUID(java.util.UUID) ConsumerConfiguration(org.apache.pulsar.client.api.ConsumerConfiguration) Collectors(java.util.stream.Collectors) ProducerConfiguration(org.apache.pulsar.client.api.ProducerConfiguration) Executors(java.util.concurrent.Executors) Sets(com.google.common.collect.Sets) Matchers.any(org.mockito.Matchers.any) MessageIdImpl(org.apache.pulsar.client.impl.MessageIdImpl) CountDownLatch(java.util.concurrent.CountDownLatch) Consumer(org.apache.pulsar.client.api.Consumer) List(java.util.List) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) FutureUtil(org.apache.pulsar.common.util.FutureUtil) Modifier(java.lang.reflect.Modifier) ProducerConsumerBase(org.apache.pulsar.client.api.ProducerConsumerBase) ConsumerCryptoFailureAction(org.apache.pulsar.client.api.ConsumerCryptoFailureAction) TopicName(org.apache.pulsar.common.naming.TopicName) DataProvider(org.testng.annotations.DataProvider) Assert.assertEquals(org.testng.Assert.assertEquals) Callable(java.util.concurrent.Callable) CompletableFuture(java.util.concurrent.CompletableFuture) Message(org.apache.pulsar.client.api.Message) Mockito.spy(org.mockito.Mockito.spy) Lists(com.google.common.collect.Lists) Assert(org.testng.Assert) PulsarClient(org.apache.pulsar.client.api.PulsarClient) ExecutorService(java.util.concurrent.ExecutorService) ManagedLedgerImpl(org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl) Logger(org.slf4j.Logger) Files(java.nio.file.Files) Assert.fail(org.testng.Assert.fail) IOException(java.io.IOException) Field(java.lang.reflect.Field) EntryCacheImpl(org.apache.bookkeeper.mledger.impl.EntryCacheImpl) SubscriptionType(org.apache.pulsar.client.api.SubscriptionType) Mockito.verify(org.mockito.Mockito.verify) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) CryptoKeyReader(org.apache.pulsar.client.api.CryptoKeyReader) MessageId(org.apache.pulsar.client.api.MessageId) Paths(java.nio.file.Paths) Assert.assertTrue(org.testng.Assert.assertTrue) ConsumerImpl(org.apache.pulsar.client.impl.ConsumerImpl) Producer(org.apache.pulsar.client.api.Producer) Message(org.apache.pulsar.client.api.Message) ConsumerConfiguration(org.apache.pulsar.client.api.ConsumerConfiguration) ProducerConfiguration(org.apache.pulsar.client.api.ProducerConfiguration) MessageIdImpl(org.apache.pulsar.client.impl.MessageIdImpl) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) Test(org.testng.annotations.Test)

Aggregations

Consumer (org.apache.pulsar.client.api.Consumer)45 Test (org.testng.annotations.Test)40 Producer (org.apache.pulsar.client.api.Producer)35 Message (org.apache.pulsar.client.api.Message)34 ConsumerConfiguration (org.apache.pulsar.client.api.ConsumerConfiguration)29 ProducerConfiguration (org.apache.pulsar.client.api.ProducerConfiguration)27 PulsarClientException (org.apache.pulsar.client.api.PulsarClientException)22 CompletableFuture (java.util.concurrent.CompletableFuture)15 MessageId (org.apache.pulsar.client.api.MessageId)15 ExecutionException (java.util.concurrent.ExecutionException)14 IOException (java.io.IOException)12 CountDownLatch (java.util.concurrent.CountDownLatch)12 ExecutorService (java.util.concurrent.ExecutorService)12 PulsarClient (org.apache.pulsar.client.api.PulsarClient)10 List (java.util.List)9 Map (java.util.Map)9 Future (java.util.concurrent.Future)9 TimeUnit (java.util.concurrent.TimeUnit)9 PersistentTopic (org.apache.pulsar.broker.service.persistent.PersistentTopic)9 SubscriptionType (org.apache.pulsar.client.api.SubscriptionType)9