Get started

This hands-on tutorial provides instructions and examples on how to construct schemas. For instructions on administrative tasks, see Manage schema.

Construct a schema

bytes

This example demonstrates how to construct a bytes schema using language-specific clients and use it to produce and consume messages.

  • Java
  • C++
  • Python
  • Go
  1. Producer<byte[]> producer = pulsarClient.newProducer(Schema.BYTES)
  2. .topic("my-topic")
  3. .create();
  4. Consumer<byte[]> consumer = pulsarClient.newConsumer(Schema.BYTES)
  5. .topic("my-topic")
  6. .subscriptionName("my-sub")
  7. .subscribe();
  8. producer.newMessage().value("message".getBytes()).send();
  9. Message<byte[]> message = consumer.receive(5, TimeUnit.SECONDS);
  1. SchemaInfo schemaInfo = SchemaInfo(SchemaType::BYTES, "Bytes", "");
  2. Producer producer;
  3. client.createProducer("topic-bytes", ProducerConfiguration().setSchema(schemaInfo), producer);
  4. std::array<char, 1024> buffer;
  5. producer.send(MessageBuilder().setContent(buffer.data(), buffer.size()).build());
  6. Consumer consumer;
  7. res = client.subscribe("topic-bytes", "my-sub", ConsumerConfiguration().setSchema(schemaInfo), consumer);
  8. Message msg;
  9. consumer.receive(msg, 3000);
  1. producer = client.create_producer(
  2. 'bytes-schema-topic',
  3. schema=BytesSchema())
  4. producer.send(b"Hello")
  5. consumer = client.subscribe(
  6. 'bytes-schema-topic',
  7. 'sub',
  8. schema=BytesSchema())
  9. msg = consumer.receive()
  10. data = msg.value()
  1. producer, err := client.CreateProducer(pulsar.ProducerOptions{
  2. Topic: "my-topic",
  3. Schema: pulsar.NewBytesSchema(nil),
  4. })
  5. id, err := producer.Send(context.Background(), &pulsar.ProducerMessage{
  6. Value: []byte("message"),
  7. })
  8. consumer, err := client.Subscribe(pulsar.ConsumerOptions{
  9. Topic: "my-topic",
  10. Schema: pulsar.NewBytesSchema(nil),
  11. SubscriptionName: "my-sub",
  12. Type: pulsar.Exclusive,
  13. })

string

This example demonstrates how to construct a string schema using language-specific clients and use it to produce and consume messages.

  • Java
  • C++
  • Python
  • Go
  1. Producer<String> producer = client.newProducer(Schema.STRING).create();
  2. producer.newMessage().value("Hello Pulsar!").send();
  3. Consumer<String> consumer = client.newConsumer(Schema.STRING).subscribe();
  4. Message<String> message = consumer.receive();
  1. SchemaInfo schemaInfo = SchemaInfo(SchemaType::STRING, "String", "");
  2. Producer producer;
  3. client.createProducer("topic-string", ProducerConfiguration().setSchema(schemaInfo), producer);
  4. producer.send(MessageBuilder().setContent("message").build());
  5. Consumer consumer;
  6. client.subscribe("topic-string", "my-sub", ConsumerConfiguration().setSchema(schemaInfo), consumer);
  7. Message msg;
  8. consumer.receive(msg, 3000);
  1. producer = client.create_producer(
  2. 'string-schema-topic',
  3. schema=StringSchema())
  4. producer.send("Hello")
  5. consumer = client.subscribe(
  6. 'string-schema-topic',
  7. 'sub',
  8. schema=StringSchema())
  9. msg = consumer.receive()
  10. str = msg.value()
  1. producer, err := client.CreateProducer(pulsar.ProducerOptions{
  2. Topic: "my-topic",
  3. Schema: pulsar.NewStringSchema(nil),
  4. })
  5. id, err := producer.Send(context.Background(), &pulsar.ProducerMessage{
  6. Value: "message",
  7. })
  8. consumer, err := client.Subscribe(pulsar.ConsumerOptions{
  9. Topic: "my-topic",
  10. Schema: pulsar.NewStringSchema(nil),
  11. SubscriptionName: "my-sub",
  12. Type: pulsar.Exclusive,
  13. })
  14. msg, err := consumer.Receive(context.Background())

