From d12e2990bed0d3fa53a3cd1faed92202bf03deed Mon Sep 17 00:00:00 2001 From: Matthew Bargar Date: Mon, 14 Mar 2016 17:13:32 -0400 Subject: [PATCH 1/3] Count API - count the number of documents in an index pattern --- src/plugins/kibana/index.js | 2 + .../routes/api/search/count/register_count.js | 25 ++++++++ .../kibana/server/routes/api/search/index.js | 5 ++ test/api_intern.js | 3 +- test/unit/api/search/_count.js | 64 +++++++++++++++++++ test/unit/api/search/index.js | 23 +++++++ 6 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 src/plugins/kibana/server/routes/api/search/count/register_count.js create mode 100644 src/plugins/kibana/server/routes/api/search/index.js create mode 100644 test/unit/api/search/_count.js create mode 100644 test/unit/api/search/index.js diff --git a/src/plugins/kibana/index.js b/src/plugins/kibana/index.js index b1ea675fd1057..88ab65eb3d38a 100644 --- a/src/plugins/kibana/index.js +++ b/src/plugins/kibana/index.js @@ -1,4 +1,5 @@ import ingest from './server/routes/api/ingest'; +import search from './server/routes/api/search'; module.exports = function (kibana) { return new kibana.Plugin({ @@ -38,6 +39,7 @@ module.exports = function (kibana) { init: function (server, options) { ingest(server); + search(server); } }); diff --git a/src/plugins/kibana/server/routes/api/search/count/register_count.js b/src/plugins/kibana/server/routes/api/search/count/register_count.js new file mode 100644 index 0000000000000..6e1592a2b0cb1 --- /dev/null +++ b/src/plugins/kibana/server/routes/api/search/count/register_count.js @@ -0,0 +1,25 @@ +import _ from 'lodash'; +import handleESError from '../../../../lib/handle_es_error'; + +export default function registerCount(server) { + server.route({ + path: '/api/kibana/{id}/_count', + method: 'POST', + handler: function (req, reply) { + const boundCallWithRequest = _.partial(server.plugins.elasticsearch.callWithRequest, req); + + boundCallWithRequest('count', { + allowNoIndices: false, + index: req.params.id + }) + .then( + function (res) { + reply({count: res.count}); + }, + function (error) { + reply(handleESError(error)); + } + ); + } + }); +} diff --git a/src/plugins/kibana/server/routes/api/search/index.js b/src/plugins/kibana/server/routes/api/search/index.js new file mode 100644 index 0000000000000..2dfea0d380d4f --- /dev/null +++ b/src/plugins/kibana/server/routes/api/search/index.js @@ -0,0 +1,5 @@ +import registerCount from './count/register_count'; + +export default function (server) { + registerCount(server); +} diff --git a/test/api_intern.js b/test/api_intern.js index c8b9b9aee4040..c30303e96c593 100644 --- a/test/api_intern.js +++ b/test/api_intern.js @@ -1,6 +1,7 @@ define({ suites: [ - 'test/unit/api/ingest/index' + 'test/unit/api/ingest/index', + 'test/unit/api/search/index' ], excludeInstrumentation: /(fixtures|node_modules)\//, loaderOptions: { diff --git a/test/unit/api/search/_count.js b/test/unit/api/search/_count.js new file mode 100644 index 0000000000000..eb27d941830f1 --- /dev/null +++ b/test/unit/api/search/_count.js @@ -0,0 +1,64 @@ +define(function (require) { + var Promise = require('bluebird'); + var _ = require('intern/dojo/node!lodash'); + var expect = require('intern/dojo/node!expect.js'); + + return function (bdd, scenarioManager, request) { + bdd.describe('Count API', function postIngest() { + + bdd.before(function () { + return scenarioManager.client.create({ + index: 'foo-1', + type: 'bar', + id: '1', + body: { + foo: 'bar' + } + }) + .then(function () { + return scenarioManager.client.create({ + index: 'foo-2', + type: 'bar', + id: '2', + body: { + foo: 'bar' + } + }); + }) + .then(function () { + return scenarioManager.client.indices.refresh({ + index: ['foo-1', 'foo-2'] + }); + }); + }); + + bdd.after(function () { + return scenarioManager.reload('emptyKibana') + .then(function () { + scenarioManager.client.indices.delete({ + index: 'foo*' + }); + }); + }); + + bdd.it('should return 200 with a document count for existing indices', function () { + return request.post('/kibana/foo-*/_count') + .expect(200) + .then(function (response) { + expect(response.body.count).to.be(2); + }); + }); + + bdd.it('should return 404 if a pattern matches no indices', function () { + return request.post('/kibana/doesnotexist-*/_count') + .expect(404); + }); + + bdd.it('should return 404 if a concrete index does not exist', function () { + return request.post('/kibana/concrete/_count') + .expect(404); + }); + + }); + }; +}); diff --git a/test/unit/api/search/index.js b/test/unit/api/search/index.js new file mode 100644 index 0000000000000..4da8df89441dd --- /dev/null +++ b/test/unit/api/search/index.js @@ -0,0 +1,23 @@ +define(function (require) { + var bdd = require('intern!bdd'); + var serverConfig = require('intern/dojo/node!../../../serverConfig'); + var ScenarioManager = require('intern/dojo/node!../../../fixtures/scenario_manager'); + var request = require('intern/dojo/node!supertest-as-promised'); + var url = require('intern/dojo/node!url'); + var count = require('./_count'); + + bdd.describe('search API', function () { + var scenarioManager = new ScenarioManager(url.format(serverConfig.servers.elasticsearch)); + request = request(url.format(serverConfig.servers.kibana) + '/api'); + + bdd.before(function () { + return scenarioManager.load('emptyKibana'); + }); + + bdd.after(function () { + return scenarioManager.unload('emptyKibana'); + }); + + count(bdd, scenarioManager, request); + }); +}); From 41fe73e57e7bdaf53596d4071f7095625ee7c4d1 Mon Sep 17 00:00:00 2001 From: Matthew Bargar Date: Tue, 15 Mar 2016 10:59:45 -0400 Subject: [PATCH 2/3] Support both GET and POST in the count API --- .../routes/api/search/count/register_count.js | 29 ++++++++++++------- test/unit/api/search/_count.js | 8 +++++ test/unit/api/search/index.js | 2 +- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/plugins/kibana/server/routes/api/search/count/register_count.js b/src/plugins/kibana/server/routes/api/search/count/register_count.js index 6e1592a2b0cb1..969906efb3484 100644 --- a/src/plugins/kibana/server/routes/api/search/count/register_count.js +++ b/src/plugins/kibana/server/routes/api/search/count/register_count.js @@ -2,16 +2,14 @@ import _ from 'lodash'; import handleESError from '../../../../lib/handle_es_error'; export default function registerCount(server) { - server.route({ - path: '/api/kibana/{id}/_count', - method: 'POST', - handler: function (req, reply) { - const boundCallWithRequest = _.partial(server.plugins.elasticsearch.callWithRequest, req); + const path = '/api/kibana/{id}/_count'; + const handler = function (req, reply) { + const boundCallWithRequest = _.partial(server.plugins.elasticsearch.callWithRequest, req); - boundCallWithRequest('count', { - allowNoIndices: false, - index: req.params.id - }) + boundCallWithRequest('count', { + allowNoIndices: false, + index: req.params.id + }) .then( function (res) { reply({count: res.count}); @@ -20,6 +18,17 @@ export default function registerCount(server) { reply(handleESError(error)); } ); - } + }; + + server.route({ + path, + method: 'POST', + handler + }); + + server.route({ + path, + method: 'GET', + handler }); } diff --git a/test/unit/api/search/_count.js b/test/unit/api/search/_count.js index eb27d941830f1..239a936cfd1ed 100644 --- a/test/unit/api/search/_count.js +++ b/test/unit/api/search/_count.js @@ -49,6 +49,14 @@ define(function (require) { }); }); + bdd.it('should support GET requests as well', function () { + return request.get('/kibana/foo-*/_count') + .expect(200) + .then(function (response) { + expect(response.body.count).to.be(2); + }); + }); + bdd.it('should return 404 if a pattern matches no indices', function () { return request.post('/kibana/doesnotexist-*/_count') .expect(404); diff --git a/test/unit/api/search/index.js b/test/unit/api/search/index.js index 4da8df89441dd..85fd81bc12253 100644 --- a/test/unit/api/search/index.js +++ b/test/unit/api/search/index.js @@ -1,6 +1,6 @@ define(function (require) { var bdd = require('intern!bdd'); - var serverConfig = require('intern/dojo/node!../../../serverConfig'); + var serverConfig = require('intern/dojo/node!../../../server_config'); var ScenarioManager = require('intern/dojo/node!../../../fixtures/scenario_manager'); var request = require('intern/dojo/node!supertest-as-promised'); var url = require('intern/dojo/node!url'); From 6b16b0b77e8930a3bf860fe96d0ff14f7984cc64 Mon Sep 17 00:00:00 2001 From: Matthew Bargar Date: Tue, 15 Mar 2016 16:51:25 -0400 Subject: [PATCH 3/3] Hapi can accept two methods for one route --- .../routes/api/search/count/register_count.js | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/plugins/kibana/server/routes/api/search/count/register_count.js b/src/plugins/kibana/server/routes/api/search/count/register_count.js index 969906efb3484..8e542afe70cf0 100644 --- a/src/plugins/kibana/server/routes/api/search/count/register_count.js +++ b/src/plugins/kibana/server/routes/api/search/count/register_count.js @@ -2,14 +2,16 @@ import _ from 'lodash'; import handleESError from '../../../../lib/handle_es_error'; export default function registerCount(server) { - const path = '/api/kibana/{id}/_count'; - const handler = function (req, reply) { - const boundCallWithRequest = _.partial(server.plugins.elasticsearch.callWithRequest, req); + server.route({ + path: '/api/kibana/{id}/_count', + method: ['POST', 'GET'], + handler: function (req, reply) { + const boundCallWithRequest = _.partial(server.plugins.elasticsearch.callWithRequest, req); - boundCallWithRequest('count', { - allowNoIndices: false, - index: req.params.id - }) + boundCallWithRequest('count', { + allowNoIndices: false, + index: req.params.id + }) .then( function (res) { reply({count: res.count}); @@ -18,17 +20,6 @@ export default function registerCount(server) { reply(handleESError(error)); } ); - }; - - server.route({ - path, - method: 'POST', - handler - }); - - server.route({ - path, - method: 'GET', - handler + } }); }