Search in sources :

Example 41 with MessageId

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

the class PulsarKafkaProducer method send.

@Override
public Future<RecordMetadata> send(ProducerRecord<K, V> record, Callback callback) {
    org.apache.pulsar.client.api.Producer<byte[]> producer;
    try {
        producer = producers.computeIfAbsent(record.topic(), topic -> createNewProducer(topic));
    } catch (Exception e) {
        if (callback != null) {
            callback.onCompletion(null, e);
        }
        CompletableFuture<RecordMetadata> future = new CompletableFuture<>();
        future.completeExceptionally(e);
        return future;
    }
    Message<byte[]> msg = getMessage(record);
    int messageSize = msg.getData().length;
    CompletableFuture<RecordMetadata> future = new CompletableFuture<>();
    CompletableFuture<MessageId> sendFuture = producer.sendAsync(msg);
    lastSendFuture.put(record.topic(), sendFuture);
    sendFuture.thenAccept((messageId) -> {
        future.complete(getRecordMetadata(record.topic(), msg, messageId, messageSize));
    }).exceptionally(ex -> {
        future.completeExceptionally(ex);
        return null;
    });
    future.handle((recordMetadata, throwable) -> {
        if (callback != null) {
            Exception exception = throwable != null ? new Exception(throwable) : null;
            callback.onCompletion(recordMetadata, exception);
        }
        return null;
    });
    return future;
}
Also used : TimeoutException(java.util.concurrent.TimeoutException) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Message(org.apache.pulsar.client.api.Message) PulsarClientKafkaConfig(org.apache.pulsar.client.kafka.compat.PulsarClientKafkaConfig) ConcurrentMap(java.util.concurrent.ConcurrentMap) ProducerBuilder(org.apache.pulsar.client.api.ProducerBuilder) Future(java.util.concurrent.Future) Map(java.util.Map) Metric(org.apache.kafka.common.Metric) MetricName(org.apache.kafka.common.MetricName) StringSerializer(org.apache.kafka.common.serialization.StringSerializer) PulsarClient(org.apache.pulsar.client.api.PulsarClient) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) PulsarProducerKafkaConfig(org.apache.pulsar.client.kafka.compat.PulsarProducerKafkaConfig) TopicPartition(org.apache.kafka.common.TopicPartition) Properties(java.util.Properties) MessageIdUtils(org.apache.pulsar.client.kafka.compat.MessageIdUtils) MessageBuilder(org.apache.pulsar.client.api.MessageBuilder) CompressionType(org.apache.pulsar.client.api.CompressionType) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) PartitionInfo(org.apache.kafka.common.PartitionInfo) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) MessageIdImpl(org.apache.pulsar.client.impl.MessageIdImpl) Base64(java.util.Base64) List(java.util.List) MessageId(org.apache.pulsar.client.api.MessageId) Serializer(org.apache.kafka.common.serialization.Serializer) Collections(java.util.Collections) TimeoutException(java.util.concurrent.TimeoutException) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) ExecutionException(java.util.concurrent.ExecutionException) CompletableFuture(java.util.concurrent.CompletableFuture) MessageId(org.apache.pulsar.client.api.MessageId)

Example 42 with MessageId

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

the class ConsumerImpl method redeliverUnacknowledgedMessages.

