import (
"encoding/binary"
"encoding/json"
"fmt"
"io/ioutil"
"github.com/google/uuid"
"github.com/riferrei/srclient"
"gopkg.in/confluentinc/confluent-kafka-go.v1/kafka"
)
type ComplexType struct {
ID int `json:"id"`
Name string `json:"name"`
}
func main() {
topic := "myTopic"
// 1) Create the producer as you would normally do using Confluent's Go client
p, err := kafka.NewProducer(&kafka.ConfigMap{"bootstrap.servers": "localhost"})
if err != nil {
panic(err)
}
defer p.Close()
go func() {
for event := range p.Events() {
switch ev := event.(type) {
case *kafka.Message:
message := ev
if ev.TopicPartition.Error != nil {
fmt.Printf("Error delivering the message '%s'\n", message.Key)
} else {
fmt.Printf("Message '%s' delivered successfully!\n", message.Key)
}
}
}
}()
// 2) Fetch the latest version of the schema, or create a new one if it is the first
schemaRegistryClient := srclient.NewSchemaRegistryClient("http://localhost:8081")
schema, err := schemaRegistryClient.GetLatestSchema(topic)
if schema == nil {
schemaBytes, _ := ioutil.ReadFile("complexType.avsc")
schema, err = schemaRegistryClient.CreateSchema(topic, string(schemaBytes), srclient.Avro)
if err != nil {
panic(fmt.Sprintf("Error creating the schema %s", err))
}
}
schemaIDBytes := make([]byte, 4)
binary.BigEndian.PutUint32(schemaIDBytes, uint32(schema.ID()))
// 3) Serialize the record using the schema provided by the client,
// making sure to include the schema id as part of the record.
newComplexType := ComplexType{ID: 1, Name: "Gopher"}
value, _ := json.Marshal(newComplexType)
native, _, _ := schema.Codec().NativeFromTextual(value)
valueBytes, _ := schema.Codec().BinaryFromNative(nil, native)
var recordValue []byte
recordValue = append(recordValue, byte(0))
recordValue = append(recordValue, schemaIDBytes...)
recordValue = append(recordValue, valueBytes...)
key, _ := uuid.NewUUID()
p.Produce(&kafka.Message{
TopicPartition: kafka.TopicPartition{
Topic: &topic, Partition: kafka.PartitionAny},
Key: []byte(key.String()), Value: recordValue}, nil)
p.Flush(15 * 1000)
}
import (
"encoding/binary"
"fmt"
"github.com/riferrei/srclient"
"gopkg.in/confluentinc/confluent-kafka-go.v1/kafka"
)
func main() {
// 1) Create the consumer as you would
// normally do using Confluent's Go client
c, err := kafka.NewConsumer(&kafka.ConfigMap{
"bootstrap.servers": "localhost",
"group.id": "myGroup",
"auto.offset.reset": "earliest",
})
if err != nil {
panic(err)
}
c.SubscribeTopics([]string{"myTopic", "^aRegex.*[Tt]opic"}, nil)
// 2) Create a instance of the client to retrieve the schemas for each message
schemaRegistryClient := srclient.NewSchemaRegistryClient("http://localhost:8081")
for {
msg, err := c.ReadMessage(-1)
if err == nil {
// 3) Recover the schema id from the message and use the
// client to retrieve the schema from Schema Registry.
// Then use it to deserialize the record accordingly.
schemaID := binary.BigEndian.Uint32(msg.Value[1:5])
schema, err := schemaRegistryClient.GetSchema(int(schemaID))
if err != nil {
panic(fmt.Sprintf("Error getting the schema with id '%d' %s", schemaID, err))
}
native, _, _ := schema.Codec().NativeFromBinary(msg.Value[5:])
value, _ := schema.Codec().TextualFromNative(nil, native)
fmt.Printf("Here is the message %s\n", string(value))
} else {
fmt.Printf("Error consuming the message: %v (%v)\n", err, msg)
}
}
c.Close()
}