Search in sources :

Example 6 with MessageIdImpl

use of org.apache.pulsar.client.impl.MessageIdImpl in project incubator-pulsar by apache.

the class PersistentFailoverE2ETest method testSimpleConsumerEventsWithPartition.

@Test
public void testSimpleConsumerEventsWithPartition() throws Exception {
    int numPartitions = 4;
    final String topicName = "persistent://prop/use/ns-abc/failover-topic2";
    final TopicName destName = TopicName.get(topicName);
    final String subName = "sub1";
    final int numMsgs = 100;
    Set<String> uniqueMessages = new HashSet<>();
    admin.persistentTopics().createPartitionedTopic(topicName, numPartitions);
    ConsumerBuilder<byte[]> consumerBuilder = pulsarClient.newConsumer().topic(topicName).subscriptionName(subName).subscriptionType(SubscriptionType.Failover);
    // 1. two consumers on the same subscription
    ActiveInactiveListenerEvent listener1 = new ActiveInactiveListenerEvent();
    ActiveInactiveListenerEvent listener2 = new ActiveInactiveListenerEvent();
    Consumer<byte[]> consumer1 = consumerBuilder.clone().consumerName("1").consumerEventListener(listener1).subscribe();
    Consumer<byte[]> consumer2 = consumerBuilder.clone().consumerName("2").consumerEventListener(listener2).subscribe();
    PersistentTopic topicRef;
    topicRef = (PersistentTopic) pulsar.getBrokerService().getTopicReference(destName.getPartition(0).toString());
    PersistentDispatcherSingleActiveConsumer disp0 = (PersistentDispatcherSingleActiveConsumer) topicRef.getSubscription(subName).getDispatcher();
    topicRef = (PersistentTopic) pulsar.getBrokerService().getTopicReference(destName.getPartition(1).toString());
    PersistentDispatcherSingleActiveConsumer disp1 = (PersistentDispatcherSingleActiveConsumer) topicRef.getSubscription(subName).getDispatcher();
    topicRef = (PersistentTopic) pulsar.getBrokerService().getTopicReference(destName.getPartition(2).toString());
    PersistentDispatcherSingleActiveConsumer disp2 = (PersistentDispatcherSingleActiveConsumer) topicRef.getSubscription(subName).getDispatcher();
    topicRef = (PersistentTopic) pulsar.getBrokerService().getTopicReference(destName.getPartition(3).toString());
    PersistentDispatcherSingleActiveConsumer disp3 = (PersistentDispatcherSingleActiveConsumer) topicRef.getSubscription(subName).getDispatcher();
    List<CompletableFuture<MessageId>> futures = Lists.newArrayListWithCapacity(numMsgs);
    Producer<byte[]> producer = pulsarClient.newProducer().topic(topicName).messageRoutingMode(MessageRoutingMode.RoundRobinPartition).create();
    for (int i = 0; i < numMsgs; i++) {
        String message = "my-message-" + i;
        futures.add(producer.sendAsync(message.getBytes()));
    }
    FutureUtil.waitForAll(futures).get();
    futures.clear();
    // equal distribution between both consumers
    int totalMessages = 0;
    Message<byte[]> msg = null;
    Set<Integer> receivedPtns = Sets.newHashSet();
    while (true) {
        msg = consumer1.receive(1, TimeUnit.SECONDS);
        if (msg == null) {
            break;
        }
        totalMessages++;
        consumer1.acknowledge(msg);
        MessageIdImpl msgId = (MessageIdImpl) msg.getMessageId();
        receivedPtns.add(msgId.getPartitionIndex());
    }
    assertTrue(Sets.difference(listener1.activePtns, receivedPtns).isEmpty());
    assertTrue(Sets.difference(listener2.inactivePtns, receivedPtns).isEmpty());
    Assert.assertEquals(totalMessages, numMsgs / 2);
    receivedPtns = Sets.newHashSet();
    while (true) {
        msg = consumer2.receive(1, TimeUnit.SECONDS);
        if (msg == null) {
            break;
        }
        totalMessages++;
        consumer2.acknowledge(msg);
        MessageIdImpl msgId = (MessageIdImpl) msg.getMessageId();
        receivedPtns.add(msgId.getPartitionIndex());
    }
    assertTrue(Sets.difference(listener1.inactivePtns, receivedPtns).isEmpty());
    assertTrue(Sets.difference(listener2.activePtns, receivedPtns).isEmpty());
    Assert.assertEquals(totalMessages, numMsgs);
    Assert.assertEquals(disp0.getActiveConsumer().consumerName(), "1");
    Assert.assertEquals(disp1.getActiveConsumer().consumerName(), "2");
    Assert.assertEquals(disp2.getActiveConsumer().consumerName(), "1");
    Assert.assertEquals(disp3.getActiveConsumer().consumerName(), "2");
    totalMessages = 0;
    for (int i = 0; i < numMsgs; i++) {
        String message = "my-message-" + i;
        futures.add(producer.sendAsync(message.getBytes()));
    }
    FutureUtil.waitForAll(futures).get();
    futures.clear();
    // add a consumer
    for (int i = 0; i < 20; i++) {
        msg = consumer1.receive(1, TimeUnit.SECONDS);
        Assert.assertNotNull(msg);
        uniqueMessages.add(new String(msg.getData()));
        consumer1.acknowledge(msg);
    }
    Consumer<byte[]> consumer3 = consumerBuilder.clone().consumerName("3").subscribe();
    Thread.sleep(CONSUMER_ADD_OR_REMOVE_WAIT_TIME);
    int consumer1Messages = 0;
    while (true) {
        msg = consumer1.receive(1, TimeUnit.SECONDS);
        if (msg == null) {
            Assert.assertEquals(consumer1Messages, 55);
            break;
        }
        consumer1Messages++;
        uniqueMessages.add(new String(msg.getData()));
        consumer1.acknowledge(msg);
    }
    int consumer2Messages = 0;
    while (true) {
        msg = consumer2.receive(1, TimeUnit.SECONDS);
        if (msg == null) {
            Assert.assertEquals(consumer2Messages, 50);
            break;
        }
        consumer2Messages++;
        uniqueMessages.add(new String(msg.getData()));
        consumer2.acknowledge(msg);
    }
    int consumer3Messages = 0;
    while (true) {
        msg = consumer3.receive(1, TimeUnit.SECONDS);
        if (msg == null) {
            Assert.assertEquals(consumer3Messages, 15, 10);
            break;
        }
        consumer3Messages++;
        uniqueMessages.add(new String(msg.getData()));
        consumer3.acknowledge(msg);
    }
    Assert.assertEquals(uniqueMessages.size(), numMsgs);
    Assert.assertEquals(disp0.getActiveConsumer().consumerName(), "1");
    Assert.assertEquals(disp1.getActiveConsumer().consumerName(), "2");
    Assert.assertEquals(disp2.getActiveConsumer().consumerName(), "3");
    Assert.assertEquals(disp3.getActiveConsumer().consumerName(), "1");
    uniqueMessages.clear();
    for (int i = 0; i < numMsgs; i++) {
        String message = "my-message-" + i;
        futures.add(producer.sendAsync(message.getBytes()));
    }
    FutureUtil.waitForAll(futures).get();
    futures.clear();
    // remove a consumer
    for (int i = 0; i < 10; i++) {
        msg = consumer1.receive(1, TimeUnit.SECONDS);
        Assert.assertNotNull(msg);
        uniqueMessages.add(new String(msg.getData()));
        consumer1.acknowledge(msg);
    }
    consumer1.close();
    Thread.sleep(CONSUMER_ADD_OR_REMOVE_WAIT_TIME);
    consumer2Messages = 0;
    while (true) {
        msg = consumer2.receive(1, TimeUnit.SECONDS);
        if (msg == null) {
            Assert.assertEquals(consumer2Messages, 70, 5);
            break;
        }
        consumer2Messages++;
        uniqueMessages.add(new String(msg.getData()));
        consumer2.acknowledge(msg);
    }
    consumer3Messages = 0;
    while (true) {
        msg = consumer3.receive(1, TimeUnit.SECONDS);
        if (msg == null) {
            Assert.assertEquals(consumer3Messages, 70, 5);
            break;
        }
        consumer3Messages++;
        uniqueMessages.add(new String(msg.getData()));
        consumer3.acknowledge(msg);
    }
    Assert.assertEquals(uniqueMessages.size(), numMsgs);
    Assert.assertEquals(disp0.getActiveConsumer().consumerName(), "2");
    Assert.assertEquals(disp1.getActiveConsumer().consumerName(), "3");
    Assert.assertEquals(disp2.getActiveConsumer().consumerName(), "2");
    Assert.assertEquals(disp3.getActiveConsumer().consumerName(), "3");
    producer.close();
    consumer2.close();
    consumer3.unsubscribe();
    admin.persistentTopics().deletePartitionedTopic(topicName);
}
Also used : MessageIdImpl(org.apache.pulsar.client.impl.MessageIdImpl) PersistentDispatcherSingleActiveConsumer(org.apache.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer) TopicName(org.apache.pulsar.common.naming.TopicName) CompletableFuture(java.util.concurrent.CompletableFuture) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) HashSet(java.util.HashSet) Test(org.testng.annotations.Test)