@Override
public void redeliverUnacknowledgedMessages(Set<MessageId> messageIds) {
    checkArgument(messageIds.stream().findFirst().get() instanceof MessageIdImpl);
    if (conf.getSubscriptionType() != SubscriptionType.Shared) {
        // We cannot redeliver single messages if subscription type is not Shared
        redeliverUnacknowledgedMessages();
        return;
    }
    ClientCnx cnx = cnx();
    if (isConnected() && cnx.getRemoteEndpointProtocolVersion() >= ProtocolVersion.v2.getNumber()) {
        int messagesFromQueue = removeExpiredMessagesFromQueue(messageIds);
        Iterable<List<MessageIdImpl>> batches = Iterables.partition(messageIds.stream().map(messageId -> (MessageIdImpl) messageId).collect(Collectors.toSet()), MAX_REDELIVER_UNACKNOWLEDGED);
        MessageIdData.Builder builder = MessageIdData.newBuilder();
        batches.forEach(ids -> {
            List<MessageIdData> messageIdDatas = ids.stream().map(messageId -> {
                // attempt to remove message from batchMessageAckTracker
                builder.setPartition(messageId.getPartitionIndex());
                builder.setLedgerId(messageId.getLedgerId());
                builder.setEntryId(messageId.getEntryId());
                return builder.build();
            }).collect(Collectors.toList());
            ByteBuf cmd = Commands.newRedeliverUnacknowledgedMessages(consumerId, messageIdDatas);
            cnx.ctx().writeAndFlush(cmd, cnx.ctx().voidPromise());
            messageIdDatas.forEach(MessageIdData::recycle);
        });
        if (messagesFromQueue > 0) {
            increaseAvailablePermits(cnx, messagesFromQueue);
        }
        builder.recycle();
        if (log.isDebugEnabled()) {
            log.debug("[{}] [{}] [{}] Redeliver unacked messages and increase {} permits", subscription, topic, consumerName, messagesFromQueue);
        }
        return;
    }
    if (cnx == null || (getState() == State.Connecting)) {
        log.warn("[{}] Client Connection needs to be establised for redelivery of unacknowledged messages", this);
    } else {
        log.warn("[{}] Reconnecting the client to redeliver the messages.", this);
        cnx.ctx().close();
    }
}
Also used : PulsarApi(org.apache.pulsar.common.api.proto.PulsarApi) Commands.hasChecksum(org.apache.pulsar.common.api.Commands.hasChecksum) LoggerFactory(org.slf4j.LoggerFactory) AckType(org.apache.pulsar.common.api.proto.PulsarApi.CommandAck.AckType) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Map(java.util.Map) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) Crc32cIntChecksum.computeChecksum(com.scurrilous.circe.checksum.Crc32cIntChecksum.computeChecksum) ReadWriteLock(java.util.concurrent.locks.ReadWriteLock) PulsarDecoder(org.apache.pulsar.common.api.PulsarDecoder) Commands(org.apache.pulsar.common.api.Commands) Set(java.util.Set) Collectors(java.util.stream.Collectors) String.format(java.lang.String.format) Objects(java.util.Objects) Consumer(org.apache.pulsar.client.api.Consumer) List(java.util.List) FutureUtil(org.apache.pulsar.common.util.FutureUtil) MessageIdData(org.apache.pulsar.common.api.proto.PulsarApi.MessageIdData) CompressionCodec(org.apache.pulsar.common.compression.CompressionCodec) AtomicIntegerFieldUpdater(java.util.concurrent.atomic.AtomicIntegerFieldUpdater) ConsumerCryptoFailureAction(org.apache.pulsar.client.api.ConsumerCryptoFailureAction) Iterables(com.google.common.collect.Iterables) ConsumerConfigurationData(org.apache.pulsar.client.impl.conf.ConsumerConfigurationData) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) ProtocolVersion(org.apache.pulsar.common.api.proto.PulsarApi.ProtocolVersion) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) Message(org.apache.pulsar.client.api.Message) SubscriptionInitialPosition(org.apache.pulsar.client.api.SubscriptionInitialPosition) ArrayList(java.util.ArrayList) ConsumerStats(org.apache.pulsar.client.api.ConsumerStats) ByteBuf(io.netty.buffer.ByteBuf) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) CompressionCodecProvider(org.apache.pulsar.common.compression.CompressionCodecProvider) MessageMetadata(org.apache.pulsar.common.api.proto.PulsarApi.MessageMetadata) ExecutorService(java.util.concurrent.ExecutorService) Timeout(io.netty.util.Timeout) Logger(org.slf4j.Logger) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) GenericFutureListener(io.netty.util.concurrent.GenericFutureListener) IOException(java.io.IOException) SubscriptionType(org.apache.pulsar.client.api.SubscriptionType) Schema(org.apache.pulsar.client.api.Schema) Commands.readChecksum(org.apache.pulsar.common.api.Commands.readChecksum) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) ValidationError(org.apache.pulsar.common.api.proto.PulsarApi.CommandAck.ValidationError) AtomicLong(java.util.concurrent.atomic.AtomicLong) MessageId(org.apache.pulsar.client.api.MessageId) CompressionType(org.apache.pulsar.common.api.proto.PulsarApi.CompressionType) InitialPosition(org.apache.pulsar.common.api.proto.PulsarApi.CommandSubscribe.InitialPosition) Future(io.netty.util.concurrent.Future) Collections(java.util.Collections) MessageIdData(org.apache.pulsar.common.api.proto.PulsarApi.MessageIdData) List(java.util.List) ArrayList(java.util.ArrayList) ByteBuf(io.netty.buffer.ByteBuf)

