UNPKG

eureka-js-client

Version:

A JavaScript implementation the Netflix OSS service registry, Eureka.

460 lines (459 loc) 14 kB
<!doctype html> <html lang="en"> <head> <title>Code coverage report for src/DnsClusterResolver.js</title> <meta charset="utf-8" /> <link rel="stylesheet" href="../prettify.css" /> <link rel="stylesheet" href="../base.css" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <style type='text/css'> .coverage-summary .sorter { background-image: url(../sort-arrow-sprite.png); } </style> </head> <body> <div class='wrapper'> <div class='pad1'> <h1> <a href="../index.html">all files</a> / <a href="index.html">src/</a> DnsClusterResolver.js </h1> <div class='clearfix'> <div class='fl pad1y space-right2'> <span class="strong">100% </span> <span class="quiet">Statements</span> <span class='fraction'>106/106</span> </div> <div class='fl pad1y space-right2'> <span class="strong">92.98% </span> <span class="quiet">Branches</span> <span class='fraction'>53/57</span> </div> <div class='fl pad1y space-right2'> <span class="strong">95.65% </span> <span class="quiet">Functions</span> <span class='fraction'>22/23</span> </div> <div class='fl pad1y space-right2'> <span class="strong">100% </span> <span class="quiet">Lines</span> <span class='fraction'>75/75</span> </div> <div class='fl pad1y'> <span class="strong">1 statement, 1 branch</span> <span class="quiet">Ignored</span> &nbsp;&nbsp;&nbsp;&nbsp; </div> </div> </div> <div class='status-line high'></div> <pre><table class="coverage"> <tr><td class="line-count quiet">1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131</td><td class="line-coverage quiet"><span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes">20×</span> <span class="cline-any cline-yes">20×</span> <span class="cline-any cline-yes">20×</span> <span class="cline-any cline-yes">20×</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes">18×</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes">10×</span> <span class="cline-any cline-yes">10×</span> <span class="cline-any cline-yes">10×</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes">21×</span> <span class="cline-any cline-yes">20×</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes">18×</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes">16×</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes">20×</span> <span class="cline-any cline-yes">20×</span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-yes"></span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes">19×</span> <span class="cline-any cline-yes">19×</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import dns from 'dns'; import async from 'async'; import shuffle from 'lodash/shuffle'; import xor from 'lodash/xor'; import Logger from './Logger'; &nbsp; <span class="fstat-no" title="function not covered" >function noop() {</span>} &nbsp; /* Locates a Eureka host using DNS lookups. The DNS records are looked up by a naming convention and TXT records must be created according to the Eureka Wiki here: https://github.com/Netflix/eureka/wiki/Configuring-Eureka-in-AWS-Cloud &nbsp; Naming convention: txt.&lt;REGION&gt;.&lt;HOST&gt; */ export default class DnsClusterResolver { constructor(config, logger) { this.logger = logger || new Logger(); this.serverList = undefined; this.config = config; if (!this.config.eureka.ec2Region) { throw new Error( 'EC2 region was undefined. ' + 'config.eureka.ec2Region must be set to resolve Eureka using DNS records.' ); } &nbsp; if (this.config.eureka.clusterRefreshInterval) { this.startClusterRefresh(); } } &nbsp; resolveEurekaUrl(callback, retryAttempt = 0) { this.getCurrentCluster((err) =&gt; { if (err) return callback(err); &nbsp; if (retryAttempt &gt; 0) { this.serverList.push(this.serverList.shift()); } const { port, servicePath, ssl } = this.config.eureka; const protocol = s</span>sl ? <span class="branch-0 cbranch-no" title="branch not covered" >'https' : 'http'; callback(null, `${protocol}://${this.serverList[0]}:${port}${servicePath}`); }); } &nbsp; getCurrentCluster(callback) { if (this.serverList) { return callback(null, this.serverList); } this.refreshCurrentCluster((err) =&gt; { if (err) return callback(err); return callback(null, this.serverList); }); } &nbsp; startClusterRefresh() { const refreshTimer = setInterval(() =&gt; { this.refreshCurrentCluster((err) =&gt; { if (<span class="missing-if-branch" title="else path not taken" >E</span>err) this.logger.warn(err.message); }); }, this.config.eureka.clusterRefreshInterval); refreshTimer.unref(); } &nbsp; refreshCurrentCluster(callback = <span class="branch-1 cbranch-no" title="branch not covered" >noop) {</span> this.resolveClusterHosts((err, hosts) =&gt; { if (err) return callback(err); // if the cluster is the same (aside from order), we want to maintain our order if (xor(this.serverList, hosts).length) { this.serverList = hosts; this.logger.info('Eureka cluster located, hosts will be used in the following order', this.serverList); } else { this.logger.debug('Eureka cluster hosts unchanged, maintaining current server list.'); } callback(); }); } &nbsp; resolveClusterHosts(callback = <span class="branch-1 cbranch-no" title="branch not covered" >noop) {</span> const { ec2Region, host, preferSameZone } = this.config.eureka; const { dataCenterInfo } = this.config.instance; const metadata = dataCenterInfo ? dataCenterInfo.metadata : undefined; const availabilityZone = metadata ? metadata['availability-zone'] : undefined; const dnsHost = `txt.${ec2Region}.${host}`; dns.resolveTxt(dnsHost, (err, addresses) =&gt; { if (err) { return callback(new Error( `Error resolving eureka cluster for region [${ec2Region}] using DNS: [${err}]` )); } const zoneRecords = [].concat(...addresses); const dnsTasks = {}; zoneRecords.forEach((zoneRecord) =&gt; { dnsTasks[zoneRecord] = (cb) =&gt; { this.resolveZoneHosts(`txt.${zoneRecord}`, cb); }; }); async.parallel(dnsTasks, (error, results) =&gt; { if (error) return callback(error); const hosts = []; const myZoneHosts = []; Object.keys(results).forEach((zone) =&gt; { if (preferSameZone &amp;&amp; availabilityZone &amp;&amp; zone.lastIndexOf(availabilityZone, 0) === 0) { myZoneHosts.push(...results[zone]); } else { hosts.push(...results[zone]); } }); const combinedHosts = [].concat(shuffle(myZoneHosts), shuffle(hosts)); if (!combinedHosts.length) { return callback( new Error(`Unable to locate any Eureka hosts in any zone via DNS @ ${dnsHost}`)); } callback(null, combinedHosts); }); }); } &nbsp; resolveZoneHosts(zoneRecord, callback) { dns.resolveTxt(zoneRecord, (err, results) =&gt; { if (err) { this.logger.warn(`Failed to resolve cluster zone ${zoneRecord}`, err.message); return callback(new Error(`Error resolving cluster zone ${zoneRecord}: [${err}]`)); } this.logger.debug(`Found Eureka Servers @ ${zoneRecord}`, results); callback(null, ([].concat(...results)).filter((value) =&gt; (!!value))); }); } } &nbsp;</pre></td></tr> </table></pre> <div class='push'></div><!-- for sticky footer --> </div><!-- /wrapper --> <div class='footer quiet pad2 space-top1 center small'> Code coverage generated by <a href="http://istanbul-js.org/" target="_blank">istanbul</a> at Fri May 31 2019 10:52:39 GMT-0700 (PDT) </div> </div> <script src="../prettify.js"></script> <script> window.onload = function () { if (typeof prettyPrint === 'function') { prettyPrint(); } }; </script> <script src="../sorter.js"></script> </body> </html>