Example 7 with MessageIdImpl

use of org.apache.pulsar.client.impl.MessageIdImpl in project incubator-pulsar by apache.

the class PersistentTopicE2ETest method testMessageReplay.

/**
 * Verify: 1. Broker should not replay already acknowledged messages 2. Dispatcher should not stuck while
 * dispatching new messages due to previous-replay of invalid/already-acked messages
 *
 * @throws Exception
 */
@Test
public void testMessageReplay() throws Exception {
    final String topicName = "persistent://prop/use/ns-abc/topic2";
    final String subName = "sub2";
    Message<byte[]> msg;
    int totalMessages = 10;
    int replayIndex = totalMessages / 2;
    Consumer<byte[]> consumer = pulsarClient.newConsumer().topic(topicName).subscriptionName(subName).subscriptionType(SubscriptionType.Shared).receiverQueueSize(1).subscribe();
    Producer<byte[]> producer = pulsarClient.newProducer().topic(topicName).create();
    PersistentTopic topicRef = (PersistentTopic) pulsar.getBrokerService().getTopicReference(topicName);
    assertNotNull(topicRef);
    PersistentSubscription subRef = topicRef.getSubscription(subName);
    PersistentDispatcherMultipleConsumers dispatcher = (PersistentDispatcherMultipleConsumers) subRef.getDispatcher();
    Field replayMap = PersistentDispatcherMultipleConsumers.class.getDeclaredField("messagesToReplay");
    replayMap.setAccessible(true);
    ConcurrentLongPairSet messagesToReplay = new ConcurrentLongPairSet(64, 1);
    assertNotNull(subRef);
    // (1) Produce messages
    for (int i = 0; i < totalMessages; i++) {
        String message = "my-message-" + i;
        producer.send(message.getBytes());
    }
    MessageIdImpl firstAckedMsg = null;
    // (2) Consume and ack messages except first message
    for (int i = 0; i < totalMessages; i++) {
        msg = consumer.receive();
        consumer.acknowledge(msg);
        MessageIdImpl msgId = (MessageIdImpl) msg.getMessageId();
        if (i == 0) {
            firstAckedMsg = msgId;
        }
        if (i < replayIndex) {
            // (3) accumulate acked messages for replay
            messagesToReplay.add(msgId.getLedgerId(), msgId.getEntryId());
        }
    }
    // (4) redelivery : should redeliver only unacked messages
    Thread.sleep(1000);
    replayMap.set(dispatcher, messagesToReplay);
    // (a) redelivery with all acked-message should clear messageReply bucket
    dispatcher.redeliverUnacknowledgedMessages(dispatcher.getConsumers().get(0));
    assertEquals(messagesToReplay.size(), 0);
    // (b) fill messageReplyBucket with already acked entry again: and try to publish new msg and read it
    messagesToReplay.add(firstAckedMsg.getLedgerId(), firstAckedMsg.getEntryId());
    replayMap.set(dispatcher, messagesToReplay);
    // send new message
    final String testMsg = "testMsg";
    producer.send(testMsg.getBytes());
    // consumer should be able to receive only new message and not the
    dispatcher.consumerFlow(dispatcher.getConsumers().get(0), 1);
    msg = consumer.receive(1, TimeUnit.SECONDS);
    assertNotNull(msg);
    assertEquals(msg.getData(), testMsg.getBytes());
    consumer.close();
    producer.close();
}
Also used : Field(java.lang.reflect.Field) ConcurrentLongPairSet(org.apache.pulsar.common.util.collections.ConcurrentLongPairSet) PersistentDispatcherMultipleConsumers(org.apache.pulsar.broker.service.persistent.PersistentDispatcherMultipleConsumers) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) MessageIdImpl(org.apache.pulsar.client.impl.MessageIdImpl) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription) Test(org.testng.annotations.Test)

