public static void GetAllSubjects(Config config)
        {
            var topicName = Guid.NewGuid().ToString();

            var testSchema1 =
                "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"Confluent.Kafka.Examples.AvroSpecific" +
                "\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favorite_number\",\"type\":[\"i" +
                "nt\",\"null\"]},{\"name\":\"favorite_color\",\"type\":[\"string\",\"null\"]}]}";

            var sr = new CachedSchemaRegistryClient(new SchemaRegistryConfig {
                SchemaRegistryUrl = config.Server
            });

            var subjectsBefore = sr.GetAllSubjectsAsync().Result;

            var subject = sr.ConstructKeySubjectName(topicName);
            var id      = sr.RegisterSchemaAsync(subject, testSchema1).Result;

            var subjectsAfter = sr.GetAllSubjectsAsync().Result;

            Assert.Equal(1, subjectsAfter.Count - subjectsBefore.Count);

            sr.RegisterSchemaAsync(subject, testSchema1).Wait();

            var subjectsAfter2 = sr.GetAllSubjectsAsync().Result;

            Assert.Equal(subjectsAfter.Count, subjectsAfter2.Count);

            Assert.True(subjectsAfter2.Contains(subject));
        }
예제 #2
0
        public static void RegisterIncompatibleSchema(string server)
        {
            var topicName = Guid.NewGuid().ToString();

            var testSchema1 =
                "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"Confluent.Kafka.Examples.AvroSpecific" +
                "\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favorite_number\",\"type\":[\"i" +
                "nt\",\"null\"]},{\"name\":\"favorite_color\",\"type\":[\"string\",\"null\"]}]}";

            var sr = new CachedSchemaRegistryClient(new Dictionary <string, object> {
                { "schema.registry.url", server }
            });

            var subject = sr.ConstructKeySubjectName(topicName, "Confluent.Kafka.Examples.AvroSpecific.User");
            var id      = sr.RegisterSchemaAsync(subject, testSchema1).Result;

            var testSchema2 = // incompatible with testSchema1
                              "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"Confluent.Kafka.Examples.AvroSpecific" +
                              "\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favorite_number\",\"type\":[\"i" +
                              "nt\",\"null\"]},{\"name\":\"favorite_shape\",\"type\":[\"string\",\"null\"]}]}";

            Assert.False(sr.IsCompatibleAsync(subject, testSchema2).Result);

            Assert.Throws <AggregateException>(() => sr.RegisterSchemaAsync(subject, testSchema2).Result);

            Assert.True(sr.GetAllSubjectsAsync().Result.Contains(subject));
        }
예제 #3
0
        public static void GetId(Config config)
        {
            var topicName = Guid.NewGuid().ToString();

            var testSchema1 =
                "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"Confluent.Kafka.Examples.AvroSpecific" +
                "\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favorite_number\",\"type\":[\"i" +
                "nt\",\"null\"]},{\"name\":\"favorite_color\",\"type\":[\"string\",\"null\"]}]}";

            var sr = new CachedSchemaRegistryClient(new SchemaRegistryConfig {
                SchemaRegistryUrl = config.Server
            });

            var subject = sr.ConstructKeySubjectName(topicName);
            var id      = sr.RegisterSchemaAsync(subject, testSchema1).Result;
            var id2     = sr.GetSchemaIdAsync(subject, testSchema1).Result;

            Assert.Equal(id, id2);

            Assert.Throws <SchemaRegistryException>(() =>
            {
                try
                {
                    sr.GetSchemaIdAsync(subject, "{\"type\": \"string\"}").Wait();
                }
                catch (AggregateException e)
                {
                    throw e.InnerException;
                }
            });
        }
