예제 #1
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>Enumerable representing stream of messages decoded from byte[].</returns>
        /// <remarks>The return type is an Enumerable as the message could be a compressed message set.</remarks>
        public static IEnumerable <Message> DecodeMessage(long offset, byte[] payload)
        {
            var crc    = payload.Take(4);
            var stream = new ReadByteStream(payload.Skip(4));

            if (crc.SequenceEqual(Crc32.ComputeHash(stream.Payload)) == false)
            {
                throw new FailCrcCheckException("Payload did not match CRC validation.");
            }

            var message = new Message
            {
                Meta = new MessageMetadata {
                    Offset = offset
                },
                MagicNumber = stream.ReadByte(),
                Attribute   = stream.ReadByte(),
                Key         = stream.ReadIntString()
            };

            var codec = (MessageCodec)(ProtocolConstants.AttributeCodeMask & message.Attribute);

            switch (codec)
            {
            case MessageCodec.CodecNone:
                message.Value = stream.ReadIntString();
                yield return(message);

                break;

            case MessageCodec.CodecGzip:
                var gZipData = stream.ReadIntPrefixedBytes();
                foreach (var m in DecodeMessageSet(Compression.Unzip(gZipData)))
                {
                    yield return(m);
                }
                break;

            default:
                throw new NotSupportedException(string.Format("Codec type of {0} is not supported.", codec));
            }
        }