Skip to content

Commit

Permalink
Adds Health.js
Browse files Browse the repository at this point in the history
  • Loading branch information
montymxb committed Nov 2, 2017
1 parent 3002b25 commit 4b78644
Show file tree
Hide file tree
Showing 4 changed files with 259 additions and 3 deletions.
131 changes: 131 additions & 0 deletions spec/Health.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
"use strict";
/* Tests for Health reporting */

import Health from '../src/Health';

describe('Parse server health', () => {
it('should have expected default health report', (done) => {
expect(Health.getReport()).toEqual({
status: 'ok'
});

done();
});

it('should return expected complex report', (done) => {
Health.set('callback', function() {
return 'fancy_status';
});

done();
});

it('should return ok for get default status', (done) => {
const status = Health.get('status');
expect(status).toBe('ok');

done();
});

it('should set and get plain data', (done) => {
const string = 'foo-boo!';
Health.set('critical_status', string);
expect(Health.get('critical_status')).toBe(string);
expect(Health.getRaw('critical_status')).toBe(string);

const int = 42;
Health.set('critical_status', int);
expect(Health.get('critical_status')).toBe(int);
expect(Health.getRaw('critical_status')).toBe(int);

done();
});

it('should set and get data from a callback', (done) => {
Health.set('realtime_status', function() {
return 'super_good';
});

// test plain get
expect(Health.get('realtime_status')).toBe('super_good');

// test raw get
expect(Health.getRaw('realtime_status') instanceof Function).toBe(true);

done();
});

it('should empty report with clear all', (done) => {
Health.reset();
let all = Health.getAll();
expect(Object.keys(all).length > 0).toBe(true);

Health.clearAll();
all = Health.getAll();
expect(Object.keys(all).length).toBe(0);

done();
});

it('should go back to default on reset', (done) => {
Health.clearAll();
const all = Health.getAll();
expect(Object.keys(all).length).toBe(0);

Health.reset();
expect(Health.get('status')).toBe('ok');

done();
});

it('should add and override with setAll', (done) => {
Health.setAll({
status: 'new_status',
running: 1,
db: (() => {
return 'good';
})
});

expect(Health.get('status')).toBe('new_status');
expect(Health.get('running')).toBe(1);
expect(Health.get('db')).toBe('good');

// reset
Health.clearAll();
Health.set('status', 'ok');

done();
});

it('should remove data on clear', (done) => {
const key = 'unneeded';

Health.set(key, 1);
expect(Health.get(key)).toBe(1);

Health.clear(key);
expect(Health.get(key)).toBe(undefined);

done();
});

it('should remove callback on clear', (done) => {
const key = 'callback';

Health.set(key, function() {
return 'in_place';
});
expect(Health.get(key)).toBe('in_place');

Health.clear(key);
expect(Health.get(key)).toBe(undefined);

done();
});

it('should return null on unknown get', (done) => {
expect(Health.get('not_a_known_item')).toBe(undefined);
done();
})
});
1 change: 1 addition & 0 deletions spec/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ describe('server', () => {
url: 'http://localhost:8378/1/health',
}, (error, response) => {
expect(response.statusCode).toBe(200);
console.dir(response.body);
done();
});
});
Expand Down
125 changes: 125 additions & 0 deletions src/Health.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
//
// Holds configuration used for reporting server health statistics
// Additional callbacks to get information for reporting can be registered here
//

const Health = {

/**
* Sets up our report with default data
*/
setup() {
// reset to get started
this.reset();
},

/**
* Returns the default report data
*
* @returns {{status: string}}
*/
getDefaultReportData() {
return {
status: 'ok'
};
},

/**
* Gets the raw value for a given key
*
* @param {string }key Key to get value of
*/
getRaw(key) {
return this.reportData[key];
},

/**
* Gets a particular value in our health report
*
* @param {string} key Key to get value of
*/
get(key) {
const value = this.getRaw(key);
if(!(value instanceof Function)) {
// return data normally
return value;
} else {
// return function result
return value();
}
},

/**
* Gets all data, replacing functions with their call results
*
* @returns {{}}
*/
getAll() {
const all = {};
for(const key in this.reportData) {
all[key] = this.get(key);
}
return all;
},

/**
* Sets a key/value pair of our health report
* The
*
* @param {string} key Key to set report data on
* @param {string|int|Object|Function} value Report data to set, this can also be a callback
*/
set(key, value) {
this.reportData[key] = value;
},

/**
* Sets all the given data on the current report, overriding any pre-existing data
*
* @param {Object} data
*/
setAll(data) {
for(const key in data) {
this.reportData[key] = data[key];
}
},

/**
* Clears a given key for this report
*
* @param key
*/
clear(key) {
delete this.reportData[key];
},

/**
* Clears all report data
*/
clearAll() {
this.reportData = {};
},

/**
* Prepares and returns the current health report
*
* @returns {{status: string}|*}
*/
getReport() {
// return our prepared report
return this.getAll();
},

/**
* Resets the current report data to it's defaults
*/
reset() {
this.reportData = this.getDefaultReportData();
}

};

// reset to populate report data
Health.setup();

module.exports = Health;
5 changes: 2 additions & 3 deletions src/ParseServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { SessionsRouter } from './Routers/SessionsRouter';
import { UsersRouter } from './Routers/UsersRouter';
import { PurgeRouter } from './Routers/PurgeRouter';
import { AudiencesRouter } from './Routers/AudiencesRouter';
import Health from './Health';

import { ParseServerRESTController } from './ParseServerRESTController';
import * as controllers from './Controllers';
Expand Down Expand Up @@ -138,9 +139,7 @@ class ParseServer {
}));

api.use('/health', (function(req, res) {
res.json({
status: 'ok'
});
res.json(Health.getReport());
}));

api.use('/', bodyParser.urlencoded({extended: false}), new PublicAPIRouter().expressRouter());
Expand Down

0 comments on commit 4b78644

Please sign in to comment.