Slight refactor to the api module, so it will simply extend the client like it did
This commit is contained in:
46
Gruntfile.js
46
Gruntfile.js
@ -23,19 +23,28 @@ module.exports = function (grunt) {
|
||||
options: {
|
||||
colors: true,
|
||||
require: 'should',
|
||||
reporter: 'dot'
|
||||
reporter: 'dot',
|
||||
bail: true,
|
||||
timeout: 11000
|
||||
}
|
||||
},
|
||||
jshint: {
|
||||
source: {
|
||||
src: [
|
||||
'src/**/*.js',
|
||||
'test/**/*.js',
|
||||
'Gruntfile.js'
|
||||
]
|
||||
},
|
||||
],
|
||||
options: {
|
||||
jshintrc: true
|
||||
jshintrc: '.jshintrc'
|
||||
}
|
||||
},
|
||||
tests: {
|
||||
src: [
|
||||
'test/**/*.js'
|
||||
],
|
||||
options: {
|
||||
jshintrc: 'test/.jshintrc'
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@ -52,6 +61,14 @@ module.exports = function (grunt) {
|
||||
options: {
|
||||
interupt: true
|
||||
}
|
||||
},
|
||||
run: {
|
||||
generate_js_api: {
|
||||
cmd: 'node',
|
||||
args: [
|
||||
'scripts/generate/js_api/index.js'
|
||||
]
|
||||
}
|
||||
}//,
|
||||
// docular: {
|
||||
// groups: [
|
||||
@ -100,10 +117,27 @@ module.exports = function (grunt) {
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
|
||||
|
||||
// Default task.
|
||||
// grunt.registerTask('docs', ['docular']);
|
||||
grunt.registerTask('test', ['jshint', 'mochaTest']);
|
||||
grunt.registerTask('default', ['jshint', 'mochaTest:unit']);
|
||||
|
||||
grunt.task.registerMultiTask('run', 'used to run arbitrary commands', function () {
|
||||
var done = this.async();
|
||||
var proc = require('child_process').spawn(
|
||||
this.data.cmd,
|
||||
this.data.args,
|
||||
{
|
||||
stdio: ['ignore', 'pipe', 'pipe']
|
||||
}
|
||||
);
|
||||
|
||||
proc.stdout.on('data', grunt.log.write);
|
||||
proc.stderr.on('data', grunt.log.error);
|
||||
|
||||
proc.on('close', function (exitCode) {
|
||||
done(!exitCode);
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
@ -24,7 +24,8 @@
|
||||
"grunt-contrib-watch": "~0.5.3",
|
||||
"expect.js": "~0.2.0",
|
||||
"async": "~0.2.9",
|
||||
"optimist": "~0.6.0"
|
||||
"optimist": "~0.6.0",
|
||||
"minimatch": "~0.2.12"
|
||||
},
|
||||
"license": "Apache License",
|
||||
"dependencies": {
|
||||
|
||||
@ -4,30 +4,48 @@ var path = require('path');
|
||||
var fs = require('fs');
|
||||
var mkdirp = require('mkdirp');
|
||||
|
||||
var outputDir = _.joinPath(__dirname, '../../../src/api/');
|
||||
var outputPath = _.joinPath(__dirname, '../../../src/lib/api.js');
|
||||
|
||||
var templates = require('./templates');
|
||||
var specs = require('./spec')(outputDir);
|
||||
var specs = require('./spec');
|
||||
|
||||
// completely delete the output directory
|
||||
function clean(path) {
|
||||
if (fs.existsSync(path)) {
|
||||
var clean = (function () {
|
||||
function rmDirRecursive(path) {
|
||||
fs.readdirSync(path).forEach(function (file, index) {
|
||||
var curPath = path + '/' + file;
|
||||
if (fs.statSync(curPath).isDirectory()) { // recurse
|
||||
clean(curPath);
|
||||
rmDirRecursive(curPath);
|
||||
} else { // delete file
|
||||
fs.unlinkSync(curPath);
|
||||
}
|
||||
});
|
||||
fs.rmdirSync(path);
|
||||
}
|
||||
|
||||
return function (path) {
|
||||
try {
|
||||
var stats = fs.statSync(path);
|
||||
if (stats && stats.isDirectory()) {
|
||||
console.log('removing', path, 'directory recursively');
|
||||
rmDirRecursive(path);
|
||||
} else {
|
||||
console.log('removing', path);
|
||||
fs.unlinkSync(path);
|
||||
}
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
exports.run = function () {
|
||||
var defs = [];
|
||||
var namespaces = [];
|
||||
|
||||
clean(outputPath);
|
||||
var actions = _.map(specs, function (spec) {
|
||||
spec.urls = _.map(
|
||||
_.sortBy(
|
||||
@ -67,9 +85,9 @@ exports.run = function () {
|
||||
});
|
||||
|
||||
var docUrl = spec.docUrl;
|
||||
var location = _.map(spec.name.split('.'), _.camelCase).join('.');
|
||||
|
||||
spec = _.pick(spec, [
|
||||
'name',
|
||||
'methods',
|
||||
'params',
|
||||
'urls',
|
||||
@ -85,7 +103,6 @@ exports.run = function () {
|
||||
]);
|
||||
}, {});
|
||||
|
||||
var location = _.map(spec.name.split('.'), _.camelCase).join('.');
|
||||
if (~location.indexOf('.')) {
|
||||
var steps = location.split('.');
|
||||
namespaces.push(steps.slice(0, -1).join('.'));
|
||||
@ -94,27 +111,18 @@ exports.run = function () {
|
||||
|
||||
// escape method names with "special" keywords
|
||||
location = location.replace(/(^|\.)(delete|default)(\.|$)/g, '[\'$2\']');
|
||||
|
||||
return templates.clientAction({spec: spec, location: location, docUrl: docUrl });
|
||||
return {
|
||||
spec: spec,
|
||||
location: location,
|
||||
docUrl: docUrl
|
||||
};
|
||||
});
|
||||
|
||||
namespaces = _.map(_.unique(namespaces.sort(), true), function (namespace) {
|
||||
return templates.clientActionNamespace({
|
||||
get: namespace,
|
||||
set: namespace.replace(/\./g, '.prototype.'),
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
var l = templates.lines(0);
|
||||
l('var ClientAction = require(\'./client_action\');');
|
||||
l('var errors = require(\'./errors\');');
|
||||
l('');
|
||||
l('exports.attach = function (Client) {').in();
|
||||
l.split(namespaces.join('') + '\n' + actions.join('\n'));
|
||||
l.out('};');
|
||||
|
||||
fs.writeFileSync(_.joinPath(__dirname, '../../../src/lib/api.js'), l.toString());
|
||||
console.log('writing', actions.length, 'api actions to', outputPath);
|
||||
fs.writeFileSync(outputPath, templates.apiFile({
|
||||
actions: actions,
|
||||
namespaces: _.unique(namespaces.sort(), true)
|
||||
}));
|
||||
};
|
||||
|
||||
exports.run();
|
||||
48
scripts/generate/js_api/spec.js
Normal file
48
scripts/generate/js_api/spec.js
Normal file
@ -0,0 +1,48 @@
|
||||
var _ = require('../../../src/lib/utils')
|
||||
|
||||
var docs = _.requireDir(module, '../../../es_api_spec/api');
|
||||
var aliases = require('./aliases');
|
||||
|
||||
var castNotFoundRE = /exists/;
|
||||
var usesBulkBodyRE = /^(bulk|msearch)$/;
|
||||
|
||||
var defs = [];
|
||||
|
||||
// itterate all of the found docs
|
||||
Object.keys(docs).forEach(function (filename) {
|
||||
Object.keys(docs[filename]).forEach(function (name) {
|
||||
var def = docs[filename][name];
|
||||
def.name = name;
|
||||
defs.push(def);
|
||||
})
|
||||
});
|
||||
|
||||
module.exports = _.map(defs, function (def) {
|
||||
var name = def.name;
|
||||
var steps = name.split('.');
|
||||
|
||||
var spec = {
|
||||
name: name,
|
||||
methods: _.map(def.methods, function (m) { return m.toUpperCase(); }),
|
||||
docUrl: def.documentation,
|
||||
urlParts: def.url.parts,
|
||||
params: def.url.params,
|
||||
urls: _.difference(def.url.paths, aliases[name]),
|
||||
body: def.body || null,
|
||||
path2lib: _.repeat('../', steps.length + 1) + 'lib/'
|
||||
};
|
||||
|
||||
if (def.body && def.body.requires) {
|
||||
spec.needBody = true;
|
||||
}
|
||||
|
||||
if (usesBulkBodyRE.test(name)) {
|
||||
spec.bulkBody = true;
|
||||
}
|
||||
|
||||
if (castNotFoundRE.test(name)) {
|
||||
spec.castNotFound = true;
|
||||
}
|
||||
|
||||
return spec;
|
||||
});
|
||||
27
scripts/generate/js_api/templates/api_file.tmpl
Normal file
27
scripts/generate/js_api/templates/api_file.tmpl
Normal file
@ -0,0 +1,27 @@
|
||||
var ca = require('./client_action').create;
|
||||
var errors = require('./errors');
|
||||
|
||||
var api = module.exports = {};
|
||||
|
||||
api._namespaces = <%= stringify(namespaces) %>;<%
|
||||
|
||||
_.each(actions, function (action) {
|
||||
var namespace = action.location.split('.').shift();
|
||||
if (_.contains(namespaces, namespace)) {
|
||||
_.pull(namespaces, namespace);
|
||||
var className = _.studlyCase(namespace) + 'NS';
|
||||
%>
|
||||
|
||||
api.<%= namespace %> = function <%= className %>(client) {
|
||||
if (this instanceof <%= className %>) {
|
||||
this.client = client;
|
||||
} else {
|
||||
return new <%= className %>(client);
|
||||
}
|
||||
};<%
|
||||
}
|
||||
%>
|
||||
|
||||
<%= partials.client_action(action) %><%
|
||||
|
||||
}); %>
|
||||
@ -9,4 +9,4 @@ _.each(spec.params, function(param, paramName) { %>
|
||||
}
|
||||
%><% }) %>
|
||||
*/
|
||||
Client.prototype<%= (location[0] === '[' ? '' : '.') + location %> = ClientAction(<%= stringify(spec, true) %>);
|
||||
api<%= (location[0] === '[' ? '' : '.') + location %> = ca(<%= stringify(spec, true) %>);
|
||||
@ -268,7 +268,9 @@ var templateGlobals = {
|
||||
l('this.client.request(request, cb);');
|
||||
}
|
||||
return l.toString();
|
||||
}
|
||||
},
|
||||
|
||||
partials: templates
|
||||
};
|
||||
|
||||
fs.readdirSync(path.resolve(__dirname)).forEach(function (filename) {
|
||||
@ -288,9 +290,6 @@ fs.readdirSync(path.resolve(__dirname)).forEach(function (filename) {
|
||||
templates.text = templates.string;
|
||||
|
||||
module.exports = {
|
||||
lines: lines,
|
||||
action: templates.action,
|
||||
clientAction: templates.client_action,
|
||||
clientActionNamespace: templates.client_action_namespace,
|
||||
apiFile: templates.api_file,
|
||||
urlParamRE: urlParamRE
|
||||
};
|
||||
@ -32,9 +32,10 @@ module.exports = Client;
|
||||
|
||||
var _ = require('./utils');
|
||||
var ClientConfig = require('./client_config');
|
||||
// var api = _.reKey(_.requireDir(module, '../api'), _.camelCase);
|
||||
var ca = require('./client_action').create;
|
||||
var q = require('q');
|
||||
var errors = require('./errors');
|
||||
var api = require('./api.js');
|
||||
|
||||
function Client(config) {
|
||||
this.client = this;
|
||||
@ -48,11 +49,13 @@ function Client(config) {
|
||||
});
|
||||
this.config.client = this;
|
||||
|
||||
for (var i = 0; i < _namespaces.length; i++) {
|
||||
this[_namespaces[i]] = new this[_namespaces[i]](this);
|
||||
for (var i = 0; i < this._namespaces.length; i++) {
|
||||
this[this._namespaces[i]] = new this[this._namespaces[i]](this);
|
||||
}
|
||||
}
|
||||
|
||||
Client.prototype = api;
|
||||
|
||||
/**
|
||||
* Perform a request with the client's transport
|
||||
*
|
||||
@ -91,7 +94,7 @@ Client.prototype.request = function (params, cb) {
|
||||
}
|
||||
|
||||
if (params.body && params.method === 'GET') {
|
||||
_.nextTick(cb, new TypeError('Body can not be sent with method "GET"'));
|
||||
respond(new TypeError('Body can not be sent with method "GET"'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -164,12 +167,13 @@ Client.prototype.request = function (params, cb) {
|
||||
* @param {Object} params - Currently just a placeholder, no params used at this time
|
||||
* @param {Function} cb - callback
|
||||
*/
|
||||
Client.prototype.ping = function (params, cb) {
|
||||
this.request({
|
||||
method: 'HEAD',
|
||||
path: '/'
|
||||
}, cb);
|
||||
};
|
||||
Client.prototype.ping = ca({
|
||||
methods: ['HEAD'],
|
||||
params: {},
|
||||
url: {
|
||||
fmt: '/'
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Ask an ES node for a list of all the nodes, add/remove nodes from the connection
|
||||
@ -193,26 +197,14 @@ Client.prototype.sniff = function (cb) {
|
||||
}
|
||||
cb(err, resp);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var _namespaces = [];
|
||||
|
||||
/**
|
||||
* These names of the properties that hold namespace objects in the Client prototype
|
||||
* @type {Array}
|
||||
* Shutdown the connections, log outputs, and clear timers
|
||||
*/
|
||||
Client.namespace = function (namespace) {
|
||||
var steps = namespace.split('.');
|
||||
var path = [];
|
||||
var on = Client;
|
||||
var i;
|
||||
for (i = 0; i < steps.length; i ++) {
|
||||
path.push(steps[i]);
|
||||
_namespaces.push(path.join('.'));
|
||||
on.prototype[steps[i]] = function ClientActionNamespace(client) {
|
||||
this.client = client;
|
||||
};
|
||||
}
|
||||
Client.prototype.close = function () {
|
||||
this.config.log.close();
|
||||
this.config.connectionPool.close();
|
||||
};
|
||||
|
||||
require('./api.js').attach(Client);
|
||||
|
||||
@ -51,6 +51,15 @@ function Log(config) {
|
||||
}
|
||||
_.inherits(Log, EventEmitter);
|
||||
|
||||
|
||||
Log.prototype.close = function () {
|
||||
this.emit('closing');
|
||||
if (EventEmitter.listenerCount(this)) {
|
||||
console.error('Something is still listening for log events, but the logger is closing.');
|
||||
this.clearAllListeners();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Levels observed by the loggers, ordered by rank
|
||||
*
|
||||
|
||||
396
src/lib/api.js
396
src/lib/api.js
File diff suppressed because it is too large
Load Diff
@ -32,9 +32,10 @@ module.exports = Client;
|
||||
|
||||
var _ = require('./utils');
|
||||
var ClientConfig = require('./client_config');
|
||||
// var api = _.reKey(_.requireDir(module, '../api'), _.camelCase);
|
||||
var ca = require('./client_action').create;
|
||||
var q = require('q');
|
||||
var errors = require('./errors');
|
||||
var api = require('./api.js');
|
||||
|
||||
function Client(config) {
|
||||
this.client = this;
|
||||
@ -48,11 +49,13 @@ function Client(config) {
|
||||
});
|
||||
this.config.client = this;
|
||||
|
||||
for (var i = 0; i < _namespaces.length; i++) {
|
||||
this[_namespaces[i]] = new this[_namespaces[i]](this);
|
||||
for (var i = 0; i < this._namespaces.length; i++) {
|
||||
this[this._namespaces[i]] = new this[this._namespaces[i]](this);
|
||||
}
|
||||
}
|
||||
|
||||
Client.prototype = api;
|
||||
|
||||
/**
|
||||
* Perform a request with the client's transport
|
||||
*
|
||||
@ -91,7 +94,7 @@ Client.prototype.request = function (params, cb) {
|
||||
}
|
||||
|
||||
if (params.body && params.method === 'GET') {
|
||||
_.nextTick(cb, new TypeError('Body can not be sent with method "GET"'));
|
||||
respond(new TypeError('Body can not be sent with method "GET"'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -164,12 +167,13 @@ Client.prototype.request = function (params, cb) {
|
||||
* @param {Object} params - Currently just a placeholder, no params used at this time
|
||||
* @param {Function} cb - callback
|
||||
*/
|
||||
Client.prototype.ping = function (params, cb) {
|
||||
this.request({
|
||||
method: 'HEAD',
|
||||
path: '/'
|
||||
}, cb);
|
||||
};
|
||||
Client.prototype.ping = ca({
|
||||
methods: ['HEAD'],
|
||||
params: {},
|
||||
url: {
|
||||
fmt: '/'
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Ask an ES node for a list of all the nodes, add/remove nodes from the connection
|
||||
@ -193,26 +197,14 @@ Client.prototype.sniff = function (cb) {
|
||||
}
|
||||
cb(err, resp);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var _namespaces = [];
|
||||
|
||||
/**
|
||||
* These names of the properties that hold namespace objects in the Client prototype
|
||||
* @type {Array}
|
||||
* Shutdown the connections, log outputs, and clear timers
|
||||
*/
|
||||
Client.namespace = function (namespace) {
|
||||
var steps = namespace.split('.');
|
||||
var path = [];
|
||||
var on = Client;
|
||||
var i;
|
||||
for (i = 0; i < steps.length; i ++) {
|
||||
path.push(steps[i]);
|
||||
_namespaces.push(path.join('.'));
|
||||
on.prototype[steps[i]] = function ClientActionNamespace(client) {
|
||||
this.client = client;
|
||||
};
|
||||
}
|
||||
Client.prototype.close = function () {
|
||||
this.config.log.close();
|
||||
this.config.connectionPool.close();
|
||||
};
|
||||
|
||||
require('./api.js').attach(Client);
|
||||
|
||||
@ -2,10 +2,10 @@
|
||||
* Constructs a function that can be called to make a request to ES
|
||||
* @type {[type]}
|
||||
*/
|
||||
module.exports = function clientAction(spec) {
|
||||
exports.create = function clientAction(spec) {
|
||||
return function (params, cb) {
|
||||
return exec(this.client, spec, params, cb);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var errors = require('./errors');
|
||||
@ -76,7 +76,7 @@ var castType = {
|
||||
};
|
||||
|
||||
function resolveUrl(url, params) {
|
||||
var vars = {}, name, i, key;
|
||||
var vars = {}, i, key;
|
||||
|
||||
if (url.req) {
|
||||
// url has required params
|
||||
@ -128,7 +128,7 @@ function resolveUrl (url, params) {
|
||||
// remove it from the params so that it isn't sent to the final request
|
||||
delete params[name];
|
||||
}, {}));
|
||||
};
|
||||
}
|
||||
|
||||
function exec(client, spec, params, cb) {
|
||||
if (typeof params === 'function') {
|
||||
@ -139,20 +139,25 @@ function exec(client, spec, params, cb) {
|
||||
cb = typeof cb === 'function' ? cb : _.noop;
|
||||
}
|
||||
|
||||
var request = {
|
||||
ignore: params.ignore
|
||||
};
|
||||
var request = {};
|
||||
var parts = {};
|
||||
var query = {};
|
||||
var i;
|
||||
|
||||
if (spec.needsBody && !params.body) {
|
||||
return _.nextTick(cb, new TyperError(spec.name + ' requires a request body.'));
|
||||
return _.nextTick(cb, new TypeError('A request body is required.'));
|
||||
}
|
||||
|
||||
if (params.body) {
|
||||
request.body = params.body;
|
||||
request.bulkBody = spec.bulkBody;
|
||||
}
|
||||
|
||||
if (spec.bulkBody) {
|
||||
request.bulkBody = true;
|
||||
}
|
||||
|
||||
if (params.ignore) {
|
||||
request.ignore = _.isArray(params.ignore) ? params.ignore : [params.ignore];
|
||||
}
|
||||
|
||||
if (spec.methods.length === 1) {
|
||||
@ -238,4 +243,4 @@ function exec(client, spec, params, cb) {
|
||||
} else {
|
||||
client.request(request, cb);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -54,12 +54,14 @@ ConnectionAbstract.prototype.setStatus = function (status) {
|
||||
|
||||
this.status = status;
|
||||
|
||||
if (status === 'dead') {
|
||||
if (status === 'dead' || status === 'closed') {
|
||||
if (this.__deadTimeout) {
|
||||
clearTimeout(this.__deadTimeout);
|
||||
}
|
||||
if (status === 'dead') {
|
||||
this.__deadTimeout = setTimeout(this.bound.resuscitate, this.config.deadTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
this.emit('status changed', status, origStatus, this);
|
||||
};
|
||||
|
||||
@ -93,13 +93,15 @@ ConnectionPool.prototype._remove = function (connection) {
|
||||
connection.setStatus('closed');
|
||||
connection.removeListener('status changed', this.bound.onStatusChanged);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ConnectionPool.prototype.setNodes = function (nodeConfigs) {
|
||||
var i;
|
||||
var connection;
|
||||
var i;
|
||||
var id;
|
||||
var node;
|
||||
var toRemove = _.clone(this.index);
|
||||
|
||||
for (i = 0; i < nodeConfigs.length; i++) {
|
||||
node = nodeConfigs[i];
|
||||
if (node.hostname && node.port) {
|
||||
@ -115,9 +117,9 @@ ConnectionPool.prototype.setNodes = function (nodeConfigs) {
|
||||
}
|
||||
|
||||
_.each(toRemove, this._remove, this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
ConnectionPool.prototype.empty = function () {
|
||||
ConnectionPool.prototype.close = function () {
|
||||
this.setNodes([]);
|
||||
};
|
||||
ConnectionPool.prototype.empty = ConnectionPool.prototype.close;
|
||||
|
||||
@ -70,8 +70,6 @@ HttpConnection.prototype.request = function (params, cb) {
|
||||
headers: _.defaults(params.headers || {}, defaultHeaders)
|
||||
});
|
||||
|
||||
log.debug('starting request', requestId);
|
||||
|
||||
// general clean-up procedure to run after the request, can only run once
|
||||
var cleanUp = function (err) {
|
||||
clearTimeout(timeoutId);
|
||||
@ -80,7 +78,7 @@ HttpConnection.prototype.request = function (params, cb) {
|
||||
incoming && incoming.removeAllListeners();
|
||||
|
||||
log.debug('calling back request', requestId, err ? 'with error "' + err.message + '"' : '');
|
||||
_.nextTick(cb, err, reqParams, response, status);
|
||||
cb(err, reqParams, response, status);
|
||||
|
||||
// override so this doesn't get called again
|
||||
cleanUp = _.noop;
|
||||
@ -88,9 +86,7 @@ HttpConnection.prototype.request = function (params, cb) {
|
||||
|
||||
reqParams.agent = this.agent;
|
||||
|
||||
request = http.request(reqParams);
|
||||
|
||||
request.on('response', function (_incoming) {
|
||||
request = http.request(reqParams, function (_incoming) {
|
||||
incoming = _incoming;
|
||||
status = incoming.statusCode;
|
||||
incoming.setEncoding('utf8');
|
||||
|
||||
@ -51,6 +51,15 @@ function Log(config) {
|
||||
}
|
||||
_.inherits(Log, EventEmitter);
|
||||
|
||||
|
||||
Log.prototype.close = function () {
|
||||
this.emit('closing');
|
||||
if (EventEmitter.listenerCount(this)) {
|
||||
console.error('Something is still listening for log events, but the logger is closing.');
|
||||
this.clearAllListeners();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Levels observed by the loggers, ordered by rank
|
||||
*
|
||||
|
||||
@ -85,7 +85,7 @@ LoggerAbstract.prototype.setupListeners = function (levels) {
|
||||
*/
|
||||
LoggerAbstract.prototype.cleanUpListeners = _.handler(function () {
|
||||
_.each(this.listeningLevels, function (level) {
|
||||
this.bridge.removeListener(level, this.handlers[level]);
|
||||
this.bridge.removeListener(level, this.bound['on' + _.ucfirst(level)]);
|
||||
}, this);
|
||||
});
|
||||
|
||||
|
||||
@ -295,7 +295,7 @@ utils.inherits = function (constructor, superConstructor) {
|
||||
* @returns {String}
|
||||
*/
|
||||
utils.trim = function (str) {
|
||||
return typeof str !== 'string' ? str.replace(/^\s+|\s+$/g, '') : '';
|
||||
return typeof str === 'string' ? str.replace(/^\s+|\s+$/g, '') : '';
|
||||
};
|
||||
|
||||
utils.collectMatches = function (text, regExp) {
|
||||
@ -385,8 +385,13 @@ utils.applyArgs = function (func, context, args, sliceIndex) {
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
_.nextTick = function (cb) {
|
||||
console.log('tick');
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
// bind the function and schedule it
|
||||
process.nextTick(_.bindKey(_, 'applyArgs', cb, null, arguments, 1));
|
||||
process.nextTick(function () {
|
||||
console.log('tock');
|
||||
cb.apply(null, args);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
// exports['cluster.node_info'] =
|
||||
// '//TODO: this enpoint ***needs*** work, many of the possible urls are not supported';
|
||||
@ -1,54 +0,0 @@
|
||||
var _ = require('../../../src/lib/utils')
|
||||
|
||||
var docs = _.requireDir(module, '../../../es_api_spec/api');
|
||||
var aliases = require('./aliases');
|
||||
var notes = require('./notes');
|
||||
|
||||
var castNotFoundRE = /exists/;
|
||||
var usesBulkBodyRE = /^(bulk|msearch)$/;
|
||||
|
||||
var defs = [];
|
||||
|
||||
// itterate all of the found docs
|
||||
Object.keys(docs).forEach(function (filename) {
|
||||
Object.keys(docs[filename]).forEach(function (name) {
|
||||
var def = docs[filename][name];
|
||||
def.name = name;
|
||||
defs.push(def);
|
||||
})
|
||||
});
|
||||
|
||||
module.exports = function (outputDir) {
|
||||
return _.map(defs, function (def) {
|
||||
var name = def.name;
|
||||
var steps = name.split('.');
|
||||
|
||||
var spec = {
|
||||
fileName: steps.pop() + '.js',
|
||||
dirName: _.joinPath(outputDir, steps.join('/') || './'),
|
||||
name: name,
|
||||
methods: _.map(def.methods, function (m) { return m.toUpperCase(); }),
|
||||
docUrl: def.documentation,
|
||||
urlParts: def.url.parts,
|
||||
params: def.url.params,
|
||||
urls: _.difference(def.url.paths, aliases[name]),
|
||||
body: def.body || null,
|
||||
path2lib: _.repeat('../', steps.length + 1) + 'lib/',
|
||||
notes: notes[name],
|
||||
};
|
||||
|
||||
if (def.body && def.body.requires) {
|
||||
spec.needBody = true;
|
||||
}
|
||||
|
||||
if (usesBulkBodyRE.test(name)) {
|
||||
spec.bulkBody = true;
|
||||
}
|
||||
|
||||
if (castNotFoundRE.test(name)) {
|
||||
spec.castNotFound = true;
|
||||
}
|
||||
|
||||
return spec;
|
||||
});
|
||||
};
|
||||
@ -1 +0,0 @@
|
||||
<%= set %> = <%= get %>;
|
||||
@ -1,7 +0,0 @@
|
||||
if (<%= get %>.toLowerCase && (<%= get %> = <%= get %>.toLowerCase())
|
||||
&& (<%= get %> === 'no' || <%= get %> === 'off')
|
||||
) {
|
||||
<%= set %> = false;
|
||||
} else {
|
||||
<%= set %> = !!<%= get %>;
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
Client.namespace(<%= stringify(get) %>);
|
||||
@ -1,5 +0,0 @@
|
||||
if (_.isNumeric(<%= get %>) || _.isInterval(<%= get %>)) {
|
||||
<%= set %> = <%= get %>;
|
||||
} else {
|
||||
throw new TypeError('Invalid <%= name %>: ' + <%= get %> + ' should be a number or in interval notation (an integer followed by one of Mwdhmsy).');
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
if (_.contains(<%= _.camelCase(name) %>Options, <%= get %>)) {
|
||||
<%= set %> = <%= get %>;
|
||||
} else {
|
||||
throw new TypeError(
|
||||
'Invalid <%= name %>: ' + <%= get %> +
|
||||
' should be one of ' + <%= _.camelCase(name) %>Options.join(', ') + '.'
|
||||
);
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
switch (typeof <%= get %>) {
|
||||
case 'string':
|
||||
<%= set %> = <%= get %>;
|
||||
break;
|
||||
case 'object':
|
||||
if (_.isArray(<%= get %>)) {
|
||||
<%= set %> = <%= get %>.join(',');
|
||||
} else {
|
||||
throw new TypeError('Invalid <%= name %>: ' + <%= get %> + ' should be a comma seperated list, array, or boolean.');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
<%= set %> = !!<%= get %>;
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
if (_.isNumeric(<%= get %>)) {
|
||||
<%= set %> = <%= get %> * 1;
|
||||
} else {
|
||||
throw new TypeError('Invalid <%= name %>: ' + <%= get %> + ' should be a number.');
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
if (typeof <%= get %> !== 'object' && <%= get %>) {
|
||||
<%= set %> = '' + <%= get %>;
|
||||
} else {
|
||||
throw new TypeError('Invalid <%= name %>: ' + <%= get %> + ' should be a string.');
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
if (<%= get %> instanceof Date) {
|
||||
<%= set %> = <%= get %>.getTime();
|
||||
} else if (_.isNumeric(<%= get %>)) {
|
||||
<%= set %> = <%= get %>;
|
||||
} else {
|
||||
throw new TypeError('Invalid <%= name %>: ' + <%= get %> + ' should be be some sort of time.');
|
||||
}
|
||||
@ -5,23 +5,25 @@ var path = require('path'),
|
||||
expect = require('expect.js'),
|
||||
server = require('./server'),
|
||||
_ = require('../../../src/lib/utils'),
|
||||
es = require('../../../src/elasticsearch');
|
||||
es = require('../../../src/elasticsearch'),
|
||||
Minimatch = require('minimatch').Minimatch;
|
||||
|
||||
var argv = require('optimist')
|
||||
.default('executable', path.join(process.env.ES_HOME, './bin/elasticsearch'))
|
||||
.default('clusterName', 'yaml-test-runner')
|
||||
.default('dataPath', '/tmp/yaml-test-runner')
|
||||
.default('hostname', 'localhost')
|
||||
.default('port', '9200')
|
||||
.default('match', '**')
|
||||
.boolean('createServer')
|
||||
.argv;
|
||||
|
||||
// if (argv.hostname || argv.port) {
|
||||
// console.log('working with ES instance at ' + argv.hostname + ':' + argv.port);
|
||||
// }
|
||||
Error.stackTraceLimit = Infinity;
|
||||
|
||||
// Where do the tests live?
|
||||
var TEST_DIR = path.resolve(__dirname, '../../../es_api_spec/test/');
|
||||
|
||||
// test names matching this will be run
|
||||
var doRE = /(^|\/)(.*)\/.*/;
|
||||
var doPattern = new Minimatch(argv.match);
|
||||
|
||||
// a reference to a personal instance of ES Server
|
||||
var esServer = null;
|
||||
@ -40,18 +42,50 @@ function clearIndices(done) {
|
||||
}, done);
|
||||
}
|
||||
|
||||
// before running any tests...
|
||||
before(function (done) {
|
||||
// start our personal ES Server
|
||||
this.timeout(null);
|
||||
if (argv.hostname) {
|
||||
done();
|
||||
} else {
|
||||
function createClient() {
|
||||
if (client) {
|
||||
client.close();
|
||||
}
|
||||
|
||||
client = new es.Client({
|
||||
hosts: [
|
||||
{
|
||||
hostname: esServer ? esServer.__hostname : argv.hostname,
|
||||
port: esServer ? esServer.__port : argv.port
|
||||
}
|
||||
],
|
||||
// log: null
|
||||
log: {
|
||||
type: 'file',
|
||||
level: 'trace',
|
||||
path: logFile
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function createServer(done) {
|
||||
server.start(argv, function (err, server) {
|
||||
esServer = server;
|
||||
done(err);
|
||||
});
|
||||
}
|
||||
|
||||
// before running any tests...
|
||||
before(function (done) {
|
||||
// start our personal ES Server
|
||||
this.timeout(null);
|
||||
if (argv.createServer) {
|
||||
createServer(done);
|
||||
} else {
|
||||
createClient();
|
||||
client.ping(function (err) {
|
||||
if (err) {
|
||||
createServer(done);
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
before(function (done) {
|
||||
@ -66,22 +100,7 @@ before(function (done) {
|
||||
});
|
||||
|
||||
before(function () {
|
||||
Error.stackTraceLimit = Infinity;
|
||||
// create the client
|
||||
client = new es.Client({
|
||||
hosts: [
|
||||
{
|
||||
hostname: esServer ? esServer.__hostname : argv.hostname,
|
||||
port: esServer ? esServer.__port : argv.port
|
||||
}
|
||||
],
|
||||
log: null
|
||||
// log: {
|
||||
// type: 'file',
|
||||
// level: ['error', 'warning', 'trace'],
|
||||
// path: logFile
|
||||
// }
|
||||
});
|
||||
createClient();
|
||||
});
|
||||
|
||||
before(clearIndices);
|
||||
@ -97,7 +116,7 @@ function loadDir(dir) {
|
||||
var location = path.join(dir, fileName),
|
||||
stat = fs.statSync(location);
|
||||
|
||||
if (stat.isFile() && fileName.match(/\.yaml$/) && location.match(doRE)) {
|
||||
if (stat.isFile() && fileName.match(/\.yaml$/) && doPattern.match(path.relative(TEST_DIR, location))) {
|
||||
loadFile(location);
|
||||
}
|
||||
else if (stat.isDirectory()) {
|
||||
@ -188,25 +207,21 @@ function rangeMatchesCurrentVersion(rangeString, done) {
|
||||
}
|
||||
|
||||
/**
|
||||
* read the file's contents, parse the yaml, pass to makeTest
|
||||
* read the file's contents, parse the yaml, pass to makeTestFromYamlDoc
|
||||
*
|
||||
* @param {String} path - Full path to yaml file
|
||||
* @return {undefined}
|
||||
*/
|
||||
function loadFile(location) {
|
||||
var docsInFile = [];
|
||||
|
||||
jsYaml.loadAll(
|
||||
fs.readFileSync(location, { encoding: 'utf8' }),
|
||||
function (testConfig) {
|
||||
docsInFile.push(testConfig);
|
||||
function (doc) {
|
||||
makeTestFromYamlDoc(doc);
|
||||
},
|
||||
{
|
||||
filename: location
|
||||
}
|
||||
);
|
||||
|
||||
_.each(docsInFile, makeTest);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -217,15 +232,15 @@ function loadFile(location) {
|
||||
* @param {Object} testConfigs - The yaml document
|
||||
* @return {undefined}
|
||||
*/
|
||||
function makeTest(testConfig, count) {
|
||||
function makeTestFromYamlDoc(yamlDoc, count) {
|
||||
var setup;
|
||||
if (_.has(testConfig, 'setup')) {
|
||||
(new ActionRunner(testConfig.setup)).each(function (action, name) {
|
||||
if (_.has(yamlDoc, 'setup')) {
|
||||
(new ActionRunner(yamlDoc.setup)).each(function (action, name) {
|
||||
before(action);
|
||||
});
|
||||
delete testConfig.setup;
|
||||
delete yamlDoc.setup;
|
||||
}
|
||||
_.forOwn(testConfig, function (test, description) {
|
||||
_.forOwn(yamlDoc, function (test, description) {
|
||||
describe(description, function () {
|
||||
var actions = new ActionRunner(test);
|
||||
actions.each(function (action, name) {
|
||||
@ -462,21 +477,23 @@ ActionRunner.prototype = {
|
||||
if (catcher instanceof RegExp) {
|
||||
// error message should match the regexp
|
||||
expect(error.message).to.match(catcher);
|
||||
error = null;
|
||||
} else if (typeof catcher === 'function') {
|
||||
// error should be an instance of
|
||||
expect(error).to.be.a(catcher);
|
||||
error = null;
|
||||
} else {
|
||||
throw new Error('Invalid catcher ' + catcher);
|
||||
return done(new Error('Invalid catcher ' + catcher));
|
||||
}
|
||||
} else {
|
||||
throw error;
|
||||
return done(error);
|
||||
}
|
||||
}
|
||||
|
||||
done();
|
||||
done(error);
|
||||
}, this));
|
||||
} else {
|
||||
throw new Error('stepped in do_do, did not find a function');
|
||||
done(new Error('stepped in do_do, did not find a function'));
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
21971
test/integration/yaml-suite/log
Normal file
21971
test/integration/yaml-suite/log
Normal file
File diff suppressed because it is too large
Load Diff
@ -16,8 +16,8 @@ exports.start = function (params, cb) {
|
||||
[
|
||||
'-f',
|
||||
'-Des.cluster.name=' + params.clusterName,
|
||||
params.port ? '-D es.http.port=' + params.port : undefined,
|
||||
'-Des.path.data=' + params.dataPath,
|
||||
'-Des.logger.level=DEBUG',
|
||||
'-Des.gateway.type=none',
|
||||
'-Des.index.store.type=memory',
|
||||
'-Des.discovery.zen.ping.multicast.enabled=false',
|
||||
@ -34,15 +34,14 @@ exports.start = function (params, cb) {
|
||||
);
|
||||
|
||||
server.stdout.on('data', function (line) {
|
||||
line = line.toString();
|
||||
line = _.trim(line.toString());
|
||||
var match;
|
||||
// console.log(_.trim(line));
|
||||
if (!params.port && (match = line.match(/bound_address \{inet\[\/?([^:]+):(\d+)\]\}/))) {
|
||||
if (match = line.match(/bound_address \{inet\[\/?([^:]+):(\d+)\]\}/)) {
|
||||
server.__hostname = match[1];
|
||||
server.__port = match[2];
|
||||
}
|
||||
|
||||
if (line.match(/started\s*$/)) {
|
||||
if (line.match(/started\s*$/m)) {
|
||||
console.log('Personal ES Server started at', server.__hostname + ':' + server.__port);
|
||||
server.stdout.removeAllListeners();
|
||||
server.stderr.removeAllListeners();
|
||||
@ -51,9 +50,13 @@ exports.start = function (params, cb) {
|
||||
});
|
||||
|
||||
server.stderr.on('data', function (line) {
|
||||
console.error(_.trim(line));
|
||||
console.error(_.trim(line.toString()));
|
||||
});
|
||||
|
||||
server.on('exit', function (code) {
|
||||
console.log('Personal ES Server Shutdown with exit code', code);
|
||||
})
|
||||
|
||||
process.on('exit', function () {
|
||||
server.kill();
|
||||
});
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
--require should
|
||||
--reporter dot
|
||||
--timeout 11000
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
var es = require('../../src/elasticsearch'),
|
||||
api = require('../../src/lib/utils').requireDir(module, '../../src/api'),
|
||||
api = require('../../src/lib/api'),
|
||||
expect = require('expect.js');
|
||||
|
||||
describe('Client instances creation', function () {
|
||||
@ -10,7 +10,7 @@ describe('Client instances creation', function () {
|
||||
});
|
||||
|
||||
it('inherits the api', function () {
|
||||
client.bulk.should.be.exactly(api.bulk);
|
||||
client.cluster.nodeStats.should.be.exactly(api.cluster.node_stats);
|
||||
client.bulk.should.eql(api.bulk);
|
||||
client.cluster.nodeStats.should.eql(api.cluster.prototype.nodeStats);
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,45 +0,0 @@
|
||||
var es = require('../../src/elasticsearch'),
|
||||
sinon = require('sinon'),
|
||||
expect = require('expect.js');
|
||||
|
||||
describe('transport', function () {
|
||||
|
||||
describe('#sniff', function () {
|
||||
it('does a head request to "/"', function (done) {
|
||||
var c = new es.Client();
|
||||
// stub the tranports request method, arg 1 is a callback
|
||||
sinon.stub(c.transport, 'request').callsArgAsync(1);
|
||||
|
||||
c.transport.sniff(function (err, resp) {
|
||||
var spy = c.transport.request.getCall(0),
|
||||
params = spy.args[0];
|
||||
|
||||
params.should.have.type('object');
|
||||
params.should.have.property('path', '/_cluster/nodes');
|
||||
if (params.method) {
|
||||
params.should.be('GET');
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when sniffOnStart === true', function () {
|
||||
|
||||
describe('and the cluster is down', function () {
|
||||
before(function (done) {
|
||||
var c = new es.Client({
|
||||
sniffOnStart: true,
|
||||
hosts: [
|
||||
'intentionally-not-a-real-cluster.com:9200'
|
||||
]
|
||||
});
|
||||
c.on('sniff complete', done);
|
||||
});
|
||||
|
||||
it('should not have any connections in the connection pool', function () {
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -114,25 +114,6 @@ describe('Utils', function () {
|
||||
});
|
||||
|
||||
|
||||
describe('Lodash Modifications', function () {
|
||||
|
||||
describe('#map', function () {
|
||||
it('returns an object when passed an object', function () {
|
||||
var out = _.map({a: 1, b: 2}, function (val) { return val * 2; });
|
||||
expect(out).to.eql({a: 2, b: 4});
|
||||
});
|
||||
|
||||
it('returns an array for anything else', function () {
|
||||
var std = _.map([1, 2, 3], function (val) { return val * 2; });
|
||||
expect(std)
|
||||
.to.be.a('array')
|
||||
.and.to.eql(_.map('123', function (val) { return val * 2; }));
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('String Transformers', function () {
|
||||
|
||||
describe('#camelCase', function () {
|
||||
Reference in New Issue
Block a user