Search in sources :

Example 6 with MessageIdData

use of org.apache.pulsar.common.api.proto.MessageIdData in project pulsar by apache.

the class ConsumerImpl method messageReceived.

void messageReceived(CommandMessage cmdMessage, ByteBuf headersAndPayload, ClientCnx cnx) {
    List<Long> ackSet = Collections.emptyList();
    if (cmdMessage.getAckSetsCount() > 0) {
        ackSet = new ArrayList<>(cmdMessage.getAckSetsCount());
        for (int i = 0; i < cmdMessage.getAckSetsCount(); i++) {
            ackSet.add(cmdMessage.getAckSetAt(i));
        }
    }
    int redeliveryCount = cmdMessage.getRedeliveryCount();
    MessageIdData messageId = cmdMessage.getMessageId();
    long consumerEpoch = DEFAULT_CONSUMER_EPOCH;
    // if broker send messages to client with consumerEpoch, we should set consumerEpoch to message
    if (cmdMessage.hasConsumerEpoch()) {
        consumerEpoch = cmdMessage.getConsumerEpoch();
    }
    if (log.isDebugEnabled()) {
        log.debug("[{}][{}] Received message: {}/{}", topic, subscription, messageId.getLedgerId(), messageId.getEntryId());
    }
    if (!verifyChecksum(headersAndPayload, messageId)) {
        // discard message with checksum error
        discardCorruptedMessage(messageId, cnx, ValidationError.ChecksumMismatch);
        return;
    }
    BrokerEntryMetadata brokerEntryMetadata;
    MessageMetadata msgMetadata;
    try {
        brokerEntryMetadata = Commands.parseBrokerEntryMetadataIfExist(headersAndPayload);
        msgMetadata = Commands.parseMessageMetadata(headersAndPayload);
    } catch (Throwable t) {
        discardCorruptedMessage(messageId, cnx, ValidationError.ChecksumMismatch);
        return;
    }
    final int numMessages = msgMetadata.getNumMessagesInBatch();
    final int numChunks = msgMetadata.hasNumChunksFromMsg() ? msgMetadata.getNumChunksFromMsg() : 0;
    final boolean isChunkedMessage = numChunks > 1 && conf.getSubscriptionType() != SubscriptionType.Shared;
    MessageIdImpl msgId = new MessageIdImpl(messageId.getLedgerId(), messageId.getEntryId(), getPartitionIndex());
    if (acknowledgmentsGroupingTracker.isDuplicate(msgId)) {
        if (log.isDebugEnabled()) {
            log.debug("[{}] [{}] Ignoring message as it was already being acked earlier by same consumer {}/{}", topic, subscription, consumerName, msgId);
        }
        increaseAvailablePermits(cnx, numMessages);
        return;
    }
    ByteBuf decryptedPayload = decryptPayloadIfNeeded(messageId, redeliveryCount, msgMetadata, headersAndPayload, cnx);
    boolean isMessageUndecryptable = isMessageUndecryptable(msgMetadata);
    if (decryptedPayload == null) {
        // Message was discarded or CryptoKeyReader isn't implemented
        return;
    }
    // uncompress decryptedPayload and release decryptedPayload-ByteBuf
    ByteBuf uncompressedPayload = (isMessageUndecryptable || isChunkedMessage) ? decryptedPayload.retain() : uncompressPayloadIfNeeded(messageId, msgMetadata, decryptedPayload, cnx, true);
    decryptedPayload.release();
    if (uncompressedPayload == null) {
        // Message was discarded on decompression error
        return;
    }
    if (conf.getPayloadProcessor() != null) {
        // uncompressedPayload is released in this method so we don't need to call release() again
        processPayloadByProcessor(brokerEntryMetadata, msgMetadata, uncompressedPayload, msgId, schema, redeliveryCount, ackSet, consumerEpoch);
        return;
    }
    // and return undecrypted payload
    if (isMessageUndecryptable || (numMessages == 1 && !msgMetadata.hasNumMessagesInBatch())) {
        // right now, chunked messages are only supported by non-shared subscription
        if (isChunkedMessage) {
            uncompressedPayload = processMessageChunk(uncompressedPayload, msgMetadata, msgId, messageId, cnx);
            if (uncompressedPayload == null) {
                return;
            }
            // last chunk received: so, stitch chunked-messages and clear up chunkedMsgBuffer
            if (log.isDebugEnabled()) {
                log.debug("Chunked message completed chunkId {}, total-chunks {}, msgId {} sequenceId {}", msgMetadata.getChunkId(), msgMetadata.getNumChunksFromMsg(), msgId, msgMetadata.getSequenceId());
            }
            // remove buffer from the map, set the chunk message id
            ChunkedMessageCtx chunkedMsgCtx = chunkedMessagesMap.remove(msgMetadata.getUuid());
            if (chunkedMsgCtx.chunkedMessageIds.length > 0) {
                msgId = new ChunkMessageIdImpl(chunkedMsgCtx.chunkedMessageIds[0], chunkedMsgCtx.chunkedMessageIds[chunkedMsgCtx.chunkedMessageIds.length - 1]);
            }
            // add chunked messageId to unack-message tracker, and reduce pending-chunked-message count
            unAckedChunkedMessageIdSequenceMap.put(msgId, chunkedMsgCtx.chunkedMessageIds);
            pendingChunkedMessageCount--;
            chunkedMsgCtx.recycle();
        }
        // If the topic is non-persistent, we should not ignore any messages.
        if (this.topicName.isPersistent() && isSameEntry(msgId) && isPriorEntryIndex(messageId.getEntryId())) {
            // We need to discard entries that were prior to startMessageId
            if (log.isDebugEnabled()) {
                log.debug("[{}] [{}] Ignoring message from before the startMessageId: {}", subscription, consumerName, startMessageId);
            }
            uncompressedPayload.release();
            return;
        }
        final MessageImpl<T> message = newMessage(msgId, brokerEntryMetadata, msgMetadata, uncompressedPayload, schema, redeliveryCount, consumerEpoch);
        uncompressedPayload.release();
        if (deadLetterPolicy != null && possibleSendToDeadLetterTopicMessages != null && redeliveryCount >= deadLetterPolicy.getMaxRedeliverCount()) {
            possibleSendToDeadLetterTopicMessages.put((MessageIdImpl) message.getMessageId(), Collections.singletonList(message));
        }
        executeNotifyCallback(message);
    } else {
        // handle batch message enqueuing; uncompressed payload has all messages in batch
        receiveIndividualMessagesFromBatch(brokerEntryMetadata, msgMetadata, redeliveryCount, ackSet, uncompressedPayload, messageId, cnx, consumerEpoch);
        uncompressedPayload.release();
    }
    tryTriggerListener();
}
Also used : MessageIdData(org.apache.pulsar.common.api.proto.MessageIdData) ByteBuf(io.netty.buffer.ByteBuf) MessageMetadata(org.apache.pulsar.common.api.proto.MessageMetadata) SingleMessageMetadata(org.apache.pulsar.common.api.proto.SingleMessageMetadata) AtomicLong(java.util.concurrent.atomic.AtomicLong) BrokerEntryMetadata(org.apache.pulsar.common.api.proto.BrokerEntryMetadata)

