UNPKG

@confluentinc/schemaregistry

Version:
396 lines (395 loc) 13.4 kB
"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 json_1 = require("../serde/json"); 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], }, }); //Inspired by dotnet client const schemaString = (0, json_stringify_deterministic_1.default)({ "$schema": "http://json-schema.org/draft-04/schema#", "title": "Person", "type": "object", "additionalProperties": false, "required": [ "FirstName", "LastName" ], "properties": { "FirstName": { "type": "string" }, "MiddleName": { "type": [ "null", "string" ] }, "LastName": { "type": "string" }, "Gender": { "oneOf": [ { "$ref": "#/definitions/Gender" } ] }, "NumberWithRange": { "type": "integer", "format": "int32", "maximum": 5.0, "minimum": 2.0 }, "Birthday": { "type": "string", "format": "date-time" }, "Company": { "oneOf": [ { "$ref": "#/definitions/Company" }, { "type": "null" } ] }, "Cars": { "type": [ "array", "null" ], "items": { "$ref": "#/definitions/Car" } } }, "definitions": { "Gender": { "type": "integer", "description": "", "x-enumNames": [ "Male", "Female" ], "enum": [ 0, 1 ] }, "Company": { "type": "object", "additionalProperties": false, "properties": { "Name": { "type": [ "null", "string" ] } } }, "Car": { "type": "object", "additionalProperties": false, "properties": { "Name": { "type": [ "null", "string" ] }, "Manufacturer": { "oneOf": [ { "$ref": "#/definitions/Company" }, { "type": "null" } ] } } } } }); const orderDetailsSchema = { schema: (0, json_stringify_deterministic_1.default)({ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "http://example.com/order_details.schema.json", "title": "OrderDetails", "description": "Order Details", "type": "object", "properties": { "id": { "description": "Order Id", "type": "integer" }, "customer": { "description": "Customer", "$ref": "http://example.com/customer.schema.json" }, "payment_id": { "description": "Payment Id", "type": "string" } }, "required": ["id", "customer"] }), schemaType: 'JSON', }; const orderSchema = { schema: (0, json_stringify_deterministic_1.default)({ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "http://example.com/referencedproduct.schema.json", "title": "Order", "description": "Order", "type": "object", "properties": { "order_details": { "description": "Order Details", "$ref": "http://example.com/order_details.schema.json" }, "order_date": { "description": "Order Date", "type": "string", "format": "date-time" } }, "required": ["order_details"] }), schemaType: 'JSON', }; const customerSchema = { schema: (0, json_stringify_deterministic_1.default)({ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "http://example.com/customer.schema.json", "title": "Customer", "description": "Customer Data", "type": "object", "properties": { "name": { "Description": "Customer name", "type": "string" }, "id": { "description": "Customer id", "type": "integer" }, "email": { "description": "Customer email", "type": "string" } }, "required": ["name", "id"] }), schemaType: 'JSON', }; const messageValue = { "firstName": "Real", "middleName": "Name", "lastName": "LastName D. Roger", "gender": "Male", "numberWithRange": 3, "birthday": 7671, "company": { "name": "WarpStream" }, "cars": [ { "name": "Flink", "manufacturer": { "name": "Immerok" } }, { "name": "Car", "manufacturer": { "name": "Car Maker" } } ] }; const metadata = { properties: { owner: 'Bob Jones', email: 'bob@acme.com', }, }; const schemaInfo = { schema: schemaString, metadata: metadata, schemaType: 'JSON' }; (0, globals_1.describe)('SchemaRegistryClient json 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 json", async () => { const testTopic = (0, uuid_1.v4)(); await schemaRegistryClient.register(testTopic + "-value", schemaInfo); serializerConfig = { useLatestVersion: true }; serializer = new json_1.JsonSerializer(schemaRegistryClient, serde_1.SerdeType.VALUE, serializerConfig); deserializer = new json_1.JsonDeserializer(schemaRegistryClient, serde_1.SerdeType.VALUE, {}); const outgoingMessage = { key: 'key', value: await serializer.serialize(testTopic, messageValue) }; await producer.send({ topic: testTopic, messages: [outgoingMessage] }); consumer = kafka.consumer({ kafkaJS: { groupId: 'test-group', fromBeginning: true, partitionAssigners: [kafka_javascript_1.KafkaJS.PartitionAssigners.roundRobin], }, }); 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 serialize with autoRegisterSchemas enabled and useLatestVersion disabled", async () => { const testTopic = (0, uuid_1.v4)(); serializerConfig = { autoRegisterSchemas: true, useLatestVersion: false }; serializer = new json_1.JsonSerializer(schemaRegistryClient, serde_1.SerdeType.VALUE, serializerConfig); const outgoingMessage = { key: 'key', value: await serializer.serialize(testTopic, messageValue) }; await producer.send({ topic: testTopic, messages: [outgoingMessage] }); }); (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 json_1.JsonSerializer(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 referenced schemas", async () => { const testTopic = (0, uuid_1.v4)(); serializerConfig = { useLatestVersion: true }; serializer = new json_1.JsonSerializer(schemaRegistryClient, serde_1.SerdeType.VALUE, serializerConfig); deserializer = new json_1.JsonDeserializer(schemaRegistryClient, serde_1.SerdeType.VALUE, {}); const customerSubject = (0, uuid_1.v4)(); const orderDetailsSubject = (0, uuid_1.v4)(); await schemaRegistryClient.register(customerSubject, customerSchema); const customerIdVersion = (await schemaRegistryClient.getLatestSchemaMetadata(customerSubject)).version; const customerReference = { name: "http://example.com/customer.schema.json", subject: customerSubject, version: customerIdVersion, }; orderDetailsSchema.references = [customerReference]; await schemaRegistryClient.register(orderDetailsSubject, orderDetailsSchema); const orderDetailsIdVersion = (await schemaRegistryClient.getLatestSchemaMetadata(orderDetailsSubject)).version; const orderDetailsReference = { name: "http://example.com/order_details.schema.json", subject: orderDetailsSubject, version: orderDetailsIdVersion, }; orderSchema.references = [orderDetailsReference]; await schemaRegistryClient.register(testTopic + "-value", orderSchema); const order = { order_details: { id: 1, customer: { name: "Bob Jones", id: 1, email: "bob@jones.com" }, payment_id: "1234" }, order_date: "2021-07-15T12:00:00Z" }; const outgoingMessage = { key: 'key', value: await serializer.serialize(testTopic, order) }; await producer.send({ topic: testTopic, messages: [outgoingMessage] }); consumer = kafka.consumer({ kafkaJS: { groupId: 'test-group', fromBeginning: true, partitionAssigners: [kafka_javascript_1.KafkaJS.PartitionAssigners.roundRobin], }, }); 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(order); }, }); // Wait around until we get a message, and then disconnect. while (!messageRcvd) { await new Promise((resolve) => setTimeout(resolve, 100)); } await consumer.disconnect(); }, 30000); });