key/value

This example shows how to construct a key/value schema using language-specific clients and use it to produce and consume messages.

  • Java
  • C++
  1. Construct a key/value schema with INLINE encoding type.

    1. Schema<KeyValue<Integer, String>> kvSchema = Schema.KeyValue(
    2. Schema.INT32,
    3. Schema.STRING,
    4. KeyValueEncodingType.INLINE
    5. );

    Alternatively, construct a key/value schema with SEPARATED encoding type.

    1. Schema<KeyValue<Integer, String>> kvSchema = Schema.KeyValue(
    2. Schema.INT32,
    3. Schema.STRING,
    4. KeyValueEncodingType.SEPARATED
    5. );
  2. Produce messages using a key/value schema.

    1. Producer<KeyValue<Integer, String>> producer = client.newProducer(kvSchema)
    2. .topic(topicName)
    3. .create();
    4. final int key = 100;
    5. final String value = "value-100";
    6. // send the key/value message
    7. producer.newMessage()
    8. .value(new KeyValue(key, value))
    9. .send();
  3. Consume messages using a key/value schema.

    1. Consumer<KeyValue<Integer, String>> consumer = client.newConsumer(kvSchema)
    2. ...
    3. .topic(topicName)
    4. .subscriptionName(subscriptionName).subscribe();
    5. // receive key/value pair
    6. Message<KeyValue<Integer, String>> msg = consumer.receive();
    7. KeyValue<Integer, String> kv = msg.getValue();
  4. Construct a key/value schema with INLINE encoding type.

    1. //Prepare keyValue schema
    2. std::string jsonSchema =
    3. R"({"type":"record","name":"cpx","fields":[{"name":"re","type":"double"},{"name":"im","type":"double"}]})";
    4. SchemaInfo keySchema(JSON, "key-json", jsonSchema);
    5. SchemaInfo valueSchema(JSON, "value-json", jsonSchema);
    6. SchemaInfo keyValueSchema(keySchema, valueSchema, KeyValueEncodingType::INLINE);
  5. Produce messages using a key/value schema.

    1. //Create Producer
    2. Producer producer;
    3. client.createProducer("my-topic", ProducerConfiguration().setSchema(keyValueSchema), producer);
    4. //Prepare message
    5. std::string jsonData = "{\"re\":2.1,\"im\":1.23}";
    6. KeyValue keyValue(std::move(jsonData), std::move(jsonData));
    7. Message msg = MessageBuilder().setContent(keyValue).setProperty("x", "1").build();
    8. //Send message
    9. producer.send(msg);
  6. Consume messages using a key/value schema.

    1. //Create Consumer
    2. Consumer consumer;
    3. client.subscribe("my-topic", "my-sub", ConsumerConfiguration().setSchema(keyValueSchema), consumer);
    4. //Receive message
    5. Message message;
    6. consumer.receive(message);

Avro

  • Java
  • C++
  • Python
  • Go

Suppose you have a SensorReading class as follows, and you’d like to transmit it over a Pulsar topic.

  1. public class SensorReading {
  2. public float temperature;
  3. public SensorReading(float temperature) {
  4. this.temperature = temperature;
  5. }
  6. // A no-arg constructor is required
  7. public SensorReading() {
  8. }
  9. public float getTemperature() {
  10. return temperature;
  11. }
  12. public void setTemperature(float temperature) {
  13. this.temperature = temperature;
  14. }
  15. }