Example 7 with MessageIdData

use of org.apache.pulsar.common.api.proto.MessageIdData in project pulsar by apache.

the class ConsumerImpl method getRedeliveryMessageIdData.

private CompletableFuture<List<MessageIdData>> getRedeliveryMessageIdData(List<MessageIdImpl> messageIds) {
    if (messageIds == null || messageIds.isEmpty()) {
        return CompletableFuture.completedFuture(Collections.emptyList());
    }
    List<MessageIdData> data = new ArrayList<>(messageIds.size());
    List<CompletableFuture<Void>> futures = new ArrayList<>(messageIds.size());
    messageIds.forEach(messageId -> {
        CompletableFuture<Boolean> future = processPossibleToDLQ(messageId);
        futures.add(future.thenAccept(sendToDLQ -> {
            if (!sendToDLQ) {
                data.add(new MessageIdData().setPartition(messageId.getPartitionIndex()).setLedgerId(messageId.getLedgerId()).setEntryId(messageId.getEntryId()));
            }
        }));
    });
    return FutureUtil.waitForAll(futures).thenCompose(v -> CompletableFuture.completedFuture(data));
}
Also used : EncryptionKey(org.apache.pulsar.common.api.EncryptionContext.EncryptionKey) SubscriptionMode(org.apache.pulsar.client.api.SubscriptionMode) MessageIdData(org.apache.pulsar.common.api.proto.MessageIdData) Producer(org.apache.pulsar.client.api.Producer) LoggerFactory(org.slf4j.LoggerFactory) MessageCryptoBc(org.apache.pulsar.client.impl.crypto.MessageCryptoBc) MessageCrypto(org.apache.pulsar.client.api.MessageCrypto) StringUtils(org.apache.commons.lang3.StringUtils) KeyValue(org.apache.pulsar.common.api.proto.KeyValue) ByteBuffer(java.nio.ByteBuffer) GrowableArrayBlockingQueue(org.apache.pulsar.common.util.collections.GrowableArrayBlockingQueue) ProtocolVersion(org.apache.pulsar.common.api.proto.ProtocolVersion) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) TxnID(org.apache.pulsar.client.api.transaction.TxnID) Handle(io.netty.util.Recycler.Handle) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ExecutorProvider(org.apache.pulsar.client.util.ExecutorProvider) Runnables.catchingAndLoggingThrowables(org.apache.pulsar.common.util.Runnables.catchingAndLoggingThrowables) Map(java.util.Map) Messages(org.apache.pulsar.client.api.Messages) RetryMessageUtil(org.apache.pulsar.client.util.RetryMessageUtil) CompletableFutureCancellationHandler(org.apache.pulsar.common.util.CompletableFutureCancellationHandler) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) ReadWriteLock(java.util.concurrent.locks.ReadWriteLock) BrokerEntryMetadata(org.apache.pulsar.common.api.proto.BrokerEntryMetadata) Crc32cIntChecksum(com.scurrilous.circe.checksum.Crc32cIntChecksum) ValidationError(org.apache.pulsar.common.api.proto.CommandAck.ValidationError) BitSetRecyclable(org.apache.pulsar.common.util.collections.BitSetRecyclable) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) BlockingQueue(java.util.concurrent.BlockingQueue) EncryptionContext(org.apache.pulsar.common.api.EncryptionContext) ComparisonChain(com.google.common.collect.ComparisonChain) Collectors(java.util.stream.Collectors) PulsarByteBufAllocator(org.apache.pulsar.common.allocator.PulsarByteBufAllocator) Recycler(io.netty.util.Recycler) Objects(java.util.Objects) Consumer(org.apache.pulsar.client.api.Consumer) List(java.util.List) FutureUtil(org.apache.pulsar.common.util.FutureUtil) MessageMetadata(org.apache.pulsar.common.api.proto.MessageMetadata) ConcurrentOpenHashMap(org.apache.pulsar.common.util.collections.ConcurrentOpenHashMap) EncryptionKeys(org.apache.pulsar.common.api.proto.EncryptionKeys) CommandMessage(org.apache.pulsar.common.api.proto.CommandMessage) ReferenceCountUtil(io.netty.util.ReferenceCountUtil) Optional(java.util.Optional) SchemaInfo(org.apache.pulsar.common.schema.SchemaInfo) SortedMap(java.util.SortedMap) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) CompressionCodec(org.apache.pulsar.common.compression.CompressionCodec) Iterables(com.google.common.collect.Iterables) AtomicIntegerFieldUpdater(java.util.concurrent.atomic.AtomicIntegerFieldUpdater) ConsumerCryptoFailureAction(org.apache.pulsar.client.api.ConsumerCryptoFailureAction) TopicName(org.apache.pulsar.common.naming.TopicName) ConsumerConfigurationData(org.apache.pulsar.client.impl.conf.ConsumerConfigurationData) AckType(org.apache.pulsar.common.api.proto.CommandAck.AckType) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) Message(org.apache.pulsar.client.api.Message) SubscriptionInitialPosition(org.apache.pulsar.client.api.SubscriptionInitialPosition) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) SchemaType(org.apache.pulsar.common.schema.SchemaType) ArrayList(java.util.ArrayList) Commands(org.apache.pulsar.common.protocol.Commands) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ByteBuf(io.netty.buffer.ByteBuf) Commands.hasChecksum(org.apache.pulsar.common.protocol.Commands.hasChecksum) TopicDoesNotExistException(org.apache.pulsar.client.api.PulsarClientException.TopicDoesNotExistException) CompressionCodecProvider(org.apache.pulsar.common.compression.CompressionCodecProvider) CompressionType(org.apache.pulsar.common.api.proto.CompressionType) TypedMessageBuilder(org.apache.pulsar.client.api.TypedMessageBuilder) SafeCollectionUtils(org.apache.pulsar.common.util.SafeCollectionUtils) DEFAULT_CONSUMER_EPOCH(org.apache.pulsar.common.protocol.Commands.DEFAULT_CONSUMER_EPOCH) Timeout(io.netty.util.Timeout) Logger(org.slf4j.Logger) TransactionImpl(org.apache.pulsar.client.impl.transaction.TransactionImpl) InitialPosition(org.apache.pulsar.common.api.proto.CommandSubscribe.InitialPosition) DeadLetterPolicy(org.apache.pulsar.client.api.DeadLetterPolicy) IOException(java.io.IOException) AtomicLongFieldUpdater(java.util.concurrent.atomic.AtomicLongFieldUpdater) SubscriptionType(org.apache.pulsar.client.api.SubscriptionType) Schema(org.apache.pulsar.client.api.Schema) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) MessageId(org.apache.pulsar.client.api.MessageId) TreeMap(java.util.TreeMap) SingleMessageMetadata(org.apache.pulsar.common.api.proto.SingleMessageMetadata) Collections(java.util.Collections) CompletableFuture(java.util.concurrent.CompletableFuture) MessageIdData(org.apache.pulsar.common.api.proto.MessageIdData) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean)

