@@ -548,25 +548,27 @@ void ConsumerImpl::messageReceived(const ClientConnectionPtr& cnx, const proto::
548548 bool & isChecksumValid, proto::BrokerEntryMetadata& brokerEntryMetadata,
549549 proto::MessageMetadata& metadata, SharedBuffer& payload) {
550550 LOG_DEBUG (getName () << " Received Message -- Size: " << payload.readableBytes ());
551-
552- if (!decryptMessageIfNeeded (cnx, msg, metadata, payload)) {
553- // Message was discarded or not consumed due to decryption failure
554- return ;
555- }
556-
557551 if (!isChecksumValid) {
558552 // Message discarded for checksum error
559553 discardCorruptedMessage (cnx, msg.message_id (), CommandAck_ValidationError_ChecksumMismatch);
560554 return ;
561555 }
562556
563- auto redeliveryCount = msg.redelivery_count ();
564- const bool isMessageUndecryptable =
565- metadata.encryption_keys_size () > 0 && !config_.getCryptoKeyReader ().get () &&
566- config_.getCryptoFailureAction () == ConsumerCryptoFailureAction::CONSUME;
557+ auto encryptionContext = metadata.encryption_keys_size () > 0
558+ ? optional<EncryptionContext>{std::in_place, metadata, false }
559+ : std::nullopt ;
567560
561+ auto decryptResult = decryptMessageIfNeeded (cnx, encryptionContext, payload, msg.message_id ());
562+ if (decryptResult == FAILED) {
563+ // Message was discarded due to decryption failure or not consumed due to decryption failure
564+ return ;
565+ } else if (decryptResult == CONSUME_ENCRYPTED) {
566+ encryptionContext->isDecryptionFailed_ = true ;
567+ }
568+
569+ auto redeliveryCount = msg.redelivery_count ();
568570 const bool isChunkedMessage = metadata.num_chunks_from_msg () > 1 ;
569- if (!isMessageUndecryptable && !isChunkedMessage) {
571+ if (decryptResult == DECRYPTED && !isChunkedMessage) {
570572 if (!uncompressMessageIfNeeded (cnx, msg.message_id (), metadata, payload, true )) {
571573 // Message was discarded on decompression error
572574 return ;
@@ -586,9 +588,9 @@ void ConsumerImpl::messageReceived(const ClientConnectionPtr& cnx, const proto::
586588 }
587589 }
588590
589- Message m (messageId, brokerEntryMetadata, metadata, payload);
591+ Message m{std::make_shared<MessageImpl>(messageId, brokerEntryMetadata, metadata, payload, std::nullopt ,
592+ getTopicPtr (), std::move (encryptionContext))};
590593 m.impl_ ->cnx_ = cnx.get ();
591- m.impl_ ->setTopicName (getTopicPtr ());
592594 m.impl_ ->setRedeliveryCount (msg.redelivery_count ());
593595
594596 if (metadata.has_schema_version ()) {
@@ -610,14 +612,16 @@ void ConsumerImpl::messageReceived(const ClientConnectionPtr& cnx, const proto::
610612 return ;
611613 }
612614
613- if (metadata.has_num_messages_in_batch ()) {
615+ // When the decryption failed, the whole batch message will be treated as a single message.
616+ if (metadata.has_num_messages_in_batch () && decryptResult == DECRYPTED) {
614617 BitSet::Data words (msg.ack_set_size ());
615618 for (int i = 0 ; i < words.size (); i++) {
616619 words[i] = msg.ack_set (i);
617620 }
618621 BitSet ackSet{std::move (words)};
619622 Lock lock (mutex_);
620- numOfMessageReceived = receiveIndividualMessagesFromBatch (cnx, m, ackSet, msg.redelivery_count ());
623+ numOfMessageReceived =
624+ receiveIndividualMessagesFromBatch (cnx, m, ackSet, msg.redelivery_count (), encryptionContext);
621625 } else {
622626 // try convert key value data.
623627 m.impl_ ->convertPayloadToKeyValue (config_.getSchema ());
@@ -742,9 +746,9 @@ void ConsumerImpl::notifyPendingReceivedCallback(Result result, Message& msg,
742746}
743747
744748// Zero Queue size is not supported with Batch Messages
745- uint32_t ConsumerImpl::receiveIndividualMessagesFromBatch (const ClientConnectionPtr& cnx,
746- Message& batchedMessage, const BitSet& ackSet,
747- int redeliveryCount ) {
749+ uint32_t ConsumerImpl::receiveIndividualMessagesFromBatch (
750+ const ClientConnectionPtr& cnx, Message& batchedMessage, const BitSet& ackSet, int redeliveryCount ,
751+ const optional<EncryptionContext>& encryptionContext ) {
748752 auto batchSize = batchedMessage.impl_ ->metadata .num_messages_in_batch ();
749753 LOG_DEBUG (" Received Batch messages of size - " << batchSize
750754 << " -- msgId: " << batchedMessage.getMessageId ());
@@ -756,7 +760,8 @@ uint32_t ConsumerImpl::receiveIndividualMessagesFromBatch(const ClientConnection
756760 std::vector<Message> possibleToDeadLetter;
757761 for (int i = 0 ; i < batchSize; i++) {
758762 // This is a cheap copy since message contains only one shared pointer (impl_)
759- Message msg = Commands::deSerializeSingleMessageInBatch (batchedMessage, i, batchSize, acker);
763+ Message msg =
764+ Commands::deSerializeSingleMessageInBatch (batchedMessage, i, batchSize, acker, encryptionContext);
760765 msg.impl_ ->setRedeliveryCount (redeliveryCount);
761766 msg.impl_ ->setTopicName (batchedMessage.impl_ ->topicName_ );
762767 msg.impl_ ->convertPayloadToKeyValue (config_.getSchema ());
@@ -812,50 +817,51 @@ uint32_t ConsumerImpl::receiveIndividualMessagesFromBatch(const ClientConnection
812817 return batchSize - skippedMessages;
813818}
814819
815- bool ConsumerImpl::decryptMessageIfNeeded (const ClientConnectionPtr& cnx, const proto::CommandMessage& msg,
816- const proto::MessageMetadata& metadata, SharedBuffer& payload) {
817- if (!metadata.encryption_keys_size ()) {
818- return true ;
820+ auto ConsumerImpl::decryptMessageIfNeeded (const ClientConnectionPtr& cnx,
821+ const optional<EncryptionContext>& context, SharedBuffer& payload,
822+ const proto::MessageIdData& msgId) -> DecryptResult {
823+ if (!context.has_value ()) {
824+ return DECRYPTED;
819825 }
820826
821827 // If KeyReader is not configured throw exception based on config param
822828 if (!config_.isEncryptionEnabled ()) {
823829 if (config_.getCryptoFailureAction () == ConsumerCryptoFailureAction::CONSUME) {
824830 LOG_WARN (getName () << " CryptoKeyReader is not implemented. Consuming encrypted message." );
825- return true ;
831+ return CONSUME_ENCRYPTED ;
826832 } else if (config_.getCryptoFailureAction () == ConsumerCryptoFailureAction::DISCARD) {
827833 LOG_WARN (getName () << " Skipping decryption since CryptoKeyReader is not implemented and config "
828834 " is set to discard" );
829- discardCorruptedMessage (cnx, msg. message_id () , CommandAck_ValidationError_DecryptionError);
835+ discardCorruptedMessage (cnx, msgId , CommandAck_ValidationError_DecryptionError);
830836 } else {
831837 LOG_ERROR (getName () << " Message delivery failed since CryptoKeyReader is not implemented to "
832838 " consume encrypted message" );
833- auto messageId = MessageIdBuilder::from (msg. message_id () ).build ();
839+ auto messageId = MessageIdBuilder::from (msgId ).build ();
834840 unAckedMessageTrackerPtr_->add (messageId);
835841 }
836- return false ;
842+ return FAILED ;
837843 }
838844
839845 SharedBuffer decryptedPayload;
840- if (msgCrypto_->decrypt (metadata , payload, config_.getCryptoKeyReader (), decryptedPayload)) {
846+ if (msgCrypto_->decrypt (*context , payload, config_.getCryptoKeyReader (), decryptedPayload)) {
841847 payload = decryptedPayload;
842- return true ;
848+ return DECRYPTED ;
843849 }
844850
845851 if (config_.getCryptoFailureAction () == ConsumerCryptoFailureAction::CONSUME) {
846852 // Note, batch message will fail to consume even if config is set to consume
847853 LOG_WARN (
848854 getName () << " Decryption failed. Consuming encrypted message since config is set to consume." );
849- return true ;
855+ return CONSUME_ENCRYPTED ;
850856 } else if (config_.getCryptoFailureAction () == ConsumerCryptoFailureAction::DISCARD) {
851857 LOG_WARN (getName () << " Discarding message since decryption failed and config is set to discard" );
852- discardCorruptedMessage (cnx, msg. message_id () , CommandAck_ValidationError_DecryptionError);
858+ discardCorruptedMessage (cnx, msgId , CommandAck_ValidationError_DecryptionError);
853859 } else {
854860 LOG_ERROR (getName () << " Message delivery failed since unable to decrypt incoming message" );
855- auto messageId = MessageIdBuilder::from (msg. message_id () ).build ();
861+ auto messageId = MessageIdBuilder::from (msgId ).build ();
856862 unAckedMessageTrackerPtr_->add (messageId);
857863 }
858- return false ;
864+ return FAILED ;
859865}
860866
861867bool ConsumerImpl::uncompressMessageIfNeeded (const ClientConnectionPtr& cnx,
0 commit comments