Example 8 with MessageIdImpl

use of org.apache.pulsar.client.impl.MessageIdImpl in project incubator-pulsar by apache.

the class PersistentTopicE2ETest method testProducerReturnedMessageId.

@Test
public void testProducerReturnedMessageId() throws Exception {
    final String topicName = "persistent://prop/use/ns-abc/topic-xyz";
    // 1. producer connect
    Producer<byte[]> producer = pulsarClient.newProducer().topic(topicName).create();
    PersistentTopic topicRef = (PersistentTopic) pulsar.getBrokerService().getTopicReference(topicName);
    assertNotNull(topicRef);
    assertEquals(topicRef.getProducers().size(), 1);
    ManagedLedgerImpl managedLedger = (ManagedLedgerImpl) topicRef.getManagedLedger();
    long ledgerId = managedLedger.getLedgersInfoAsList().get(0).getLedgerId();
    // 2. producer publish messages
    final int SyncMessages = 10;
    for (int i = 0; i < SyncMessages; i++) {
        String message = "my-message-" + i;
        MessageId receivedMessageId = producer.send(message.getBytes());
        assertEquals(receivedMessageId, new MessageIdImpl(ledgerId, i, -1));
    }
    // 3. producer publish messages async
    final int AsyncMessages = 10;
    final CountDownLatch counter = new CountDownLatch(AsyncMessages);
    for (int i = SyncMessages; i < (SyncMessages + AsyncMessages); i++) {
        String content = "my-message-" + i;
        Message<byte[]> msg = MessageBuilder.create().setContent(content.getBytes()).build();
        final int index = i;
        producer.sendAsync(msg).thenRun(() -> {
            assertEquals(msg.getMessageId(), new MessageIdImpl(ledgerId, index, -1));
            counter.countDown();
        }).exceptionally((ex) -> {
            return null;
        });
    }
    counter.await();
    // 4. producer disconnect
    producer.close();
}
Also used : ManagedLedgerImpl(org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) MessageIdImpl(org.apache.pulsar.client.impl.MessageIdImpl) CountDownLatch(java.util.concurrent.CountDownLatch) MessageId(org.apache.pulsar.client.api.MessageId) Test(org.testng.annotations.Test)

