Skip to main content

Use schema registry with Java producers and consumers

Aiven for Apache Kafka® provides schema registry functionality through Karapace. Karapace lets you store, retrieve, and evolve schemas without rebuilding producer or consumer code.

The examples use Avro. For Protobuf or JSON Schema, generate the classes first, then apply the same connection and authentication settings.

Workflow overview​

To produce and consume Avro messages in Java using the schema registry:

  1. Define your Avro schema.
  2. Generate Java classes from the schema.
  3. Add the required Maven dependencies.
  4. Optional: Create a keystore, and create a truststore only if you use SASL authentication.
  5. Configure your Kafka producer and consumer properties.

Prerequisites​

Get connection details​

On the service Overview page, open Connection information.

  1. On the Apache Kafka tab, copy the Service URI for the bootstrap servers.
  2. On the Schema Registry tab, copy the Service URI, User, and Password.

Variables​

Replace the following placeholders in the example configuration:

VariableDescription
BOOTSTRAPSERVERSKafka service URI from Connection information on the service overview page
KEYSTOREPath to the keystore file
KEYSTOREPASSWORDPassword for the keystore
TRUSTSTOREPath to the truststore file
TRUSTSTOREPASSWORDPassword for the truststore
SSLKEYPASSWORDPassword for the private key in the keystore
SCHEMAREGISTRYURLSchema registry URI from Connection information
SCHEMAREGISTRYUSERSchema registry username from Connection information
SCHEMAREGISTRYPASSWORDSchema registry password from Connection information
TOPIC_NAMEKafka topic name

Define an Avro schema​

Create an Avro schema file. For example, save the following schema in a file named ClickRecord.avsc:

{
"type": "record",
"name": "ClickRecord",
"namespace": "io.aiven.avro.example",
"fields": [
{"name": "session_id", "type": "string"},
{"name": "browser", "type": ["string", "null"]},
{"name": "campaign", "type": ["string", "null"]},
{"name": "channel", "type": "string"},
{"name": "referrer", "type": ["string", "null"], "default": "None"},
{"name": "ip", "type": ["string", "null"]}
]
}

This schema defines a record named ClickRecord in the namespace io.aiven.avro.example. The record has the fields session_id, browser, campaign, channel, referrer, and ip.

Generate Java classes and add dependencies​

Generate Java classes from your schema, then add the required dependencies to your pom.xml:

Configure producer and consumer properties​

For complete example code, see the Aiven examples GitHub repository.

Producer configuration​

props.put(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, BOOTSTRAPSERVERS);
props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "SSL");
props.put(SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG, TRUSTSTORE);
props.put(SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG, TRUSTSTOREPASSWORD);
props.put(SslConfigs.SSL_KEYSTORE_TYPE_CONFIG, "PKCS12");
props.put(SslConfigs.SSL_KEYSTORE_LOCATION_CONFIG, KEYSTORE);
props.put(SslConfigs.SSL_KEYSTORE_PASSWORD_CONFIG, KEYSTOREPASSWORD);
props.put(SslConfigs.SSL_KEY_PASSWORD_CONFIG, SSLKEYPASSWORD);
props.put("schema.registry.url", SCHEMAREGISTRYURL);
props.put("basic.auth.credentials.source", "USER_INFO");
props.put("basic.auth.user.info", SCHEMAREGISTRYUSER + ":" + SCHEMAREGISTRYPASSWORD);
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, KafkaAvroSerializer.class.getName());

Consumer configuration​

props.put(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, BOOTSTRAPSERVERS);
props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "SSL");
props.put(SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG, TRUSTSTORE);
props.put(SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG, TRUSTSTOREPASSWORD);
props.put(SslConfigs.SSL_KEYSTORE_TYPE_CONFIG, "PKCS12");
props.put(SslConfigs.SSL_KEYSTORE_LOCATION_CONFIG, KEYSTORE);
props.put(SslConfigs.SSL_KEYSTORE_PASSWORD_CONFIG, KEYSTOREPASSWORD);
props.put(SslConfigs.SSL_KEY_PASSWORD_CONFIG, SSLKEYPASSWORD);
props.put("schema.registry.url", SCHEMAREGISTRYURL);
props.put("basic.auth.credentials.source", "USER_INFO");
props.put("basic.auth.user.info", SCHEMAREGISTRYUSER + ":" + SCHEMAREGISTRYPASSWORD);
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, KafkaAvroDeserializer.class.getName());
props.put(KafkaAvroDeserializerConfig.SPECIFIC_AVRO_READER_CONFIG, true);
props.put(ConsumerConfig.GROUP_ID_CONFIG, "clickrecord-example-group");

Replace the placeholders with the values from the variables section.

Related pages