@confluentinc/schemaregistry
Version:
Node.js client for Confluent Schema Registry
464 lines (463 loc) • 18.5 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const kafka_javascript_1 = require("@confluentinc/kafka-javascript");
const schemaregistry_client_1 = require("../schemaregistry-client");
const globals_1 = require("@jest/globals");
const test_constants_1 = require("../test/test-constants");
const avro_1 = require("../serde/avro");
const serde_1 = require("../serde/serde");
const json_stringify_deterministic_1 = __importDefault(require("json-stringify-deterministic"));
const uuid_1 = require("uuid");
let schemaRegistryClient;
let serializerConfig;
let serializer;
let deserializer;
let producer;
let consumer;
const kafkaBrokerList = 'localhost:9092';
const kafka = new kafka_javascript_1.KafkaJS.Kafka({
kafkaJS: {
brokers: [kafkaBrokerList],
},
});
const userSchemaString = (0, json_stringify_deterministic_1.default)({
type: 'record',
name: 'User',
fields: [
{ name: 'name', type: 'string' },
{ name: 'age', type: 'int' },
],
});
const messageValue = {
"name": "Bob Jones",
"age": 25
};
const metadata = {
properties: {
owner: 'Bob Jones',
email: 'bob@acme.com',
},
};
const schemaInfo = {
schema: userSchemaString,
metadata: metadata
};
(0, globals_1.describe)('Schema Registry Avro Integration Test', () => {
(0, globals_1.beforeEach)(async () => {
schemaRegistryClient = new schemaregistry_client_1.SchemaRegistryClient(test_constants_1.clientConfig);
producer = kafka.producer({
kafkaJS: {
allowAutoTopicCreation: true,
acks: 1,
compression: kafka_javascript_1.KafkaJS.CompressionTypes.GZIP,
}
});
await producer.connect();
consumer = kafka.consumer({
kafkaJS: {
groupId: 'test-group',
fromBeginning: true,
partitionAssigners: [kafka_javascript_1.KafkaJS.PartitionAssigners.roundRobin],
},
});
});
(0, globals_1.afterEach)(async () => {
await producer.disconnect();
});
(0, globals_1.it)("Should serialize and deserialize Avro", async () => {
const testTopic = (0, uuid_1.v4)();
await schemaRegistryClient.register(testTopic + "-value", schemaInfo);
serializerConfig = { useLatestVersion: true };
serializer = new avro_1.AvroSerializer(schemaRegistryClient, serde_1.SerdeType.VALUE, serializerConfig);
deserializer = new avro_1.AvroDeserializer(schemaRegistryClient, serde_1.SerdeType.VALUE, {});
const outgoingMessage = {
key: 'key',
value: await serializer.serialize(testTopic, messageValue)
};
await producer.send({
topic: testTopic,
messages: [outgoingMessage]
});
await consumer.connect();
await consumer.subscribe({ topic: testTopic });
let messageRcvd = false;
await consumer.run({
eachMessage: async ({ message }) => {
const decodedMessage = {
...message,
value: await deserializer.deserialize(testTopic, message.value)
};
messageRcvd = true;
(0, globals_1.expect)(decodedMessage.value).toMatchObject(messageValue);
},
});
// Wait around until we get a message, and then disconnect.
while (!messageRcvd) {
await new Promise((resolve) => setTimeout(resolve, 100));
}
await consumer.disconnect();
}, 30000);
(0, globals_1.it)('Should fail to serialize with useLatestVersion enabled and autoRegisterSchemas disabled', async () => {
const testTopic = (0, uuid_1.v4)();
serializerConfig = { autoRegisterSchemas: false, useLatestVersion: true };
serializer = new avro_1.AvroSerializer(schemaRegistryClient, serde_1.SerdeType.VALUE, serializerConfig);
const messageValue = { "name": "Bob Jones", "age": 25 };
await (0, globals_1.expect)(serializer.serialize(testTopic, messageValue)).rejects.toThrowError();
});
(0, globals_1.it)('Should serialize with autoRegisterSchemas enabled and useLatestVersion disabled', async () => {
const testTopic = (0, uuid_1.v4)();
await schemaRegistryClient.register(testTopic + ' -value', schemaInfo);
serializerConfig = { autoRegisterSchemas: true, useLatestVersion: false };
serializer = new avro_1.AvroSerializer(schemaRegistryClient, serde_1.SerdeType.VALUE, serializerConfig);
const messageValue = { "name": "Bob Jones", "age": 25 };
await serializer.serialize(testTopic, messageValue);
});
//TODO: Add test for Incompatible Types. The current Kafka Client runs console.error instead of throwing error
//Should use a spy, Jest wasn't playing nice with the spy
(0, globals_1.it)('Should produce generic message to multiple topics', async () => {
const topic1 = (0, uuid_1.v4)();
const topic2 = (0, uuid_1.v4)();
await schemaRegistryClient.register(topic1, schemaInfo);
await schemaRegistryClient.register(topic2, schemaInfo);
serializerConfig = { autoRegisterSchemas: true };
serializer = new avro_1.AvroSerializer(schemaRegistryClient, serde_1.SerdeType.VALUE, serializerConfig);
deserializer = new avro_1.AvroDeserializer(schemaRegistryClient, serde_1.SerdeType.VALUE, {});
const outgoingMessage1 = {
key: 'key',
value: await serializer.serialize(topic1, messageValue)
};
const outgoingMessage2 = {
key: 'key',
value: await serializer.serialize(topic2, messageValue)
};
await producer.send({ topic: topic1, messages: [outgoingMessage1] });
await producer.send({ topic: topic2, messages: [outgoingMessage2] });
let consumer2 = kafka.consumer({
kafkaJS: {
groupId: 'test-group',
fromBeginning: true,
partitionAssigners: [kafka_javascript_1.KafkaJS.PartitionAssigners.roundRobin],
},
});
await consumer.connect();
await consumer.subscribe({ topic: topic1 });
await consumer2.connect();
await consumer2.subscribe({ topic: topic2 });
let messageRcvd = false;
let messageRcvd2 = false;
await consumer.run({
eachMessage: async ({ message }) => {
const decodedMessage = {
...message,
value: await deserializer.deserialize(topic1, message.value)
};
messageRcvd = true;
(0, globals_1.expect)(decodedMessage.value).toMatchObject(messageValue);
},
});
await consumer2.run({
eachMessage: async ({ message }) => {
const decodedMessage = {
...message,
value: await deserializer.deserialize(topic2, message.value)
};
messageRcvd2 = true;
(0, globals_1.expect)(decodedMessage.value).toMatchObject(messageValue);
},
});
while (!messageRcvd || !messageRcvd2) {
await new Promise((resolve) => setTimeout(resolve, 100));
}
await consumer.disconnect();
await consumer2.disconnect();
}, 30000);
});
(0, globals_1.describe)('Schema Registry Avro Integration Test - Primitives', () => {
(0, globals_1.beforeEach)(async () => {
schemaRegistryClient = new schemaregistry_client_1.SchemaRegistryClient(test_constants_1.clientConfig);
producer = kafka.producer({
kafkaJS: {
allowAutoTopicCreation: true,
acks: 1,
compression: kafka_javascript_1.KafkaJS.CompressionTypes.GZIP,
}
});
await producer.connect();
serializerConfig = { useLatestVersion: true };
serializer = new avro_1.AvroSerializer(schemaRegistryClient, serde_1.SerdeType.VALUE, serializerConfig);
deserializer = new avro_1.AvroDeserializer(schemaRegistryClient, serde_1.SerdeType.VALUE, {});
consumer = kafka.consumer({
kafkaJS: {
groupId: 'test-group',
fromBeginning: true,
partitionAssigners: [kafka_javascript_1.KafkaJS.PartitionAssigners.roundRobin],
},
});
});
(0, globals_1.afterEach)(async () => {
await producer.disconnect();
});
(0, globals_1.it)('Should serialize and deserialize string', async () => {
const stringTopic = (0, uuid_1.v4)();
const stringSchemaString = (0, json_stringify_deterministic_1.default)({
type: 'string',
});
const stringSchemaInfo = {
schema: stringSchemaString,
metadata: metadata
};
await schemaRegistryClient.register(stringTopic + "-value", stringSchemaInfo);
const stringMessageValue = "Hello, World!";
const outgoingStringMessage = {
key: 'key',
value: await serializer.serialize(stringTopic, stringMessageValue)
};
await producer.send({
topic: stringTopic,
messages: [outgoingStringMessage]
});
await consumer.connect();
await consumer.subscribe({ topic: stringTopic });
let messageRcvd = false;
await consumer.run({
eachMessage: async ({ message }) => {
const decodedMessage = {
...message,
value: await deserializer.deserialize(stringTopic, message.value)
};
messageRcvd = true;
(0, globals_1.expect)(decodedMessage.value).toBe(stringMessageValue);
},
});
while (!messageRcvd) {
await new Promise((resolve) => setTimeout(resolve, 100));
}
await consumer.disconnect();
}, 30000);
(0, globals_1.it)('Should serialize and deserialize bytes', async () => {
const topic = (0, uuid_1.v4)();
const schemaString = (0, json_stringify_deterministic_1.default)({
type: 'bytes',
});
const stringSchemaInfo = {
schema: schemaString,
metadata: metadata
};
await schemaRegistryClient.register(topic + "-value", stringSchemaInfo);
const messageValue = Buffer.from("Hello, World!");
const outgoingMessage = {
key: 'key',
value: await serializer.serialize(topic, messageValue)
};
await producer.send({
topic: topic,
messages: [outgoingMessage]
});
await consumer.connect();
await consumer.subscribe({ topic });
let messageRcvd = false;
await consumer.run({
eachMessage: async ({ message }) => {
const decodedMessage = {
...message,
value: await deserializer.deserialize(topic, message.value)
};
messageRcvd = true;
(0, globals_1.expect)(decodedMessage.value).toBe(messageValue);
},
});
while (!messageRcvd) {
await new Promise((resolve) => setTimeout(resolve, 100));
}
await consumer.disconnect();
}, 30000);
(0, globals_1.it)('Should serialize and deserialize int', async () => {
const topic = (0, uuid_1.v4)();
const schemaString = (0, json_stringify_deterministic_1.default)({
type: 'int',
});
const stringSchemaInfo = {
schema: schemaString,
metadata: metadata
};
await schemaRegistryClient.register(topic + "-value", stringSchemaInfo);
const messageValue = 25;
const outgoingMessage = {
key: 'key',
value: await serializer.serialize(topic, messageValue)
};
await producer.send({
topic: topic,
messages: [outgoingMessage]
});
await consumer.connect();
await consumer.subscribe({ topic });
let messageRcvd = false;
await consumer.run({
eachMessage: async ({ message }) => {
const decodedMessage = {
...message,
value: await deserializer.deserialize(topic, message.value)
};
messageRcvd = true;
(0, globals_1.expect)(decodedMessage.value).toBe(messageValue);
},
});
while (!messageRcvd) {
await new Promise((resolve) => setTimeout(resolve, 100));
}
await consumer.disconnect();
}, 30000);
(0, globals_1.it)('Should serialize and deserialize long', async () => {
const topic = (0, uuid_1.v4)();
const schemaString = (0, json_stringify_deterministic_1.default)({
type: 'long',
});
const stringSchemaInfo = {
schema: schemaString,
metadata: metadata
};
await schemaRegistryClient.register(topic + "-value", stringSchemaInfo);
const messageValue = 25;
const outgoingMessage = {
key: 'key',
value: await serializer.serialize(topic, messageValue)
};
await producer.send({
topic: topic,
messages: [outgoingMessage]
});
await consumer.connect();
await consumer.subscribe({ topic });
let messageRcvd = false;
await consumer.run({
eachMessage: async ({ message }) => {
const decodedMessage = {
...message,
value: await deserializer.deserialize(topic, message.value)
};
messageRcvd = true;
(0, globals_1.expect)(decodedMessage.value).toBe(messageValue);
},
});
while (!messageRcvd) {
await new Promise((resolve) => setTimeout(resolve, 100));
}
await consumer.disconnect();
}, 30000);
(0, globals_1.it)('Should serialize and deserialize boolean', async () => {
const topic = (0, uuid_1.v4)();
const schemaString = (0, json_stringify_deterministic_1.default)({
type: 'boolean',
});
const stringSchemaInfo = {
schema: schemaString,
metadata: metadata
};
await schemaRegistryClient.register(topic + "-value", stringSchemaInfo);
const messageValue = true;
const outgoingMessage = {
key: 'key',
value: await serializer.serialize(topic, messageValue)
};
await producer.send({
topic: topic,
messages: [outgoingMessage]
});
await consumer.connect();
await consumer.subscribe({ topic });
let messageRcvd = false;
await consumer.run({
eachMessage: async ({ message }) => {
const decodedMessage = {
...message,
value: await deserializer.deserialize(topic, message.value)
};
messageRcvd = true;
(0, globals_1.expect)(decodedMessage.value).toBe(messageValue);
},
});
while (!messageRcvd) {
await new Promise((resolve) => setTimeout(resolve, 100));
}
await consumer.disconnect();
}, 30000);
(0, globals_1.it)('Should serialize and deserialize float', async () => {
const topic = (0, uuid_1.v4)();
const schemaString = (0, json_stringify_deterministic_1.default)({
type: 'float',
});
const stringSchemaInfo = {
schema: schemaString,
metadata: metadata
};
await schemaRegistryClient.register(topic + "-value", stringSchemaInfo);
const messageValue = 1.354;
const outgoingMessage = {
key: 'key',
value: await serializer.serialize(topic, messageValue)
};
await producer.send({
topic: topic,
messages: [outgoingMessage]
});
await consumer.connect();
await consumer.subscribe({ topic });
let messageRcvd = false;
await consumer.run({
eachMessage: async ({ message }) => {
const decodedMessage = {
...message,
value: await deserializer.deserialize(topic, message.value)
};
messageRcvd = true;
(0, globals_1.expect)(decodedMessage.value).toBe(messageValue);
},
});
while (!messageRcvd) {
await new Promise((resolve) => setTimeout(resolve, 100));
}
await consumer.disconnect();
}, 30000);
(0, globals_1.it)('Should serialize and deserialize double', async () => {
const topic = (0, uuid_1.v4)();
const schemaString = (0, json_stringify_deterministic_1.default)({
type: 'double',
});
const stringSchemaInfo = {
schema: schemaString,
metadata: metadata
};
await schemaRegistryClient.register(topic + "-value", stringSchemaInfo);
const messageValue = 1.354;
const outgoingMessage = {
key: 'key',
value: await serializer.serialize(topic, messageValue)
};
await producer.send({
topic: topic,
messages: [outgoingMessage]
});
await consumer.connect();
await consumer.subscribe({ topic });
let messageRcvd = false;
await consumer.run({
eachMessage: async ({ message }) => {
const decodedMessage = {
...message,
value: await deserializer.deserialize(topic, message.value)
};
messageRcvd = true;
(0, globals_1.expect)(decodedMessage.value).toBe(messageValue);
},
});
while (!messageRcvd) {
await new Promise((resolve) => setTimeout(resolve, 100));
}
await consumer.disconnect();
}, 30000);
//Waiting on the null case
});