UNPKG

@confluentinc/schemaregistry

Version:
938 lines (937 loc) 32.8 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const globals_1 = require("@jest/globals"); const serde_1 = require("../../serde/serde"); const schemaregistry_client_1 = require("../../schemaregistry-client"); const local_driver_1 = require("../../rules/encryption/localkms/local-driver"); const encrypt_executor_1 = require("../../rules/encryption/encrypt-executor"); const json_1 = require("../../serde/json"); const rule_registry_1 = require("@confluentinc/schemaregistry/serde/rule-registry"); const json_stringify_deterministic_1 = __importDefault(require("json-stringify-deterministic")); const jsonata_executor_1 = require("@confluentinc/schemaregistry/rules/jsonata/jsonata-executor"); const kms_registry_1 = require("@confluentinc/schemaregistry/rules/encryption/kms-registry"); const fieldEncryptionExecutor = encrypt_executor_1.FieldEncryptionExecutor.register(); jsonata_executor_1.JsonataExecutor.register(); local_driver_1.LocalKmsDriver.register(); //const baseURL = 'http://localhost:8081' const baseURL = 'mock://'; const topic = 'topic1'; const subject = topic + '-value'; const rootSchema = ` { "type": "object", "properties": { "otherField": { "$ref": "DemoSchema" } } } `; const rootSchema2020_12 = ` { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "otherField": { "$ref": "DemoSchema" } } } `; const demoSchema = ` { "type": "object", "properties": { "intField": { "type": "integer" }, "doubleField": { "type": "number" }, "stringField": { "type": "string", "confluent:tags": [ "PII" ] }, "boolField": { "type": "boolean" }, "bytesField": { "type": "string", "contentEncoding": "base64", "confluent:tags": [ "PII" ] } } } `; const demoSchemaWithUnion = ` { "type": "object", "properties": { "intField": { "type": "integer" }, "doubleField": { "type": "number" }, "stringField": { "oneOf": [ { "type": "null" }, { "type": "string" } ], "confluent:tags": [ "PII" ] }, "boolField": { "type": "boolean" }, "bytesField": { "type": "string", "contentEncoding": "base64", "confluent:tags": [ "PII" ] } } } `; const demoSchema2020_12 = ` { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "intField": { "type": "integer" }, "doubleField": { "type": "number" }, "stringField": { "type": "string", "confluent:tags": [ "PII" ] }, "boolField": { "type": "boolean" }, "bytesField": { "type": "string", "contentEncoding": "base64", "confluent:tags": [ "PII" ] } } } `; const complexSchema = ` { "type": "object", "properties": { "arrayField": { "type": "array", "items": { "type": "string" }, "confluent:tags": [ "PII" ] }, "objectField": { "type": "object", "properties": { "stringField": { "type": "string" } }, "confluent:tags": [ "PII" ] }, "unionField": { "oneOf": [ { "type": "null" }, { "type": "string" } ], "confluent:tags": [ "PII" ] } } } `; const defSchema = ` { "$schema" : "http://json-schema.org/draft-07/schema#", "additionalProperties" : false, "definitions" : { "Address" : { "additionalProperties" : false, "properties" : { "doornumber" : { "type" : "integer" }, "doorpin" : { "confluent:tags" : [ "PII" ], "type" : "string" } }, "type" : "object" } }, "properties" : { "address" : { "$ref" : "#/definitions/Address" }, "name" : { "confluent:tags" : [ "PII" ], "type" : "string" } }, "title" : "Sample Event", "type" : "object" } `; (0, globals_1.describe)('JsonSerializer', () => { (0, globals_1.afterEach)(async () => { let conf = { baseURLs: [baseURL], cacheCapacity: 1000 }; let client = schemaregistry_client_1.SchemaRegistryClient.newClient(conf); await client.deleteSubject(subject, false); await client.deleteSubject(subject, true); }); (0, globals_1.it)('basic serialization', async () => { let conf = { baseURLs: [baseURL], cacheCapacity: 1000 }; let client = schemaregistry_client_1.SchemaRegistryClient.newClient(conf); let ser = new json_1.JsonSerializer(client, serde_1.SerdeType.VALUE, { autoRegisterSchemas: true, validate: true }); let obj = { intField: 123, doubleField: 45.67, stringField: 'hi', boolField: true, bytesField: Buffer.from([0, 0, 0, 1]).toString('base64') }; let bytes = await ser.serialize(topic, obj); let deser = new json_1.JsonDeserializer(client, serde_1.SerdeType.VALUE, {}); let obj2 = await deser.deserialize(topic, bytes); (0, globals_1.expect)(obj2).toEqual(obj); }); (0, globals_1.it)('basic serialization 2020-12', async () => { let conf = { baseURLs: [baseURL], cacheCapacity: 1000 }; let client = schemaregistry_client_1.SchemaRegistryClient.newClient(conf); let ser = new json_1.JsonSerializer(client, serde_1.SerdeType.VALUE, { useLatestVersion: true, validate: true }); let obj = { intField: 123, doubleField: 45.67, stringField: 'hi', boolField: true, bytesField: Buffer.from([0, 0, 0, 1]).toString('base64') }; let info = { schemaType: 'JSON', schema: demoSchema2020_12 }; await client.register(subject, info, false); let bytes = await ser.serialize(topic, obj); let deser = new json_1.JsonDeserializer(client, serde_1.SerdeType.VALUE, {}); let obj2 = await deser.deserialize(topic, bytes); (0, globals_1.expect)(obj2).toEqual(obj); }); (0, globals_1.it)('serialize nested', async () => { let conf = { baseURLs: [baseURL], cacheCapacity: 1000 }; let client = schemaregistry_client_1.SchemaRegistryClient.newClient(conf); let ser = new json_1.JsonSerializer(client, serde_1.SerdeType.VALUE, { autoRegisterSchemas: true, validate: true }); let nested = { intField: 123, doubleField: 45.67, stringField: 'hi', boolField: true, bytesField: Buffer.from([0, 0, 0, 1]).toString('base64') }; let obj = { otherField: nested }; let bytes = await ser.serialize(topic, obj); let deser = new json_1.JsonDeserializer(client, serde_1.SerdeType.VALUE, {}); let obj2 = await deser.deserialize(topic, bytes); (0, globals_1.expect)(obj2).toEqual(obj); }); (0, globals_1.it)('serialize reference', async () => { let conf = { baseURLs: [baseURL], cacheCapacity: 1000 }; let client = schemaregistry_client_1.SchemaRegistryClient.newClient(conf); let ser = new json_1.JsonSerializer(client, serde_1.SerdeType.VALUE, { useLatestVersion: true, validate: true }); let info = { schemaType: 'JSON', schema: demoSchema }; await client.register('demo-value', info, false); info = { schemaType: 'JSON', schema: rootSchema, references: [{ name: 'DemoSchema', subject: 'demo-value', version: 1 }] }; await client.register(subject, info, false); let obj = { intField: 123, doubleField: 45.67, stringField: 'hi', boolField: true, bytesField: Buffer.from([0, 0, 0, 1]).toString('base64') }; let bytes = await ser.serialize(topic, obj); let deser = new json_1.JsonDeserializer(client, serde_1.SerdeType.VALUE, {}); let obj2 = await deser.deserialize(topic, bytes); (0, globals_1.expect)(obj2).toEqual(obj); }); (0, globals_1.it)('serialize reference 2020_12', async () => { let conf = { baseURLs: [baseURL], cacheCapacity: 1000 }; let client = schemaregistry_client_1.SchemaRegistryClient.newClient(conf); let ser = new json_1.JsonSerializer(client, serde_1.SerdeType.VALUE, { useLatestVersion: true, validate: true }); let info = { schemaType: 'JSON', schema: demoSchema2020_12 }; await client.register('demo-value', info, false); info = { schemaType: 'JSON', schema: rootSchema2020_12, references: [{ name: 'DemoSchema', subject: 'demo-value', version: 1 }] }; await client.register(subject, info, false); let obj = { intField: 123, doubleField: 45.67, stringField: 'hi', boolField: true, bytesField: Buffer.from([0, 0, 0, 1]).toString('base64') }; let bytes = await ser.serialize(topic, obj); let deser = new json_1.JsonDeserializer(client, serde_1.SerdeType.VALUE, {}); let obj2 = await deser.deserialize(topic, bytes); (0, globals_1.expect)(obj2).toEqual(obj); }); (0, globals_1.it)('basic failing validation', async () => { let conf = { baseURLs: [baseURL], cacheCapacity: 1000 }; let client = schemaregistry_client_1.SchemaRegistryClient.newClient(conf); let ser = new json_1.JsonSerializer(client, serde_1.SerdeType.VALUE, { useLatestVersion: true, validate: true }); let obj = { intField: 123, doubleField: 45.67, stringField: 'hi', boolField: true, bytesField: Buffer.from([0, 0, 0, 1]).toString('base64') }; let jsonSchema = json_1.JsonSerializer.messageToSchema(obj); let info = { schemaType: 'JSON', schema: JSON.stringify(jsonSchema) }; await client.register(subject, info, false); let bytes = await ser.serialize(topic, obj); let deser = new json_1.JsonDeserializer(client, serde_1.SerdeType.VALUE, {}); let obj2 = await deser.deserialize(topic, bytes); (0, globals_1.expect)(obj2).toEqual(obj); let diffObj = { intField: '123', doubleField: 45.67, stringField: 'hi', boolField: true, bytesField: Buffer.from([0, 0, 0, 1]).toString('base64') }; await (0, globals_1.expect)(() => ser.serialize(topic, diffObj)).rejects.toThrow(serde_1.SerializationError); }); (0, globals_1.it)('basic encryption', async () => { let conf = { baseURLs: [baseURL], cacheCapacity: 1000 }; let client = schemaregistry_client_1.SchemaRegistryClient.newClient(conf); let serConfig = { useLatestVersion: true, ruleConfig: { secret: 'mysecret' } }; let ser = new json_1.JsonSerializer(client, serde_1.SerdeType.VALUE, serConfig); let dekClient = fieldEncryptionExecutor.client; let encRule = { name: 'test-encrypt', kind: 'TRANSFORM', mode: schemaregistry_client_1.RuleMode.WRITEREAD, type: 'ENCRYPT', tags: ['PII'], params: { 'encrypt.kek.name': 'kek1', 'encrypt.kms.type': 'local-kms', 'encrypt.kms.key.id': 'mykey', }, onFailure: 'ERROR,NONE' }; let ruleSet = { domainRules: [encRule] }; let info = { schemaType: 'JSON', schema: demoSchema, ruleSet }; await client.register(subject, info, false); let obj = { intField: 123, doubleField: 45.67, stringField: 'hi', boolField: true, bytesField: Buffer.from([0, 0, 0, 1]).toString('base64') }; let bytes = await ser.serialize(topic, obj); // reset encrypted field obj.stringField = 'hi'; obj.bytesField = Buffer.from([0, 0, 0, 1]).toString('base64'); let deserConfig = { ruleConfig: { secret: 'mysecret' } }; let deser = new json_1.JsonDeserializer(client, serde_1.SerdeType.VALUE, deserConfig); fieldEncryptionExecutor.client = dekClient; let obj2 = await deser.deserialize(topic, bytes); (0, globals_1.expect)(obj2).toEqual(obj); (0, kms_registry_1.clearKmsClients)(); let registry = new rule_registry_1.RuleRegistry(); registry.registerExecutor(new encrypt_executor_1.FieldEncryptionExecutor()); deser = new json_1.JsonDeserializer(client, serde_1.SerdeType.VALUE, {}, registry); obj2 = await deser.deserialize(topic, bytes); (0, globals_1.expect)(obj2).not.toEqual(obj); }); (0, globals_1.it)('basic encryption 2020-12', async () => { let conf = { baseURLs: [baseURL], cacheCapacity: 1000 }; let client = schemaregistry_client_1.SchemaRegistryClient.newClient(conf); let serConfig = { useLatestVersion: true, ruleConfig: { secret: 'mysecret' } }; let ser = new json_1.JsonSerializer(client, serde_1.SerdeType.VALUE, serConfig); let dekClient = fieldEncryptionExecutor.client; let encRule = { name: 'test-encrypt', kind: 'TRANSFORM', mode: schemaregistry_client_1.RuleMode.WRITEREAD, type: 'ENCRYPT', tags: ['PII'], params: { 'encrypt.kek.name': 'kek1', 'encrypt.kms.type': 'local-kms', 'encrypt.kms.key.id': 'mykey', }, onFailure: 'ERROR,NONE' }; let ruleSet = { domainRules: [encRule] }; let info = { schemaType: 'JSON', schema: demoSchema2020_12, ruleSet }; await client.register(subject, info, false); let obj = { intField: 123, doubleField: 45.67, stringField: 'hi', boolField: true, bytesField: Buffer.from([0, 0, 0, 1]).toString('base64') }; let bytes = await ser.serialize(topic, obj); // reset encrypted field obj.stringField = 'hi'; obj.bytesField = Buffer.from([0, 0, 0, 1]).toString('base64'); let deserConfig = { ruleConfig: { secret: 'mysecret' } }; let deser = new json_1.JsonDeserializer(client, serde_1.SerdeType.VALUE, deserConfig); fieldEncryptionExecutor.client = dekClient; let obj2 = await deser.deserialize(topic, bytes); (0, globals_1.expect)(obj2).toEqual(obj); (0, kms_registry_1.clearKmsClients)(); let registry = new rule_registry_1.RuleRegistry(); registry.registerExecutor(new encrypt_executor_1.FieldEncryptionExecutor()); deser = new json_1.JsonDeserializer(client, serde_1.SerdeType.VALUE, {}, registry); obj2 = await deser.deserialize(topic, bytes); (0, globals_1.expect)(obj2).not.toEqual(obj); }); (0, globals_1.it)('encryption with def', async () => { let conf = { baseURLs: [baseURL], cacheCapacity: 1000 }; let client = schemaregistry_client_1.SchemaRegistryClient.newClient(conf); let serConfig = { useLatestVersion: true, ruleConfig: { secret: 'mysecret' } }; let ser = new json_1.JsonSerializer(client, serde_1.SerdeType.VALUE, serConfig); let dekClient = fieldEncryptionExecutor.client; let encRule = { name: 'test-encrypt', kind: 'TRANSFORM', mode: schemaregistry_client_1.RuleMode.WRITEREAD, type: 'ENCRYPT', tags: ['PII'], params: { 'encrypt.kek.name': 'kek1', 'encrypt.kms.type': 'local-kms', 'encrypt.kms.key.id': 'mykey', }, onFailure: 'ERROR,NONE' }; let ruleSet = { domainRules: [encRule] }; let info = { schemaType: 'JSON', schema: defSchema, ruleSet }; await client.register(subject, info, false); let addr = { doornumber: 123, doorpin: 'hi' }; let obj = { address: addr, name: 'bob' }; let bytes = await ser.serialize(topic, obj); // reset encrypted field obj.name = 'bob'; obj.address.doorpin = 'hi'; let deserConfig = { ruleConfig: { secret: 'mysecret' } }; let deser = new json_1.JsonDeserializer(client, serde_1.SerdeType.VALUE, deserConfig); fieldEncryptionExecutor.client = dekClient; let obj2 = await deser.deserialize(topic, bytes); (0, globals_1.expect)(obj2).toEqual(obj); (0, kms_registry_1.clearKmsClients)(); let registry = new rule_registry_1.RuleRegistry(); registry.registerExecutor(new encrypt_executor_1.FieldEncryptionExecutor()); deser = new json_1.JsonDeserializer(client, serde_1.SerdeType.VALUE, {}, registry); obj2 = await deser.deserialize(topic, bytes); (0, globals_1.expect)(obj2).not.toEqual(obj); }); (0, globals_1.it)('encryption with union', async () => { let conf = { baseURLs: [baseURL], cacheCapacity: 1000 }; let client = schemaregistry_client_1.SchemaRegistryClient.newClient(conf); let serConfig = { useLatestVersion: true, ruleConfig: { secret: 'mysecret' } }; let ser = new json_1.JsonSerializer(client, serde_1.SerdeType.VALUE, serConfig); let dekClient = fieldEncryptionExecutor.client; let encRule = { name: 'test-encrypt', kind: 'TRANSFORM', mode: schemaregistry_client_1.RuleMode.WRITEREAD, type: 'ENCRYPT', tags: ['PII'], params: { 'encrypt.kek.name': 'kek1', 'encrypt.kms.type': 'local-kms', 'encrypt.kms.key.id': 'mykey', }, onFailure: 'ERROR,ERROR' }; let ruleSet = { domainRules: [encRule] }; let info = { schemaType: 'JSON', schema: demoSchemaWithUnion, ruleSet }; await client.register(subject, info, false); let obj = { intField: 123, doubleField: 45.67, stringField: 'hi', boolField: true, bytesField: Buffer.from([0, 0, 0, 1]).toString('base64') }; let bytes = await ser.serialize(topic, obj); // reset encrypted field obj.stringField = 'hi'; obj.bytesField = Buffer.from([0, 0, 0, 1]).toString('base64'); let deserConfig = { ruleConfig: { secret: 'mysecret' } }; let deser = new json_1.JsonDeserializer(client, serde_1.SerdeType.VALUE, deserConfig); fieldEncryptionExecutor.client = dekClient; let obj2 = await deser.deserialize(topic, bytes); (0, globals_1.expect)(obj2).toEqual(obj); }); (0, globals_1.it)('encryption with reference', async () => { let conf = { baseURLs: [baseURL], cacheCapacity: 1000 }; let client = schemaregistry_client_1.SchemaRegistryClient.newClient(conf); let serConfig = { useLatestVersion: true, ruleConfig: { secret: 'mysecret' } }; let ser = new json_1.JsonSerializer(client, serde_1.SerdeType.VALUE, serConfig); let dekClient = fieldEncryptionExecutor.client; let info = { schemaType: 'JSON', schema: demoSchema, }; await client.register('demo-value', info, false); let encRule = { name: 'test-encrypt', kind: 'TRANSFORM', mode: schemaregistry_client_1.RuleMode.WRITEREAD, type: 'ENCRYPT', tags: ['PII'], params: { 'encrypt.kek.name': 'kek1', 'encrypt.kms.type': 'local-kms', 'encrypt.kms.key.id': 'mykey', }, onFailure: 'ERROR,ERROR' }; let ruleSet = { domainRules: [encRule] }; info = { schemaType: 'JSON', schema: rootSchema, references: [{ name: 'DemoSchema', subject: 'demo-value', version: 1 }], ruleSet }; await client.register(subject, info, false); let nested = { intField: 123, doubleField: 45.67, stringField: 'hi', boolField: true, bytesField: Buffer.from([0, 0, 0, 1]).toString('base64') }; let obj = { otherField: nested }; let bytes = await ser.serialize(topic, obj); // reset encrypted field nested.stringField = 'hi'; nested.bytesField = Buffer.from([0, 0, 0, 1]).toString('base64'); let deserConfig = { ruleConfig: { secret: 'mysecret' } }; let deser = new json_1.JsonDeserializer(client, serde_1.SerdeType.VALUE, deserConfig); fieldEncryptionExecutor.client = dekClient; let obj2 = await deser.deserialize(topic, bytes); (0, globals_1.expect)(obj2).toEqual(obj); }); (0, globals_1.it)('complex encryption', async () => { let conf = { baseURLs: [baseURL], cacheCapacity: 1000 }; let client = schemaregistry_client_1.SchemaRegistryClient.newClient(conf); let serConfig = { useLatestVersion: true, ruleConfig: { secret: 'mysecret' } }; let ser = new json_1.JsonSerializer(client, serde_1.SerdeType.VALUE, serConfig); let dekClient = fieldEncryptionExecutor.client; let encRule = { name: 'test-encrypt', kind: 'TRANSFORM', mode: schemaregistry_client_1.RuleMode.WRITEREAD, type: 'ENCRYPT', tags: ['PII'], params: { 'encrypt.kek.name': 'kek1', 'encrypt.kms.type': 'local-kms', 'encrypt.kms.key.id': 'mykey', }, onFailure: 'ERROR,NONE' }; let ruleSet = { domainRules: [encRule] }; let info = { schemaType: 'JSON', schema: complexSchema, ruleSet }; await client.register(subject, info, false); let obj = { arrayField: ['hello'], objectField: { 'stringField': 'world' }, unionField: 'bye', }; let bytes = await ser.serialize(topic, obj); let deserConfig = { ruleConfig: { secret: 'mysecret' } }; let deser = new json_1.JsonDeserializer(client, serde_1.SerdeType.VALUE, deserConfig); fieldEncryptionExecutor.client = dekClient; let obj2 = await deser.deserialize(topic, bytes); (0, globals_1.expect)(obj2.arrayField).toEqual(['hello']); (0, globals_1.expect)(obj2.objectField.stringField).toEqual('world'); (0, globals_1.expect)(obj2.unionField).toEqual('bye'); }); (0, globals_1.it)('complex encryption with null', async () => { let conf = { baseURLs: [baseURL], cacheCapacity: 1000 }; let client = schemaregistry_client_1.SchemaRegistryClient.newClient(conf); let serConfig = { useLatestVersion: true, ruleConfig: { secret: 'mysecret' } }; let ser = new json_1.JsonSerializer(client, serde_1.SerdeType.VALUE, serConfig); let dekClient = fieldEncryptionExecutor.client; let encRule = { name: 'test-encrypt', kind: 'TRANSFORM', mode: schemaregistry_client_1.RuleMode.WRITEREAD, type: 'ENCRYPT', tags: ['PII'], params: { 'encrypt.kek.name': 'kek1', 'encrypt.kms.type': 'local-kms', 'encrypt.kms.key.id': 'mykey', }, onFailure: 'ERROR,NONE' }; let ruleSet = { domainRules: [encRule] }; let info = { schemaType: 'JSON', schema: complexSchema, ruleSet }; await client.register(subject, info, false); let obj = { arrayField: ['hello'], objectField: { 'stringField': 'world' }, unionField: null, }; let bytes = await ser.serialize(topic, obj); let deserConfig = { ruleConfig: { secret: 'mysecret' } }; let deser = new json_1.JsonDeserializer(client, serde_1.SerdeType.VALUE, deserConfig); fieldEncryptionExecutor.client = dekClient; let obj2 = await deser.deserialize(topic, bytes); (0, globals_1.expect)(obj2.arrayField).toEqual(['hello']); (0, globals_1.expect)(obj2.objectField.stringField).toEqual('world'); (0, globals_1.expect)(obj2.unionField).toEqual(null); }); (0, globals_1.it)('jsonata fully compatible', async () => { let rule1To2 = "$merge([$sift($, function($v, $k) {$k != 'size'}), {'height': $.'size'}])"; let rule2To1 = "$merge([$sift($, function($v, $k) {$k != 'height'}), {'size': $.'height'}])"; let rule2To3 = "$merge([$sift($, function($v, $k) {$k != 'height'}), {'length': $.'height'}])"; let rule3To2 = "$merge([$sift($, function($v, $k) {$k != 'length'}), {'height': $.'length'}])"; let conf = { baseURLs: [baseURL], cacheCapacity: 1000 }; let client = schemaregistry_client_1.SchemaRegistryClient.newClient(conf); client.updateConfig(subject, { compatibilityGroup: 'application.version' }); let widget = { name: 'alice', size: 123, version: 1, }; let jsonSchema = json_1.JsonSerializer.messageToSchema(widget); let info = { schemaType: 'JSON', schema: JSON.stringify(jsonSchema), metadata: { properties: { "application.version": "v1" } } }; await client.register(subject, info, false); let newWidget = { name: 'alice', height: 123, version: 1, }; jsonSchema = json_1.JsonSerializer.messageToSchema(newWidget); info = { schemaType: 'JSON', schema: JSON.stringify(jsonSchema), metadata: { properties: { "application.version": "v2" } }, ruleSet: { migrationRules: [ { name: 'myRule1', kind: 'TRANSFORM', mode: schemaregistry_client_1.RuleMode.UPGRADE, type: 'JSONATA', expr: rule1To2, }, { name: 'myRule2', kind: 'TRANSFORM', mode: schemaregistry_client_1.RuleMode.DOWNGRADE, type: 'JSONATA', expr: rule2To1, }, ] } }; await client.register(subject, info, false); let newerWidget = { name: 'alice', length: 123, version: 1, }; jsonSchema = json_1.JsonSerializer.messageToSchema(newerWidget); info = { schemaType: 'JSON', schema: JSON.stringify(jsonSchema), metadata: { properties: { "application.version": "v3" } }, ruleSet: { migrationRules: [ { name: 'myRule1', kind: 'TRANSFORM', mode: schemaregistry_client_1.RuleMode.UPGRADE, type: 'JSONATA', expr: rule2To3, }, { name: 'myRule2', kind: 'TRANSFORM', mode: schemaregistry_client_1.RuleMode.DOWNGRADE, type: 'JSONATA', expr: rule3To2, }, ] } }; await client.register(subject, info, false); let serConfig1 = { useLatestWithMetadata: { "application.version": "v1" } }; let ser1 = new json_1.JsonSerializer(client, serde_1.SerdeType.VALUE, serConfig1); let bytes = await ser1.serialize(topic, widget); await deserializeWithAllVersions(client, ser1, bytes, widget, newWidget, newerWidget); let serConfig2 = { useLatestWithMetadata: { "application.version": "v2" } }; let ser2 = new json_1.JsonSerializer(client, serde_1.SerdeType.VALUE, serConfig2); bytes = await ser2.serialize(topic, newWidget); await deserializeWithAllVersions(client, ser2, bytes, widget, newWidget, newerWidget); let serConfig3 = { useLatestWithMetadata: { "application.version": "v3" } }; let ser3 = new json_1.JsonSerializer(client, serde_1.SerdeType.VALUE, serConfig3); bytes = await ser3.serialize(topic, newerWidget); await deserializeWithAllVersions(client, ser3, bytes, widget, newWidget, newerWidget); }); async function deserializeWithAllVersions(client, ser, bytes, widget, newWidget, newerWidget) { let deserConfig1 = { useLatestWithMetadata: { "application.version": "v1" } }; let deser1 = new json_1.JsonDeserializer(client, serde_1.SerdeType.VALUE, deserConfig1); deser1.client = ser.client; let newobj = await deser1.deserialize(topic, bytes); (0, globals_1.expect)((0, json_stringify_deterministic_1.default)(newobj)).toEqual((0, json_stringify_deterministic_1.default)(widget)); let deserConfig2 = { useLatestWithMetadata: { "application.version": "v2" } }; let deser2 = new json_1.JsonDeserializer(client, serde_1.SerdeType.VALUE, deserConfig2); newobj = await deser2.deserialize(topic, bytes); (0, globals_1.expect)((0, json_stringify_deterministic_1.default)(newobj)).toEqual((0, json_stringify_deterministic_1.default)(newWidget)); let deserConfig3 = { useLatestWithMetadata: { "application.version": "v3" } }; let deser3 = new json_1.JsonDeserializer(client, serde_1.SerdeType.VALUE, deserConfig3); newobj = await deser3.deserialize(topic, bytes); (0, globals_1.expect)((0, json_stringify_deterministic_1.default)(newobj)).toEqual((0, json_stringify_deterministic_1.default)(newerWidget)); } });