Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@natcl
Last active September 6, 2018 13:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save natcl/682bc3011b19c7e6bac30fbbeef12e74 to your computer and use it in GitHub Desktop.
Save natcl/682bc3011b19c7e6bac30fbbeef12e74 to your computer and use it in GitHub Desktop.
Node-RED Json-RPC validation subflow

json-rpc

JSON-RPC Node-RED example

About

This is your project's README.md file. It helps users understand what your project does, how to use it and anything else they may need to know.

[{"id":"b02fc92d.2f9688","type":"tab","label":"JSON-RPC","disabled":false,"info":""},{"id":"26b8631b.4edf14","type":"subflow","name":"RPC Out","info":"","in":[{"x":200,"y":120,"wires":[{"id":"e5dba7aa.1a21a"},{"id":"eee31871.b64cd8"}]}],"out":[]},{"id":"445e80b1.1eddc8","type":"subflow","name":"RPC In","info":"","in":[],"out":[{"x":320,"y":80,"wires":[{"id":"f6099f9f.77f4d8","port":0},{"id":"c3f90927.91895","port":0},{"id":"fd36e564.f8be9","port":0},{"id":"9d1fa4e4.44b73","port":0}]}]},{"id":"dd511956.d1cf48","type":"subflow","name":"multiply","info":"","in":[{"x":100,"y":80,"wires":[{"id":"ccaeca13.1b2b7"}]}],"out":[{"x":380,"y":80,"wires":[{"id":"ccaeca13.1b2b7","port":0},{"id":"34f93dd.39e3ac2","port":0}]}]},{"id":"bbd9aac2.b726e8","type":"subflow","name":"mqtt request","info":"","in":[{"x":60,"y":220,"wires":[{"id":"ff1ab12.b2f6c5"}]}],"out":[{"x":1020,"y":80,"wires":[{"id":"c0cfd6ec.903d88","port":0}]},{"x":1020,"y":140,"wires":[{"id":"8ea93e18.0cf82","port":0}]}]},{"id":"1d89fec7.4210f9","type":"subflow","name":"RPC Processing","info":"# RPC Processing\n\nThis subflow takes a `msg.methods` objects containing a list of method names (as the key) along with their schema as the value. For example:\n\n```\n{\n \"drinkBeer\": {\n \"title\": \"drinkBeer\",\n \"type\": \"object\",\n \"properties\": {\n \"bitterness\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"bitterness\"\n ]\n },\n \"drinkWine\": {\n \"title\": \"drinkWine\",\n \"type\": \"object\",\n \"properties\": {\n \"cépage\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"cépage\"\n ]\n }\n}\n```\n\nIf the validation is successful, the subflow will send the `params` as `msg.payload` with the method name in `msg.rpcMethod` and the if as `msg.rpcId` through the first output.\n\nIf an error occurs it will be sent out the second output.\n\nAnother instance of the subflow can be added after the processing of the `params` which will then format an appropriate JSON-RPC result.","in":[{"x":80,"y":220,"wires":[{"id":"366cf82.bd70c88"}]}],"out":[{"x":1620,"y":360,"wires":[{"id":"9e0d0715.fb9bb","port":0},{"id":"c58dc574.e4d3a","port":0}]},{"x":1220,"y":580,"wires":[{"id":"9f26b70f.05d3","port":0}]}],"outputLabels":["Valid","Error"]},{"id":"f08869b3.9645d","type":"mqtt-broker","z":"","name":"","broker":"$(IP_BROKER)","port":"1883","tls":"","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","willTopic":"","willQos":"0","willRetain":"false","willPayload":""},{"id":"32869217.f5d70e","type":"http response","z":"26b8631b.4edf14","name":"","statusCode":"","headers":{},"x":670,"y":80,"wires":[]},{"id":"bad6d85.cf2b528","type":"mqtt out","z":"26b8631b.4edf14","name":"","topic":"","qos":"","retain":"","broker":"f08869b3.9645d","x":670,"y":140,"wires":[]},{"id":"e5dba7aa.1a21a","type":"switch","z":"26b8631b.4edf14","name":"","property":"res","propertyType":"msg","rules":[{"t":"nnull"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":330,"y":120,"wires":[["32869217.f5d70e"],["c22fd09b.ec5f3"]]},{"id":"c22fd09b.ec5f3","type":"change","z":"26b8631b.4edf14","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"'json-rpc/testhost/resp/' & rpcMethod ","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":500,"y":140,"wires":[["bad6d85.cf2b528"]]},{"id":"f6099f9f.77f4d8","type":"http in","z":"445e80b1.1eddc8","name":"","url":"/request","method":"post","upload":false,"swaggerDoc":"","x":120,"y":80,"wires":[[]]},{"id":"c3f90927.91895","type":"mqtt in","z":"445e80b1.1eddc8","name":"","topic":"json-rpc/testhost/request","qos":"2","broker":"f08869b3.9645d","x":150,"y":120,"wires":[[]]},{"id":"fd36e564.f8be9","type":"mqtt in","z":"445e80b1.1eddc8","name":"","topic":"json-rpc/*/request","qos":"2","broker":"f08869b3.9645d","x":130,"y":160,"wires":[[]]},{"id":"ccaeca13.1b2b7","type":"function","z":"dd511956.d1cf48","name":"multiply","func":"msg.payload = msg.payload.x * msg.payload.y;\nif (msg.payload > 100) {\n node.error(\"Can't multiply if result is above 100\", msg);\n return;\n}\nreturn msg;","outputs":1,"noerr":0,"x":240,"y":80,"wires":[[]]},{"id":"34f93dd.39e3ac2","type":"catch","z":"dd511956.d1cf48","name":"","scope":["ccaeca13.1b2b7"],"x":240,"y":160,"wires":[[]]},{"id":"3ead4025.85d768","type":"mqtt out","z":"bbd9aac2.b726e8","name":"","topic":"","qos":"","retain":"","broker":"f08869b3.9645d","x":810,"y":220,"wires":[]},{"id":"8ea93e18.0cf82","type":"mqtt in","z":"bbd9aac2.b726e8","name":"","topic":"+/+/resp/#","qos":"2","broker":"f08869b3.9645d","x":120,"y":80,"wires":[["6f846d1.fb79c14"]]},{"id":"6f846d1.fb79c14","type":"json","z":"bbd9aac2.b726e8","name":"","pretty":false,"x":290,"y":80,"wires":[["5b2b034.d301f7c"]]},{"id":"7c800b53.2fc33c","type":"delay","z":"bbd9aac2.b726e8","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":540,"y":160,"wires":[["580e75fb.dca4d4"]]},{"id":"ff1ab12.b2f6c5","type":"json-schema-validator","z":"bbd9aac2.b726e8","name":"RPC Schema validation","func":"{\n \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n \"description\": \"A JSON RPC 2.0 request\",\n \"oneOf\": [\n {\n \"description\": \"An individual request\",\n \"$ref\": \"#/definitions/request\"\n },\n {\n \"description\": \"An array of requests\",\n \"type\": \"array\",\n \"items\": { \"$ref\": \"#/definitions/request\" }\n }\n ],\n \"definitions\": {\n \"request\": {\n \"type\": \"object\",\n \"required\": [ \"jsonrpc\", \"method\" ],\n \"properties\": {\n \"jsonrpc\": { \"enum\": [ \"2.0\" ] },\n \"method\": {\n \"type\": \"string\"\n },\n \"id\": {\n \"type\": [ \"string\", \"number\", \"null\" ],\n \"note\": [\n \"While allowed, null should be avoided: http://www.jsonrpc.org/specification#id1\",\n \"While allowed, a number with a fractional part should be avoided: http://www.jsonrpc.org/specification#id2\"\n ]\n },\n \"params\": {\n \"type\": [ \"array\", \"object\" ]\n }\n }\n }\n }\n}","x":290,"y":220,"wires":[["9f398031.6497e8","7c800b53.2fc33c"]]},{"id":"5b2b034.d301f7c","type":"json-schema-validator","z":"bbd9aac2.b726e8","name":"RPC Schema answer validation","func":"{\n \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n \"description\": \"A JSON RPC 2.0 response\",\n \"oneOf\": [\n { \"$ref\": \"#/definitions/success\" },\n { \"$ref\": \"#/definitions/error\" },\n {\n \"type\": \"array\",\n \"items\": {\n \"oneOf\": [\n { \"$ref\": \"#/definitions/success\" },\n { \"$ref\": \"#/definitions/error\" }\n ]\n }\n }\n ],\n \"definitions\": {\n \"common\": {\n \"required\": [ \"id\", \"jsonrpc\" ],\n \"not\": {\n \"description\": \"cannot have result and error at the same time\",\n \"required\": [ \"result\", \"error\" ]\n },\n \"type\": \"object\",\n \"properties\": {\n \"id\": {\n \"type\": [ \"string\", \"integer\", \"null\" ],\n \"note\": [\n \"spec says a number which should not contain a fractional part\",\n \"We choose integer here, but this is unenforceable with some languages\"\n ]\n },\n \"jsonrpc\": { \"enum\": [ \"2.0\" ] }\n }\n },\n \"success\": {\n \"description\": \"A success. The result member is then required and can be anything.\",\n \"allOf\": [\n { \"$ref\": \"#/definitions/common\" },\n { \"required\": [ \"result\" ] }\n ]\n },\n \"error\": {\n \"allOf\" : [\n { \"$ref\": \"#/definitions/common\" },\n {\n \"required\": [ \"error\" ],\n \"properties\": {\n \"error\": {\n \"type\": \"object\",\n \"required\": [ \"code\", \"message\" ],\n \"properties\": {\n \"code\": {\n \"type\": \"integer\",\n \"note\": [ \"unenforceable in some languages\" ]\n },\n \"message\": { \"type\": \"string\" },\n \"data\": {\n \"description\": \"optional, can be anything\"\n }\n }\n }\n }\n }\n ]\n }\n }\n}","x":510,"y":80,"wires":[["c0cfd6ec.903d88"]]},{"id":"9f398031.6497e8","type":"function","z":"bbd9aac2.b726e8","name":"add to queue","func":"var requests;\n\nif (!flow.get('requests')) {\n requests = {};\n flow.set('requests', requests);\n} else {\n requests = flow.get('requests');\n}\n\nlet hostname = msg.topic.split('/')[1];\nlet id = msg._msgid;\n\nrequests[id] = {};\nrequests[id].hostname = hostname;\nrequests[id].success = false;\n\nreturn msg;","outputs":1,"noerr":0,"x":550,"y":220,"wires":[["3ead4025.85d768"]]},{"id":"c0cfd6ec.903d88","type":"function","z":"bbd9aac2.b726e8","name":"filter from queue","func":"let requests = flow.get('requests');\nlet hostname = msg.topic.split('/')[1];\n\nif (requests) {\n if (requests.hasOwnProperty(msg.payload.id)) {\n if (requests[msg.payload.id].hostname == hostname || requests[msg.payload.id].hostname == '*') {\n requests[msg.payload.id].success = true;\n return msg; \n }\n }\n}\n\n \n","outputs":1,"noerr":0,"x":780,"y":80,"wires":[[]]},{"id":"580e75fb.dca4d4","type":"function","z":"bbd9aac2.b726e8","name":"delete from queue","func":"let requests = flow.get('requests');\nif (requests[msg._msgid].success === false) {\n node.warn(`Request ${msg._msgid} timed out`);\n}\ndelete requests[msg._msgid];","outputs":1,"noerr":0,"x":750,"y":160,"wires":[[]]},{"id":"304a9b02.82d6e4","type":"json-schema-validator","z":"1d89fec7.4210f9","name":"JSON-RPC validation","func":"{\n \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n \"description\": \"A JSON RPC 2.0 request\",\n \"oneOf\": [\n {\n \"description\": \"An individual request\",\n \"$ref\": \"#/definitions/request\"\n },\n {\n \"description\": \"An array of requests\",\n \"type\": \"array\",\n \"items\": { \"$ref\": \"#/definitions/request\" }\n }\n ],\n \"definitions\": {\n \"request\": {\n \"type\": \"object\",\n \"required\": [ \"jsonrpc\", \"method\" ],\n \"properties\": {\n \"jsonrpc\": { \"enum\": [ \"2.0\" ] },\n \"method\": {\n \"type\": \"string\"\n },\n \"id\": {\n \"type\": [ \"string\", \"number\", \"null\" ],\n \"note\": [\n \"While allowed, null should be avoided: http://www.jsonrpc.org/specification#id1\",\n \"While allowed, a number with a fractional part should be avoided: http://www.jsonrpc.org/specification#id2\"\n ]\n },\n \"params\": {\n \"type\": [ \"array\", \"object\" ]\n }\n }\n }\n }\n}","x":720,"y":220,"wires":[["e2553d07.1f7288"]]},{"id":"d6f17470.49146","type":"json","z":"1d89fec7.4210f9","name":"rpcToJson","property":"payload","action":"obj","pretty":false,"x":530,"y":220,"wires":[["304a9b02.82d6e4"]]},{"id":"2513d5e5.149b3a","type":"catch","z":"1d89fec7.4210f9","name":"","scope":["9e0d0715.fb9bb","d6f17470.49146","bb816574.b743e8","304a9b02.82d6e4"],"x":200,"y":580,"wires":[["53d602c6.5db1ac"]]},{"id":"17d3eeb1.3db9a1","type":"switch","z":"1d89fec7.4210f9","name":"","property":"payload","propertyType":"msg","rules":[{"t":"jsonata_exp","v":"payload.method in $keys($flowContext('methods'))","vt":"jsonata"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":1150,"y":220,"wires":[["cb7b3a21.6dadb8"],["bb816574.b743e8"]]},{"id":"9e0d0715.fb9bb","type":"json-schema-validator","z":"1d89fec7.4210f9","name":"method validation","func":"","x":1490,"y":200,"wires":[[]]},{"id":"cb7b3a21.6dadb8","type":"change","z":"1d89fec7.4210f9","name":"params","rules":[{"t":"set","p":"schema","pt":"msg","to":"$lookup($flowContext('methods'), payload.method) ~> $lookup(\"request\")","tot":"jsonata"},{"t":"set","p":"rpcMethod","pt":"msg","to":"payload.method","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"payload.params ? payload.params : {}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1300,"y":200,"wires":[["9e0d0715.fb9bb"]]},{"id":"9f26b70f.05d3","type":"change","z":"1d89fec7.4210f9","name":"","rules":[{"t":"set","p":"statusCode","pt":"msg","to":"500","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":1040,"y":580,"wires":[[]]},{"id":"e2553d07.1f7288","type":"change","z":"1d89fec7.4210f9","name":"store rpcId","rules":[{"t":"set","p":"rpcId","pt":"msg","to":"payload.id","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":950,"y":220,"wires":[["17d3eeb1.3db9a1"]]},{"id":"bb816574.b743e8","type":"function","z":"1d89fec7.4210f9","name":"MethodNotFound Error","func":"msg._error = [`Method ${msg.payload.method} not found`];\nnode.error(\"Method not found\", msg);","outputs":0,"noerr":0,"x":1350,"y":280,"wires":[]},{"id":"53d602c6.5db1ac","type":"switch","z":"1d89fec7.4210f9","name":"","property":"error.source.name","propertyType":"msg","rules":[{"t":"cont","v":"method validation","vt":"str"},{"t":"eq","v":"rpcToJson","vt":"str"},{"t":"eq","v":"MethodNotFound Error","vt":"str"},{"t":"eq","v":"JSON-RPC validation","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":5,"x":370,"y":580,"wires":[["a6c8fdf5.e80f3"],["73540088.a795c"],["46c2f54.b51da8c"],["ba376f32.1917f"],["32a652a2.05bfd6"]]},{"id":"32a652a2.05bfd6","type":"change","z":"1d89fec7.4210f9","name":"format RPC Error","rules":[{"t":"set","p":"payload","pt":"msg","to":"{ \t \"jsonrpc\": \"2.0\",\t \"error\": { \t \"code\": rpcErrorCode ? rpcErrorCode: -32000,\t \"message\": error.message,\t \"data\": _error ? _error: error.source\t },\t \"id\": rpcId ? rpcId: payload.id\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":810,"y":580,"wires":[["9f26b70f.05d3"]]},{"id":"fcecb3c6.fc7a08","type":"change","z":"1d89fec7.4210f9","name":"","rules":[{"t":"set","p":"methods","pt":"flow","to":"methods","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":430,"y":120,"wires":[[]]},{"id":"7aa7e63e.17a768","type":"switch","z":"1d89fec7.4210f9","name":"set methods","property":"methods","propertyType":"msg","rules":[{"t":"nnull"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":210,"y":120,"wires":[["fcecb3c6.fc7a08"],["a03d5815.39df7"]],"outputLabels":["set methods",""]},{"id":"a03d5815.39df7","type":"switch","z":"1d89fec7.4210f9","name":"Response ?","property":"rpcMethod","propertyType":"msg","rules":[{"t":"nnull"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":350,"y":220,"wires":[["c58dc574.e4d3a"],["d6f17470.49146"]],"outputLabels":["format result",""]},{"id":"c58dc574.e4d3a","type":"change","z":"1d89fec7.4210f9","name":"format RPC Response","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t \"jsonrpc\": \"2.0\",\t \"result\": payload,\t \"id\": rpcId\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":380,"y":360,"wires":[[]]},{"id":"501be81.ca08218","type":"comment","z":"1d89fec7.4210f9","name":"Error processing","info":"","x":220,"y":520,"wires":[]},{"id":"f19912b0.7f5fd","type":"comment","z":"1d89fec7.4210f9","name":"Request processing","info":"","x":370,"y":180,"wires":[]},{"id":"c53eecb7.99b97","type":"comment","z":"1d89fec7.4210f9","name":"Response processing","info":"","x":380,"y":320,"wires":[]},{"id":"a6c8fdf5.e80f3","type":"change","z":"1d89fec7.4210f9","name":"","rules":[{"t":"set","p":"rpcErrorCode","pt":"msg","to":"-32602","tot":"num"},{"t":"set","p":"error.message","pt":"msg","to":"Invalid params","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":560,"y":540,"wires":[["32a652a2.05bfd6"]]},{"id":"46c2f54.b51da8c","type":"change","z":"1d89fec7.4210f9","name":"","rules":[{"t":"set","p":"rpcErrorCode","pt":"msg","to":"-32601","tot":"num"},{"t":"set","p":"error.message","pt":"msg","to":"Method not found","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":560,"y":620,"wires":[["32a652a2.05bfd6"]]},{"id":"73540088.a795c","type":"change","z":"1d89fec7.4210f9","name":"","rules":[{"t":"set","p":"rpcErrorCode","pt":"msg","to":"-32700","tot":"num"},{"t":"set","p":"error.message","pt":"msg","to":"Parse error","tot":"str"},{"t":"set","p":"rpcId","pt":"msg","to":"-1","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":560,"y":580,"wires":[["32a652a2.05bfd6"]]},{"id":"ba376f32.1917f","type":"change","z":"1d89fec7.4210f9","name":"","rules":[{"t":"set","p":"rpcErrorCode","pt":"msg","to":"-32600","tot":"num"},{"t":"set","p":"error.message","pt":"msg","to":"Invalid Request","tot":"str"},{"t":"set","p":"rpcId","pt":"msg","to":"-1","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":560,"y":660,"wires":[["32a652a2.05bfd6"]]},{"id":"366cf82.bd70c88","type":"switch","z":"1d89fec7.4210f9","name":"Error ?","property":"error","propertyType":"msg","rules":[{"t":"nnull"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":170,"y":220,"wires":[["53d602c6.5db1ac"],["7aa7e63e.17a768"]]},{"id":"f14ca926.bfaab8","type":"comment","z":"1d89fec7.4210f9","name":"populate methods and schemas","info":"","x":270,"y":80,"wires":[]},{"id":"ac67b449.b87658","type":"inject","z":"b02fc92d.2f9688","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":800,"wires":[["1aecb4e6.09f0fb"]]},{"id":"545f3867.47411","type":"template","z":"b02fc92d.2f9688","name":"invalid json","field":"payload","fieldType":"msg","format":"javascript","syntax":"mustache","template":"{ \n \"jsonrpcs\":\"2.0,\n \"method\":\"getGameMode\",\n \"params\":{ \n \"ip\": \"172.0.0.1\"\n },\n \"id\":1\n}","output":"str","x":330,"y":860,"wires":[["de28797b.fd9118"]]},{"id":"4d1c5a76.2456b4","type":"inject","z":"b02fc92d.2f9688","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":860,"wires":[["545f3867.47411"]]},{"id":"de28797b.fd9118","type":"http request","z":"b02fc92d.2f9688","name":"","method":"POST","ret":"obj","url":"http://127.0.0.1:2003/request","tls":"","x":790,"y":720,"wires":[["bfe1efae.a49fc"]]},{"id":"647eb118.66fec8","type":"inject","z":"b02fc92d.2f9688","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":760,"wires":[["80e7293c.9cca38"]]},{"id":"bfe1efae.a49fc","type":"json-schema-validator","z":"b02fc92d.2f9688","name":"RPC Schema answer validation","func":"{\n \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n \"description\": \"A JSON RPC 2.0 response\",\n \"oneOf\": [\n { \"$ref\": \"#/definitions/success\" },\n { \"$ref\": \"#/definitions/error\" },\n {\n \"type\": \"array\",\n \"items\": {\n \"oneOf\": [\n { \"$ref\": \"#/definitions/success\" },\n { \"$ref\": \"#/definitions/error\" }\n ]\n }\n }\n ],\n \"definitions\": {\n \"common\": {\n \"required\": [ \"id\", \"jsonrpc\" ],\n \"not\": {\n \"description\": \"cannot have result and error at the same time\",\n \"required\": [ \"result\", \"error\" ]\n },\n \"type\": \"object\",\n \"properties\": {\n \"id\": {\n \"type\": [ \"string\", \"integer\", \"null\" ],\n \"note\": [\n \"spec says a number which should not contain a fractional part\",\n \"We choose integer here, but this is unenforceable with some languages\"\n ]\n },\n \"jsonrpc\": { \"enum\": [ \"2.0\" ] }\n }\n },\n \"success\": {\n \"description\": \"A success. The result member is then required and can be anything.\",\n \"allOf\": [\n { \"$ref\": \"#/definitions/common\" },\n { \"required\": [ \"result\" ] }\n ]\n },\n \"error\": {\n \"allOf\" : [\n { \"$ref\": \"#/definitions/common\" },\n {\n \"required\": [ \"error\" ],\n \"properties\": {\n \"error\": {\n \"type\": \"object\",\n \"required\": [ \"code\", \"message\" ],\n \"properties\": {\n \"code\": {\n \"type\": \"integer\",\n \"note\": [ \"unenforceable in some languages\" ]\n },\n \"message\": { \"type\": \"string\" },\n \"data\": {\n \"description\": \"optional, can be anything\"\n }\n }\n }\n }\n }\n ]\n }\n }\n}","x":1030,"y":720,"wires":[["18967a1a.d40446"]]},{"id":"18967a1a.d40446","type":"debug","z":"b02fc92d.2f9688","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1270,"y":720,"wires":[]},{"id":"62be90.fd4ee17","type":"inject","z":"b02fc92d.2f9688","name":"","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":110,"y":140,"wires":[["a4d891ef.aca5c8"]]},{"id":"fbac9ce4.e9b728","type":"switch","z":"b02fc92d.2f9688","name":"","property":"rpcMethod","propertyType":"msg","rules":[{"t":"eq","v":"multiply","vt":"str"},{"t":"eq","v":"getRandomDrink","vt":"str"},{"t":"eq","v":"getTimeDelta","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":4,"x":610,"y":180,"wires":[["b7ad37d0.685b6"],["ce8d823.05cef8"],["e0cfdc32.4cecd"],["ffac8463.6dd31"]],"outputLabels":["","","","unhandled Method"]},{"id":"ce8d823.05cef8","type":"function","z":"b02fc92d.2f9688","name":"getRandomDrink","func":"if (msg.payload.drinkType == 'wine') {\n msg.payload = 'Cabernet';\n}\n\nif (msg.payload.drinkType == 'beer') {\n msg.payload = 'Pale Ale';\n}\nreturn msg;","outputs":1,"noerr":0,"x":830,"y":120,"wires":[["e452d56d.979058"]]},{"id":"a4d891ef.aca5c8","type":"template","z":"b02fc92d.2f9688","name":"methods","field":"methods","fieldType":"msg","format":"yaml","syntax":"mustache","template":"multiply:\n request:\n title: multiply\n type: object\n properties:\n x:\n type: number\n y:\n type: number\n required:\n - x\n - y\ngetRandomDrink:\n request:\n title: getRandomDrink\n type: object\n properties:\n drinkType:\n type: string\n enum:\n - beer\n - wine\n required:\n - drinkType\n \ngetTimeDelta:\n request:\n title: getTimeDelta\n type: object\n properties:\n timestamp:\n type: number\n required:\n - timestamp","output":"yaml","x":280,"y":140,"wires":[["f32aa13c.c446d"]]},{"id":"4d81c735.2165","type":"inject","z":"b02fc92d.2f9688","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":520,"wires":[["1830fee9.ec8611"]]},{"id":"a1387b1c.d58a68","type":"comment","z":"b02fc92d.2f9688","name":"2 methods: multiply and getRandomDrink","info":"","x":540,"y":460,"wires":[]},{"id":"1830fee9.ec8611","type":"change","z":"b02fc92d.2f9688","name":"getRandomDrink: valid ","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t \"jsonrpc\": \"2.0\",\t \"method\": \"getRandomDrink\",\t \"params\": {\t \"drinkType\": \"wine\"\t },\t \"id\": _msgid\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":520,"wires":[["de28797b.fd9118"]]},{"id":"f3c0e308.1a293","type":"change","z":"b02fc92d.2f9688","name":"getRandomDrink: wrong drink ","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t \"jsonrpc\": \"2.0\",\t \"method\": \"getRandomDrink\",\t \"params\": {\t \"drinkType\": \"scotch\"\t },\t \"id\": _msgid\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":560,"wires":[["de28797b.fd9118"]]},{"id":"a5cb6582.0539d8","type":"inject","z":"b02fc92d.2f9688","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":560,"wires":[["f3c0e308.1a293"]]},{"id":"471e2bcd.72d85c","type":"change","z":"b02fc92d.2f9688","name":"multiply: valid","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t \"jsonrpc\": \"2.0\",\t \"method\": \"multiply\",\t \"params\": {\t \"x\": 3,\t \"y\": 4\t },\t \"id\": _msgid\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":340,"y":620,"wires":[["de28797b.fd9118"]]},{"id":"e38dc5e9.ec29b","type":"inject","z":"b02fc92d.2f9688","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":620,"wires":[["471e2bcd.72d85c"]]},{"id":"e2609339.af96","type":"change","z":"b02fc92d.2f9688","name":"multiply: missing param","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t \"jsonrpc\": \"2.0\",\t \"method\": \"multiply\",\t \"params\": {\t \"x\": 3\t },\t \"id\": _msgid\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":370,"y":660,"wires":[["de28797b.fd9118"]]},{"id":"95dd937.458bb7","type":"inject","z":"b02fc92d.2f9688","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":660,"wires":[["e2609339.af96"]]},{"id":"80e7293c.9cca38","type":"change","z":"b02fc92d.2f9688","name":"unkown method","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t \"jsonrpc\": \"2.0\",\t \"method\": \"makeCoffee\",\t \"params\": {\t \"coffeeType\": 'black'\t },\t \"id\": _msgid\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":340,"y":760,"wires":[["de28797b.fd9118"]]},{"id":"1aecb4e6.09f0fb","type":"change","z":"b02fc92d.2f9688","name":"invalid RPC","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t \"method\": \"makeCoffee\",\t \"params\": {\t \"coffeeType\": 'black'\t },\t \"id\": _msgid\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":330,"y":800,"wires":[["de28797b.fd9118"]]},{"id":"ffac8463.6dd31","type":"function","z":"b02fc92d.2f9688","name":"Todo: unhandled method","func":"\nreturn msg;","outputs":1,"noerr":0,"x":850,"y":200,"wires":[[]]},{"id":"6f581f61.7749b8","type":"comment","z":"b02fc92d.2f9688","name":"Example JSON-RPC Server","info":"","x":180,"y":40,"wires":[]},{"id":"b971c262.23901","type":"comment","z":"b02fc92d.2f9688","name":"Example HTTP JSON-RPC Client","info":"","x":190,"y":460,"wires":[]},{"id":"da5a0675.0fcbf8","type":"inject","z":"b02fc92d.2f9688","name":"","topic":"json-rpc/testhost/request","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":1040,"wires":[["6cfb79d6.5c372"]]},{"id":"6cfb79d6.5c372","type":"change","z":"b02fc92d.2f9688","name":"getRandomDrink: valid ","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t \"jsonrpc\": \"2.0\",\t \"method\": \"getRandomDrink\",\t \"params\": {\t \"drinkType\": \"beer\"\t },\t \"id\": _msgid\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":1040,"wires":[["c52b1f9b.26f3e8"]]},{"id":"ae98dff8.3b0a3","type":"change","z":"b02fc92d.2f9688","name":"getRandomDrink: wrong drink ","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t \"jsonrpc\": \"2.0\",\t \"method\": \"getRandomDrink\",\t \"params\": {\t \"drinkType\": \"scotch\"\t },\t \"id\": _msgid\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":1080,"wires":[["c52b1f9b.26f3e8"]]},{"id":"ad9d1c26.29d828","type":"inject","z":"b02fc92d.2f9688","name":"","topic":"json-rpc/testhost/request","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":1080,"wires":[["ae98dff8.3b0a3"]]},{"id":"1ccd9f45.811f19","type":"comment","z":"b02fc92d.2f9688","name":"Example MQTT JSON-RPC Client","info":"","x":200,"y":980,"wires":[]},{"id":"778bc1a3.bd9978","type":"comment","z":"b02fc92d.2f9688","name":"Method processing","info":"","x":710,"y":40,"wires":[]},{"id":"f32aa13c.c446d","type":"subflow:1d89fec7.4210f9","z":"b02fc92d.2f9688","name":"","x":460,"y":220,"wires":[["fbac9ce4.e9b728"],["aa6cea0.3f2c998"]]},{"id":"e452d56d.979058","type":"subflow:1d89fec7.4210f9","z":"b02fc92d.2f9688","name":"","x":1080,"y":120,"wires":[["aa6cea0.3f2c998"],["aa6cea0.3f2c998"]]},{"id":"c52b1f9b.26f3e8","type":"subflow:bbd9aac2.b726e8","z":"b02fc92d.2f9688","name":"","x":790,"y":800,"wires":[["bfe1efae.a49fc"],[]]},{"id":"b7ad37d0.685b6","type":"subflow:dd511956.d1cf48","z":"b02fc92d.2f9688","name":"","x":800,"y":80,"wires":[["e452d56d.979058"]]},{"id":"c404c560.f0914","type":"change","z":"b02fc92d.2f9688","name":"multiply: above 100","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t \"jsonrpc\": \"2.0\",\t \"method\": \"multiply\",\t \"params\": {\t \"x\": 100,\t \"y\": 3\t },\t \"id\": _msgid\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":700,"wires":[["de28797b.fd9118"]]},{"id":"19f32441.0c8ac4","type":"inject","z":"b02fc92d.2f9688","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":700,"wires":[["c404c560.f0914"]]},{"id":"2f4ece53.7f961a","type":"inject","z":"b02fc92d.2f9688","name":"*","topic":"json-rpc/*/request","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":1140,"wires":[["35578c83.4081c4"]]},{"id":"35578c83.4081c4","type":"change","z":"b02fc92d.2f9688","name":"getRandomDrink: valid ","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t \"jsonrpc\": \"2.0\",\t \"method\": \"getRandomDrink\",\t \"params\": {\t \"drinkType\": \"beer\"\t },\t \"id\": _msgid\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":1140,"wires":[["c52b1f9b.26f3e8"]]},{"id":"84f7b37e.6a8e3","type":"inject","z":"b02fc92d.2f9688","name":"testhost2","topic":"json-rpc/testhost2/request","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":1180,"wires":[["8e76028e.a1b2f"]]},{"id":"8e76028e.a1b2f","type":"change","z":"b02fc92d.2f9688","name":"getRandomDrink: valid ","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t \"jsonrpc\": \"2.0\",\t \"method\": \"getRandomDrink\",\t \"params\": {\t \"drinkType\": \"beer\"\t },\t \"id\": _msgid\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":1180,"wires":[["c52b1f9b.26f3e8"]]},{"id":"db1706e5.03282","type":"subflow:445e80b1.1eddc8","z":"b02fc92d.2f9688","name":"","x":250,"y":220,"wires":[["f32aa13c.c446d"]]},{"id":"aa6cea0.3f2c998","type":"subflow:26b8631b.4edf14","z":"b02fc92d.2f9688","name":"","x":1345,"y":240,"wires":[]},{"id":"81aa944f.6c5ec","type":"change","z":"b02fc92d.2f9688","name":"multiply: valid","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t \"jsonrpc\": \"2.0\",\t \"method\": \"multiply\",\t \"params\": {\t \"x\": 3,\t \"y\": 4\t },\t \"id\": _msgid\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":340,"y":1220,"wires":[["c52b1f9b.26f3e8"]]},{"id":"c564c5ba.4956a8","type":"inject","z":"b02fc92d.2f9688","name":"","topic":"json-rpc/testhost/request","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":1220,"wires":[["81aa944f.6c5ec"]]},{"id":"cb264b5e.6a3528","type":"inject","z":"b02fc92d.2f9688","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":1320,"wires":[["9b02e216.86311"]]},{"id":"9b02e216.86311","type":"change","z":"b02fc92d.2f9688","name":"getRandomDrink: valid ","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t \"jsonrpc\": \"2.0\",\t \"method\": \"getRandomDrink\",\t \"params\": {\t \"drinkType\": \"wine\"\t },\t \"id\": _msgid\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":1320,"wires":[["59725386.59aef4"]]},{"id":"60455fb7.d3e878","type":"tcp request","z":"b02fc92d.2f9688","server":"localhost","port":"8787","out":"sit","splitc":" ","name":"","x":930,"y":1320,"wires":[["4e57c9e2.4230a8"]]},{"id":"28ebf41e.5c1f1c","type":"debug","z":"b02fc92d.2f9688","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1450,"y":1320,"wires":[]},{"id":"4e57c9e2.4230a8","type":"function","z":"b02fc92d.2f9688","name":"","func":"msg.payload = msg.payload.toString()\nreturn msg;","outputs":1,"noerr":0,"x":1130,"y":1320,"wires":[["3eb2ecb.2aad594"]]},{"id":"59725386.59aef4","type":"json","z":"b02fc92d.2f9688","name":"","property":"payload","action":"","pretty":false,"x":590,"y":1320,"wires":[["a79338ee.30232"]]},{"id":"3eb2ecb.2aad594","type":"json","z":"b02fc92d.2f9688","name":"","property":"payload","action":"","pretty":false,"x":1270,"y":1320,"wires":[["28ebf41e.5c1f1c","f9898ae3.3e8418","df15444c.27fca8"]]},{"id":"e7013c3e.5a258","type":"change","z":"b02fc92d.2f9688","name":"multiply: above 100","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t \"jsonrpc\": \"2.0\",\t \"method\": \"multiply\",\t \"params\": {\t \"x\": 100,\t \"y\": 3\t },\t \"id\": _msgid\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":1360,"wires":[["59725386.59aef4"]]},{"id":"dc8dab67.7b2748","type":"inject","z":"b02fc92d.2f9688","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":1360,"wires":[["e7013c3e.5a258"]]},{"id":"20b00f12.fba37","type":"change","z":"b02fc92d.2f9688","name":"getTimeDelta: valid ","rules":[{"t":"set","p":"timestamp","pt":"msg","to":"payload","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"{\t \"jsonrpc\": \"2.0\",\t \"method\": \"getTimeDelta\",\t \"params\": {\t \"timestamp\": payload\t },\t \"id\": _msgid\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":1420,"wires":[["59725386.59aef4"]]},{"id":"73baa10b.88afa8","type":"inject","z":"b02fc92d.2f9688","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":1420,"wires":[["20b00f12.fba37"]]},{"id":"e0cfdc32.4cecd","type":"change","z":"b02fc92d.2f9688","name":"getTimeDelta","rules":[{"t":"set","p":"payload","pt":"msg","to":"$millis() - payload.timestamp","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":810,"y":160,"wires":[["e452d56d.979058","b8194618.7bccf8"]]},{"id":"b3a6e80b.ce39a8","type":"change","z":"b02fc92d.2f9688","name":"getTimeDelta: valid ","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t \"jsonrpc\": \"2.0\",\t \"method\": \"getTimeDelta\",\t \"params\": {\t \"timestamp\": payload\t },\t \"id\": _msgid\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":900,"wires":[["de28797b.fd9118"]]},{"id":"1f6e296b.796af7","type":"inject","z":"b02fc92d.2f9688","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":900,"wires":[["b3a6e80b.ce39a8"]]},{"id":"b749a5a2.0c15b","type":"change","z":"b02fc92d.2f9688","name":"getTimeDelta: valid ","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t \"jsonrpc\": \"2.0\",\t \"method\": \"getTimeDelta\",\t \"params\": {\t \"timestamp\": payload\t },\t \"id\": _msgid\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":1260,"wires":[["c52b1f9b.26f3e8"]]},{"id":"3c441b17.0e5acc","type":"inject","z":"b02fc92d.2f9688","name":"","topic":"json-rpc/testhost/request","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":1260,"wires":[["b749a5a2.0c15b"]]},{"id":"a79338ee.30232","type":"change","z":"b02fc92d.2f9688","name":"\\n","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload & '\\n'","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":730,"y":1320,"wires":[["60455fb7.d3e878"]]},{"id":"f9898ae3.3e8418","type":"debug","z":"b02fc92d.2f9688","name":"","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload.result","x":1470,"y":1360,"wires":[]},{"id":"472eb255.32f35c","type":"tcp in","z":"445e80b1.1eddc8","name":"","server":"server","host":"","port":"8787","datamode":"stream","datatype":"utf8","newline":"\\n","topic":"","base64":false,"x":100,"y":200,"wires":[["9d1fa4e4.44b73"]]},{"id":"9d1fa4e4.44b73","type":"json","z":"445e80b1.1eddc8","name":"","property":"payload","action":"","pretty":false,"x":250,"y":200,"wires":[[]]},{"id":"16247389.9763ac","type":"tcp out","z":"26b8631b.4edf14","host":"","port":"","beserver":"reply","base64":false,"end":false,"name":"","x":670,"y":220,"wires":[]},{"id":"eee31871.b64cd8","type":"json","z":"26b8631b.4edf14","name":"","property":"payload","action":"","pretty":false,"x":330,"y":220,"wires":[["9bc5283b.76e98"]]},{"id":"9bc5283b.76e98","type":"change","z":"26b8631b.4edf14","name":"\\n","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload & '\\n'","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":470,"y":220,"wires":[["16247389.9763ac"]]},{"id":"df15444c.27fca8","type":"change","z":"b02fc92d.2f9688","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$millis() - timestamp","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1356.6666259765625,"y":1440,"wires":[["cb2663a8.032c58"]]},{"id":"cb2663a8.032c58","type":"debug","z":"b02fc92d.2f9688","name":"","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","x":1530,"y":1440,"wires":[]},{"id":"cc3964f1.65e94","type":"udp in","z":"b02fc92d.2f9688","name":"","iface":"","port":"3434","ipv":"udp4","multicast":"false","group":"","datatype":"utf8","x":240,"y":280,"wires":[["d0d9ada0.a00db8"]]},{"id":"73b6d679.6849f","type":"debug","z":"b02fc92d.2f9688","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":610,"y":300,"wires":[]},{"id":"d0d9ada0.a00db8","type":"json","z":"b02fc92d.2f9688","name":"","property":"payload","action":"","pretty":false,"x":370,"y":280,"wires":[["f32aa13c.c446d"]]},{"id":"b8194618.7bccf8","type":"debug","z":"b02fc92d.2f9688","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":949.9999389648438,"y":371.6666564941406,"wires":[]}]
{"$":"faae2b152f95d7a8690df440d90f5fadAyWDIezENM0KOQWznu0EgOmXXhlWvA=="}
{
"name": "json-rpc",
"description": "JSON-RPC Node-RED example",
"version": "0.0.1",
"dependencies": {
"node-red-contrib-json-schema-validator": "0.0.3"
},
"scripts": {
"start": "node node_modules/node-red/red.js -v -u ."
},
"node-red": {
"settings": {
"flowFile": "flow.json",
"credentialsFile": "flow_cred.json"
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment