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);
        }
Example #2
0
        public async Task CannotDeserializeIntoNonCompatibleType()
        {
            var client    = CreateClient();
            var groupName = TestEnvironment.SchemaRegistryGroup;
            var employee  = new Employee()
            {
                Age = 42, Name = "Caketown"
            };

            var serializer = new SchemaRegistryAvroSerializer(client, groupName, new SchemaRegistryAvroSerializerOptions {
                AutoRegisterSchemas = true
            });
            var content = await serializer.SerializeAsync <MessageContent, Employee>(employee);

            var schemaId = content.ContentType.ToString().Split('+')[1];

            // deserialize with the new schema, which is NOT backward compatible with the old schema as it adds a new field
            Assert.That(
                async() => await serializer.DeserializeAsync <Employee_V2>(content),
                Throws.InstanceOf <SchemaRegistryAvroException>()
                .And.Property(nameof(Exception.InnerException)).InstanceOf <AvroException>()
                .And.Property(nameof(SchemaRegistryAvroException.SchemaId)).EqualTo(schemaId));

            #region Snippet:SchemaRegistryAvroException
            try
            {
                Employee_V2 employeeV2 = await serializer.DeserializeAsync <Employee_V2>(content);
            }
            catch (SchemaRegistryAvroException exception)
            {
                // When this exception occurs when deserializing, the exception message will contain the schema ID that was used to
                // serialize the data.
                Console.WriteLine(exception);

                // We might also want to look up the specific schema from Schema Registry so that we can log the schema definition
                if (exception.SchemaId != null)
                {
                    SchemaRegistrySchema schema = await client.GetSchemaAsync(exception.SchemaId);

                    Console.WriteLine(schema.Definition);
                }
            }
            #endregion
        }