Example 8 with MessageIdData

use of org.apache.pulsar.common.api.proto.MessageIdData in project pulsar by apache.

the class ConsumerImpl method internalGetLastMessageIdAsync.

private void internalGetLastMessageIdAsync(final Backoff backoff, final AtomicLong remainingTime, CompletableFuture<GetLastMessageIdResponse> future) {
    ClientCnx cnx = cnx();
    if (isConnected() && cnx != null) {
        if (!Commands.peerSupportsGetLastMessageId(cnx.getRemoteEndpointProtocolVersion())) {
            future.completeExceptionally(new PulsarClientException.NotSupportedException(String.format("The command `GetLastMessageId` is not supported for the protocol version %d. " + "The consumer is %s, topic %s, subscription %s", cnx.getRemoteEndpointProtocolVersion(), consumerName, topicName.toString(), subscription)));
            return;
        }
        long requestId = client.newRequestId();
        ByteBuf getLastIdCmd = Commands.newGetLastMessageId(consumerId, requestId);
        log.info("[{}][{}] Get topic last message Id", topic, subscription);
        cnx.sendGetLastMessageId(getLastIdCmd, requestId).thenAccept(cmd -> {
            MessageIdData lastMessageId = cmd.getLastMessageId();
            MessageIdImpl markDeletePosition = null;
            if (cmd.hasConsumerMarkDeletePosition()) {
                markDeletePosition = new MessageIdImpl(cmd.getConsumerMarkDeletePosition().getLedgerId(), cmd.getConsumerMarkDeletePosition().getEntryId(), -1);
            }
            log.info("[{}][{}] Successfully getLastMessageId {}:{}", topic, subscription, lastMessageId.getLedgerId(), lastMessageId.getEntryId());
            MessageId lastMsgId = lastMessageId.getBatchIndex() <= 0 ? new MessageIdImpl(lastMessageId.getLedgerId(), lastMessageId.getEntryId(), lastMessageId.getPartition()) : new BatchMessageIdImpl(lastMessageId.getLedgerId(), lastMessageId.getEntryId(), lastMessageId.getPartition(), lastMessageId.getBatchIndex());
            future.complete(new GetLastMessageIdResponse(lastMsgId, markDeletePosition));
        }).exceptionally(e -> {
            log.error("[{}][{}] Failed getLastMessageId command", topic, subscription);
            future.completeExceptionally(PulsarClientException.wrap(e.getCause(), String.format("The subscription %s of the topic %s gets the last message id was failed", subscription, topicName.toString())));
            return null;
        });
    } else {
        long nextDelay = Math.min(backoff.next(), remainingTime.get());
        if (nextDelay <= 0) {
            future.completeExceptionally(new PulsarClientException.TimeoutException(String.format("The subscription %s of the topic %s could not get the last message id " + "withing configured timeout", subscription, topicName.toString())));
            return;
        }
        internalPinnedExecutor.schedule(() -> {
            log.warn("[{}] [{}] Could not get connection while getLastMessageId -- Will try again in {} ms", topic, getHandlerName(), nextDelay);
            remainingTime.addAndGet(-nextDelay);
            internalGetLastMessageIdAsync(backoff, remainingTime, future);
        }, nextDelay, TimeUnit.MILLISECONDS);
    }
}
Also used : EncryptionKey(org.apache.pulsar.common.api.EncryptionContext.EncryptionKey) SubscriptionMode(org.apache.pulsar.client.api.SubscriptionMode) MessageIdData(org.apache.pulsar.common.api.proto.MessageIdData) Producer(org.apache.pulsar.client.api.Producer) LoggerFactory(org.slf4j.LoggerFactory) MessageCryptoBc(org.apache.pulsar.client.impl.crypto.MessageCryptoBc) MessageCrypto(org.apache.pulsar.client.api.MessageCrypto) StringUtils(org.apache.commons.lang3.StringUtils) KeyValue(org.apache.pulsar.common.api.proto.KeyValue) ByteBuffer(java.nio.ByteBuffer) GrowableArrayBlockingQueue(org.apache.pulsar.common.util.collections.GrowableArrayBlockingQueue) ProtocolVersion(org.apache.pulsar.common.api.proto.ProtocolVersion) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) TxnID(org.apache.pulsar.client.api.transaction.TxnID) Handle(io.netty.util.Recycler.Handle) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ExecutorProvider(org.apache.pulsar.client.util.ExecutorProvider) Runnables.catchingAndLoggingThrowables(org.apache.pulsar.common.util.Runnables.catchingAndLoggingThrowables) Map(java.util.Map) Messages(org.apache.pulsar.client.api.Messages) RetryMessageUtil(org.apache.pulsar.client.util.RetryMessageUtil) CompletableFutureCancellationHandler(org.apache.pulsar.common.util.CompletableFutureCancellationHandler) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) ReadWriteLock(java.util.concurrent.locks.ReadWriteLock) BrokerEntryMetadata(org.apache.pulsar.common.api.proto.BrokerEntryMetadata) Crc32cIntChecksum(com.scurrilous.circe.checksum.Crc32cIntChecksum) ValidationError(org.apache.pulsar.common.api.proto.CommandAck.ValidationError) BitSetRecyclable(org.apache.pulsar.common.util.collections.BitSetRecyclable) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) BlockingQueue(java.util.concurrent.BlockingQueue) EncryptionContext(org.apache.pulsar.common.api.EncryptionContext) ComparisonChain(com.google.common.collect.ComparisonChain) Collectors(java.util.stream.Collectors) PulsarByteBufAllocator(org.apache.pulsar.common.allocator.PulsarByteBufAllocator) Recycler(io.netty.util.Recycler) Objects(java.util.Objects) Consumer(org.apache.pulsar.client.api.Consumer) List(java.util.List) FutureUtil(org.apache.pulsar.common.util.FutureUtil) MessageMetadata(org.apache.pulsar.common.api.proto.MessageMetadata) ConcurrentOpenHashMap(org.apache.pulsar.common.util.collections.ConcurrentOpenHashMap) EncryptionKeys(org.apache.pulsar.common.api.proto.EncryptionKeys) CommandMessage(org.apache.pulsar.common.api.proto.CommandMessage) ReferenceCountUtil(io.netty.util.ReferenceCountUtil) Optional(java.util.Optional) SchemaInfo(org.apache.pulsar.common.schema.SchemaInfo) SortedMap(java.util.SortedMap) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) CompressionCodec(org.apache.pulsar.common.compression.CompressionCodec) Iterables(com.google.common.collect.Iterables) AtomicIntegerFieldUpdater(java.util.concurrent.atomic.AtomicIntegerFieldUpdater) ConsumerCryptoFailureAction(org.apache.pulsar.client.api.ConsumerCryptoFailureAction) TopicName(org.apache.pulsar.common.naming.TopicName) ConsumerConfigurationData(org.apache.pulsar.client.impl.conf.ConsumerConfigurationData) AckType(org.apache.pulsar.common.api.proto.CommandAck.AckType) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) Message(org.apache.pulsar.client.api.Message) SubscriptionInitialPosition(org.apache.pulsar.client.api.SubscriptionInitialPosition) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) SchemaType(org.apache.pulsar.common.schema.SchemaType) ArrayList(java.util.ArrayList) Commands(org.apache.pulsar.common.protocol.Commands) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ByteBuf(io.netty.buffer.ByteBuf) Commands.hasChecksum(org.apache.pulsar.common.protocol.Commands.hasChecksum) TopicDoesNotExistException(org.apache.pulsar.client.api.PulsarClientException.TopicDoesNotExistException) CompressionCodecProvider(org.apache.pulsar.common.compression.CompressionCodecProvider) CompressionType(org.apache.pulsar.common.api.proto.CompressionType) TypedMessageBuilder(org.apache.pulsar.client.api.TypedMessageBuilder) SafeCollectionUtils(org.apache.pulsar.common.util.SafeCollectionUtils) DEFAULT_CONSUMER_EPOCH(org.apache.pulsar.common.protocol.Commands.DEFAULT_CONSUMER_EPOCH) Timeout(io.netty.util.Timeout) Logger(org.slf4j.Logger) TransactionImpl(org.apache.pulsar.client.impl.transaction.TransactionImpl) InitialPosition(org.apache.pulsar.common.api.proto.CommandSubscribe.InitialPosition) DeadLetterPolicy(org.apache.pulsar.client.api.DeadLetterPolicy) IOException(java.io.IOException) AtomicLongFieldUpdater(java.util.concurrent.atomic.AtomicLongFieldUpdater) SubscriptionType(org.apache.pulsar.client.api.SubscriptionType) Schema(org.apache.pulsar.client.api.Schema) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) MessageId(org.apache.pulsar.client.api.MessageId) TreeMap(java.util.TreeMap) SingleMessageMetadata(org.apache.pulsar.common.api.proto.SingleMessageMetadata) Collections(java.util.Collections) MessageIdData(org.apache.pulsar.common.api.proto.MessageIdData) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) ByteBuf(io.netty.buffer.ByteBuf) MessageId(org.apache.pulsar.client.api.MessageId)