Create a Producer<SensorReading> (or Consumer<SensorReading>) like this:

  1. Producer<SensorReading> producer = client.newProducer(AvroSchema.of(SensorReading.class))
  2. .topic("sensor-readings")
  3. .create();
  1. // Send messages
  2. static const std::string exampleSchema =
  3. "{\"type\":\"record\",\"name\":\"Example\",\"namespace\":\"test\","
  4. "\"fields\":[{\"name\":\"a\",\"type\":\"int\"},{\"name\":\"b\",\"type\":\"int\"}]}";
  5. Producer producer;
  6. ProducerConfiguration producerConf;
  7. producerConf.setSchema(SchemaInfo(AVRO, "Avro", exampleSchema));
  8. client.createProducer("topic-avro", producerConf, producer);
  9. // Receive messages
  10. static const std::string exampleSchema =
  11. "{\"type\":\"record\",\"name\":\"Example\",\"namespace\":\"test\","
  12. "\"fields\":[{\"name\":\"a\",\"type\":\"int\"},{\"name\":\"b\",\"type\":\"int\"}]}";
  13. ConsumerConfiguration consumerConf;
  14. Consumer consumer;
  15. consumerConf.setSchema(SchemaInfo(AVRO, "Avro", exampleSchema));
  16. client.subscribe("topic-avro", "sub-2", consumerConf, consumer)

You can declare an AvroSchema using Python through one of the following methods.

Method 1: Record

Declare an AvroSchema by passing a class that inherits from pulsar.schema.Record and defines the fields as class variables.

  1. class Example(Record):
  2. a = Integer()
  3. b = Integer()
  4. producer = client.create_producer(
  5. 'avro-schema-topic',
  6. schema=AvroSchema(Example))
  7. r = Example(a=1, b=2)
  8. producer.send(r)
  9. consumer = client.subscribe(
  10. 'avro-schema-topic',
  11. 'sub',
  12. schema=AvroSchema(Example))
  13. msg = consumer.receive()
  14. e = msg.value()

Method 2: JSON definition

  1. Declare an AvroSchema using JSON. In this case, Avro schemas are defined using JSON.

    Below is an example of AvroSchema defined using a JSON file (company.avsc).

    1. {
    2. "doc": "this is doc",
    3. "namespace": "example.avro",
    4. "type": "record",
    5. "name": "Company",
    6. "fields": [
    7. {"name": "name", "type": ["null", "string"]},
    8. {"name": "address", "type": ["null", "string"]},
    9. {"name": "employees", "type": ["null", {"type": "array", "items": {
    10. "type": "record",
    11. "name": "Employee",
    12. "fields": [
    13. {"name": "name", "type": ["null", "string"]},
    14. {"name": "age", "type": ["null", "int"]}
    15. ]
    16. }}]},
    17. {"name": "labels", "type": ["null", {"type": "map", "values": "string"}]}
    18. ]
    19. }
  2. Load a schema definition from a file by using avro.schema or fastavro.schema.

    If you use the JSON definition method to declare an AvroSchema, you need to:

    • Use Python dict to produce and consume messages, which is different from using the Record method.
    • Set the value of the _record_cls parameter to None when generating an AvroSchema object.

    Example

    1. from fastavro.schema import load_schema
    2. from pulsar.schema import *
    3. schema_definition = load_schema("examples/company.avsc")
    4. avro_schema = AvroSchema(None, schema_definition=schema_definition)
    5. producer = client.create_producer(
    6. topic=topic,
    7. schema=avro_schema)
    8. consumer = client.subscribe(topic, 'test', schema=avro_schema)
    9. company = {
    10. "name": "company-name" + str(i),
    11. "address": 'xxx road xxx street ' + str(i),
    12. "employees": [
    13. {"name": "user" + str(i), "age": 20 + i},
    14. {"name": "user" + str(i), "age": 30 + i},
    15. {"name": "user" + str(i), "age": 35 + i},
    16. ],
    17. "labels": {
    18. "industry": "software" + str(i),
    19. "scale": ">100",
    20. "funds": "1000000.0"
    21. }
    22. }
    23. producer.send(company)
    24. msg = consumer.receive()
    25. # Users could get a dict object by `value()` method.
    26. msg.value()

