private static Byte[] CreatePayload(Int64 offset, Byte magicByte, Byte attributes, Byte[] key, Byte[] payload)
        {
            var crcContentStream = new MemoryStream();
            var crcContentWriter = new BigEndianBinaryWriter(crcContentStream);

            crcContentWriter.Write(magicByte);
            crcContentWriter.Write(attributes);
            crcContentWriter.Write((Int32)key.Length);
            crcContentWriter.Write(key);
            crcContentWriter.Write(payload.Length);
            crcContentWriter.Write(payload);
            var crcContentBytes = crcContentStream.ToArray();

            var crc = Crc32Provider.Compute(crcContentBytes);

            var messageStream = new MemoryStream();
            var messageWriter = new BigEndianBinaryWriter(messageStream);

            messageWriter.Write(crc);
            messageWriter.Write(crcContentBytes);
            var messageBytes = messageStream.ToArray();

            var messageSetStream = new MemoryStream();
            var messageSetWriter = new BigEndianBinaryWriter(messageSetStream);
            var messageSize      = messageBytes.Length;

            messageSetWriter.Write(offset);
            messageSetWriter.Write(messageSize);
            messageSetWriter.Write(messageBytes);
            return(messageSetStream.ToArray());
        }
Esempio n. 2
0
        /// <summary>
        /// Decode messages from a payload and assign it a given kafka offset.
        /// </summary>
        /// <param name="offset">The offset represting the log entry from kafka of this message.</param>
        /// <param name="payload">The byte[] encode as a message from kafka.</param>
        /// <returns>The message</returns>
        /// <remarks>The return type is an Enumerable as the message could be a compressed message set.</remarks>
        internal static Message DecodeMessage(long offset, int partitionId, KafkaDecoder decoder, int messageSize)
        {
            var crc           = decoder.ReadUInt32();
            var calculatedCrc = Crc32Provider.Compute(decoder.Buffer, decoder.Offset, messageSize - 4);

            if (calculatedCrc != crc)
            {
                throw new FailCrcCheckException("Payload did not match CRC validation.");
            }

            var message = new Message
            {
                Meta        = new MessageMetadata(offset, partitionId),
                MagicNumber = decoder.ReadByte(),
                Attribute   = decoder.ReadByte(),
                Key         = decoder.ReadBytes(),
            };
            var codec = (MessageCodec)(ProtocolConstants.AttributeCodeMask & message.Attribute);

            switch (codec)
            {
            case MessageCodec.CodecNone:
                message.Value = decoder.ReadBytes();
                break;

            default:
                throw new NotSupportedException(string.Format("Codec type of {0} is not supported.", codec));
            }
            return(message);
        }
Esempio n. 3
0
        public KafkaEncoder CalculateCrc(int crcMarker)
        {
            var crc     = Crc32Provider.Compute(buffer, crcMarker, offset - crcMarker);
            var current = offset;

            offset = crcMarker - 4;
            Write(crc);
            offset = current;
            return(this);
        }
 private byte[] CreateKeyForPartition(int partitionId)
 {
     while (true)
     {
         var key = Guid.NewGuid().ToString().ToIntSizedBytes();
         if ((Crc32Provider.Compute(key) % 2) == partitionId)
         {
             return(key);
         }
     }
 }
Esempio n. 5
0
        public MetadataResponse.Partition Select(MetadataResponse.Topic topic, byte[] key)
        {
            if (topic == null)
            {
                throw new ArgumentNullException(nameof(topic));
            }
            if (topic.Partitions.Count <= 0)
            {
                throw new CachedMetadataException($"topic/{topic.TopicName} has no partitions.")
                      {
                          TopicName = topic.TopicName
                      }
            }
            ;

            long partitionId;
            var  partitions = topic.Partitions;

            if (key == null)
            {
                // use round robin
                var paritionIndex = _roundRobinTracker.AddOrUpdate(topic.TopicName, p => 0, (s, i) => (i + 1) % partitions.Count);
                return(partitions[paritionIndex]);
            }
            else
            {
                // use key hash
                partitionId = Crc32Provider.Compute(key) % partitions.Count;
                var partition = partitions.FirstOrDefault(x => x.PartitionId == partitionId);
                if (partition != null)
                {
                    return(partition);
                }
            }

            throw new CachedMetadataException($"Hash function return partition/{partitionId}, but the available partitions are {string.Join(",", partitions.Select(x => x.PartitionId))}")
                  {
                      TopicName = topic.TopicName,
                      Partition = (int)partitionId
                  };
        }
    }
Esempio n. 6
0
        public Partition Select(Topic topic, byte[] key)
        {
            if (topic == null)
            {
                throw new ArgumentNullException("topic");
            }
            if (topic.Partitions.Count <= 0)
            {
                throw new ApplicationException(string.Format("Topic ({0}) has no partitions.", topic.Name));
            }

            //use round robin
            var partitions = topic.Partitions;

            if (key == null)
            {
                //use round robin
                var paritionIndex = _roundRobinTracker.AddOrUpdate(topic.Name, p => 0, (s, i) =>
                {
                    return((i + 1) % partitions.Count);
                });

                return(partitions[paritionIndex]);
            }

            //use key hash
            var partitionId = Crc32Provider.Compute(key) % partitions.Count;
            var partition   = partitions.FirstOrDefault(x => x.PartitionId == partitionId);

            if (partition == null)
            {
                throw new InvalidPartitionException(string.Format("Hash function return partition id: {0}, but the available partitions are:{1}",
                                                                  partitionId, string.Join(",", partitions.Select(x => x.PartitionId))));
            }

            return(partition);
        }