public async Task CanSerializeAndDeserializeWithCompatibleSchema() { var client = CreateClient(); var groupName = TestEnvironment.SchemaRegistryGroup; var employee = new Employee_V2 { Age = 42, Name = "Caketown", City = "Redmond" }; var encoder = new SchemaRegistryAvroEncoder(client, groupName, new SchemaRegistryAvroObjectEncoderOptions() { AutoRegisterSchemas = true }); var messageData = await encoder.EncodeMessageDataAsync <MessageWithMetadata>(employee, typeof(Employee_V2)); // deserialize using the old schema, which is forward compatible with the new schema // if you swap the old schema and the new schema in your mind, then this can also be thought as a backwards compatible test var deserializedObject = await encoder.DecodeMessageDataAsync <Employee>(messageData); var readEmployee = deserializedObject as Employee; Assert.IsNotNull(readEmployee); Assert.AreEqual("Caketown", readEmployee.Name); Assert.AreEqual(42, readEmployee.Age); // deserialize using the new schema to make sure we are respecting it var readEmployeeV2 = await encoder.DecodeMessageDataAsync <Employee_V2>(messageData); Assert.IsNotNull(readEmployee); Assert.AreEqual("Caketown", readEmployeeV2.Name); Assert.AreEqual(42, readEmployeeV2.Age); Assert.AreEqual("Redmond", readEmployeeV2.City); }
public async Task CanUseEncoderWithServiceBusMessageUsingFunc() { var client = CreateClient(); var groupName = TestEnvironment.SchemaRegistryGroup; var encoder = new SchemaRegistryAvroEncoder(client, groupName, new SchemaRegistryAvroObjectEncoderOptions { AutoRegisterSchemas = true }); var employee = new Employee { Age = 42, Name = "Caketown" }; ServiceBusMessage message = await encoder.EncodeMessageDataAsync(employee, messageFactory : bd => new ServiceBusMessage(bd)); string[] contentType = message.ContentType.Split('+'); Assert.AreEqual(2, contentType.Length); Assert.AreEqual("avro/binary", contentType[0]); Assert.IsNotEmpty(contentType[1]); ServiceBusReceivedMessage receivedMessage = ServiceBusModelFactory.ServiceBusReceivedMessage(body: message.Body, contentType: message.ContentType); Employee deserialized = await encoder.DecodeMessageDataAsync <Employee>(receivedMessage); // decoding should not alter the message contentType = message.ContentType.Split('+'); Assert.AreEqual(2, contentType.Length); Assert.AreEqual("avro/binary", contentType[0]); Assert.IsNotEmpty(contentType[1]); // verify the payload was decoded correctly Assert.IsNotNull(deserialized); Assert.AreEqual("Caketown", deserialized.Name); Assert.AreEqual(42, deserialized.Age); }
public async Task CanUseEncoderWithEventData() { var client = CreateClient(); var groupName = TestEnvironment.SchemaRegistryGroup; #region Snippet:SchemaRegistryAvroEncodeEventData var encoder = new SchemaRegistryAvroEncoder(client, groupName, new SchemaRegistryAvroObjectEncoderOptions { AutoRegisterSchemas = true }); var employee = new Employee { Age = 42, Name = "Caketown" }; EventData eventData = await encoder.EncodeMessageDataAsync <EventData>(employee); #if SNIPPET // the schema Id will be included as a parameter of the content type Console.WriteLine(eventData.ContentType); // the serialized Avro data will be stored in the EventBody Console.WriteLine(eventData.EventBody); #endif #endregion Assert.IsFalse(((MessageWithMetadata)eventData).IsReadOnly); string[] contentType = eventData.ContentType.Split('+'); Assert.AreEqual(2, contentType.Length); Assert.AreEqual("avro/binary", contentType[0]); Assert.IsNotEmpty(contentType[1]); #region Snippet:SchemaRegistryAvroDecodeEventData Employee deserialized = await encoder.DecodeMessageDataAsync <Employee>(eventData); #if SNIPPET Console.WriteLine(deserialized.Age); Console.WriteLine(deserialized.Name); #endif #endregion // decoding should not alter the message contentType = eventData.ContentType.Split('+'); Assert.AreEqual(2, contentType.Length); Assert.AreEqual("avro/binary", contentType[0]); Assert.IsNotEmpty(contentType[1]); // verify the payload was decoded correctly Assert.IsNotNull(deserialized); Assert.AreEqual("Caketown", deserialized.Name); Assert.AreEqual(42, deserialized.Age); }
public async Task CannotDeserializeWithNullSchemaId() { var client = CreateClient(); var groupName = TestEnvironment.SchemaRegistryGroup; var encoder = new SchemaRegistryAvroEncoder(client, groupName, new SchemaRegistryAvroObjectEncoderOptions { AutoRegisterSchemas = true }); var messageData = new MessageWithMetadata { Data = new BinaryData(Array.Empty <byte>()), ContentType = null }; Assert.ThrowsAsync <ArgumentNullException>(async() => await encoder.DecodeMessageDataAsync <TimeZoneInfo>(messageData)); await Task.CompletedTask; }
public async Task CannotDeserializeIntoNonCompatibleType() { var client = CreateClient(); var groupName = TestEnvironment.SchemaRegistryGroup; var employee = new Employee() { Age = 42, Name = "Caketown" }; var encoder = new SchemaRegistryAvroEncoder(client, groupName, new SchemaRegistryAvroObjectEncoderOptions() { AutoRegisterSchemas = true }); var messageData = await encoder.EncodeMessageDataAsync <MessageWithMetadata>(employee, typeof(Employee)); // deserialize with the new schema, which is NOT backward compatible with the old schema as it adds a new field Assert.That( async() => await encoder.DecodeMessageDataAsync <Employee_V2>(messageData), Throws.InstanceOf <AvroException>()); }
public async Task CanSerializeAndDeserializeGenericRecord() { var client = CreateClient(); var groupName = TestEnvironment.SchemaRegistryGroup; var record = new GenericRecord((RecordSchema)Employee._SCHEMA); record.Add("Name", "Caketown"); record.Add("Age", 42); var encoder = new SchemaRegistryAvroEncoder(client, groupName, new SchemaRegistryAvroObjectEncoderOptions { AutoRegisterSchemas = true }); var messageData = await encoder.EncodeMessageDataAsync <MessageWithMetadata>(record, typeof(GenericRecord)); var deserializedObject = await encoder.DecodeMessageDataAsync <GenericRecord>(messageData); var readRecord = deserializedObject as GenericRecord; Assert.IsNotNull(readRecord); Assert.AreEqual("Caketown", readRecord.GetValue(0)); Assert.AreEqual(42, readRecord.GetValue(1)); }
public async Task CanSerializeAndDeserialize() { var client = CreateClient(); var groupName = TestEnvironment.SchemaRegistryGroup; var employee = new Employee { Age = 42, Name = "Caketown" }; #region Snippet:SchemaRegistryAvroEncodeDecodeMessageWithMetadata var encoder = new SchemaRegistryAvroEncoder(client, groupName, new SchemaRegistryAvroObjectEncoderOptions() { AutoRegisterSchemas = true }); MessageWithMetadata messageData = await encoder.EncodeMessageDataAsync <MessageWithMetadata>(employee, typeof(Employee)); Employee decodedEmployee = await encoder.DecodeMessageDataAsync <Employee>(messageData); #endregion Assert.IsNotNull(decodedEmployee); Assert.AreEqual("Caketown", decodedEmployee.Name); Assert.AreEqual(42, decodedEmployee.Age); }
public async Task CanDecodePreamble() { var client = CreateClient(); var groupName = TestEnvironment.SchemaRegistryGroup; var encoder = new SchemaRegistryAvroEncoder(client, groupName, new SchemaRegistryAvroObjectEncoderOptions { AutoRegisterSchemas = true }); var employee = new Employee { Age = 42, Name = "Caketown" }; EventData eventData = await encoder.EncodeMessageDataAsync <EventData>(employee); string schemaId = eventData.ContentType.Split('+')[1]; eventData.ContentType = "avro/binary"; using var stream = new MemoryStream(); stream.Write(new byte[] { 0, 0, 0, 0 }, 0, 4); var encoding = new UTF8Encoding(false); stream.Write(encoding.GetBytes(schemaId), 0, 32); stream.Write(eventData.Body.ToArray(), 0, eventData.Body.Length); stream.Position = 0; eventData.EventBody = BinaryData.FromStream(stream); Employee deserialized = await encoder.DecodeMessageDataAsync <Employee>(eventData); // decoding should not alter the message Assert.AreEqual("avro/binary", eventData.ContentType); // verify the payload was decoded correctly Assert.IsNotNull(deserialized); Assert.AreEqual("Caketown", deserialized.Name); Assert.AreEqual(42, deserialized.Age); }