Suppose you have an avroExampleStruct class as follows, and you’d like to transmit it over a Pulsar topic.

  1. type avroExampleStruct struct {
  2. ID int
  3. Name string
  4. }
  1. Add an avroSchemaDef like this:

    1. var (
    2. exampleSchemaDef = "{\"type\":\"record\",\"name\":\"Example\",\"namespace\":\"test\"," +
    3. "\"fields\":[{\"name\":\"ID\",\"type\":\"int\"},{\"name\":\"Name\",\"type\":\"string\"}]}"
    4. )
  2. Create producer and consumer to send/receive messages:

    1. //Create producer and send message
    2. producer, err := client.CreateProducer(pulsar.ProducerOptions{
    3. Topic: "my-topic",
    4. Schema: pulsar.NewAvroSchema(exampleSchemaDef, nil),
    5. })
    6. msgId, err := producer.Send(context.Background(), &pulsar.ProducerMessage{
    7. Value: avroExampleStruct{
    8. ID: 10,
    9. Name: "avroExampleStruct",
    10. },
    11. })
    12. //Create Consumer and receive message
    13. consumer, err := client.Subscribe(pulsar.ConsumerOptions{
    14. Topic: "my-topic",
    15. Schema: pulsar.NewAvroSchema(exampleSchemaDef, nil),
    16. SubscriptionName: "my-sub",
    17. Type: pulsar.Shared,
    18. })
    19. message, err := consumer.Receive(context.Background())

JSON

  • Java
  • C++
  • Python
  • Go

Similar to using AvroSchema, you can declare a JsonSchema by passing a class. The only difference is to use JsonSchema instead of AvroSchema when defining the schema type, as shown below. For how to use AvroSchema via record, see Method 1 - Record.

  1. static class SchemaDemo {
  2. public String name;
  3. public int age;
  4. }
  5. Producer<SchemaDemo> producer = pulsarClient.newProducer(Schema.JSON(SchemaDemo.class))
  6. .topic("my-topic")
  7. .create();
  8. Consumer<SchemaDemo> consumer = pulsarClient.newConsumer(Schema.JSON(SchemaDemo.class))
  9. .topic("my-topic")
  10. .subscriptionName("my-sub")
  11. .subscribe();
  12. SchemaDemo schemaDemo = new SchemaDemo();
  13. schemaDemo.name = "puslar";
  14. schemaDemo.age = 20;
  15. producer.newMessage().value(schemaDemo).send();
  16. Message<SchemaDemo> message = consumer.receive(5, TimeUnit.SECONDS);

To declare a JSON schema using C++, do the following:

  1. Pass a JSON string like this:

    1. Std::string jsonSchema = R"({"type":"record","name":"cpx","fields":[{"name":"re","type":"double"},{"name":"im","type":"double"}]})";
    2. SchemaInfo schemaInfo = SchemaInfo(JSON, "JSON", jsonSchema);
  2. Create a producer and use it to send messages.

    1. client.createProducer("my-topic", ProducerConfiguration().setSchema(schemaInfo), producer);
    2. std::string jsonData = "{\"re\":2.1,\"im\":1.23}";
    3. producer.send(MessageBuilder().setContent(std::move(jsonData)).build());
  3. Create consumer and receive message.

    1. Consumer consumer;
    2. client.subscribe("my-topic", "my-sub", ConsumerConfiguration().setSchema(schemaInfo), consumer);
    3. Message msg;
    4. consumer.receive(msg);

