From 0695aa0498dcb04e6689289e21dcbf8e5315ce13 Mon Sep 17 00:00:00 2001 From: Jacob Quatier Date: Sat, 30 Apr 2016 18:42:45 -0700 Subject: [PATCH] Filtering UP instances by default. Added tests. --- CHANGES.md | 2 ++ README.md | 13 +++++++++++++ src/EurekaClient.js | 16 ++++++++++++---- src/defaultConfig.js | 1 + test/EurekaClient.test.js | 31 ++++++++++++++++++++++++++----- 5 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 CHANGES.md diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 0000000..91f2134 --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,2 @@ +## 3.0.0 + - Populate registry cache with instances that have a status of `UP`, `filterUpInstances` can be set to `false` to disable. diff --git a/README.md b/README.md index 8424983..0b8dcaa 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,19 @@ If your have multiple availability zones and your DNS entries set up according t This will cause the client to perform a DNS lookup using `config.eureka.host` and `config.eureka.ec2Region`. The naming convention for the DNS TXT records required for this to function is also described in the Wiki article above. +## Configuration Options +option | default value | description +---- | --- | --- +`logger` | console logging | logger implementation for the client to use +`eureka.heartbeatInterval` | `30000` | milliseconds to wait between heartbeats +`eureka.registryFetchInterval` | `30000` | milliseconds to wait between registry fetches +`eureka.fetchRegistry` | `true` | enable/disable registry fetching +`eureka.filterUpInstances` | `true` | enable/disable filtering of instances with status === `UP` +`eureka.servicePath` | `/eureka/v2/apps/` | path to eureka REST service +`eureka.ssl` | `false` | enable SSL communication with Eureka server +`eureka.useDns` | `false` | look up Eureka server using DNS, see [Looking up Eureka Servers in AWS using DNS](#looking-up-eureka-servers-in-aws-using-dns) +`eureka.fetchMetadata` | `true` | fetch AWS metadata when in AWS environment, see [Configuring for AWS environments](#configuring-for-aws-environments) +`eureka.useLocalMetadata` | `false` | use local IP and local hostname from metadata when in an AWS environment. ## Debugging diff --git a/src/EurekaClient.js b/src/EurekaClient.js index 47758f0..77f8d46 100644 --- a/src/EurekaClient.js +++ b/src/EurekaClient.js @@ -340,19 +340,27 @@ export default class Eureka { /* Transforms the given application and places in client cache. If an application - has a single instance, the instance is placed into the cache as an array of one + has a single instance, the instance is placed into the cache as an array of one */ transformApp(app, cache) { if (app.instance.length) { - cache.app[app.name.toUpperCase()] = app.instance; - cache.vip[app.instance[0].vipAddress] = app.instance; - } else { + const instances = app.instance.filter((instance) => (this.validateInstance(instance))); + cache.app[app.name.toUpperCase()] = instances; + cache.vip[app.instance[0].vipAddress] = instances; + } else if (this.validateInstance(app.instance)) { const instances = [app.instance]; cache.vip[app.instance.vipAddress] = instances; cache.app[app.name.toUpperCase()] = instances; } } + /* + Returns true if instance filtering is disabled, or if the instance is UP + */ + validateInstance(instance) { + return (!this.config.eureka.filterUpInstances || instance.status === 'UP'); + } + /* Fetches the metadata using the built-in client and updates the instance configuration with the hostname and IP address. If the value of the config diff --git a/src/defaultConfig.js b/src/defaultConfig.js index c90d424..8e825c3 100644 --- a/src/defaultConfig.js +++ b/src/defaultConfig.js @@ -4,6 +4,7 @@ export default { heartbeatInterval: 30000, registryFetchInterval: 30000, fetchRegistry: true, + filterUpInstances: true, servicePath: '/eureka/v2/apps/', ssl: false, useDns: false, diff --git a/test/EurekaClient.test.js b/test/EurekaClient.test.js index ee2eb33..b5dee4b 100644 --- a/test/EurekaClient.test.js +++ b/test/EurekaClient.test.js @@ -512,9 +512,9 @@ describe('Eureka client', () => { registry = { applications: { application: {} }, }; - instance1 = { host: '127.0.0.1', port: 1000, vipAddress: 'vip1' }; - instance2 = { host: '127.0.0.2', port: 2000, vipAddress: 'vip2' }; - instance3 = { host: '127.0.0.2', port: 2000, vipAddress: 'vip2' }; + instance1 = { host: '127.0.0.1', port: 1000, vipAddress: 'vip1', status: 'UP' }; + instance2 = { host: '127.0.0.2', port: 2000, vipAddress: 'vip2', status: 'UP' }; + instance3 = { host: '127.0.0.2', port: 2000, vipAddress: 'vip2', status: 'UP' }; app1 = { name: 'theapp', instance: instance1 }; app2 = { name: 'theapptwo', instance: [instance2, instance3] }; client = new Eureka(config); @@ -548,6 +548,7 @@ describe('Eureka client', () => { let app; let instance1; let instance2; + let downInstance; let theVip; let cache; beforeEach(() => { @@ -556,8 +557,9 @@ describe('Eureka client', () => { }); client = new Eureka(config); theVip = 'theVip'; - instance1 = { host: '127.0.0.1', port: 1000, vipAddress: theVip }; - instance2 = { host: '127.0.0.2', port: 2000, vipAddress: theVip }; + instance1 = { host: '127.0.0.1', port: 1000, vipAddress: theVip, status: 'UP' }; + instance2 = { host: '127.0.0.2', port: 2000, vipAddress: theVip, status: 'UP' }; + downInstance = { host: '127.0.0.2', port: 2000, vipAddress: theVip, status: 'DOWN' }; app = { name: 'theapp' }; cache = { app: {}, vip: {} }; }); @@ -575,6 +577,25 @@ describe('Eureka client', () => { expect(cache.app[app.name.toUpperCase()].length).to.equal(2); expect(cache.vip[theVip].length).to.equal(2); }); + + it('should filter UP instances by default', () => { + app.instance = [instance1, instance2, downInstance]; + client.transformApp(app, cache); + expect(cache.app[app.name.toUpperCase()].length).to.equal(2); + expect(cache.vip[theVip].length).to.equal(2); + }); + + it('should not filter UP instances when filterUpInstances === false', () => { + config = makeConfig({ + instance: { dataCenterInfo: { name: 'Amazon' } }, + eureka: { filterUpInstances: false }, + }); + client = new Eureka(config); + app.instance = [instance1, instance2, downInstance]; + client.transformApp(app, cache); + expect(cache.app[app.name.toUpperCase()].length).to.equal(3); + expect(cache.vip[theVip].length).to.equal(3); + }); }); describe('addInstanceMetadata()', () => {