Example 43 with MessageId

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

the class ConsumerImpl method getLastMessageIdAsync.

CompletableFuture<MessageId> getLastMessageIdAsync() {
    if (getState() == State.Closing || getState() == State.Closed) {
        return FutureUtil.failedFuture(new PulsarClientException.AlreadyClosedException("Consumer was already closed"));
    }
    AtomicLong opTimeoutMs = new AtomicLong(client.getConfiguration().getOperationTimeoutMs());
    Backoff backoff = new Backoff(100, TimeUnit.MILLISECONDS, opTimeoutMs.get() * 2, TimeUnit.MILLISECONDS, 0, TimeUnit.MILLISECONDS);
    CompletableFuture<MessageId> getLastMessageIdFuture = new CompletableFuture<>();
    internalGetLastMessageIdAsync(backoff, opTimeoutMs, getLastMessageIdFuture);
    return getLastMessageIdFuture;
}
Also used : AtomicLong(java.util.concurrent.atomic.AtomicLong) CompletableFuture(java.util.concurrent.CompletableFuture) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) MessageId(org.apache.pulsar.client.api.MessageId)

Example 44 with MessageId

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

the class ResendRequestTest method testExclusiveSingleAckedNormalTopic.

@Test(timeOut = testTimeout)
public void testExclusiveSingleAckedNormalTopic() throws Exception {
    String key = "testExclusiveSingleAckedNormalTopic";
    final String topicName = "persistent://prop/use/ns-abc/topic-" + key;
    final String subscriptionName = "my-ex-subscription-" + key;
    final String messagePredicate = "my-message-" + key + "-";
    final int totalMessages = 10;
    HashSet<MessageId> messageIdHashSet = new HashSet<MessageId>();
    HashSet<String> messageDataHashSet = new HashSet<String>();
    // 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);
    // 2. Create consumer
    Consumer<byte[]> consumer = pulsarClient.newConsumer().topic(topicName).subscriptionName(subscriptionName).receiverQueueSize(7).subscribe();
    // 3. producer publish messages
    for (int i = 0; i < totalMessages; i++) {
        String message = messagePredicate + i;
        producer.send(message.getBytes());
    }
    // 4. Receive messages
    Message<byte[]> message = consumer.receive();
    log.info("Message received " + new String(message.getData()));
    for (int i = 1; i < totalMessages; i++) {
        Message<byte[]> msg = consumer.receive();
        log.info("Message received " + new String(msg.getData()));
        messageDataHashSet.add(new String(msg.getData()));
    }
    printIncomingMessageQueue(consumer);
    // 5. Ack 1st message and ask for resend
    consumer.acknowledge(message);
    log.info("Message acked " + new String(message.getData()));
    messageIdHashSet.add(message.getMessageId());
    messageDataHashSet.add(new String(message.getData()));
    consumer.redeliverUnacknowledgedMessages();
    log.info("Resend Messages Request sent");
    // 6. Check if messages resent in correct order
    for (int i = 0; i < totalMessages - 1; i++) {
        message = consumer.receive();
        log.info("Message received " + new String(message.getData()));
        if (i < 2) {
            messageIdHashSet.add(message.getMessageId());
            consumer.acknowledge(message);
        }
        log.info("Message acked " + new String(message.getData()));
        assertTrue(messageDataHashSet.contains(new String(message.getData())));
    }
    assertEquals(messageIdHashSet.size(), 3);
    assertEquals(messageDataHashSet.size(), totalMessages);
    printIncomingMessageQueue(consumer);
    // 7. Request resend 2nd time - you should receive 4 messages
    consumer.redeliverUnacknowledgedMessages();
    log.info("Resend Messages Request sent");
    message = consumer.receive(2000, TimeUnit.MILLISECONDS);
    while (message != null) {
        log.info("Message received " + new String(message.getData()));
        consumer.acknowledge(message);
        log.info("Message acked " + new String(message.getData()));
        messageIdHashSet.add(message.getMessageId());
        messageDataHashSet.add(new String(message.getData()));
        message = consumer.receive(5000, TimeUnit.MILLISECONDS);
    }
    assertEquals(messageIdHashSet.size(), totalMessages);
    assertEquals(messageDataHashSet.size(), totalMessages);
    printIncomingMessageQueue(consumer);
    // 9. Calling resend after acking all messages - expectin 0 messages
    consumer.redeliverUnacknowledgedMessages();
    assertEquals(consumer.receive(2000, TimeUnit.MILLISECONDS), null);
    // 10. Checking message contents
    for (int i = 0; i < totalMessages; i++) {
        assertTrue(messageDataHashSet.contains(messagePredicate + i));
    }
}
Also used : PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) MessageId(org.apache.pulsar.client.api.MessageId) HashSet(java.util.HashSet) Test(org.testng.annotations.Test)

