private ProducerActor <T> .OpSendMsg <T> CreateOpSendMsg(KeyedBatch keyedBatch)
        {
            var encryptedPayload = keyedBatch.CompressedBatchMetadataAndPayload;

            if (Container.Configuration.EncryptionEnabled && Container.Crypto != null)
            {
                try
                {
                    encryptedPayload = Container.Crypto.Encrypt(Container.Configuration.EncryptionKeys, Container.Configuration.CryptoKeyReader, keyedBatch.MessageMetadata, encryptedPayload);
                }
                catch (PulsarClientException e)
                {
                    // Unless config is set to explicitly publish un-encrypted message upon failure, fail the request
                    if (Container.Configuration.CryptoFailureAction != ProducerCryptoFailureAction.Send)
                    {
                        throw;
                    }
                    _log.Warning($"[{TopicName}] [{ProducerName}] Failed to encrypt message '{e.Message}'. Proceeding with publishing unencrypted message");
                    encryptedPayload = keyedBatch.CompressedBatchMetadataAndPayload;
                }
            }
            if (encryptedPayload.Length > Container.MaxMessageSize)
            {
                Discard(new PulsarClientException.InvalidMessageException("Message Size is bigger than " + Container.MaxMessageSize + " bytes"));
                return(null);
            }

            var  numMessagesInBatch    = keyedBatch.Messages.Count;
            long currentBatchSizeBytes = 0;

            foreach (var message in keyedBatch.Messages)
            {
                currentBatchSizeBytes += message.Data.Length;
            }

            keyedBatch.MessageMetadata.ProducerName       = Container.ProducerName;
            keyedBatch.MessageMetadata.PublishTime        = (ulong)DateTimeHelper.CurrentUnixTimeMillis();
            keyedBatch.MessageMetadata.NumMessagesInBatch = numMessagesInBatch;

            if (CurrentTxnidMostBits != -1)
            {
                keyedBatch.MessageMetadata.TxnidMostBits = (ulong)CurrentTxnidMostBits;
            }
            if (CurrentTxnidLeastBits != -1)
            {
                keyedBatch.MessageMetadata.TxnidLeastBits = (ulong)CurrentTxnidLeastBits;
            }
            var cmd = Commands.NewSend(Container.ProducerId, keyedBatch.SequenceId, numMessagesInBatch, keyedBatch.MessageMetadata, new ReadOnlySequence <byte>(encryptedPayload));

            var op = ProducerActor <T> .OpSendMsg <T> .Create((List <Message <T> >) keyedBatch.Messages, cmd, keyedBatch.SequenceId);

            op.NumMessagesInBatch = numMessagesInBatch;
            op.BatchSizeByte      = currentBatchSizeBytes;
            return(op);
        }
        public override bool Add(Message <T> msg, Action <object, Exception> callback)
        {
            if (_log.IsDebugEnabled)
            {
                _log.Debug($"[{TopicName}] [{ProducerName}] add message to batch, num messages in batch so far is {NumMessagesInBatch}");
            }
            NumMessagesInBatch++;
            CurrentBatchSize += msg.Data.Length;
            var key = GetKey(msg);

            if (!_batches.TryGetValue(key, out var part))
            {
                part = new KeyedBatch();
                part.AddMsg(msg, callback);
                part.CompressionType = CompressionType;
                part.Compressor      = Compressor;
                part.MaxBatchSize    = MaxBatchSize;
                part.TopicName       = TopicName;
                part.ProducerName    = ProducerName;
                if (!_batches.ContainsKey(key))
                {
                    _batches.Add(key, part);
                }
                if (msg.Metadata.OriginalMetadata.ShouldSerializeTxnidMostBits() && CurrentTxnidMostBits == -1)
                {
                    CurrentTxnidMostBits = (long)msg.Metadata.OriginalMetadata.TxnidMostBits;
                }
                if (msg.Metadata.OriginalMetadata.ShouldSerializeTxnidLeastBits() && CurrentTxnidLeastBits == -1)
                {
                    CurrentTxnidLeastBits = (long)msg.Metadata.OriginalMetadata.TxnidLeastBits;
                }
            }
            else
            {
                part.AddMsg(msg, callback);
            }
            return(BatchFull);
        }