Example 9 with MessageIdData

use of org.apache.pulsar.common.api.proto.MessageIdData in project pulsar by apache.

the class ConsumerImpl method connectionOpened.

@Override
public void connectionOpened(final ClientCnx cnx) {
    previousExceptions.clear();
    if (getState() == State.Closing || getState() == State.Closed) {
        setState(State.Closed);
        closeConsumerTasks();
        deregisterFromClientCnx();
        client.cleanupConsumer(this);
        clearReceiverQueue();
        return;
    }
    log.info("[{}][{}] Subscribing to topic on cnx {}, consumerId {}", topic, subscription, cnx.ctx().channel(), consumerId);
    long requestId = client.newRequestId();
    if (duringSeek.get()) {
        acknowledgmentsGroupingTracker.flushAndClean();
    }
    SUBSCRIBE_DEADLINE_UPDATER.compareAndSet(this, 0L, System.currentTimeMillis() + client.getConfiguration().getOperationTimeoutMs());
    int currentSize;
    synchronized (this) {
        currentSize = incomingMessages.size();
        startMessageId = clearReceiverQueue();
        if (possibleSendToDeadLetterTopicMessages != null) {
            possibleSendToDeadLetterTopicMessages.clear();
        }
    }
    boolean isDurable = subscriptionMode == SubscriptionMode.Durable;
    final MessageIdData startMessageIdData;
    // For non-durable we are going to restart from the next entry.
    if (!isDurable && startMessageId != null) {
        startMessageIdData = new MessageIdData().setLedgerId(startMessageId.getLedgerId()).setEntryId(startMessageId.getEntryId()).setBatchIndex(startMessageId.getBatchIndex());
    } else {
        startMessageIdData = null;
    }
    SchemaInfo si = schema.getSchemaInfo();
    if (si != null && (SchemaType.BYTES == si.getType() || SchemaType.NONE == si.getType())) {
        // don't set schema for Schema.BYTES
        si = null;
    }
    // startMessageRollbackDurationInSec should be consider only once when consumer connects to first time
    long startMessageRollbackDuration = (startMessageRollbackDurationInSec > 0 && startMessageId != null && startMessageId.equals(initialStartMessageId)) ? startMessageRollbackDurationInSec : 0;
    // synchronized this, because redeliverUnAckMessage eliminate the epoch inconsistency between them
    synchronized (this) {
        setClientCnx(cnx);
        ByteBuf request = Commands.newSubscribe(topic, subscription, consumerId, requestId, getSubType(), priorityLevel, consumerName, isDurable, startMessageIdData, metadata, readCompacted, conf.isReplicateSubscriptionState(), InitialPosition.valueOf(subscriptionInitialPosition.getValue()), startMessageRollbackDuration, si, createTopicIfDoesNotExist, conf.getKeySharedPolicy(), // Use the current epoch to subscribe.
        conf.getSubscriptionProperties(), CONSUMER_EPOCH.get(this));
        cnx.sendRequestWithId(request, requestId).thenRun(() -> {
            synchronized (ConsumerImpl.this) {
                if (changeToReadyState()) {
                    consumerIsReconnectedToBroker(cnx, currentSize);
                } else {
                    // Consumer was closed while reconnecting, close the connection to make sure the broker
                    // drops the consumer on its side
                    setState(State.Closed);
                    deregisterFromClientCnx();
                    client.cleanupConsumer(this);
                    cnx.channel().close();
                    return;
                }
            }
            resetBackoff();
            boolean firstTimeConnect = subscribeFuture.complete(this);
            // command to receive messages.
            if (!(firstTimeConnect && hasParentConsumer) && getCurrentReceiverQueueSize() != 0) {
                increaseAvailablePermits(cnx, getCurrentReceiverQueueSize());
            }
        }).exceptionally((e) -> {
            deregisterFromClientCnx();
            if (getState() == State.Closing || getState() == State.Closed) {
                // Consumer was closed while reconnecting, close the connection to make sure the broker
                // drops the consumer on its side
                cnx.channel().close();
                return null;
            }
            log.warn("[{}][{}] Failed to subscribe to topic on {}", topic, subscription, cnx.channel().remoteAddress());
            if (e.getCause() instanceof PulsarClientException && PulsarClientException.isRetriableError(e.getCause()) && System.currentTimeMillis() < SUBSCRIBE_DEADLINE_UPDATER.get(ConsumerImpl.this)) {
                reconnectLater(e.getCause());
            } else if (!subscribeFuture.isDone()) {
                // unable to create new consumer, fail operation
                setState(State.Failed);
                closeConsumerTasks();
                subscribeFuture.completeExceptionally(PulsarClientException.wrap(e, String.format("Failed to subscribe the topic %s " + "with subscription name %s when connecting to the broker", topicName.toString(), subscription)));
                client.cleanupConsumer(this);
            } else if (e.getCause() instanceof TopicDoesNotExistException) {
                // The topic was deleted after the consumer was created, and we're
                // not allowed to recreate the topic. This can happen in few cases:
                // * Regex consumer getting error after topic gets deleted
                // * Regular consumer after topic is manually delete and with
                // auto-topic-creation set to false
                // No more retries are needed in this case.
                setState(State.Failed);
                closeConsumerTasks();
                client.cleanupConsumer(this);
                log.warn("[{}][{}] Closed consumer because topic does not exist anymore {}", topic, subscription, cnx.channel().remoteAddress());
            } else {
                // consumer was subscribed and connected but we got some error, keep trying
                reconnectLater(e.getCause());
            }
            return null;
        });
    }
}
Also used : MessageIdData(org.apache.pulsar.common.api.proto.MessageIdData) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) ByteBuf(io.netty.buffer.ByteBuf) TopicDoesNotExistException(org.apache.pulsar.client.api.PulsarClientException.TopicDoesNotExistException) SchemaInfo(org.apache.pulsar.common.schema.SchemaInfo)

