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);
}
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();
}
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();
}
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);
}
}
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);
}
}
Aggregations