Example 45 with MessageId

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

the class SubscriptionSeekTest method testSeek.

@Test
public void testSeek() throws Exception {
    final String topicName = "persistent://prop/use/ns-abc/testSeek";
    Producer<byte[]> producer = pulsarClient.newProducer().topic(topicName).create();
    // Disable pre-fetch in consumer to track the messages received
    org.apache.pulsar.client.api.Consumer<byte[]> consumer = pulsarClient.newConsumer().topic(topicName).subscriptionName("my-subscription").receiverQueueSize(0).subscribe();
    PersistentTopic topicRef = (PersistentTopic) pulsar.getBrokerService().getTopicReference(topicName);
    assertNotNull(topicRef);
    assertEquals(topicRef.getProducers().size(), 1);
    assertEquals(topicRef.getSubscriptions().size(), 1);
    List<MessageId> messageIds = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        String message = "my-message-" + i;
        MessageId msgId = producer.send(message.getBytes());
        messageIds.add(msgId);
    }
    PersistentSubscription sub = topicRef.getSubscription("my-subscription");
    assertEquals(sub.getNumberOfEntriesInBacklog(), 10);
    consumer.seek(MessageId.latest);
    assertEquals(sub.getNumberOfEntriesInBacklog(), 0);
    // Wait for consumer to reconnect
    Thread.sleep(500);
    consumer.seek(MessageId.earliest);
    assertEquals(sub.getNumberOfEntriesInBacklog(), 10);
    Thread.sleep(500);
    consumer.seek(messageIds.get(5));
    assertEquals(sub.getNumberOfEntriesInBacklog(), 5);
}
Also used : PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) ArrayList(java.util.ArrayList) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription) MessageId(org.apache.pulsar.client.api.MessageId) Test(org.testng.annotations.Test)

Aggregations

MessageId (org.apache.pulsar.client.api.MessageId)65 Test (org.testng.annotations.Test)42 CompletableFuture (java.util.concurrent.CompletableFuture)25 Message (org.apache.pulsar.client.api.Message)22 PulsarClientException (org.apache.pulsar.client.api.PulsarClientException)16 List (java.util.List)14 TimeUnit (java.util.concurrent.TimeUnit)14 Producer (org.apache.pulsar.client.api.Producer)14 Future (java.util.concurrent.Future)13 Consumer (org.apache.pulsar.client.api.Consumer)13 MessageIdImpl (org.apache.pulsar.client.impl.MessageIdImpl)13 ExecutorService (java.util.concurrent.ExecutorService)11 Logger (org.slf4j.Logger)11 LoggerFactory (org.slf4j.LoggerFactory)11 ByteBuf (io.netty.buffer.ByteBuf)10 HashSet (java.util.HashSet)10 Map (java.util.Map)10 Lists (com.google.common.collect.Lists)8 IOException (java.io.IOException)8 ArrayList (java.util.ArrayList)8