Poll2PushConverter With Call Chain

This helper node aims at performing synchronous calls for polling in case of an async API (calls that return prior to completion, e.g. in the case of non blocking calls in OW, the initial request is returned with a submission success and an activation id in order to follow up on the result).

Generic_T4 2-Copy of PEF CHAIN drawio

The main difference from the previous PollTOPushConverter (https://flows.nodered.org/flow/fe8a1ff325abebcf99ffc63744a3c231/in/VOf-0UrN5e2j) is that it supports also function chaining (through a msg.functionChain or UI set boolean parameter). This means that if the activated function can chain itself, to avoid OW maximum runtime timeout, the node can follow-up on the new activation ID and push a notification until all the chain has finished.

poll2pushFC_simple

The according function should return as a response the following structure:

  • have a result.status field with the 'Completed' (if chain is finished) or 'Continuing' string if the function has handed over to a new function in the chain.
  • have a result.newActivationIDURL field that indicates the updated ID with which to check the follow-up action's status

The node also can get credentials from the msg.creds field of the input message.

[{"id":"789351ac.02c9d","type":"subflow","name":"PollTOPushConverterFC","info":"This helper node aims at performing synchronous calls for polling in case of an async API (calls that return prior to completion, e.g. in the case of non blocking calls in OW, the initial request is returned with a submission success and an activation id in order to follow up on the result). The main difference from the main PollTOPushConverter is that it supports also function chaining (through a msg.functionChain or UI set boolean parameter).\n\nThe according function should return as a response the following structure:\n-have a result.status field with the 'Completed' (if chain is finished) or 'Continuing' string if the function has handed over to a new function in the chain.\n- have a result.newActivationIDURL field that indicates the updated ID with which to check the follow-up action's status \n\nThe remaining operations are similar with the standard PollTOPushConverter. The node does polling to a specific endpoint in order to detect whether the function has successfully finished\n\nThe node has three outputs:\n - Output 1 indicates successful finalization of the API call\n - Output 2 indicates intermediate failure and was added to return the reason for failure\n - Output 3 indicates final failure after max attempts\n\nCurrently the node assumes that in case of failure we get a >=40X return code, but this may not always be the case.\n\nThe node can be configured for the URL (msg.url), the HTTP method (msg.method), the maximum attempts (msg.maxAttempts), polling period (msg.pollPeriod), the status code above which to retry (msg.retryCode) and the status code for deciding the final success (msg.acceptCode). The msg properties override the UI set properties.\n\nGiven that conditions upon which the initial call needs to be polled are highly dependent on the used API, the node assumes that the initial call has been performed a priori.\n\nCredentials for accessing the HTTP endpoint can be set via msg.creds or through the UI (input msg prevails).\n \n","category":"PHYSICS Helpers","in":[{"x":60,"y":160,"wires":[{"id":"7d194c10.33b51c"}]}],"out":[{"x":1380,"y":40,"wires":[{"id":"f9d0aba7.72382","port":0},{"id":"1bbc6fa0.4879c","port":0}]},{"x":780,"y":260,"wires":[{"id":"c2cf68b7.263d4","port":0}]},{"x":780,"y":360,"wires":[{"id":"c2cf68b7.263d4","port":1}]}],"env":[{"name":"maxAttempts","type":"str","value":"3"},{"name":"pollPeriod","type":"str","value":"3000"},{"name":"method","type":"str","value":""},{"name":"url","type":"str","value":"http://10.100.59.182:3233/api/v1/namespaces/_/activations/"},{"name":"retryCode","type":"num","value":"202"},{"name":"acceptCode","type":"num","value":"200"},{"name":"functionChain","type":"bool","value":"true"}],"color":"#b4e8a9"},{"id":"7d194c10.33b51c","type":"function","z":"789351ac.02c9d","name":"defaults+activation id","func":"\nif (msg.hasOwnProperty('maxAttempts')){\n    msg.iterations=msg.maxAttempts;\n} else {\n    msg.iterations=env.get('maxAttempts');\n}\n//needed to reset the iterations after function chaining\nmsg.defaultAttempts=msg.iterations;\n\nif (msg.hasOwnProperty('pollPeriod')){\n    \n} else {\n    msg.pollPeriod=env.get('pollPeriod');\n}\n\nif (msg.hasOwnProperty('method')){\n    \n} else {\n    msg.method=env.get('method');\n}\n\nif (msg.hasOwnProperty('url')){\n    \n} else {\n    msg.url=env.get('url');\n}\n\nif (msg.hasOwnProperty('retryCode')){\n    \n} else {\n    msg.retryCode=env.get('retryCode');\n}\n\nif (msg.hasOwnProperty('acceptCode')){\n    \n} else {\n    msg.acceptCode=env.get('acceptCode');\n}\n\nif (msg.hasOwnProperty('creds')){\n    \n} else {\n    msg.creds=env.get('creds');\n}\n\nif (msg.hasOwnProperty('functionChain')){\n    \n} else {\n    msg.functionChain=env.get('functionChain');\n}\n\nif (msg.hasOwnProperty('inputData')){\n    if (msg.inputData.hasOwnProperty('creds')){\n        msg.creds=msg.inputData.creds;\n    }\n}\n\n\n\nmsg.delay=msg.pollPeriod;\nmsg.start=Date.now();\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":200,"y":160,"wires":[["cad17b04.a2b4d8"]]},{"id":"4be3f205.3e8dc4","type":"function","z":"789351ac.02c9d","name":"iterations--","func":"msg.iterations=msg.iterations-1;\nreturn msg;","outputs":1,"noerr":0,"x":350,"y":300,"wires":[["c2cf68b7.263d4","d8305759.866988"]]},{"id":"c2cf68b7.263d4","type":"switch","z":"789351ac.02c9d","name":"if iterations finished","property":"iterations","propertyType":"msg","rules":[{"t":"gte","v":"1","vt":"num"},{"t":"lt","v":"1","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":550,"y":300,"wires":[["cad17b04.a2b4d8"],[]]},{"id":"76299695.812bd8","type":"comment","z":"789351ac.02c9d","name":"SUCCESS","info":"","x":1100,"y":60,"wires":[]},{"id":"48093072.b17a6","type":"comment","z":"789351ac.02c9d","name":"FINAL FAIL","info":"","x":890,"y":360,"wires":[]},{"id":"d5960f2f.2e9448","type":"delay","z":"789351ac.02c9d","name":"delay","pauseType":"delayv","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":170,"y":300,"wires":[["4be3f205.3e8dc4"]]},{"id":"471b3d64.265894","type":"http request","z":"789351ac.02c9d","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"","tls":"2934f390.711324","persist":false,"proxy":"","authType":"","x":590,"y":160,"wires":[["8694180b.ec1c68"]]},{"id":"8694180b.ec1c68","type":"switch","z":"789351ac.02c9d","name":"Status code check","property":"statusCode","propertyType":"msg","rules":[{"t":"lte","v":"acceptCode","vt":"msg"},{"t":"gte","v":"retryCode","vt":"msg"}],"checkall":"true","repair":false,"outputs":2,"x":810,"y":160,"wires":[["f9d0aba7.72382"],["d5960f2f.2e9448"]]},{"id":"ef03414f.ad9d78","type":"comment","z":"789351ac.02c9d","name":"RETRY FAIL","info":"","x":890,"y":260,"wires":[]},{"id":"66bbc0cf.0c62f","type":"debug","z":"789351ac.02c9d","name":"BEFORE AUTH","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":370,"y":100,"wires":[]},{"id":"13791c2d.8cea7c","type":"debug","z":"789351ac.02c9d","name":"URL","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"url","targetType":"msg","x":580,"y":100,"wires":[]},{"id":"cad17b04.a2b4d8","type":"function","z":"789351ac.02c9d","name":"add auth","func":"msg.headers={};\nvar auth = 'Basic ' + new Buffer(msg.creds).toString('base64');\nmsg.headers = {\n    \"Authorization\": auth\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":420,"y":160,"wires":[["471b3d64.265894"]]},{"id":"f2b7c4e4.a24c3","type":"function","z":"789351ac.02c9d","name":"adapt to new activation","func":"\n\nmsg.url=msg.payload.response.result.newActivationIDURL;\nmsg.iterations=msg.defaultAttempts+1;\nconsole.log('IN ADAPTATION TO ACTIVATION',msg.url);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1500,"y":160,"wires":[["d5960f2f.2e9448","ee1dbf44.7368f8"]]},{"id":"c338e47b.b00ed","type":"comment","z":"789351ac.02c9d","name":"FUNCTION CHAIN CONTINUATION","info":"","x":1240,"y":240,"wires":[]},{"id":"ee1dbf44.7368f8","type":"debug","z":"789351ac.02c9d","name":"AFTER CONTINUATION IN Poll2Push","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"payload","targetType":"msg","x":1420,"y":300,"wires":[]},{"id":"f9d0aba7.72382","type":"switch","z":"789351ac.02c9d","name":"is Chain","property":"functionChain","propertyType":"msg","rules":[{"t":"false"},{"t":"true"}],"checkall":"true","repair":false,"outputs":2,"x":1020,"y":160,"wires":[[],["6da1eea0.969368","1bbc6fa0.4879c"]]},{"id":"6da1eea0.969368","type":"debug","z":"789351ac.02c9d","name":"RESULT STATUS","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"payload","targetType":"msg","x":1100,"y":300,"wires":[]},{"id":"f20a68d.9711598","type":"debug","z":"789351ac.02c9d","name":"AFTER CODE CHECK","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"functionChain","targetType":"msg","x":890,"y":100,"wires":[]},{"id":"36905e62.dfad92","type":"debug","z":"789351ac.02c9d","name":"TOP1","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"payload","targetType":"msg","x":1120,"y":100,"wires":[]},{"id":"9610a737.bf275","type":"debug","z":"789351ac.02c9d","name":"TOP2","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"payload","targetType":"msg","x":1300,"y":100,"wires":[]},{"id":"c52af08f.756ee8","type":"debug","z":"789351ac.02c9d","name":"TOP3","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"payload","targetType":"msg","x":1600,"y":100,"wires":[]},{"id":"1bbc6fa0.4879c","type":"function","z":"789351ac.02c9d","name":"compare completion","func":"console.log('IN COMPARE COMPLETION',msg.payload.response);\nif (msg.payload.response.result.status==='Completed'){\n    return [msg,null];\n} else {\n    return [null,msg];\n}\n","outputs":2,"noerr":0,"initialize":"","finalize":"","x":1240,"y":160,"wires":[["c52af08f.756ee8"],["f2b7c4e4.a24c3"]]},{"id":"d8305759.866988","type":"debug","z":"789351ac.02c9d","name":"URL","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"iterations","targetType":"msg","x":500,"y":380,"wires":[]},{"id":"2934f390.711324","type":"tls-config","z":"789351ac.02c9d","name":"","cert":"","key":"","ca":"","certname":"","keyname":"","caname":"","servername":"","verifyservercert":false},{"id":"4b0793e93fa7e4c7","type":"http request","z":"427024e5.37e404","name":"initial activation","method":"POST","ret":"obj","paytoqs":"ignore","url":"","tls":"31ef8d59.cd9b1a","persist":false,"proxy":"","authType":"basic","x":660,"y":260,"wires":[["540c6a96ffd0ab86","41d82e9930225447"]]},{"id":"540c6a96ffd0ab86","type":"switch","z":"427024e5.37e404","name":"Code check","property":"statusCode","propertyType":"msg","rules":[{"t":"eq","v":"200","vt":"str"},{"t":"eq","v":"202","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":850,"y":260,"wires":[["3f83511dcd92a7ef"],["d8a8d3a0c03139a4"]]},{"id":"d8a8d3a0c03139a4","type":"function","z":"427024e5.37e404","name":"add OW activation id from reply","func":"\nmsg.activationID=msg.headers['x-openwhisk-activation-id'];\nmsg.headers={};\nmsg.url='https://10.100.59.208/api/v1/namespaces/_/activations/'+msg.activationID;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":550,"y":380,"wires":[["dd0f71bd93defd96"]]},{"id":"dd0f71bd93defd96","type":"subflow:789351ac.02c9d","z":"427024e5.37e404","name":"","env":[{"name":"maxAttempts","value":"20","type":"str"},{"name":"pollPeriod","value":"10000","type":"str"},{"name":"functionChain","value":"false","type":"bool"}],"x":820,"y":380,"wires":[["e66da8b9c97a2d05"],["d7b0aa24bf20315b"],["92aeb58e8babadf4"]]},{"id":"e66da8b9c97a2d05","type":"debug","z":"427024e5.37e404","name":"SUCCESS","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1050,"y":340,"wires":[]},{"id":"d7b0aa24bf20315b","type":"debug","z":"427024e5.37e404","name":"RETRY FAIL","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1050,"y":380,"wires":[]},{"id":"92aeb58e8babadf4","type":"debug","z":"427024e5.37e404","name":"FINAL FAIL","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1050,"y":420,"wires":[]},{"id":"3f83511dcd92a7ef","type":"debug","z":"427024e5.37e404","name":"FINISHED SUCCESSFULLY","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1040,"y":220,"wires":[]},{"id":"41d82e9930225447","type":"debug","z":"427024e5.37e404","name":"INITIAL RESPONSE","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":800,"y":180,"wires":[]},{"id":"f7c18ea1ec6662e6","type":"inject","z":"427024e5.37e404","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":260,"wires":[["c36ec2ae72710ac8"]]},{"id":"c36ec2ae72710ac8","type":"function","z":"427024e5.37e404","name":"insert action invocation url--ADD CREDS","func":"msg.url='https://10.100.59.208/api/v1/namespaces/guest/actions/helloLab';\nmsg.payload={};\n\n\nmsg.creds='USER:PWD';\n\nmsg.headers={};\nvar auth = 'Basic ' + new Buffer(msg.creds).toString('base64');\nmsg.headers = {\n    \"Authorization\": auth\n}\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":400,"y":260,"wires":[["4b0793e93fa7e4c7"]]},{"id":"31ef8d59.cd9b1a","type":"tls-config","name":"","cert":"","key":"","ca":"","certname":"","keyname":"","caname":"","servername":"","verifyservercert":false}]

Flow Info

Created 2 years, 1 month ago
Updated 1 year ago
Rating: not yet rated

Owner

Actions

Rate:

Node Types

Core
  • comment (x4)
  • debug (x14)
  • delay (x1)
  • function (x7)
  • http request (x2)
  • inject (x1)
  • switch (x4)
  • tls-config (x2)
Other
  • subflow (x1)
  • subflow:789351ac.02c9d (x1)

Tags

  • Poll2PushConverter
  • FunctionChain
  • Openwhisk
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option