예제 #4
0
        public static void IsCompatible(string server)
        {
            var topicName = Guid.NewGuid().ToString();

            var testSchema1 =
                "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"Confluent.Kafka.Examples.AvroSpecific" +
                "\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favorite_number\",\"type\":[\"i" +
                "nt\",\"null\"]},{\"name\":\"favorite_color\",\"type\":[\"string\",\"null\"]}]}";

            var sr = new CachedSchemaRegistryClient(new Dictionary <string, object> {
                { "schema.registry.url", server }
            });

            var subject = sr.ConstructKeySubjectName(topicName, "Confluent.Kafka.Examples.AvroSpecific.User");
            var id      = sr.RegisterSchemaAsync(subject, testSchema1).Result;

            var testSchema2 = // incompatible with testSchema1
                              "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"Confluent.Kafka.Examples.AvroSpecific" +
                              "\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favorite_number\",\"type\":[\"i" +
                              "nt\",\"null\"]},{\"name\":\"favorite_shape\",\"type\":[\"string\",\"null\"]}]}";

            Assert.False(sr.IsCompatibleAsync(subject, testSchema2).Result);
            Assert.True(sr.IsCompatibleAsync(subject, testSchema1).Result);

            // Note: backwards / forwards compatibility scenarios are not tested here. This is really just testing the API call.
        }
        public void ConstructKeySubjectName_Topic1()
        {
            var config = new SchemaRegistryConfig {
                Url = "irrelevanthost:8081"
            };
            var src = new CachedSchemaRegistryClient(config);

            Assert.Equal("mytopic-key", src.ConstructKeySubjectName("mytopic", "myschemaname"));
        }
예제 #6
0
        public void ConstructKeySubjectName()
        {
            var config = new Dictionary <string, object>
            {
                { "schema.registry.url", "irrelevanthost:8081" }
            };

            CachedSchemaRegistryClient src = new CachedSchemaRegistryClient(config);

            Assert.Equal("mytopic-key", src.ConstructKeySubjectName("mytopic"));
        }
        public void ConstructKeySubjectName_TopicRecord()
        {
            var config = new SchemaRegistryConfig
            {
                Url = "irrelevanthost:8081",
                KeySubjectNameStrategy = SubjectNameStrategy.TopicRecord
            };
            var src = new CachedSchemaRegistryClient(config);

            Assert.Equal("mytopic-myschemaname", src.ConstructKeySubjectName("mytopic", "myschemaname"));
        }
예제 #8
0
        public static void IsCompatible_Topic(Config config)
        {
            var sr = new CachedSchemaRegistryClient(new SchemaRegistryConfig {
                Url = config.Server
            });

            var testSchema1 =
                "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"Confluent.Kafka.Examples.AvroSpecific" +
                "\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favorite_number\",\"type\":[\"i" +
                "nt\",\"null\"]},{\"name\":\"favorite_color\",\"type\":[\"string\",\"null\"]}]}";

            var testSchema2 = // incompatible with testSchema1
                              "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"Confluent.Kafka.Examples.AvroSpecific" +
                              "\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favorite_number\",\"type\":[\"i" +
                              "nt\",\"null\"]},{\"name\":\"favorite_shape\",\"type\":[\"string\",\"null\"]}]}";


            // case 1: record specified.
            var topicName = Guid.NewGuid().ToString();
            var subject   = sr.ConstructKeySubjectName(topicName, "Confluent.Kafka.Examples.AvroSpecific.User");

            sr.RegisterSchemaAsync(subject, testSchema1).Wait();

            Assert.False(sr.IsCompatibleAsync(subject, testSchema2).Result);
            Assert.True(sr.IsCompatibleAsync(subject, testSchema1).Result);


            // case 2: record not specified.
            topicName = Guid.NewGuid().ToString();
            subject   = sr.ConstructKeySubjectName(topicName);

            sr.RegisterSchemaAsync(subject, testSchema1).Wait();

            Assert.False(sr.IsCompatibleAsync(subject, testSchema2).Result);
            Assert.True(sr.IsCompatibleAsync(subject, testSchema1).Result);


            // Note: backwards / forwards compatibility scenarios are not tested here. This is really just testing the API call.
        }
예제 #9
0
        public static void Failover(Config config)
        {
            var testSchema =
                "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"Confluent.Kafka.Examples.AvroSpecific" +
                "\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favorite_number\",\"type\":[\"i" +
                "nt\",\"null\"]},{\"name\":\"favorite_color\",\"type\":[\"string\",\"null\"]}]}";

            using (var sr = new CachedSchemaRegistryClient(new SchemaRegistryConfig {
                Url = $"{config.Server},http://localhost:65432"
            }))
            {
                var topicName = Guid.NewGuid().ToString();
                var subject   = sr.ConstructKeySubjectName(topicName);
                var id        = sr.RegisterSchemaAsync(subject, testSchema).Result;
                var id2       = sr.GetSchemaIdAsync(subject, testSchema).Result;
                Assert.Equal(id, id2);
            }

            using (var sr = new CachedSchemaRegistryClient(new SchemaRegistryConfig {
                Url = $"http://localhost:65432,{config.Server}"
            }))
            {
                var topicName = Guid.NewGuid().ToString();
                var subject   = sr.ConstructKeySubjectName(topicName);
                var id        = sr.RegisterSchemaAsync(subject, testSchema).Result;
                var id2       = sr.GetSchemaIdAsync(subject, testSchema).Result;
                Assert.Equal(id, id2);
            }

            using (var sr = new CachedSchemaRegistryClient(new SchemaRegistryConfig {
                Url = $"http://localhost:65432,http://localhost:65431"
            }))
            {
                var topicName = Guid.NewGuid().ToString();
                var subject   = sr.ConstructKeySubjectName(topicName);

                Assert.Throws <HttpRequestException>(() =>
                {
                    try
                    {
                        sr.RegisterSchemaAsync(subject, testSchema).Wait();
                    }
                    catch (AggregateException e)
                    {
                        throw e.InnerException;
                    }
                });
            }
        }