You can declare a JsonSchema by passing a class that inherits from pulsar.schema.Record and defines the fields as class variables. This is similar to using AvroSchema. The only difference is to use JsonSchema instead of AvroSchema when defining schema type, as shown below. For how to use AvroSchema via record, see (#method-1-record).

  1. producer = client.create_producer(
  2. 'avro-schema-topic',
  3. schema=JsonSchema(Example))
  4. consumer = client.subscribe(
  5. 'avro-schema-topic',
  6. 'sub',
  7. schema=JsonSchema(Example))

Suppose you have an avroExampleStruct class as follows, and you’d like to transmit it as JSON form over a Pulsar topic.

  1. type jsonExampleStruct struct {
  2. ID int `json:"id"`
  3. Name string `json:"name"`
  4. }
  1. Add a jsonSchemaDef like this:
  1. jsonSchemaDef = "{\"type\":\"record\",\"name\":\"Example\",\"namespace\":\"test\"," +
  2. "\"fields\":[{\"name\":\"ID\",\"type\":\"int\"},{\"name\":\"Name\",\"type\":\"string\"}]}"
  1. Create a producer/consumer to send/receive messages:
  1. //Create producer and send message
  2. producer, err := client.CreateProducer(pulsar.ProducerOptions{
  3. Topic: "my-topic",
  4. Schema: pulsar.NewJSONSchema(jsonSchemaDef, nil),
  5. })
  6. msgId, err := producer.Send(context.Background(), &pulsar.ProducerMessage{
  7. Value: jsonExampleStruct{
  8. ID: 10,
  9. Name: "jsonExampleStruct",
  10. },
  11. })
  12. //Create Consumer and receive message
  13. consumer, err := client.Subscribe(pulsar.ConsumerOptions{
  14. Topic: "my-topic",
  15. Schema: pulsar.NewJSONSchema(jsonSchemaDef, nil),
  16. SubscriptionName: "my-sub",
  17. Type: pulsar.Exclusive,
  18. })
  19. message, err := consumer.Receive(context.Background())

ProtobufNative

  • Java
  • C++

The following example shows how to create a producer/consumer with a ProtobufNative schema using Java.

  1. Generate the DemoMessage class using Protobuf3 or later versions.

    1. syntax = "proto3";
    2. message DemoMessage {
    3. string stringField = 1;
    4. double doubleField = 2;
    5. int32 intField = 6;
    6. TestEnum testEnum = 4;
    7. SubMessage nestedField = 5;
    8. repeated string repeatedField = 10;
    9. proto.external.ExternalMessage externalMessage = 11;
    10. }
  2. Create a producer/consumer to send/receive messages.

    1. Producer<DemoMessage> producer = pulsarClient.newProducer(Schema.PROTOBUF_NATIVE(DemoMessage.class))
    2. .topic("my-topic")
    3. .create();
    4. Consumer<DemoMessage> consumer = pulsarClient.newConsumer(Schema.PROTOBUF_NATIVE(DemoMessage.class))
    5. .topic("my-topic")
    6. .subscriptionName("my-sub")
    7. .subscribe();
    8. SchemaDemo schemaDemo = new SchemaDemo();
    9. schemaDemo.name = "puslar";
    10. schemaDemo.age = 20;
    11. producer.newMessage().value(DemoMessage.newBuilder().setStringField("string-field-value")
    12. .setIntField(1).build()).send();
    13. Message<DemoMessage> message = consumer.receive(5, TimeUnit.SECONDS);

The following example shows how to create a producer/consumer with a ProtobufNative schema.

  1. Generate the User class using Protobuf3 or later versions.

    1. syntax = "proto3";
    2. message User {
    3. string name = 1;
    4. int32 age = 2;
    5. }
  2. Include the ProtobufNativeSchema.h in your source code. Ensure the Protobuf dependency has been added to your project.

    1. #include <pulsar/ProtobufNativeSchema.h>
  3. Create a producer to send a User instance.

    1. ProducerConfiguration producerConf;
    2. producerConf.setSchema(createProtobufNativeSchema(User::GetDescriptor()));
    3. Producer producer;
    4. client.createProducer("topic-protobuf", producerConf, producer);
    5. User user;
    6. user.set_name("my-name");
    7. user.set_age(10);
    8. std::string content;
    9. user.SerializeToString(&content);
    10. producer.send(MessageBuilder().setContent(content).build());
  4. Create a consumer to receive a User instance.

    1. ConsumerConfiguration consumerConf;
    2. consumerConf.setSchema(createProtobufNativeSchema(User::GetDescriptor()));
    3. consumerConf.setSubscriptionInitialPosition(InitialPositionEarliest);
    4. Consumer consumer;
    5. client.subscribe("topic-protobuf", "my-sub", consumerConf, consumer);
    6. Message msg;
    7. consumer.receive(msg);
    8. User user2;
    9. user2.ParseFromArray(msg.getData(), msg.getLength());

Protobuf

  • Java
  • C++
  • Go

Constructing a protobuf schema using Java is similar to constructing a ProtobufNative schema. The only difference is to use PROTOBUF instead of PROTOBUF_NATIVE when defining schema type as shown below.

  1. Generate the DemoMessage class using Protobuf3 or later versions.

    1. syntax = "proto3";
    2. message DemoMessage {
    3. string stringField = 1;
    4. double doubleField = 2;
    5. int32 intField = 6;
    6. TestEnum testEnum = 4;
    7. SubMessage nestedField = 5;
    8. repeated string repeatedField = 10;
    9. proto.external.ExternalMessage externalMessage = 11;
    10. }
  2. Create a producer/consumer to send/receive messages.

    1. Producer<DemoMessage> producer = pulsarClient.newProducer(Schema.PROTOBUF(DemoMessage.class))
    2. .topic("my-topic")
    3. .create();
    4. Consumer<DemoMessage> consumer = pulsarClient.newConsumer(Schema.PROTOBUF(DemoMessage.class))
    5. .topic("my-topic")
    6. .subscriptionName("my-sub")
    7. .subscribe();
    8. SchemaDemo schemaDemo = new SchemaDemo();
    9. schemaDemo.name = "puslar";
    10. schemaDemo.age = 20;
    11. producer.newMessage().value(DemoMessage.newBuilder().setStringField("string-field-value")
    12. .setIntField(1).build()).send();
    13. Message<DemoMessage> message = consumer.receive(5, TimeUnit.SECONDS);

Constructing a protobuf schema using C++ is similar to that using JSON. The only difference is to use PROTOBUF instead of JSON when defining the schema type as shown below.

  1. std::string jsonSchema =
  2. R"({"type":"record","name":"cpx","fields":[{"name":"re","type":"double"},{"name":"im","type":"double"}]})";
  3. SchemaInfo schemaInfo = SchemaInfo(pulsar::PROTOBUF, "PROTOBUF", jsonSchema);
  1. Create a producer to send messages.

    1. Producer producer;
    2. client.createProducer("my-topic", ProducerConfiguration().setSchema(schemaInfo), producer);
    3. std::string jsonData = "{\"re\":2.1,\"im\":1.23}";
    4. producer.send(MessageBuilder().setContent(std::move(jsonData)).build());
  2. Create a consumer to receive messages.

    1. Consumer consumer;
    2. client.subscribe("my-topic", "my-sub", ConsumerConfiguration().setSchema(schemaInfo), consumer);
    3. Message msg;
    4. consumer.receive(msg);

Suppose you have a protobufDemo class as follows, and you’d like to transmit it in JSON form over a Pulsar topic.

  1. type protobufDemo struct {
  2. Num int32 `protobuf:"varint,1,opt,name=num,proto3" json:"num,omitempty"`
  3. Msf string `protobuf:"bytes,2,opt,name=msf,proto3" json:"msf,omitempty"`
  4. XXX_NoUnkeyedLiteral struct{} `json:"-"`
  5. XXX_unrecognized []byte `json:"-"`
  6. XXX_sizecache int32 `json:"-"`
  7. }
  1. Add a protoSchemaDef like this:

    1. var (
    2. protoSchemaDef = "{\"type\":\"record\",\"name\":\"Example\",\"namespace\":\"test\"," +
    3. "\"fields\":[{\"name\":\"num\",\"type\":\"int\"},{\"name\":\"msf\",\"type\":\"string\"}]}"
    4. )
  2. Create a producer/consumer to send/receive messages:

    1. psProducer := pulsar.NewProtoSchema(protoSchemaDef, nil)
    2. producer, err := client.CreateProducer(pulsar.ProducerOptions{
    3. Topic: "proto",
    4. Schema: psProducer,
    5. })
    6. msgId, err := producer.Send(context.Background(), &pulsar.ProducerMessage{
    7. Value: &protobufDemo{
    8. Num: 100,
    9. Msf: "pulsar",
    10. },
    11. })
    12. psConsumer := pulsar.NewProtoSchema(protoSchemaDef, nil)
    13. consumer, err := client.Subscribe(pulsar.ConsumerOptions{
    14. Topic: "proto",
    15. SubscriptionName: "sub-1",
    16. Schema: psConsumer,
    17. SubscriptionInitialPosition: pulsar.SubscriptionPositionEarliest,
    18. })
    19. msg, err := consumer.Receive(context.Background())

Native Avro

This example shows how to construct a native Avro schema.

  1. org.apache.avro.Schema nativeAvroSchema = ;
  2. Producer<byte[]> producer = pulsarClient.newProducer().topic("ingress").create();
  3. byte[] content = ;
  4. producer.newMessage(Schema.NATIVE_AVRO(nativeAvroSchema)).value(content).send();

AUTO_PRODUCE

Suppose you have a Pulsar topic P, a producer processing messages from a Kafka topic K, an application reading the messages from K and writing the messages to P.

This example shows how to construct an AUTO_PRODUCE schema to verify whether the bytes produced by K can be sent to P.

  1. Produce<byte[]> pulsarProducer = client.newProducer(Schema.AUTO_PRODUCE_BYTES())
  2. .create();
  3. byte[] kafkaMessageBytes = ;
  4. pulsarProducer.produce(kafkaMessageBytes);

AUTO_CONSUME

Suppose you have a Pulsar topic P and a consumer MySQL that receives messages from P, and you want to check if these messages have the information that your application needs to count.

This example shows how to construct an AUTO_CONSUME schema to verify whether the bytes produced by P can be sent to MySQL.

  1. Consumer<GenericRecord> pulsarConsumer = client.newConsumer(Schema.AUTO_CONSUME())
  2. .subscribe();
  3. Message<GenericRecord> msg = consumer.receive() ;
  4. GenericRecord record = msg.getValue();
  5. record.getFields().forEach((field -> {
  6. if (field.getName().equals("theNeedFieldName")) {
  7. Object recordField = record.getField(field);
  8. //Do some things
  9. }
  10. }));

Customize schema storage

By default, Pulsar stores various data types of schemas in Apache BookKeeper deployed alongside Pulsar. Alternatively, you can use another storage system if needed.

To use a non-default (non-BookKeeper) storage system for Pulsar schemas, you need to implement the following Java interfaces before deploying custom schema storage:

Implement SchemaStorage interface

The SchemaStorage interface has the following methods:

  1. public interface SchemaStorage {
  2. // How schemas are updated
  3. CompletableFuture<SchemaVersion> put(String key, byte[] value, byte[] hash);
  4. // How schemas are fetched from storage
  5. CompletableFuture<StoredSchema> get(String key, SchemaVersion version);
  6. // How schemas are deleted
  7. CompletableFuture<SchemaVersion> delete(String key);
  8. // Utility method for converting a schema version byte array to a SchemaVersion object
  9. SchemaVersion versionFromBytes(byte[] version);
  10. // Startup behavior for the schema storage client
  11. void start() throws Exception;
  12. // Shutdown behavior for the schema storage client
  13. void close() throws Exception;
  14. }

Get started - 图1tip

For a complete example of schema storage implementation, see the BookKeeperSchemaStorage class.

Implement SchemaStorageFactory interface

The SchemaStorageFactory interface has the following method:

  1. public interface SchemaStorageFactory {
  2. @NotNull
  3. SchemaStorage create(PulsarService pulsar) throws Exception;
  4. }

Get started - 图2tip

For a complete example of schema storage factory implementation, see the BookKeeperSchemaStorageFactory class.

Deploy custom schema storage

To use your custom schema storage implementation, perform the following steps.

  1. Package the implementation in a JAR file.

  2. Add the JAR file to the lib folder in your Pulsar binary or source distribution.

  3. Change the schemaRegistryStorageClassName configuration in the conf/broker.conf file to your custom factory class.

  4. Start Pulsar.