From b039fdad8b48e1e29745d6aefa515c3b6bcd4e89 Mon Sep 17 00:00:00 2001 From: geek Date: Fri, 12 May 2017 14:59:37 -0500 Subject: [PATCH] Better metrics insert and service changes --- portal-data/lib/index.js | 54 +++++++++++--- portal-data/test/index.js | 148 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+), 10 deletions(-) diff --git a/portal-data/lib/index.js b/portal-data/lib/index.js index fa886260..b98281bd 100644 --- a/portal-data/lib/index.js +++ b/portal-data/lib/index.js @@ -125,10 +125,32 @@ module.exports = class Data { }); } - getMetrics (deploymentId) { + getMetrics (containerId) { return new Promise((resolve, reject) => { - this._db.metrics.query({ deploymentId }, (err, metrics) => { - return err ? reject(err) : resolve(metrics || []); + this._db.metrics.get(containerId, (err, result) => { + return err ? reject(err) : resolve(result); + }); + }); + } + + insertMetrics (containerId, metrics) { + return new Promise((resolve, reject) => { + this._db.metrics.get(containerId, (err, existing) => { + if (err) { + return reject(err); + } + + if (existing) { + this._db.metrics.update(containerId, { metrics: this._db.append(metrics) }, (err) => { + return err ? reject(err) : resolve(existing); + }); + return; + } + + const entry = { id: containerId, metrics }; + this._db.metrics.insert(entry, { merge: true }, (err) => { + return err ? reject(err) : resolve(entry); + }); }); }); } @@ -140,6 +162,7 @@ module.exports = class Data { }); }); } + updateService (deploymentId, service) { return new Promise((resolve, reject) => { this._db.deployments.get(deploymentId, { filter: 'services' }, (err, deployment) => { @@ -147,18 +170,29 @@ module.exports = class Data { return reject(err); } - const services = deployment.services.map((currentService) => { - if (currentService.name === service.name) { - currentService.count = service.count; - } - - return currentService; + const serviceToUpdate = deployment.services.find((currentService) => { + return (currentService.name === service.name); }); - this._db.deployments.update(deploymentId, { services }, (err, keys) => { + if (!serviceToUpdate) { + deployment.services.push(service); + } else { + serviceToUpdate.count = service.count; + serviceToUpdate.containers = service.containers; + } + + this._db.deployments.update(deploymentId, { services: deployment.services }, (err) => { return err ? reject(err) : resolve(service); }); }); }); } + + deploymentChanges (handler) { + return new Promise((resolve, reject) => { + this._db.deployments.changes('*', { reconnect: true, handler }, (err) => { + return err ? reject(err) : resolve(); + }); + }); + } }; diff --git a/portal-data/test/index.js b/portal-data/test/index.js index 653f1f06..8291c37f 100644 --- a/portal-data/test/index.js +++ b/portal-data/test/index.js @@ -55,3 +55,151 @@ describe('getDeployment()', () => { }); }); }); + +describe('updateService()', () => { + it('will update the services for an existing deployment', (done) => { + const data = new PortalData(internals.options); + data.connect().then(() => { + const deployment = { + name: 'User Services', + datacenter: 'us-sw-1' + }; + const service = { + name: 'consul', + containers: [ + { + server_id: '423e7432-b760-11e2-bf6c-002590c3f1a0', + alias: 'nodejsexample_consul_1', + image_id: '91b757b5-bd29-2126-5ff9-ae9235011ff5', + owner_id: '30f62ec2-24a2-6f8e-8fad-d46b04c8a0b9', + id: '81205d4a-92f4-c4d9-da8a-aafd689eeabb' + } + ], + count: 1 + }; + + data.createDeployment(deployment).then((deployment) => { + expect(deployment.id).to.exist(); + data.updateService(deployment.id, service).then((updatedService) => { + expect(updatedService).to.equal(service); + done(); + }); + }); + }); + }); +}); + +describe('deploymentChanges()', () => { + it('will execute the handler when a deployment service changes', (done) => { + const data = new PortalData(internals.options); + data.connect().then(() => { + const deployment = { + name: 'User Services', + datacenter: 'us-sw-1' + }; + const service1 = { + name: 'consul', + containers: [ + { + server_id: '423e7432-b760-11e2-bf6c-002590c3f1a0', + alias: 'nodejsexample_consul_1', + image_id: '91b757b5-bd29-2126-5ff9-ae9235011ff5', + owner_id: '30f62ec2-24a2-6f8e-8fad-d46b04c8a0b9', + id: '81205d4a-92f4-c4d9-da8a-aafd689eeabb' + } + ], + count: 1 + }; + + const service2 = { + name: 'consul', + containers: [ + { + server_id: '423e7432-b760-11e2-bf6c-002590c3f1a0', + alias: 'nodejsexample_consul_1', + image_id: '91b757b5-bd29-2126-5ff9-ae9235011ff5', + owner_id: '30f62ec2-24a2-6f8e-8fad-d46b04c8a0b9', + id: '81205d4a-92f4-c4d9-da8a-aafd689eeabb' + }, + { + server_id: '423e7432-b760-11e2-bf6c-002590c3f1a0', + alias: 'nodejsexample_consul_2', + image_id: '91b757b5-bd29-2126-5ff9-ae9235011ff5', + owner_id: '30f62ec2-24a2-6f8e-8fad-d46b04c8a0b9', + id: '81205d4a-92f4-c4d9-da8a-aafd689eeabb' + }, + { + server_id: '423e7432-b760-11e2-bf6c-002590c3f1a0', + alias: 'nodejsexample_consul_3', + image_id: '91b757b5-bd29-2126-5ff9-ae9235011ff5', + owner_id: '30f62ec2-24a2-6f8e-8fad-d46b04c8a0b9', + id: '81205d4a-92f4-c4d9-da8a-aafd689eeabb' + } + ], + count: 3 + }; + + data.createDeployment(deployment).then((deployment) => { + expect(deployment.id).to.exist(); + data.updateService(deployment.id, service1).then((updatedService1) => { + expect(updatedService1).to.equal(service1); + + let executed = false; + data.deploymentChanges((err, changes) => { + if (executed) { + return; + } + + expect(changes.before).to.exist(); + expect(changes.after).to.exist(); + done(); + executed = true; + }).then(() => { + data.updateService(deployment.id, service2).then((updatedService2) => { + expect(updatedService2).to.equal(service2); + }); + }); + }); + }); + }); + }); +}); + + +describe('insertMetrics()', () => { + it('will add new metrics to a service and won\'t overwrite existing ones', (done) => { + const data = new PortalData(internals.options); + data.connect().then(() => { + const containerId = '81205d4a-92f4-c4d9-da8a-aafd689eeabb'; + const metrics1 = [ + { + timestamp: 1494360995851, + cpu: 1.2, + memory: 23344523, + network: 5024 + } + ]; + + const metrics2 = [ + { + timestamp: 1495360995851, + cpu: 1.3, + memory: 23344523, + network: 4024 + } + ]; + + data.insertMetrics(containerId, metrics1).then((result1) => { + expect(result1.id).to.equal(containerId); + expect(result1.metrics).to.equal(metrics1); + data.insertMetrics(containerId, metrics2).then((result2) => { + expect(result2.id).to.equal(containerId); + data.getMetrics(containerId).then((results) => { + expect(results.metrics.length).to.equal(2); + done(); + }); + }); + }); + }); + }); +});