diff --git a/app.js b/app.js index dab86bd..a6aa83a 100644 --- a/app.js +++ b/app.js @@ -1,9 +1,12 @@ import { app, uuid } from 'mu'; -import request from 'request'; +import fetch from 'node-fetch'; import services from '/config/rules.js'; import bodyParser from 'body-parser'; import dns from 'dns'; +const IP_LOOKUP_CACHE = new Map(); +const IP_LOOKUP_CACHE_RETRY_TIMEOUT = 15000; + // Also parse application/json as json app.use( bodyParser.json( { type: function(req) { @@ -152,47 +155,52 @@ async function sendRequest( entry, changeSets, muCallIdTrail, muSessionId ) { const method = entry.callback.method; const url = entry.callback.url; const headers = { "Content-Type": "application/json", "MU-AUTH-ALLOWED-GROUPS": changeSets[0].allowedGroups, "mu-call-id-trail": muCallIdTrail, "mu-call-id": uuid() , "mu-session-id": muSessionId }; - - if( entry.options && entry.options.resourceFormat ) { - // we should send contents - const body = formatChangesetBody( changeSets, entry.options ); - - // TODO: we now assume the mu-auth-allowed-groups will be the same - // for each changeSet. that's a simplification and we should not - // depend on it. - - requestObject = { - url, method, - headers, - body: body - }; - } else { - // we should only inform - requestObject = { url, method, headers }; - } + // TODO: we now assume the mu-auth-allowed-groups will be the same + // for each changeSet. that's a simplification and we should not + // depend on it. + const body = entry.options && entry.options.resourceFormat ? formatChangesetBody( changeSets, entry.options ): null; + if( process.env["DEBUG_DELTA_SEND"] ) console.log(`Executing send ${method} to ${url}`); - request( requestObject, function( error, response, body ) { - if( error ) { + try { + const response = await fetch(url, { + headers, + method, + body, + }); + if(await response) { + // const respText = await response.text(); + //console.log(respText); + } + } catch(e) { console.log(`Could not send request ${method} ${url}`); console.log(error); console.log(`NOT RETRYING`); // TODO: retry a few times when delta's fail to send } - - if( response ) { - // console.log( body ); - } - }); + } async function filterMatchesForOrigin( changeSets, entry ) { if( ! entry.options || !entry.options.ignoreFromSelf ) { return changeSets; } else { - const originIpAddress = await getServiceIp( entry ); - return changeSets.filter( (changeSet) => changeSet.origin != originIpAddress ); + try { + const originIpAddress = await getServiceIp( entry ); + if(originIpAddress) { + return changeSets.filter( (changeSet) => changeSet.origin != originIpAddress ); + } else{ + // we couldn't figure what's the ip address, thus we filter everything. not great, but this is just + // for experimenting + return []; + } + } catch(e) { + // handle the case when a service is down and the dns lookup cannot be performed. + console.log(`something went wrong for changeSets ${changeSets} and entry ${entry} during lookup ${e}`); + return []; // service is down anyway, don't send. + + } } } @@ -200,13 +208,25 @@ function hostnameForEntry( entry ) { return (new URL(entry.callback.url)).hostname; } -async function getServiceIp(entry) { +async function getServiceIp(entry, retry=false) { + const hostName = hostnameForEntry( entry ); + if(!retry && IP_LOOKUP_CACHE.has(hostName)) { + return IP_LOOKUP_CACHE.get(hostName); + } return new Promise( (resolve, reject) => { dns.lookup( hostName, { family: 4 }, ( err, address) => { - if( err ) + if( err ) { + IP_LOOKUP_CACHE.set(hostName, false); + setTimeout(async ()=> { + try { + await getServiceIp(entry, true); + }catch (e) { + } + }, IP_LOOKUP_CACHE_RETRY_TIMEOUT); // retry to put it in cache after x seconds reject( err ); - else + } else + IP_LOOKUP_CACHE.set(hostName, address); resolve( address ); } ); } ); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..2d30739 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,83 @@ +{ + "name": "delta-notifier", + "version": "0.1.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "delta-notifier", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "node-fetch": "^2.6.1" + } + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + }, + "dependencies": { + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } +} diff --git a/package.json b/package.json index 89a224e..4cf179a 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,6 @@ }, "homepage": "https://github.com/mu-semtech/delta-notifier#readme", "dependencies": { - "request": "^2.88.0" + "node-fetch": "^2.6.1" } }