1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-07-26 13:48:33 +02:00

Cleanup route/metrics a bit

This commit is contained in:
ivaosthu 2016-11-11 15:46:59 +01:00
parent b14c766e97
commit 4f25533230
10 changed files with 121 additions and 86 deletions

View File

@ -22,7 +22,7 @@ class ClientMetricsStore {
this.db(TABLE) this.db(TABLE)
.whereRaw('created_at < now() - interval \'1 hour\'') .whereRaw('created_at < now() - interval \'1 hour\'')
.del() .del()
.then((res) => logger.info(`Delted ${res} metrics`)); .then((res) => logger.info(`Deleted ${res} metrics`));
} }
// Insert new client metrics // Insert new client metrics

View File

@ -0,0 +1,24 @@
const joi = require('joi');
const clientMetricsSchema = joi.object().keys({
appName: joi.string().required(),
instanceId: joi.string().required(),
bucket: joi.object().required()
.keys({
start: joi.date().required(),
stop: joi.date().required(),
toggles: joi.object(),
}),
});
const clientRegisterSchema = joi.object().keys({
appName: joi.string().required(),
instanceId: joi.string().required(),
strategies: joi.array()
.required()
.items(joi.string(), joi.any().strip()),
started: joi.date().required(),
interval: joi.number().required(),
});
module.exports = { clientMetricsSchema, clientRegisterSchema }

View File

@ -4,6 +4,7 @@ const logger = require('../logger');
const ClientMetrics = require('../client-metrics'); const ClientMetrics = require('../client-metrics');
const ClientMetricsService = require('../client-metrics/service'); const ClientMetricsService = require('../client-metrics/service');
const joi = require('joi'); const joi = require('joi');
const { clientMetricsSchema, clientRegisterSchema } = require('./metrics-schema');
module.exports = function (app, config) { module.exports = function (app, config) {
const { const {
@ -11,6 +12,7 @@ module.exports = function (app, config) {
clientStrategyStore, clientStrategyStore,
clientInstanceStore, clientInstanceStore,
} = config.stores; } = config.stores;
const metrics = new ClientMetrics(); const metrics = new ClientMetrics();
const service = new ClientMetricsService(clientMetricsStore); const service = new ClientMetricsService(clientMetricsStore);
@ -28,45 +30,17 @@ module.exports = function (app, config) {
res.json(metrics.getTogglesMetrics()); res.json(metrics.getTogglesMetrics());
}); });
const clientMetricsSchema = joi.object().keys({
appName: joi.string().required(),
instanceId: joi.string().required(),
bucket: joi.object().required()
.keys({
start: joi.date().required(),
stop: joi.date().required(),
toggles: joi.object()
.required()
.unknown()
.min(1)
.max(1000),
}),
});
app.post('/client/metrics', (req, res) => { app.post('/client/metrics', (req, res) => {
try { const data = req.body;
const data = typeof req.body === 'string' ? JSON.parse(req.body) : req.body; joi.validate(data, clientMetricsSchema, (err, cleaned) => {
const result = joi.validate(data, clientMetricsSchema); if (err) {
if (result.error) { return res.status(400).json(err);
throw result.error;
} }
service service.insert(cleaned)
.insert(result.value)
.catch(e => logger.error('Error inserting metrics data', e)); .catch(e => logger.error('Error inserting metrics data', e));
} catch (e) {
logger.error('Error receiving metrics', e); res.status(202).end();
} });
res.end();
});
const clientRegisterSchema = joi.object().keys({
appName: joi.string().required(),
instanceId: joi.string().required(),
strategies: joi.array()
.required()
.items(joi.string(), joi.any().strip()),
started: joi.date().required(),
interval: joi.number().required(),
}); });
app.post('/client/register', (req, res) => { app.post('/client/register', (req, res) => {
@ -84,10 +58,10 @@ module.exports = function (app, config) {
instanceId: cleaned.instanceId, instanceId: cleaned.instanceId,
clientIp, clientIp,
})) }))
.then(() => console.log('new client registerd')) .then(() => logger.info('New client registered!'))
.catch((error) => logger.error('Error registering client', error)); .catch((error) => logger.error('Error registering client', error));
res.end(); res.status(202).end();
}); });
}); });
@ -98,6 +72,6 @@ module.exports = function (app, config) {
app.get('/client/instances', (req, res) => { app.get('/client/instances', (req, res) => {
clientInstanceStore.getAll() clientInstanceStore.getAll()
.then(data => res.json(data)) .then(data => res.json(data))
.catch(err => console.error(err)); .catch(err => logger.error(err));
}); });
}; };

View File