예제 #10
0
        public void ConstructKeySubjectName()
        {
            var config = new Dictionary <string, object>
            {
                { "schema.registry.url", "irrelevanthost:8081" }
            };

            CachedSchemaRegistryClient src = new CachedSchemaRegistryClient(config);

            Assert.Equal("mytopic-key", src.ConstructKeySubjectName("mytopic", "myschemaname"));

            var configTopicName = new Dictionary <string, object>
            {
                { "schema.registry.url", "irrelevanthost:8081" },
                { "schema.registry.subject.name.strategy", "topic_name_strategy" }
            };

            CachedSchemaRegistryClient srcTopicName = new CachedSchemaRegistryClient(configTopicName);

            Assert.Equal("mytopic-key", srcTopicName.ConstructKeySubjectName("mytopic", "myschemaname"));

            var configRecordName = new Dictionary <string, object>
            {
                { "schema.registry.url", "irrelevanthost:8081" },
                { "schema.registry.subject.name.strategy", "record_name_strategy" }
            };

            CachedSchemaRegistryClient srcRecordName = new CachedSchemaRegistryClient(configRecordName);

            Assert.Equal("myschemaname", srcRecordName.ConstructKeySubjectName("mytopic", "myschemaname"));

            var configTopicRecordName = new Dictionary <string, object>
            {
                { "schema.registry.url", "irrelevanthost:8081" },
                { "schema.registry.subject.name.strategy", "topic_record_name_strategy" }
            };

            CachedSchemaRegistryClient srcTopicRecordName = new CachedSchemaRegistryClient(configTopicRecordName);

            Assert.Equal("mytopic-myschemaname", srcTopicRecordName.ConstructKeySubjectName("mytopic", "myschemaname"));
        }
        public static void RegisterSameSchemaTwice(string server)
        {
            var topicName = Guid.NewGuid().ToString();

            var testSchema1 =
                "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"Confluent.Kafka.Examples.AvroSpecific" +
                "\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favorite_number\",\"type\":[\"i" +
                "nt\",\"null\"]},{\"name\":\"favorite_color\",\"type\":[\"string\",\"null\"]}]}";

            var sr = new CachedSchemaRegistryClient(new Dictionary <string, object> {
                { "schema.registry.url", server }
            });

            var subject = sr.ConstructKeySubjectName(topicName);

            Assert.Equal(topicName + "-key", subject);

            var id1 = sr.RegisterSchemaAsync(subject, testSchema1).Result;
            var id2 = sr.RegisterSchemaAsync(subject, testSchema1).Result;

            Assert.Equal(id1, id2);

            Assert.True(sr.GetAllSubjectsAsync().Result.Contains(subject));
        }
