Skip to content

Commit

Permalink
added event support
Browse files Browse the repository at this point in the history
  • Loading branch information
awolden committed May 2, 2016
1 parent bf7fc60 commit be13288
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
## 3.0.0
- Added support for the following events: `started`, `registered`, `deregistered`, `heartbeat`, and `registryUpdated`.
- Improved the stability of the client when it encounters downstream DNS errors, as a side-effect the callback for `fetchRegistries()` now returns errors when they are encountered.
- Populate registry cache with instances that have a status of `UP`, `filterUpInstances` can be set to `false` to disable.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,18 @@ option | default value | description
`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.

## Events

Eureka client is an instance of `EventEmitter` and provides the following events for consumption:

event | data provided | description
---- | --- | ---
`started` | N/A | Fired when eureka client is fully registered and all registries have been updated.
`registered` | N/A | Fired when the eureka client is registered with eureka.
`deregistered` | N/A | Fired when the eureka client is deregistered with eureka.
`heartbeat` | N/A | Fired when the eureka client has successfully renewed it's lease with eureka.
`registryUpdated` | N/A | Fired when the eureka client has successfully update it's registries.

## Debugging

The library uses [request](https://github.com/request/request) for all service calls, and debugging can be turned on by passing `NODE_DEBUG=request` when you start node. This allows you you double-check the URL being called as well as other request properties.
Expand Down
9 changes: 8 additions & 1 deletion src/EurekaClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import merge from 'deepmerge';
import path from 'path';
import dns from 'dns';
import { series } from 'async';
import { EventEmitter } from 'events';

import AwsMetadata from './AwsMetadata';
import Logger from './Logger';
Expand All @@ -28,9 +29,10 @@ function getYaml(file) {
return yml;
}

export default class Eureka {
export default class Eureka extends EventEmitter {

constructor(config = {}) {
super();
// Allow passing in a custom logger:
this.logger = config.logger || new Logger();

Expand Down Expand Up @@ -134,6 +136,7 @@ export default class Eureka {
},
], (err, ...rest) => {
if (err) this.logger.warn('Error starting the Eureka Client', err);
this.emit('started');
callback(err, ...rest);
});
}
Expand Down Expand Up @@ -189,6 +192,7 @@ export default class Eureka {
'registered with eureka: ',
`${this.config.instance.app}/${this.instanceId}`
);
this.emit('registered');
return callback(null);
} else if (error) {
this.logger.warn('Error registering with eureka client.', error);
Expand Down Expand Up @@ -216,6 +220,7 @@ export default class Eureka {
'de-registered with eureka: ',
`${this.config.instance.app}/${this.instanceId}`
);
this.emit('deregistered');
return callback(null);
} else if (error) {
this.logger.warn('Error deregistering with eureka', error);
Expand Down Expand Up @@ -250,6 +255,7 @@ export default class Eureka {
}, (error, response, body) => {
if (!error && response.statusCode === 200) {
this.logger.debug('eureka heartbeat success');
this.emit('heartbeat');
} else if (!error && response.statusCode === 404) {
this.logger.warn('eureka heartbeat FAILED, Re-registering app');
this.register();
Expand Down Expand Up @@ -322,6 +328,7 @@ export default class Eureka {
if (!error && response.statusCode === 200) {
this.logger.debug('retrieved registry successfully');
this.transformRegistry(JSON.parse(body));
this.emit('registryUpdated');
return callback(null);
} else if (error) {
this.logger.warn('Error fetching registry', error);
Expand Down
41 changes: 41 additions & 0 deletions test/EurekaClient.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import sinon from 'sinon';
import chai, { expect } from 'chai';
import sinonChai from 'sinon-chai';
import request from 'request';
import { EventEmitter } from 'events';
import dns from 'dns';
import { join } from 'path';
import merge from 'deepmerge';
Expand All @@ -29,6 +30,10 @@ function makeConfig(overrides = {}) {

describe('Eureka client', () => {
describe('Eureka()', () => {
it('should extend EventEmitter', () => {
expect(new Eureka(makeConfig())).to.be.instanceof(EventEmitter);
});

it('should throw an error if no config is found', () => {
function fn() {
return new Eureka();
Expand Down Expand Up @@ -131,12 +136,16 @@ describe('Eureka client', () => {
fetchRegistrySpy = sinon.stub(client, 'fetchRegistry').callsArg(0);
heartbeatsSpy = sinon.stub(client, 'startHeartbeats');
registryFetchSpy = sinon.stub(client, 'startRegistryFetches');
const eventSpy = sinon.spy();
client.on('started', eventSpy);

client.start(() => {
expect(registerSpy).to.have.been.calledOnce;
expect(fetchRegistrySpy).to.have.been.calledOnce;
expect(heartbeatsSpy).to.have.been.calledOnce;
expect(registryFetchSpy).to.have.been.calledOnce;
expect(registryFetchSpy).to.have.been.calledOnce;
expect(eventSpy).to.have.been.calledOnce;
done();
});
});
Expand Down Expand Up @@ -228,6 +237,13 @@ describe('Eureka client', () => {
afterEach(() => {
request.post.restore();
});
it('should trigger register event', () => {
sinon.stub(request, 'post').yields(null, { statusCode: 204 }, null);
const eventSpy = sinon.spy();
client.on('registered', eventSpy);
client.register();
expect(eventSpy).to.have.been.calledOnce;
});

it('should call register URI', () => {
sinon.stub(request, 'post').yields(null, { statusCode: 204 }, null);
Expand Down Expand Up @@ -283,6 +299,14 @@ describe('Eureka client', () => {
request.del.restore();
});

it('should should trigger deregister event', () => {
sinon.stub(request, 'del').yields(null, { statusCode: 200 }, null);
const eventSpy = sinon.spy();
client.on('deregistered', eventSpy);
client.register();
client.deregister();
});

it('should call deregister URI', () => {
sinon.stub(request, 'del').yields(null, { statusCode: 200 }, null);
const deregisterCb = sinon.spy();
Expand Down Expand Up @@ -335,6 +359,15 @@ describe('Eureka client', () => {
});
});

it('should trigger a heartbeat event', () => {
sinon.stub(request, 'put').yields(null, { statusCode: 200 }, null);
const eventSpy = sinon.spy();
client.on('heartbeat', eventSpy);
client.renew();

expect(eventSpy).to.have.been.calledOnce;
});

it('should re-register on 404', () => {
sinon.stub(request, 'put').yields(null, { statusCode: 404 }, null);
sinon.stub(request, 'post').yields(null, { statusCode: 204 }, null);
Expand Down Expand Up @@ -518,6 +551,14 @@ describe('Eureka client', () => {
client.transformRegistry.restore();
});

it('should should trigger registryUpdated event', () => {
sinon.stub(request, 'get').yields(null, { statusCode: 200 }, null);
const eventSpy = sinon.spy();
client.on('registryUpdated', eventSpy);
client.fetchRegistry();
expect(eventSpy).to.have.been.calledOnce;
});

it('should call registry URI', () => {
sinon.stub(request, 'get').yields(null, { statusCode: 200 }, null);
const registryCb = sinon.spy();
Expand Down

0 comments on commit be13288

Please sign in to comment.