@ -1,32 +1,23 @@
'use strict'; 'use strict';
const clientMetricsStore = require('./mocks/fake-metrics-store'); const store = require('./mocks/store');
const featureToggleStore = require('./mocks/fake-feature-toggle-store');
const strategyStore = require('./mocks/fake-strategies-store');
const supertest = require('supertest'); const supertest = require('supertest');
const assert = require('assert'); const assert = require('assert');
const sinon = require('sinon');
let request; let request;
let featureToggleStore;
describe('Unit: The features api', () => { describe('Unit: The features api', () => {
beforeEach(done => { beforeEach(done => {
featureToggleStore.reset(); const stores = store.createStores();
const app = require('../../../app')({ const app = require('../../../app')({
baseUriPath: '', baseUriPath: '',
stores: { stores: stores,
db: sinon.stub(),
eventStore: sinon.stub(),
featureToggleStore,
clientMetricsStore,
strategyStore,
clientStrategyStore: sinon.stub(),
clientInstanceStore: sinon.stub(),
},
}); });
featureToggleStore = stores.featureToggleStore;
request = supertest(app); request = supertest(app);
done(); done();
}); });

View File

@ -1,28 +1,17 @@
'use strict'; 'use strict';
const clientMetricsStore = require('./mocks/fake-metrics-store'); const store = require('./mocks/store');
const clientStrategyStore = require('./mocks/fake-client-strategy-store');
const clientInstanceStore = require('./mocks/fake-client-instance-store');
const supertest = require('supertest'); const supertest = require('supertest');
const assert = require('assert'); const assert = require('assert');
const sinon = require('sinon');
let request; let request;
describe('Unit: The metrics api', () => { describe('Unit: The metrics api', () => {
beforeEach(done => { beforeEach(done => {
const stores = store.createStores();
const app = require('../../../app')({ const app = require('../../../app')({
baseUriPath: '', baseUriPath: '',
stores: { stores: stores,
db: sinon.stub(),
eventStore: sinon.stub(),
featureToggleStore: sinon.stub(),
clientMetricsStore,
strategyStore: sinon.stub(),
clientStrategyStore,
clientInstanceStore,
},
}); });
request = supertest(app); request = supertest(app);
@ -32,8 +21,14 @@ describe('Unit: The metrics api', () => {
it('should register client', (done) => { it('should register client', (done) => {
request request
.post('/api/client/register') .post('/api/client/register')
.send({ appName: 'demo', instanceId: 'test', strategies: ['default'], started: Date.now(), interval: 10 }) .send({
.expect(200, done); appName: 'demo',
instanceId: 'test',
strategies: ['default'],
started: Date.now(),
interval: 10
})
.expect(202, done);
}); });
it('should require appName field', (done) => { it('should require appName field', (done) => {
@ -41,4 +36,33 @@ describe('Unit: The metrics api', () => {
.post('/api/client/register') .post('/api/client/register')
.expect(400, done) .expect(400, done)
}); });
it('should require strategies field', (done) => {
request
.post('/api/client/register')
.send({
appName: 'demo',
instanceId: 'test',
//strategies: ['default'],
started: Date.now(),
interval: 10
})
.expect(400, done)
});
it('should accept client metrics', (done) => {
request
.post('/api/client/metrics')
.send({
appName: 'demo',
instanceId: '1',
bucket: {
start: Date.now(),
stop: Date.now(),
toggles: {}
}
})
.expect(202, done)
});
}); });

View File

@ -1,5 +1,6 @@
'use strict'; 'use strict';
module.exports = { module.exports = {
reset: () => {},
insert: () => Promise.resolve(), insert: () => Promise.resolve(),
}; };

View File

@ -1,5 +1,6 @@
'use strict'; 'use strict';
module.exports = { module.exports = {
reset: () => {},
insert: () => Promise.resolve(), insert: () => Promise.resolve(),
}; };

View File

@ -1,5 +1,7 @@
'use strict'; 'use strict';
module.exports = { module.exports = {
reset: () => {},
getMetricsLastHour: () => Promise.resolve([]), getMetricsLastHour: () => Promise.resolve([]),
insert: () => Promise.resolve(),
}; };

View File

@ -0,0 +1,27 @@
const sinon = require('sinon');
const clientMetricsStore = require('./fake-metrics-store');
const clientStrategyStore = require('./fake-client-strategy-store');
const clientInstanceStore = require('./fake-client-instance-store');
const featureToggleStore = require('./fake-feature-toggle-store');
const strategyStore = require('./fake-strategies-store');
module.exports = {
createStores: () => {
clientMetricsStore.reset();
clientStrategyStore.reset();
clientInstanceStore.reset();
featureToggleStore.reset();
strategyStore.reset();
return {
db: sinon.stub(),
clientMetricsStore,
clientStrategyStore,
clientInstanceStore,
featureToggleStore,
strategyStore,
}
}
};

View File

@ -1,32 +1,23 @@
'use strict'; 'use strict';
const clientMetricsStore = require('./mocks/fake-metrics-store'); const store = require('./mocks/store');
const featureToggleStore = require('./mocks/fake-feature-toggle-store');
const strategyStore = require('./mocks/fake-strategies-store');
const supertest = require('supertest'); const supertest = require('supertest');
const assert = require('assert'); const assert = require('assert');
const sinon = require('sinon'); const sinon = require('sinon');
let request; let request;
let strategyStore;
describe('Unit: The strategies api', () => { describe('Unit: The strategies api', () => {
beforeEach(done => { beforeEach(done => {
strategyStore.reset(); const stores = store.createStores();
const app = require('../../../app')({ const app = require('../../../app')({
baseUriPath: '', baseUriPath: '',
stores: { stores: stores,
db: sinon.stub(),
eventStore: sinon.stub(),
featureToggleStore,
clientMetricsStore,
strategyStore,
clientStrategyStore: sinon.stub(),
clientInstanceStore: sinon.stub(),
},
}); });
strategyStore = stores.strategyStore;
request = supertest(app); request = supertest(app);
done(); done();
}); });