예제 #12
0
        public static void RegularAndAvro(string bootstrapServers, string schemaRegistryServers)
        {
            using (var topic1 = new TemporaryTopic(bootstrapServers, 1))
                using (var topic2 = new TemporaryTopic(bootstrapServers, 1))
                {
                    var producerConfig = new ProducerConfig
                    {
                        BootstrapServers = bootstrapServers
                    };

                    var consumerConfig = new ConsumerConfig
                    {
                        BootstrapServers = bootstrapServers,
                        GroupId          = Guid.NewGuid().ToString(),
                        SessionTimeoutMs = 6000,
                        AutoOffsetReset  = AutoOffsetReset.Earliest
                    };

                    var schemaRegistryConfig = new SchemaRegistryConfig
                    {
                        SchemaRegistryUrl = schemaRegistryServers
                    };

                    using (var schemaRegistry = new CachedSchemaRegistryClient(schemaRegistryConfig))
                        using (var producer =
                                   new ProducerBuilder <string, string>(producerConfig)
                                   .SetKeySerializer(Serializers.Utf8)
                                   .SetValueSerializer(new AvroSerializer <string>(schemaRegistry))
                                   .Build())
                        {
                            // implicit check that this does not fail.
                            producer.ProduceAsync(topic1.Name, new Message <string, string> {
                                Key = "hello", Value = "world"
                            }).Wait();

                            // check that the value type was registered with SR, and the key was not.
                            Assert.Throws <SchemaRegistryException>(() =>
                            {
                                try
                                {
                                    schemaRegistry.GetLatestSchemaAsync(schemaRegistry.ConstructKeySubjectName(topic1.Name)).Wait();
                                }
                                catch (AggregateException e)
                                {
                                    throw e.InnerException;
                                }
                            });
                            var s2 = schemaRegistry.GetLatestSchemaAsync(schemaRegistry.ConstructValueSubjectName(topic1.Name)).Result;
                        }

                    using (var schemaRegistry = new CachedSchemaRegistryClient(schemaRegistryConfig))
                        using (var producer =
                                   new ProducerBuilder <string, string>(producerConfig)
                                   .SetKeySerializer(new AvroSerializer <string>(schemaRegistry))
                                   .SetValueSerializer(Serializers.Utf8)
                                   .Build())
                        {
                            // implicit check that this does not fail.
                            producer.ProduceAsync(topic2.Name, new Message <string, string> {
                                Key = "hello", Value = "world"
                            }).Wait();

                            // check that the key type was registered with SR, and the value was not.
                            Assert.Throws <SchemaRegistryException>(() =>
                            {
                                try
                                {
                                    schemaRegistry.GetLatestSchemaAsync(schemaRegistry.ConstructValueSubjectName(topic2.Name)).Wait();
                                }
                                catch (AggregateException e)
                                {
                                    throw e.InnerException;
                                }
                            });
                            var s2 = schemaRegistry.GetLatestSchemaAsync(schemaRegistry.ConstructKeySubjectName(topic2.Name)).Result;
                        }

                    // check the above can be consumed (using regular / Avro serializers as appropriate)
                    using (var schemaRegistry = new CachedSchemaRegistryClient(schemaRegistryConfig))
                    {
                        using (var consumer =
                                   new ConsumerBuilder <string, string>(consumerConfig)
                                   .SetKeyDeserializer(Deserializers.Utf8)
                                   .SetValueDeserializer(new AvroDeserializer <string>(schemaRegistry))
                                   .Build())
                        {
                            consumer.Assign(new TopicPartitionOffset(topic1.Name, 0, 0));
                            var cr = consumer.Consume();
                            Assert.Equal("hello", cr.Key);
                            Assert.Equal("world", cr.Value);
                        }

                        using (var consumer =
                                   new ConsumerBuilder <string, string>(consumerConfig)
                                   .SetKeyDeserializer(new AvroDeserializer <string>(schemaRegistry))
                                   .SetValueDeserializer(Deserializers.Utf8).Build())
                        {
                            consumer.Assign(new TopicPartitionOffset(topic2.Name, 0, 0));
                            var cr = consumer.Consume();
                            Assert.Equal("hello", cr.Key);
                            Assert.Equal("world", cr.Value);
                        }

                        using (var consumer =
                                   new ConsumerBuilder <string, string>(consumerConfig)
                                   .SetKeyDeserializer(Deserializers.Utf8)
                                   .SetValueDeserializer(new AvroDeserializer <string>(schemaRegistry))
                                   .Build())
                        {
                            consumer.Assign(new TopicPartitionOffset(topic2.Name, 0, 0));
                            Assert.ThrowsAny <ConsumeException>(() =>
                            {
                                try
                                {
                                    consumer.Consume();
                                }
                                catch (AggregateException e)
                                {
                                    throw e.InnerException;
                                }
                            });
                        }

                        using (var consumer =
                                   new ConsumerBuilder <string, string>(consumerConfig)
                                   .SetKeyDeserializer(new AvroDeserializer <string>(schemaRegistry))
                                   .SetValueDeserializer(Deserializers.Utf8)
                                   .Build())
                        {
                            consumer.Assign(new TopicPartitionOffset(topic1.Name, 0, 0));
                            Assert.ThrowsAny <ConsumeException>(() =>
                            {
                                try
                                {
                                    consumer.Consume();
                                }
                                catch (AggregateException e)
                                {
                                    throw e.InnerException;
                                }
                            });
                        }
                    }
                }
        }