public void Producer_DisableDeliveryReports(string bootstrapServers) { LogToFile("start Producer_DisableDeliveryReports"); byte[] TestKey = new byte[] { 1, 2, 3, 4 }; byte[] TestValue = new byte[] { 5, 6, 7, 8 }; var producerConfig = new ProducerConfig { BootstrapServers = bootstrapServers, EnableDeliveryReports = false, // the below are just a few extra tests that the property is recognized (all // set to defaults). the functionality is not tested. EnableBackgroundPoll = true, DeliveryReportFields = "all" }; // If delivery reports are disabled: // 1. delivery handlers may not be specified. // 2. tasks should complete immediately. using (var producer = new ProducerBuilder <byte[], byte[]>(producerConfig).Build()) { Assert.Throws <InvalidOperationException>(() => producer.BeginProduce( singlePartitionTopic, new Message <byte[], byte[]> { Key = TestKey, Value = TestValue }, (DeliveryReport <byte[], byte[]> dr) => Console.WriteLine("should not print"))); Assert.Throws <InvalidOperationException>(() => producer.BeginProduce( new TopicPartition(singlePartitionTopic, 0), new Message <byte[], byte[]> { Key = TestKey, Value = TestValue }, (DeliveryReport <byte[], byte[]> dr) => Console.WriteLine("should not print"))); producer.BeginProduce( new TopicPartition(singlePartitionTopic, 0), new Message <byte[], byte[]> { Key = TestKey, Value = TestValue }); producer.BeginProduce( singlePartitionTopic, new Message <byte[], byte[]> { Key = TestKey, Value = TestValue }); producer.BeginProduce( new TopicPartition(singlePartitionTopic, 0), new Message <byte[], byte[]> { Key = TestKey, Value = TestValue }); var drTask = producer.ProduceAsync( singlePartitionTopic, new Message <byte[], byte[]> { Key = TestKey, Value = TestValue }); Assert.True(drTask.IsCompleted); // should complete immediately. Assert.Equal(Offset.Unset, drTask.Result.Offset); Assert.Equal(Partition.Any, drTask.Result.Partition); Assert.Equal(singlePartitionTopic, drTask.Result.Topic); Assert.Equal(TestKey, drTask.Result.Message.Key); Assert.Equal(TestValue, drTask.Result.Message.Value); drTask = producer.ProduceAsync( new TopicPartition(singlePartitionTopic, 0), new Message <byte[], byte[]> { Key = TestKey, Value = TestValue }); Assert.True(drTask.IsCompleted); // should complete immediately. Assert.Equal(Offset.Unset, drTask.Result.Offset); Assert.Equal(0, (int)drTask.Result.Partition); Assert.Equal(singlePartitionTopic, drTask.Result.Topic); Assert.Equal(TestKey, drTask.Result.Message.Key); Assert.Equal(TestValue, drTask.Result.Message.Value); Assert.Equal(0, producer.Flush(TimeSpan.FromSeconds(10))); } Assert.Equal(0, Library.HandleCount); LogToFile("end Producer_DisableDeliveryReports"); }
public static void Producer_BeginProduce(string bootstrapServers, string singlePartitionTopic, string partitionedTopic) { LogToFile("start Producer_BeginProduce"); var producerConfig = new ProducerConfig { BootstrapServers = bootstrapServers, EnableIdempotence = true }; // serializer case. int count = 0; Action <DeliveryReport <string, string> > dh = (DeliveryReport <string, string> dr) => { Assert.Equal(ErrorCode.NoError, dr.Error.Code); Assert.Equal((Partition)0, dr.Partition); Assert.Equal(singlePartitionTopic, dr.Topic); Assert.True(dr.Offset >= 0); Assert.Equal($"test key {count}", dr.Message.Key); Assert.Equal($"test val {count}", dr.Message.Value); Assert.Equal(TimestampType.CreateTime, dr.Message.Timestamp.Type); Assert.True(Math.Abs((DateTime.UtcNow - dr.Message.Timestamp.UtcDateTime).TotalMinutes) < 1.0); count += 1; }; using (var producer = new ProducerBuilder <string, string>(producerConfig).Build()) { producer.BeginProduce( new TopicPartition(singlePartitionTopic, 0), new Message <string, string> { Key = "test key 0", Value = "test val 0" }, dh); producer.BeginProduce( singlePartitionTopic, new Message <string, string> { Key = "test key 1", Value = "test val 1" }, dh); producer.Flush(TimeSpan.FromSeconds(10)); } Assert.Equal(2, count); // byte[] case. count = 0; Action <DeliveryReport <byte[], byte[]> > dh2 = (DeliveryReport <byte[], byte[]> dr) => { Assert.Equal(ErrorCode.NoError, dr.Error.Code); Assert.Equal((Partition)0, dr.Partition); Assert.Equal(singlePartitionTopic, dr.Topic); Assert.True(dr.Offset >= 0); Assert.Equal($"test key {count + 42}", Encoding.UTF8.GetString(dr.Message.Key)); Assert.Equal($"test val {count + 42}", Encoding.UTF8.GetString(dr.Message.Value)); Assert.Equal(TimestampType.CreateTime, dr.Message.Timestamp.Type); Assert.True(Math.Abs((DateTime.UtcNow - dr.Message.Timestamp.UtcDateTime).TotalMinutes) < 1.0); count += 1; }; using (var producer = new ProducerBuilder <byte[], byte[]>(producerConfig).Build()) { producer.BeginProduce( new TopicPartition(singlePartitionTopic, 0), new Message <byte[], byte[]> { Key = Encoding.UTF8.GetBytes("test key 42"), Value = Encoding.UTF8.GetBytes("test val 42") }, dh2); producer.BeginProduce( singlePartitionTopic, new Message <byte[], byte[]> { Key = Encoding.UTF8.GetBytes("test key 43"), Value = Encoding.UTF8.GetBytes("test val 43") }, dh2); producer.Flush(TimeSpan.FromSeconds(10)); } Assert.Equal(2, count); Assert.Equal(0, Library.HandleCount); LogToFile("end Producer_BeginProduce"); }
public void Producer_BeginProduce_Null(string bootstrapServers) { LogToFile("start Producer_BeginProduce_Null"); var producerConfig = new ProducerConfig { BootstrapServers = bootstrapServers }; // serializer case. int count = 0; Action <DeliveryReport <Null, Null> > dh = (DeliveryReport <Null, Null> dr) => { Assert.Equal(ErrorCode.NoError, dr.Error.Code); Assert.Equal(PersistenceStatus.Persisted, dr.Status); Assert.False(dr.Error.IsFatal); Assert.Equal((Partition)0, dr.Partition); Assert.Equal(singlePartitionTopic, dr.Topic); Assert.True(dr.Offset >= 0); Assert.Null(dr.Message.Key); Assert.Null(dr.Message.Value); Assert.Equal(TimestampType.CreateTime, dr.Message.Timestamp.Type); Assert.True(Math.Abs((DateTime.UtcNow - dr.Message.Timestamp.UtcDateTime).TotalMinutes) < 1.0); count += 1; }; using (var producer = new ProducerBuilder <Null, Null>(producerConfig).Build()) { producer.BeginProduce(new TopicPartition(singlePartitionTopic, 0), new Message <Null, Null> { }, dh); producer.BeginProduce(singlePartitionTopic, new Message <Null, Null> { }, dh); producer.Flush(TimeSpan.FromSeconds(10)); } Assert.Equal(2, count); // byte[] case. count = 0; Action <DeliveryReport <byte[], byte[]> > dh2 = (DeliveryReport <byte[], byte[]> dr) => { Assert.Equal(ErrorCode.NoError, dr.Error.Code); Assert.Equal((Partition)0, dr.Partition); Assert.Equal(singlePartitionTopic, dr.Topic); Assert.True(dr.Offset >= 0); Assert.Null(dr.Message.Key); Assert.Null(dr.Message.Value); Assert.Equal(TimestampType.CreateTime, dr.Message.Timestamp.Type); Assert.True(Math.Abs((DateTime.UtcNow - dr.Message.Timestamp.UtcDateTime).TotalMinutes) < 1.0); count += 1; }; using (var producer = new ProducerBuilder <byte[], byte[]>(producerConfig).Build()) { producer.BeginProduce(new TopicPartition(singlePartitionTopic, 0), new Message <byte[], byte[]> { }, dh2); producer.BeginProduce(singlePartitionTopic, new Message <byte[], byte[]> { }, dh2); producer.Flush(TimeSpan.FromSeconds(10)); } Assert.Equal(2, count); Assert.Equal(0, Library.HandleCount); LogToFile("end Producer_BeginProduce_Null"); }
public static void Timestamps(string bootstrapServers, string singlePartitionTopic, string partitionedTopic) { LogToFile("start Timestamps"); var producerConfig = new ProducerConfig { BootstrapServers = bootstrapServers }; var consumerConfig = new ConsumerConfig { GroupId = Guid.NewGuid().ToString(), BootstrapServers = bootstrapServers, SessionTimeoutMs = 6000 }; var drs_beginProduce = new List <DeliveryReport <Null, string> >(); var drs_task = new List <DeliveryResult <Null, string> >(); using (var producer = new ProducerBuilder <Null, string>(producerConfig).Build()) { // --- ProduceAsync, serializer case. drs_task.Add(producer.ProduceAsync( singlePartitionTopic, new Message <Null, string> { Value = "testvalue" }).Result); // TimestampType: CreateTime drs_task.Add(producer.ProduceAsync( new TopicPartition(singlePartitionTopic, 0), new Message <Null, string> { Value = "test-value", Timestamp = new Timestamp(new DateTime(2008, 11, 12, 0, 0, 0, DateTimeKind.Utc)) }).Result); // TimestampType: CreateTime (default) drs_task.Add(producer.ProduceAsync( new TopicPartition(singlePartitionTopic, 0), new Message <Null, string> { Value = "test-value" }).Result); // TimestampType: LogAppendTime Assert.Throws <ArgumentException>(() => producer.ProduceAsync( new TopicPartition(singlePartitionTopic, 0), new Message <Null, string> { Value = "test-value", Timestamp = new Timestamp(DateTime.Now, TimestampType.LogAppendTime) }).Result); // TimestampType: NotAvailable Assert.Throws <ArgumentException>(() => producer.ProduceAsync( new TopicPartition(singlePartitionTopic, 0), new Message <Null, string> { Value = "test-value", Timestamp = new Timestamp(10, TimestampType.NotAvailable) }).Result); Action <DeliveryReport <Null, string> > dh = (DeliveryReport <Null, string> dr) => drs_beginProduce.Add(dr); // --- begin produce, serializer case. producer.BeginProduce( singlePartitionTopic, new Message <Null, string> { Value = "testvalue" }, dh); // TimestampType: CreateTime producer.BeginProduce( new TopicPartition(singlePartitionTopic, 0), new Message <Null, string> { Value = "test-value", Timestamp = new Timestamp(new DateTime(2008, 11, 12, 0, 0, 0, DateTimeKind.Utc)) }, dh); // TimestampType: CreateTime (default) producer.BeginProduce( new TopicPartition(singlePartitionTopic, 0), new Message <Null, string> { Value = "test-value" }, dh); // TimestampType: LogAppendTime Assert.Throws <ArgumentException>(() => producer.BeginProduce( new TopicPartition(singlePartitionTopic, 0), new Message <Null, string> { Value = "test-value", Timestamp = new Timestamp(DateTime.Now, TimestampType.LogAppendTime) }, dh)); // TimestampType: NotAvailable Assert.Throws <ArgumentException>(() => producer.BeginProduce( new TopicPartition(singlePartitionTopic, 0), new Message <Null, string> { Value = "test-value", Timestamp = new Timestamp(10, TimestampType.NotAvailable) }, dh)); Assert.Equal(0, producer.Flush(TimeSpan.FromSeconds(10))); } var drs2_beginProduce = new List <DeliveryReport <byte[], byte[]> >(); var drs2_task = new List <DeliveryResult <byte[], byte[]> >(); using (var producer = new ProducerBuilder <byte[], byte[]>(producerConfig).Build()) { // --- ProduceAsync, byte[] case. drs2_task.Add(producer.ProduceAsync( singlePartitionTopic, new Message <byte[], byte[]> { Timestamp = Timestamp.Default }).Result); // TimestampType: CreateTime drs2_task.Add(producer.ProduceAsync( singlePartitionTopic, new Message <byte[], byte[]> { Timestamp = new Timestamp(new DateTime(2008, 11, 12, 0, 0, 0, DateTimeKind.Utc)) }).Result); // TimestampType: CreateTime (default) drs2_task.Add(producer.ProduceAsync( singlePartitionTopic, new Message <byte[], byte[]> { Timestamp = Timestamp.Default }).Result); // TimestampType: LogAppendTime Assert.Throws <ArgumentException>(() => producer.ProduceAsync( singlePartitionTopic, new Message <byte[], byte[]> { Timestamp = new Timestamp(DateTime.Now, TimestampType.LogAppendTime) }).Result); // TimestampType: NotAvailable Assert.Throws <ArgumentException>(() => producer.ProduceAsync( singlePartitionTopic, new Message <byte[], byte[]> { Timestamp = new Timestamp(10, TimestampType.NotAvailable) }).Result); // --- begin produce, byte[] case. Action <DeliveryReport <byte[], byte[]> > dh = (DeliveryReport <byte[], byte[]> dr) => drs2_beginProduce.Add(dr); producer.BeginProduce( singlePartitionTopic, new Message <byte[], byte[]> { Timestamp = Timestamp.Default }, dh); // TimestampType: CreateTime producer.BeginProduce( singlePartitionTopic, new Message <byte[], byte[]> { Timestamp = new Timestamp(new DateTime(2008, 11, 12, 0, 0, 0, DateTimeKind.Utc)) }, dh); // TimestampType: CreateTime (default) producer.BeginProduce( singlePartitionTopic, new Message <byte[], byte[]> { Timestamp = Timestamp.Default }, dh); // TimestampType: LogAppendTime Assert.Throws <ArgumentException>(() => producer.BeginProduce( singlePartitionTopic, new Message <byte[], byte[]> { Timestamp = new Timestamp(DateTime.Now, TimestampType.LogAppendTime) }, dh)); // TimestampType: NotAvailable Assert.Throws <ArgumentException>(() => producer.BeginProduce(singlePartitionTopic, new Message <byte[], byte[]> { Timestamp = new Timestamp(10, TimestampType.NotAvailable) }, dh)); Assert.Equal(0, producer.Flush(TimeSpan.FromSeconds(10))); } using (var consumer = new ConsumerBuilder <Null, string>(consumerConfig).Build()) { // serializing async assertCloseToNow(consumer, drs_task[0].TopicPartitionOffset); consumer.Assign(new List <TopicPartitionOffset>() { drs_task[1].TopicPartitionOffset }); var record = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record.Message); Assert.Equal(TimestampType.CreateTime, record.Message.Timestamp.Type); Assert.Equal(record.Message.Timestamp, new Timestamp(new DateTime(2008, 11, 12, 0, 0, 0, DateTimeKind.Utc))); assertCloseToNow(consumer, drs_task[2].TopicPartitionOffset); // serializing deliveryhandler assertCloseToNow(consumer, drs_beginProduce[0].TopicPartitionOffset); consumer.Assign(new List <TopicPartitionOffset>() { drs_beginProduce[1].TopicPartitionOffset }); record = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record.Message); Assert.Equal(TimestampType.CreateTime, record.Message.Timestamp.Type); Assert.Equal(record.Message.Timestamp, new Timestamp(new DateTime(2008, 11, 12, 0, 0, 0, DateTimeKind.Utc))); assertCloseToNow(consumer, drs_beginProduce[2].TopicPartitionOffset); } using (var consumer = new ConsumerBuilder <byte[], byte[]>(consumerConfig).Build()) { ConsumeResult <byte[], byte[]> record; // non-serializing async assertCloseToNow_byte(consumer, drs2_task[0].TopicPartitionOffset); consumer.Assign(new List <TopicPartitionOffset>() { drs2_task[1].TopicPartitionOffset }); record = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record.Message); Assert.Equal(TimestampType.CreateTime, record.Message.Timestamp.Type); Assert.Equal(record.Message.Timestamp, new Timestamp(new DateTime(2008, 11, 12, 0, 0, 0, DateTimeKind.Utc))); assertCloseToNow_byte(consumer, drs2_task[2].TopicPartitionOffset); // non-serializing deliveryhandler assertCloseToNow_byte(consumer, drs2_beginProduce[0].TopicPartitionOffset); consumer.Assign(new List <TopicPartitionOffset>() { drs2_beginProduce[1].TopicPartitionOffset }); record = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record.Message); Assert.Equal(TimestampType.CreateTime, record.Message.Timestamp.Type); Assert.Equal(record.Message.Timestamp, new Timestamp(new DateTime(2008, 11, 12, 0, 0, 0, DateTimeKind.Utc))); assertCloseToNow_byte(consumer, drs2_beginProduce[2].TopicPartitionOffset); } Assert.Equal(0, Library.HandleCount); LogToFile("end Timestamps"); }
public static void MessageHeaderProduceConsume(string bootstrapServers, string singlePartitionTopic, string partitionedTopic) { LogToFile("start MessageHeaderProduceConsume"); var producerConfig = new ProducerConfig { BootstrapServers = bootstrapServers, EnableIdempotence = true }; var consumerConfig = new ConsumerConfig { GroupId = Guid.NewGuid().ToString(), BootstrapServers = bootstrapServers, SessionTimeoutMs = 6000 }; var drs = new List <DeliveryReport <Null, string> >(); DeliveryResult <Null, string> dr_single, dr_empty, dr_null, dr_multiple, dr_duplicate; DeliveryResult <Null, string> dr_ol1, dr_ol3; using (var producer = new ProducerBuilder <Null, string>(producerConfig).Build()) { // single header value. var headers = new Headers(); headers.Add("test-header", new byte[] { 142 }); dr_single = producer.ProduceAsync( singlePartitionTopic, new Message <Null, string> { Value = "the value", Headers = headers }).Result; Assert.Single(dr_single.Message.Headers); Assert.Equal("test-header", dr_single.Message.Headers[0].Key); Assert.Equal(new byte[] { 142 }, dr_single.Message.Headers[0].Value); // empty header values var headers0 = new Headers(); dr_empty = producer.ProduceAsync( singlePartitionTopic, new Message <Null, string> { Value = "the value", Headers = headers0 }).Result; Assert.Empty(dr_empty.Message.Headers); // null header value dr_null = producer.ProduceAsync( singlePartitionTopic, new Message <Null, string> { Value = "the value" }).Result; Assert.Empty(dr_null.Message.Headers); // multiple header values (also Headers no Dictionary, since order is tested). var headers2 = new Headers(); headers2.Add("test-header-a", new byte[] { 111 }); headers2.Add("test-header-b", new byte[] { 112 }); dr_multiple = producer.ProduceAsync( singlePartitionTopic, new Message <Null, string> { Value = "the value", Headers = headers2 }).Result; Assert.Equal(2, dr_multiple.Message.Headers.Count); Assert.Equal("test-header-a", dr_multiple.Message.Headers[0].Key); Assert.Equal(new byte[] { 111 }, dr_multiple.Message.Headers[0].Value); Assert.Equal("test-header-b", dr_multiple.Message.Headers[1].Key); Assert.Equal(new byte[] { 112 }, dr_multiple.Message.Headers[1].Value); // duplicate header values (also List not Dictionary) var headers3 = new Headers(); headers3.Add(new Header("test-header-a", new byte[] { 111 })); headers3.Add(new Header("test-header-b", new byte[] { 112 })); headers3.Add(new Header("test-header-a", new byte[] { 113 })); headers3.Add(new Header("test-header-b", new byte[] { 114 })); headers3.Add(new Header("test-header-c", new byte[] { 115 })); dr_duplicate = producer.ProduceAsync(singlePartitionTopic, new Message <Null, string> { Value = "the value", Headers = headers3 }).Result; Assert.Equal(5, dr_duplicate.Message.Headers.Count); Assert.Equal("test-header-a", dr_duplicate.Message.Headers[0].Key); Assert.Equal(new byte[] { 111 }, dr_duplicate.Message.Headers[0].Value); Assert.Equal("test-header-a", dr_duplicate.Message.Headers[2].Key); Assert.Equal(new byte[] { 113 }, dr_duplicate.Message.Headers[2].Value); // Test headers work as expected with all serializing ProduceAsync variants. dr_ol1 = producer.ProduceAsync(singlePartitionTopic, new Message <Null, string> { Value = "the value" }).Result; Assert.Empty(dr_ol1.Message.Headers); dr_ol3 = producer.ProduceAsync( new TopicPartition(singlePartitionTopic, 0), new Message <Null, string> { Value = "the value", Headers = headers } ).Result; Assert.Single(dr_ol3.Message.Headers); Assert.Equal("test-header", dr_ol3.Message.Headers[0].Key); Assert.Equal(new byte[] { 142 }, dr_ol3.Message.Headers[0].Value); Action <DeliveryReport <Null, string> > dh = (DeliveryReport <Null, string> dr) => drs.Add(dr); // Test headers work as expected with all serializing Produce variants. producer.BeginProduce(singlePartitionTopic, new Message <Null, string> { Value = "the value" }, dh); producer.BeginProduce( new TopicPartition(singlePartitionTopic, 0), new Message <Null, string> { Value = "the value", Headers = headers2 }, dh); producer.Flush(TimeSpan.FromSeconds(10)); Assert.Empty(drs[0].Message.Headers); // TODO: this is intermittently not working. Assert.Equal(2, drs[1].Message.Headers.Count); } List <DeliveryReport <byte[], byte[]> > drs_2 = new List <DeliveryReport <byte[], byte[]> >(); DeliveryResult <byte[], byte[]> dr_ol4, dr_ol5, dr_ol6, dr_ol7; using (var producer = new ProducerBuilder <byte[], byte[]>(producerConfig).Build()) { var headers = new Headers(); headers.Add("hkey", new byte[] { 44 }); // Test headers work as expected with all non-serializing ProduceAsync variants. dr_ol4 = producer.ProduceAsync(singlePartitionTopic, new Message <byte[], byte[]> { Headers = null }).Result; Assert.Empty(dr_ol4.Message.Headers); dr_ol5 = producer.ProduceAsync(singlePartitionTopic, new Message <byte[], byte[]> { Headers = null }).Result; Assert.Empty(dr_ol5.Message.Headers); dr_ol6 = producer.ProduceAsync(singlePartitionTopic, new Message <byte[], byte[]> { Headers = headers }).Result; Assert.Single(dr_ol6.Message.Headers); dr_ol7 = producer.ProduceAsync(singlePartitionTopic, new Message <byte[], byte[]> { Headers = headers }).Result; Assert.Single(dr_ol7.Message.Headers); // Test headers work as expected with all non-serializing BeginProduce variants. Action <DeliveryReport <byte[], byte[]> > dh = (DeliveryReport <byte[], byte[]> dr) => drs_2.Add(dr); producer.BeginProduce(singlePartitionTopic, new Message <byte[], byte[]> { Headers = headers }, dh); producer.BeginProduce(singlePartitionTopic, new Message <byte[], byte[]> { Headers = null }, dh); producer.BeginProduce(singlePartitionTopic, new Message <byte[], byte[]> { Headers = headers }, dh); producer.BeginProduce(singlePartitionTopic, new Message <byte[], byte[]> { Headers = headers }, dh); producer.Flush(TimeSpan.FromSeconds(10)); Assert.Single(drs_2[0].Message.Headers); Assert.Empty(drs_2[1].Message.Headers); // TODO: this is intermittently not working. Assert.Single(drs_2[2].Message.Headers); Assert.Single(drs_2[3].Message.Headers); } using (var consumer = new ConsumerBuilder <byte[], byte[]>(consumerConfig).Build()) { consumer.Assign(new List <TopicPartitionOffset>() { dr_single.TopicPartitionOffset }); var record = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record.Message); Assert.Single(record.Message.Headers); Assert.Equal("test-header", record.Message.Headers[0].Key); Assert.Equal(new byte[] { 142 }, record.Message.Headers[0].Value); consumer.Assign(new List <TopicPartitionOffset>() { dr_empty.TopicPartitionOffset }); var record2 = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record2.Message); // following Java, alway instantiate a new Headers instance, even in the empty case. Assert.NotNull(record2.Message.Headers); Assert.Empty(record2.Message.Headers); consumer.Assign(new List <TopicPartitionOffset>() { dr_null.TopicPartitionOffset }); var record3 = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record3.Message); Assert.NotNull(record3.Message.Headers); Assert.Empty(record3.Message.Headers); consumer.Assign(new List <TopicPartitionOffset>() { dr_multiple.TopicPartitionOffset }); var record4 = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record4.Message); Assert.Equal(2, record4.Message.Headers.Count); Assert.Equal("test-header-a", record4.Message.Headers[0].Key); Assert.Equal("test-header-b", record4.Message.Headers[1].Key); Assert.Equal(new byte[] { 111 }, record4.Message.Headers[0].Value); Assert.Equal(new byte[] { 112 }, record4.Message.Headers[1].Value); consumer.Assign(new List <TopicPartitionOffset>() { dr_duplicate.TopicPartitionOffset }); var record5 = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record5.Message); Assert.Equal(5, record5.Message.Headers.Count); Assert.Equal("test-header-a", record5.Message.Headers[0].Key); Assert.Equal("test-header-b", record5.Message.Headers[1].Key); Assert.Equal("test-header-a", record5.Message.Headers[2].Key); Assert.Equal("test-header-b", record5.Message.Headers[3].Key); Assert.Equal("test-header-c", record5.Message.Headers[4].Key); Assert.Equal(new byte[] { 111 }, record5.Message.Headers[0].Value); Assert.Equal(new byte[] { 112 }, record5.Message.Headers[1].Value); Assert.Equal(new byte[] { 113 }, record5.Message.Headers[2].Value); Assert.Equal(new byte[] { 114 }, record5.Message.Headers[3].Value); Assert.Equal(new byte[] { 115 }, record5.Message.Headers[4].Value); Assert.Equal(new byte[] { 113 }, record5.Message.Headers.GetLast("test-header-a")); Assert.Equal(new byte[] { 114 }, record5.Message.Headers.GetLast("test-header-b")); Assert.Equal(new byte[] { 115 }, record5.Message.Headers.GetLast("test-header-c")); // Test headers work with all produce method variants. // async, serializing consumer.Assign(new List <TopicPartitionOffset>() { dr_ol1.TopicPartitionOffset }); var record6 = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record6.Message); Assert.Empty(record6.Message.Headers); consumer.Assign(new List <TopicPartitionOffset>() { dr_ol3.TopicPartitionOffset }); var record8 = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record8.Message); Assert.Single(record8.Message.Headers); // delivery-handler, serializing. consumer.Assign(new List <TopicPartitionOffset>() { drs[0].TopicPartitionOffset }); var record9 = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record9.Message); Assert.Empty(record9.Message.Headers); consumer.Assign(new List <TopicPartitionOffset>() { drs[1].TopicPartitionOffset }); var record11 = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record11.Message); Assert.Equal(2, record11.Message.Headers.Count); // async, non-serializing consumer.Assign(new List <TopicPartitionOffset>() { dr_ol4.TopicPartitionOffset }); var record12 = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record12.Message); Assert.Empty(record12.Message.Headers); consumer.Assign(new List <TopicPartitionOffset>() { dr_ol5.TopicPartitionOffset }); var record13 = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record13.Message); Assert.Empty(record13.Message.Headers); consumer.Assign(new List <TopicPartitionOffset>() { dr_ol6.TopicPartitionOffset }); var record14 = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record14.Message); Assert.Single(record14.Message.Headers); consumer.Assign(new List <TopicPartitionOffset>() { dr_ol7.TopicPartitionOffset }); var record15 = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record15.Message); Assert.Single(record15.Message.Headers); // delivery handler, non-serializing consumer.Assign(new List <TopicPartitionOffset>() { drs_2[0].TopicPartitionOffset }); var record16 = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record16.Message); Assert.Single(record16.Message.Headers); consumer.Assign(new List <TopicPartitionOffset>() { drs_2[1].TopicPartitionOffset }); var record17 = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record17.Message); Assert.Empty(record17.Message.Headers); consumer.Assign(new List <TopicPartitionOffset>() { drs_2[2].TopicPartitionOffset }); var record18 = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record18.Message); Assert.Single(record18.Message.Headers); consumer.Assign(new List <TopicPartitionOffset>() { drs_2[3].TopicPartitionOffset }); var record19 = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(record19.Message); Assert.Single(record19.Message.Headers); } // null key using (var producer = new ProducerBuilder <byte[], byte[]>(producerConfig).Build()) { var headers = new Headers(); var threw = false; try { headers.Add(null, new byte[] { 142 }); } catch { threw = true; } finally { Assert.True(threw); } var headers2 = new List <Header>(); Assert.Throws <ArgumentNullException>(() => headers2.Add(new Header(null, new byte[] { 42 }))); } // null value DeliveryResult <Null, string> nulldr; using (var producer = new ProducerBuilder <Null, string>(producerConfig).Build()) { var headers = new Headers(); headers.Add("my-header", null); nulldr = producer.ProduceAsync(singlePartitionTopic, new Message <Null, string> { Value = "test-value", Headers = headers }).Result; Assert.Single(nulldr.Headers); Assert.Null(nulldr.Headers[0].Value); } using (var consumer = new ConsumerBuilder <byte[], byte[]>(consumerConfig).Build()) { consumer.Assign(new TopicPartitionOffset(singlePartitionTopic, 0, nulldr.Offset)); var cr = consumer.Consume(TimeSpan.FromSeconds(10)); Assert.NotNull(cr?.Message); Assert.Single(cr.Headers); Assert.Equal("my-header", cr.Message.Headers[0].Key); Assert.Null(cr.Message.Headers[0].Value); } Assert.Equal(0, Library.HandleCount); LogToFile("end MessageHeaderProduceConsume"); }
public void Producer_BeginProduce_Error(string bootstrapServers) { LogToFile("start Producer_BeginProduce_Error"); var producerConfig = new ProducerConfig { BootstrapServers = bootstrapServers }; // serializer case. int count = 0; Action <DeliveryReport <Null, String> > dh = (DeliveryReport <Null, String> dr) => { Assert.Equal(ErrorCode.Local_UnknownPartition, dr.Error.Code); Assert.False(dr.Error.IsFatal); Assert.Equal((Partition)1, dr.Partition); Assert.Equal(singlePartitionTopic, dr.Topic); Assert.Equal(Offset.Invalid, dr.Offset); Assert.Null(dr.Message.Key); Assert.Equal("test", dr.Message.Value); Assert.Equal(PersistenceStatus.NotPersisted, dr.Status); Assert.Equal(TimestampType.NotAvailable, dr.Message.Timestamp.Type); count += 1; }; using (var producer = new ProducerBuilder <Null, String>(producerConfig) .SetKeySerializer(Serializers.Null) .SetValueSerializer(Serializers.Utf8) .Build()) { producer.BeginProduce(new TopicPartition(singlePartitionTopic, 1), new Message <Null, String> { Value = "test" }, dh); producer.Flush(TimeSpan.FromSeconds(10)); } Assert.Equal(1, count); // byte[] case. count = 0; Action <DeliveryReport <byte[], byte[]> > dh2 = (DeliveryReport <byte[], byte[]> dr) => { Assert.Equal(ErrorCode.Local_UnknownPartition, dr.Error.Code); Assert.Equal((Partition)42, dr.Partition); Assert.Equal(singlePartitionTopic, dr.Topic); Assert.Equal(Offset.Invalid, dr.Offset); Assert.Equal(new byte[] { 11 }, dr.Message.Key); Assert.Null(dr.Message.Value); Assert.Equal(TimestampType.NotAvailable, dr.Message.Timestamp.Type); count += 1; }; using (var producer = new ProducerBuilder <byte[], byte[]>(producerConfig).Build()) { producer.BeginProduce(new TopicPartition(singlePartitionTopic, 42), new Message <byte[], byte[]> { Key = new byte[] { 11 } }, dh2); producer.Flush(TimeSpan.FromSeconds(10)); } Assert.Equal(1, count); Assert.Equal(0, Library.HandleCount); LogToFile("end Producer_BeginProduce_Error"); }