From 6cf8ca3155a558418dbce962cf598527cd69abdc Mon Sep 17 00:00:00 2001 From: Ludovic Dussart Date: Thu, 9 Sep 2021 16:41:33 +0200 Subject: [PATCH 1/4] feat: support of AVRO bindings key Close #67 --- index.js | 13 +++++++++++++ tests/asyncapi-avro-1.9.0-bindings.yaml | 19 +++++++++++++++++++ tests/parse.test.js | 7 +++++++ 3 files changed, 39 insertions(+) create mode 100644 tests/asyncapi-avro-1.9.0-bindings.yaml diff --git a/index.js b/index.js index 28d61f73..a8ea972b 100644 --- a/index.js +++ b/index.js @@ -7,6 +7,19 @@ module.exports.parse = async ({ message, defaultSchemaFormat }) => { message['x-parser-original-payload'] = message.payload; message.payload = transformed; delete message.schemaFormat; + + async function handleProtocolKey() { + for (const protocol of Object.keys(message.bindings)) { + var key = message.bindings[protocol].key; + if (key) { + const bindingsTransformed = await avroToJsonSchema(key); + message[`x-parser-original-bindings-${protocol}-key`] = key; + message.bindings[protocol].key = bindingsTransformed; + } + } + } + + await handleProtocolKey(); }; module.exports.getMimeTypes = () => { diff --git a/tests/asyncapi-avro-1.9.0-bindings.yaml b/tests/asyncapi-avro-1.9.0-bindings.yaml new file mode 100644 index 00000000..10eba82e --- /dev/null +++ b/tests/asyncapi-avro-1.9.0-bindings.yaml @@ -0,0 +1,19 @@ +asyncapi: 2.0.0 +info: + title: My API + version: '1.0.0' +channels: + mychannel: + publish: + message: + schemaFormat: application/vnd.apache.avro;version=1.9.0 + payload: + $ref: 'schemas/Person-1.9.0-namespace.avsc' + bindings: + kafka: + key: + $ref: 'schemas/Person-1.9.0-namespace.avsc' + mqtt: + x-test: + type: string + diff --git a/tests/parse.test.js b/tests/parse.test.js index 68557317..048ef5e4 100644 --- a/tests/parse.test.js +++ b/tests/parse.test.js @@ -12,6 +12,9 @@ const outputWithAvro190 = '{"asyncapi":"2.0.0","info":{"title":"My API","version const inputWithAvro190WithNamespace = fs.readFileSync(path.resolve(__dirname, './asyncapi-avro-1.9.0-namespace.yaml'), 'utf8'); const outputWithAvro190ithNamespace = '{"asyncapi":"2.0.0","info":{"title":"My API","version":"1.0.0"},"channels":{"mychannel":{"publish":{"message":{"payload":{"type":"object","properties":{"name":{"type":"string","examples":["Donkey"],"x-parser-schema-id":""},"age":{"oneOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647,"examples":[123],"x-parser-schema-id":""},{"type":"null","x-parser-schema-id":""}],"default":null,"x-parser-schema-id":""},"favoriteProgrammingLanguage":{"type":"string","enum":["JS","Java","Go","Rust","C"],"default":"JS","x-parser-schema-id":""},"address":{"type":"object","properties":{"zipcode":{"type":"integer","minimum":-2147483648,"maximum":2147483647,"examples":[53003],"x-parser-schema-id":""}},"x-parser-schema-id":""},"someid":{"type":"string","x-parser-schema-id":""}},"x-parser-schema-id":"com.company.Person"},"x-parser-original-schema-format":"application/vnd.apache.avro;version=1.9.0","x-parser-original-payload":{"name":"Person","namespace":"com.company","type":"record","fields":[{"name":"name","type":"string","example":"Donkey"},{"name":"age","type":["null","int"],"default":null,"example":"123"},{"name":"favoriteProgrammingLanguage","type":{"name":"ProgrammingLanguage","type":"enum","symbols":["JS","Java","Go","Rust","C"],"default":"JS"}},{"name":"address","type":{"name":"Address","type":"record","fields":[{"name":"zipcode","type":"int","example":"53003"}]}},{"name":"someid","type":"uuid"}]},"schemaFormat":"application/vnd.aai.asyncapi;version=2.0.0","x-parser-message-parsed":true,"x-parser-message-name":""}}}},"x-parser-spec-parsed":true}'; +const inputWithAvro190WithBindings = fs.readFileSync(path.resolve(__dirname, './asyncapi-avro-1.9.0-bindings.yaml'), 'utf8'); +const outputWithAvro190WithBindings = '{"asyncapi":"2.0.0","info":{"title":"My API","version":"1.0.0"},"channels":{"mychannel":{"publish":{"message":{"payload":{"type":"object","properties":{"name":{"type":"string","examples":["Donkey"],"x-parser-schema-id":""},"age":{"oneOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647,"examples":[123],"x-parser-schema-id":""},{"type":"null","x-parser-schema-id":""}],"default":null,"x-parser-schema-id":""},"favoriteProgrammingLanguage":{"type":"string","enum":["JS","Java","Go","Rust","C"],"default":"JS","x-parser-schema-id":""},"address":{"type":"object","properties":{"zipcode":{"type":"integer","minimum":-2147483648,"maximum":2147483647,"examples":[53003],"x-parser-schema-id":""}},"x-parser-schema-id":""},"someid":{"type":"string","x-parser-schema-id":""}},"x-parser-schema-id":"com.company.Person"},"bindings":{"kafka":{"key":{"type":"object","properties":{"name":{"type":"string","examples":["Donkey"]},"age":{"oneOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647,"examples":[123]},{"type":"null"}],"default":null},"favoriteProgrammingLanguage":{"type":"string","enum":["JS","Java","Go","Rust","C"],"default":"JS"},"address":{"type":"object","properties":{"zipcode":{"type":"integer","minimum":-2147483648,"maximum":2147483647,"examples":[53003]}}},"someid":{"type":"string"}},"x-parser-schema-id":"com.company.Person"}},"mqtt":{"x-test":{"type":"string"}}},"x-parser-original-schema-format":"application/vnd.apache.avro;version=1.9.0","x-parser-original-payload":{"name":"Person","namespace":"com.company","type":"record","fields":[{"name":"name","type":"string","example":"Donkey"},{"name":"age","type":["null","int"],"default":null,"example":"123"},{"name":"favoriteProgrammingLanguage","type":{"name":"ProgrammingLanguage","type":"enum","symbols":["JS","Java","Go","Rust","C"],"default":"JS"}},{"name":"address","type":{"name":"Address","type":"record","fields":[{"name":"zipcode","type":"int","example":"53003"}]}},{"name":"someid","type":"uuid"}]},"x-parser-original-bindings-kafka-key":{"name":"Person","namespace":"com.company","type":"record","fields":[{"name":"name","type":"string","example":"Donkey"},{"name":"age","type":["null","int"],"default":null,"example":"123"},{"name":"favoriteProgrammingLanguage","type":{"name":"ProgrammingLanguage","type":"enum","symbols":["JS","Java","Go","Rust","C"],"default":"JS"}},{"name":"address","type":{"name":"Address","type":"record","fields":[{"name":"zipcode","type":"int","example":"53003"}]}},{"name":"someid","type":"uuid"}]},"schemaFormat":"application/vnd.aai.asyncapi;version=2.0.0","x-parser-message-parsed":true,"x-parser-message-name":""}}}},"x-parser-spec-parsed":true}'; + parser.registerSchemaParser(avroSchemaParser); describe('parse()', function() { @@ -27,4 +30,8 @@ describe('parse()', function() { const result = await parser.parse(inputWithAvro190WithNamespace, { path: __filename }); expect(JSON.stringify(result.json())).toEqual(outputWithAvro190ithNamespace); }); + it('should parse Avro schema in kafka bindings', async function() { + const result = await parser.parse(inputWithAvro190WithBindings, { path: __filename }); + expect(JSON.stringify(result.json())).toEqual(outputWithAvro190WithBindings); + }); }); From 5a1d0f2bbe6d3a7fad65b8468586e12aa41798d4 Mon Sep 17 00:00:00 2001 From: Ludovic Dussart Date: Mon, 13 Sep 2021 13:30:17 +0200 Subject: [PATCH 2/4] fixup: PR review, only handle kafka key on bindings --- index.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/index.js b/index.js index a8ea972b..372540cf 100644 --- a/index.js +++ b/index.js @@ -8,18 +8,18 @@ module.exports.parse = async ({ message, defaultSchemaFormat }) => { message.payload = transformed; delete message.schemaFormat; - async function handleProtocolKey() { - for (const protocol of Object.keys(message.bindings)) { - var key = message.bindings[protocol].key; + async function handleKafkaProtocolKey() { + if (message.bindings && message.bindings.kafka) { + var key = message.bindings.kafka.key; if (key) { const bindingsTransformed = await avroToJsonSchema(key); - message[`x-parser-original-bindings-${protocol}-key`] = key; - message.bindings[protocol].key = bindingsTransformed; + message[`x-parser-original-bindings-kafka-key`] = key; + message.bindings.kafka.key = bindingsTransformed; } } } - await handleProtocolKey(); + await handleKafkaProtocolKey(); }; module.exports.getMimeTypes = () => { From 00ed77ae7526e6c792c5a4a17338cde0c6ebc347 Mon Sep 17 00:00:00 2001 From: Ludovic Dussart Date: Fri, 17 Sep 2021 11:20:42 +0200 Subject: [PATCH 3/4] fix linter errors --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 372540cf..92df664a 100644 --- a/index.js +++ b/index.js @@ -10,10 +10,10 @@ module.exports.parse = async ({ message, defaultSchemaFormat }) => { async function handleKafkaProtocolKey() { if (message.bindings && message.bindings.kafka) { - var key = message.bindings.kafka.key; + const key = message.bindings.kafka.key; if (key) { const bindingsTransformed = await avroToJsonSchema(key); - message[`x-parser-original-bindings-kafka-key`] = key; + message['x-parser-original-bindings-kafka-key'] = key; message.bindings.kafka.key = bindingsTransformed; } } From 07716bf6505ffe48ce2f1e6891ee2606d11a5dc0 Mon Sep 17 00:00:00 2001 From: Ludovic Dussart Date: Fri, 17 Sep 2021 13:51:50 +0200 Subject: [PATCH 4/4] fixup: magicmatatjahu PR suggestion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Maciej UrbaƄczyk --- index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/index.js b/index.js index 92df664a..81660349 100644 --- a/index.js +++ b/index.js @@ -8,6 +8,7 @@ module.exports.parse = async ({ message, defaultSchemaFormat }) => { message.payload = transformed; delete message.schemaFormat; + // remove that function when https://github.com/asyncapi/spec/issues/622 will be introduced in AsyncAPI spec async function handleKafkaProtocolKey() { if (message.bindings && message.bindings.kafka) { const key = message.bindings.kafka.key;