Example 9 with MessageIdImpl

use of org.apache.pulsar.client.impl.MessageIdImpl 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)

Example 10 with MessageIdImpl

use of org.apache.pulsar.client.impl.MessageIdImpl in project incubator-pulsar by apache.

the class V1_ProducerConsumerTest method testBlockUnackedConsumerRedeliverySpecificMessagesCloseConsumerWhileProduce.

/**
 * It verifies that redelivery-of-specific messages: that redelivers all those messages even when consumer gets
 * blocked due to unacked messsages
 *
 * Usecase: Consumer starts consuming only after all messages have been produced. So, consumer consumes total
 * receiver-queue-size number messages => ask for redelivery and receives all messages again.
 *
 * @throws Exception
 */
@Test
public void testBlockUnackedConsumerRedeliverySpecificMessagesCloseConsumerWhileProduce() throws Exception {
    log.info("-- Starting {} test --", methodName);
    int unAckedMessages = pulsar.getConfiguration().getMaxUnackedMessagesPerConsumer();
    try {
        final int unAckedMessagesBufferSize = 10;
        final int receiverQueueSize = 20;
        final int totalProducedMsgs = 50;
        pulsar.getConfiguration().setMaxUnackedMessagesPerConsumer(unAckedMessagesBufferSize);
        ConsumerConfiguration conf = new ConsumerConfiguration();
        conf.setReceiverQueueSize(receiverQueueSize);
        conf.setSubscriptionType(SubscriptionType.Shared);
        // Only subscribe consumer
        ConsumerImpl consumer = (ConsumerImpl) pulsarClient.subscribe("persistent://my-property/use/my-ns/unacked-topic", "subscriber-1", conf);
        consumer.close();
        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);
        }
        // (1.a) start consumer again
        consumer = (ConsumerImpl) pulsarClient.subscribe("persistent://my-property/use/my-ns/unacked-topic", "subscriber-1", conf);
        // (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(), receiverQueueSize);
        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

MessageIdImpl (org.apache.pulsar.client.impl.MessageIdImpl)27 Test (org.testng.annotations.Test)18 MessageId (org.apache.pulsar.client.api.MessageId)15 Message (org.apache.pulsar.client.api.Message)11 CompletableFuture (java.util.concurrent.CompletableFuture)9 ExecutorService (java.util.concurrent.ExecutorService)9 TopicName (org.apache.pulsar.common.naming.TopicName)8 List (java.util.List)6 TimeUnit (java.util.concurrent.TimeUnit)6 Cleanup (lombok.Cleanup)6 FunctionConfig (org.apache.pulsar.functions.proto.Function.FunctionConfig)6 Matchers.anyString (org.mockito.Matchers.anyString)6 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)6 Map (java.util.Map)5 Set (java.util.Set)5 PersistentTopic (org.apache.pulsar.broker.service.persistent.PersistentTopic)5 Lists (com.google.common.collect.Lists)4 Collectors (java.util.stream.Collectors)4 ManagedLedgerImpl (org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl)4 FutureUtil (org.apache.pulsar.common.util.FutureUtil)4