client.js
* @module greppy/helper/service/json-wsp/client
* @author Hermann Mayer <hermann.mayer92@gmail.com>
var extend = require('extend');
var JSONWspClientHelper = function()
var JSONWspClient = function(protocol, socketOptions)
this.socket = require(protocol);
this.socketOptions = socketOptions;
* @param {Object} options - Options for this request
* @param {String} data - Data to pass on POST requests
* @param {Function} errorLogger - Function to call on errors
* @param {Function} callback - Function to call on finish
JSONWspClient.prototype.request = function(options, data, errorLogger, callback)
var req = this.socket.request(options, function(res) {
// Set the default charset of the response data
// On-data event, just append the response data to our buffer
res.on('data', function(chunk) {
// On-end event, just parse the response
var response = JSON.parse(chunks);
// The response was an fault or an error occured
if (200 !== res.statusCode || 'jsonwsp/fault' === response.type) {
return callback && callback(new Error(
((response.fault && response.fault.string) ? response.fault.string : 'UNKNOWN_ERROR')
callback && callback(null, response.result, response, res);
'Failed to parse response. Details: ' + e.message + '\n' + chunks
callback && callback(err, null, chunks, res);
req.on('error', function(err) {
callback && callback(err, null, null, null);
req.setTimeout(options.timeout, function() {
var err = new Error('Request timed out.');
if ('POST' === options.method) {
* Get the JSON-WSP specification.
* @param {String} path - Path of the specification
* @param {Function} callback - Function to call on finish
JSONWspClient.prototype.specification = function(path, callback)
// Merge given options with default options
extend(true, curOpts, this.socketOptions);
// Set the path of the specification
// Set HTTP method for calling
'Perform request on JSON-WSP service ' + (
curOpts.hostname + ':' + curOpts.port +
curOpts.path + ' -> Specification'
var logError = function(err) {
var message = 'Error occured while performing a JSON-WSP request. ' +
this.request(curOpts, null, logError, callback);
* @param {String} method - Name of the method
* @param {Object} args - Arguments of the method to call
* @param {Object} [options] - Options for this call
* @param {Function} callback - Function to call on finish
JSONWspClient.prototype.call = function(method, args, options, callback)
if ('object' !== typeof args) {
throw new Error('Args needs to be an object.');
if ('function' === typeof options) {
// Merge given options with default options
extend(true, curOpts, this.socketOptions, options);
extend(true, reqData, this.requestTemplate);
// Set HTTP method for calling
reqData.mirror.id = options.mirror || 1;
Object.keys(args).forEach(function(key) {
formatedArgsList.push(key + ': ' + JSON.stringify(args[key]));
'Perform request on JSON-WSP service ' + (
curOpts.hostname + ':' + curOpts.port +
curOpts.path + ' -> ' + method + '(' + formatedArgsList.join(', ') + ')'
var logError = function(err) {
var message = 'Error occured while performing a JSON-WSP request. ' +
this.request(curOpts, JSON.stringify(reqData), logError, callback);
* Build a JSON-WSP client instance.
* headers: {'Content-Type': 'application/json; charset=UTF-8'},
* @param {Object} config - Config of the client
JSONWspClientHelper.prototype.build = function(config)
headers: {'Content-Type': 'application/json; charset=UTF-8'},
// Merge the given config to the default config
extend(true, defaultConfig, config);
// Extract the protocol property
var protocol = defaultConfig.protocol;
delete defaultConfig.protocol;
return new JSONWspClient(protocol, defaultConfig);