Example 10 with MessageIdData

use of org.apache.pulsar.common.api.proto.MessageIdData in project pulsar by apache.

the class MessageIdImpl method toByteArray.

// batchIndex is -1 if message is non-batched message and has the batchIndex for a batch message
protected byte[] toByteArray(int batchIndex, int batchSize) {
    MessageIdData msgId = writeMessageIdData(null, batchIndex, batchSize);
    int size = msgId.getSerializedSize();
    ByteBuf serialized = Unpooled.buffer(size, size);
    msgId.writeTo(serialized);
    return serialized.array();
}
Also used : MessageIdData(org.apache.pulsar.common.api.proto.MessageIdData) ByteBuf(io.netty.buffer.ByteBuf)

Aggregations

MessageIdData (org.apache.pulsar.common.api.proto.MessageIdData)24 ByteBuf (io.netty.buffer.ByteBuf)12 CompletableFuture (java.util.concurrent.CompletableFuture)8 PositionImpl (org.apache.bookkeeper.mledger.impl.PositionImpl)8 ArrayList (java.util.ArrayList)7 Collections (java.util.Collections)6 List (java.util.List)6 MessageId (org.apache.pulsar.client.api.MessageId)6 FutureUtil (org.apache.pulsar.common.util.FutureUtil)6 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)5 Map (java.util.Map)5 Objects (java.util.Objects)5 AtomicLong (java.util.concurrent.atomic.AtomicLong)5 Collectors (java.util.stream.Collectors)5 PersistentTopic (org.apache.pulsar.broker.service.persistent.PersistentTopic)5 PulsarClientException (org.apache.pulsar.client.api.PulsarClientException)5 CommandAck (org.apache.pulsar.common.api.proto.CommandAck)5 InitialPosition (org.apache.pulsar.common.api.proto.CommandSubscribe.InitialPosition)5 MessageMetadata (org.apache.pulsar.common.api.proto.MessageMetadata)5 IOException (java.io.IOException)4