diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..6aab9b4 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v18.18.0 diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index f6c8016..0000000 --- a/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -FROM talis/ubuntu:1404-latest - -ENV DEBIAN_FRONTEND noninteractive - -RUN apt-get update && apt-get install -y --force-yes \ - curl \ - git \ - apt-transport-https \ - nodejs=8.9.4-1nodesource1 \ - python \ - build-essential \ - envconsul \ - && rm -rf /var/lib/apt/lists/* \ - && apt-get clean \ - && apt-get -y autoremove && apt-get clean && apt-get autoclean && \ - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - -RUN mkdir -p /var/talis-node -COPY . /var/talis-node - -WORKDIR /var/talis-node - - diff --git a/README.md b/README.md index 7b674fc..7142183 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ # talis-node -[![build status](https://travis-ci.org/talis/talis-node.svg?branch=master)](https://travis-ci.org/talis/talis-node) # Development Version - Not For General Use diff --git a/babel/index.js b/babel/index.js index 964beeb..e718db6 100644 --- a/babel/index.js +++ b/babel/index.js @@ -6,6 +6,8 @@ var _ = require('lodash'), md5 = require('md5'), querystring = require('querystring'); +var clientVer = require('../package.json').version || 'unknown'; + // log severities var DEBUG = "debug"; var ERROR = "error"; @@ -35,6 +37,10 @@ var BabelClient = function babelClient(config) { } this.config.babel_hostname = this.config.babel_host.split('://', 2)[1]; + + this.userAgent = (process && _.has(process, ["version", "env.NODE_ENV"])) ? "talis-node/" + + clientVer + " (nodejs/" + process.version + "; NODE_ENV=" + + process.env.NODE_ENV + ")" : "talis-node/" + clientVer; }; /** @@ -71,7 +77,8 @@ BabelClient.prototype.headTargetFeed = function headTargetFeed(target, token, pa headers: { 'Accept': 'application/json', 'Authorization':'Bearer '+token, - 'Host': this.config.babel_hostname + 'Host': this.config.babel_hostname, + 'User-Agent': this.userAgent, } }; @@ -133,6 +140,7 @@ BabelClient.prototype.getEntireTargetFeed = async function (target, token, hydra 'Accept': 'application/json', 'Authorization':'Bearer '+ token, 'Host': this.config.babel_hostname, + 'User-Agent': this.userAgent, }, }; @@ -219,7 +227,8 @@ BabelClient.prototype.getTargetFeed = function getTargetFeed(target, token, hydr headers: { 'Accept': 'application/json', 'Authorization':'Bearer '+token, - 'Host': this.config.babel_hostname + 'Host': this.config.babel_hostname, + 'User-Agent': this.userAgent, } }; @@ -261,7 +270,8 @@ BabelClient.prototype.getFeeds = function getFeeds(feeds, token, callback) { headers: { 'Accept': 'application/json', 'Authorization': 'Bearer ' + token, - 'Host': this.config.babel_hostname + 'Host': this.config.babel_hostname, + 'User-Agent': this.userAgent, } }; @@ -299,7 +309,8 @@ BabelClient.prototype.getAnnotation = function getAnnotation(token, id, callback headers: { 'Accept': 'application/json', 'Authorization':'Bearer '+token, - 'Host': this.config.babel_hostname + 'Host': this.config.babel_hostname, + 'User-Agent': this.userAgent, } }; @@ -343,7 +354,8 @@ BabelClient.prototype.getAnnotations = function getAnnotations(token, querystrin headers: { 'Accept': 'application/json', 'Authorization':'Bearer '+token, - 'Host': this.config.babel_hostname + 'Host': this.config.babel_hostname, + 'User-Agent': this.userAgent, } }; @@ -440,7 +452,8 @@ BabelClient.prototype.createAnnotation = function createAnnotation(token, data, headers: { 'Accept': 'application/json', 'Authorization':'Bearer '+token, - 'Host': this.config.babel_hostname + 'Host': this.config.babel_hostname, + 'User-Agent': this.userAgent, } }; @@ -542,7 +555,8 @@ BabelClient.prototype.updateAnnotation = function updateAnnotation(token, data, headers: { 'Accept': 'application/json', 'Authorization': 'Bearer ' + token, - 'Host': this.config.babel_hostname + 'Host': this.config.babel_hostname, + 'User-Agent': this.userAgent, } }; @@ -583,7 +597,8 @@ BabelClient.prototype.deleteAnnotation = function deleteAnnotation(token, annota headers: { 'Accept': 'application/json', 'Authorization': 'Bearer ' + token, - 'Host': this.config.babel_hostname + 'Host': this.config.babel_hostname, + 'User-Agent': this.userAgent, } }; diff --git a/babel/test/unit/babel_client_test.js b/babel/test/unit/babel_client_test.js index de59d84..6e623d1 100644 --- a/babel/test/unit/babel_client_test.js +++ b/babel/test/unit/babel_client_test.js @@ -76,6 +76,7 @@ describe("Babel Node Client Test Suite", function(){ babel_port:3000 }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(new Error('Error communicating with Babel')); }; @@ -97,6 +98,7 @@ describe("Babel Node Client Test Suite", function(){ babel_port:3000 }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {statusCode:401}); }; @@ -118,6 +120,7 @@ describe("Babel Node Client Test Suite", function(){ babel_port:3000 }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {statusCode:404}); }; @@ -139,6 +142,7 @@ describe("Babel Node Client Test Suite", function(){ }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {statusCode:204, headers:{'x-feed-new-items': '1'}}); }; @@ -159,6 +163,7 @@ describe("Babel Node Client Test Suite", function(){ }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {statusCode:204, headers:{'x-feed-new-items': '2'}}); }; @@ -364,6 +369,7 @@ describe("Babel Node Client Test Suite", function(){ }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {}, JSON.stringify({})); }; @@ -383,6 +389,7 @@ describe("Babel Node Client Test Suite", function(){ babel_port:3000 }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(new Error('Error communicating with Babel')); }; @@ -405,6 +412,7 @@ describe("Babel Node Client Test Suite", function(){ babel_port:3000 }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {statusCode:401}, JSON.stringify({error:"invalid_token", error_description:"The token is invalid or has expired"})); }; @@ -428,6 +436,7 @@ describe("Babel Node Client Test Suite", function(){ babel_port:3000 }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {}, JSON.stringify({"error":"feed_not_found", "error_description":"Feed not found"})); }; @@ -451,6 +460,7 @@ describe("Babel Node Client Test Suite", function(){ }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {}, JSON.stringify({ "count":2, "limit":25, @@ -495,6 +505,7 @@ describe("Babel Node Client Test Suite", function(){ }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {}, null); }; @@ -556,6 +567,7 @@ describe("Babel Node Client Test Suite", function(){ babel_port:3000 }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(new Error('Error communicating with Babel')); }; @@ -578,6 +590,7 @@ describe("Babel Node Client Test Suite", function(){ babel_port:3000 }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {statusCode:401}, JSON.stringify({error:"invalid_token", error_description:"The token is invalid or has expired"})); }; @@ -601,6 +614,7 @@ describe("Babel Node Client Test Suite", function(){ babel_port:3000 }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {}, JSON.stringify({"error":"feed_not_found", "error_description":"Feed not found"})); }; @@ -624,6 +638,7 @@ describe("Babel Node Client Test Suite", function(){ }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {}, JSON.stringify({ "feed_length":2, "limit":25, @@ -675,6 +690,7 @@ describe("Babel Node Client Test Suite", function(){ }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {}, null); }; @@ -724,6 +740,7 @@ describe("Babel Node Client Test Suite", function(){ babel_port:3000 }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {statusCode:401}, JSON.stringify({error:"invalid_token", error_description:"The token is invalid or has expired"})); }; @@ -746,6 +763,7 @@ describe("Babel Node Client Test Suite", function(){ babel_port:3000 }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(new Error("Error communicating with Babel")); }; @@ -769,6 +787,7 @@ describe("Babel Node Client Test Suite", function(){ }); var requestMock = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {}, JSON.stringify({ "__v": 0, "annotatedBy": "bp", @@ -808,6 +827,7 @@ describe("Babel Node Client Test Suite", function(){ }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {}, null); }; @@ -857,6 +877,7 @@ describe("Babel Node Client Test Suite", function(){ babel_port:3000 }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {statusCode:401}, JSON.stringify({error:"invalid_token", error_description:"The token is invalid or has expired"})); }; @@ -880,6 +901,7 @@ describe("Babel Node Client Test Suite", function(){ babel_port:3000 }); var requestStub = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(new Error('Error communicating with Babel')); }; @@ -903,6 +925,7 @@ describe("Babel Node Client Test Suite", function(){ }); var requestMock = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {}, JSON.stringify({ "count":2, "limit":25, @@ -947,7 +970,8 @@ describe("Babel Node Client Test Suite", function(){ }); var requestStub = function(options, callback){ - callback(null, {}, null); + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); + callback(null, {}, null); }; babel.__set__("request", requestStub); @@ -1093,6 +1117,7 @@ describe("Babel Node Client Test Suite", function(){ }); var requestStub = { post:function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); var error = new Error('The token is invalid or has expired'); error.http_code = 401; callback(error); @@ -1120,6 +1145,7 @@ describe("Babel Node Client Test Suite", function(){ }); var requestStub = { post:function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); var error = new Error('Error communicating with Babel'); callback(error); } @@ -1145,7 +1171,8 @@ describe("Babel Node Client Test Suite", function(){ }); var requestStub = { post:function(options, callback){ - var response = {statusCode: 400}; + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); + var response = {statusCode: 400}; callback(null, response, {body:'', message:'Bad Request'}); } }; @@ -1172,6 +1199,7 @@ describe("Babel Node Client Test Suite", function(){ }); var requestStub = { post: function (options, callback) { + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, { statusCode: 502 }, { message: "Bad Gateway" }); }, }; @@ -1208,6 +1236,7 @@ describe("Babel Node Client Test Suite", function(){ var requestMock = {}; requestMock.post = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {statusCode: 201}, { __v: 0, annotatedBy: 'Gordon Freeman', @@ -1256,6 +1285,7 @@ describe("Babel Node Client Test Suite", function(){ var requestMock = {}; requestMock.post = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {statusCode: 201}, { __v: 0, annotatedBy: 'Gordon Freeman', @@ -1489,6 +1519,7 @@ describe("Babel Node Client Test Suite", function(){ }); var requestStub = { put:function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); var error = new Error('The token is invalid or has expired'); error.http_code = 401; callback(error); @@ -1515,6 +1546,7 @@ describe("Babel Node Client Test Suite", function(){ }); var requestStub = { put:function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); var error = new Error('Error communicating with Babel'); callback(error); } @@ -1539,6 +1571,7 @@ describe("Babel Node Client Test Suite", function(){ }); var requestStub = { put:function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); var response = {statusCode: 400}; callback(null, response, {body:'', message:'Bad Request'}); } @@ -1565,6 +1598,7 @@ describe("Babel Node Client Test Suite", function(){ }); var requestStub = { put: function (options, callback) { + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, { statusCode: 400 }, { message: "Bad Gateway" }); }, }; @@ -1600,6 +1634,7 @@ describe("Babel Node Client Test Suite", function(){ var requestMock = {}; requestMock.put = function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {statusCode: 200}, { __v: 0, annotatedBy: 'Gordon Freeman', @@ -1668,6 +1703,7 @@ describe("Babel Node Client Test Suite", function(){ }); var requestStub = { delete:function(options, callback){ + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); var error = new Error('Error communicating with Babel'); callback(error); } diff --git a/docker-compose.yml b/docker-compose.yml index d4255da..9acbbd8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,17 +8,3 @@ services: restart: always networks: - default - talis_node_dev: - image: talis/talis-node - links: - - redis - volumes: - - ".:/var/talis-node" - command: "/bin/bash" - environment: - REDIS_TEST_HOST: "redis" - REDIS_TEST_PORT: 6379 - networks: - - default - - diff --git a/echo/index.js b/echo/index.js index f7eaf49..44e845a 100644 --- a/echo/index.js +++ b/echo/index.js @@ -5,6 +5,8 @@ var _ = require('lodash'); var codesAndLabels = require('./lib/codes-labels').codesAndLabels; var httpStatusToCode = require('./lib/codes-labels').httpStatusToCode; +var clientVer = require('../package.json').version || 'unknown'; + // log severities var DEBUG = 'debug'; var ERROR = 'error'; @@ -65,6 +67,9 @@ function queryStringParams(params) { function Client() { var config = {}; + var userAgent = (process && _.has(process, ["version", "env.NODE_ENV"])) ? "talis-node/" + + clientVer + " (nodejs/" + process.version + "; NODE_ENV=" + + process.env.NODE_ENV + ")" : "talis-node/" + clientVer; /** * Log wrapping functions @@ -190,7 +195,8 @@ function Client() { url: config.echo_endpoint + '/1/events', headers: { Accept: 'application/json', - Authorization: 'Bearer ' + token + Authorization: 'Bearer ' + token, + 'User-Agent': userAgent, }, body: data, method: 'POST', @@ -267,7 +273,8 @@ function Client() { method: 'GET', headers: { 'Content-Type': 'application/json', - Authorization: 'Bearer ' + token + Authorization: 'Bearer ' + token, + 'User-Agent': userAgent, } }; @@ -318,4 +325,4 @@ exports.createClient = function createClient(config) { var EchoClient = Client(); return new EchoClient(config); }; -exports.echoErrors = codesAndLabels \ No newline at end of file +exports.echoErrors = codesAndLabels diff --git a/echo/test/unit/echo_client_test.js b/echo/test/unit/echo_client_test.js index 2ddb2ee..3952e22 100644 --- a/echo/test/unit/echo_client_test.js +++ b/echo/test/unit/echo_client_test.js @@ -108,6 +108,7 @@ describe("Echo Node Client Test Suite", function(){ var requestStub = sandbox.stub(request, 'post') requestStub.callsFake(function (options, callback) { + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); if(!options.body){ var error = new Error('Missing field: options.body'); callback(error); @@ -128,6 +129,7 @@ describe("Echo Node Client Test Suite", function(){ var requestStub = sandbox.stub(request, 'post') requestStub.callsFake(function (options, callback) { + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); if(!options.method){ var error = new Error('Missing field: options.method'); callback(error); @@ -148,6 +150,7 @@ describe("Echo Node Client Test Suite", function(){ var requestStub = sandbox.stub(request, 'post') requestStub.callsFake(function (options, callback) { + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); if(options.method !== 'POST'){ var error = new Error('Invalid field: options.method'); callback(error); @@ -168,6 +171,7 @@ describe("Echo Node Client Test Suite", function(){ var requestStub = sandbox.stub(request, 'post') requestStub.callsFake(function (options, callback) { + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); if(!options.json){ var error = new Error('Missing field: options.json'); callback(error); @@ -188,6 +192,7 @@ describe("Echo Node Client Test Suite", function(){ var requestStub = sandbox.stub(request, 'post') requestStub.callsFake(function (options, callback) { + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback( null, {statusCode: 401}, @@ -212,6 +217,7 @@ describe("Echo Node Client Test Suite", function(){ var requestStub = sandbox.stub(request, 'post') requestStub.callsFake(function (options, callback) { + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback( null, {statusCode: 200}, @@ -314,6 +320,7 @@ describe("Echo Node Client Test Suite", function(){ var requestStub = sandbox.stub(request, 'get') requestStub.callsFake(function (options, callback) { + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); var data = "{\"head\": {\"type\": \"sum\",\"class\": \"player.timer.2\",\"property\": \"interval_with_decay\",\"group_by\": \"user\",\"filter\": {\"module_id\": \"5847ed0ef81ebd1f1b000001\",\"resource_id\": \"5899a87fd42410f2c9000001\"},\"from\": \"2016-08-29T00:00:00\",\"to\": \"2017-05-18T00:00:00\",\"count\": 2},\"results\": [{\"user\": \"8av3Jaj__vC9v9VIY_P-1w\",\"interval_with_decay\": 182920},{\"user\": \"d17T05nNTjG50sAp_R3RvQ\",\"interval_with_decay\": 21315}]}"; callback(null, {statusCode: 200}, data); }); @@ -362,6 +369,7 @@ describe("Echo Node Client Test Suite", function(){ var requestStub = sandbox.stub(request, 'get') requestStub.callsFake(function (options, callback) { + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(new Error('Error communicating with Echo')); }); @@ -393,6 +401,7 @@ describe("Echo Node Client Test Suite", function(){ var requestStub = sandbox.stub(request, 'get') requestStub.callsFake(function (options, callback) { + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback( null, {statusCode: 401}, @@ -417,6 +426,7 @@ describe("Echo Node Client Test Suite", function(){ var requestStub = sandbox.stub(request, 'get') requestStub.callsFake(function (options, callback) { + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); var data = "{\"head\": {\"type\": \"sum\",\"class\": \"player.timer.2\",\"property\": \"interval_with_decay\",\"group_by\": \"user\",\"filter\": {\"module_id\": \"5847ed0ef81ebd1f1b000001\"},\"user\": {\"exclude\": \"qVyfsQhlMY0T2_Bl7eotrg\"},\"from\": \"2017-02-01T00:00:00\",\"to\": \"2017-02-13T00:00:00\",\"count\": 2},\"results\": [{\"user\": \"8av3Jaj__vC9v9VIY_P-1w\",\"interval_with_decay\": 182920},{\"user\": \"d17T05nNTjG50sAp_R3RvQ\",\"interval_with_decay\": 21315}]}"; callback(null, {statusCode: 200}, data); }); @@ -457,6 +467,7 @@ describe("Echo Node Client Test Suite", function(){ var requestStub = sandbox.stub(request, 'get') requestStub.callsFake(function (options, callback) { + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); var data = "{\"head\": {\"type\": \"sum\",\"class\": \"player.timer.2\",\"property\": \"interval_with_decay\",\"group_by\": \"user\",\"filter\": {\"module_id\": \"5847ed0ef81ebd1f1b000001\"},\"user\": {\"exclude\": \"qVyfsQhlMY0T2_Bl7eotrg\"},\"from\": \"2017-02-01T00:00:00\",\"to\": \"2017-02-13T00:00:00\",\"count\": 2},\"results\": [{\"user\": \"8av3Jaj__vC9v9VIY_P-1w\",\"interval_with_decay\": 182920},{\"user\": \"d17T05nNTjG50sAp_R3RvQ\",\"interval_with_decay\": 21315}]}"; callback(null, {statusCode: 200}, data); }); @@ -499,6 +510,7 @@ describe("Echo Node Client Test Suite", function(){ var requestStub = sandbox.stub(request, 'get') requestStub.callsFake(function (options, callback) { + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {statusCode: 200}, data); }); @@ -532,6 +544,7 @@ describe("Echo Node Client Test Suite", function(){ var requestStub = sandbox.stub(request, 'get') requestStub.callsFake(function (options, callback) { + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {statusCode: 400}, data); }); @@ -565,6 +578,7 @@ describe("Echo Node Client Test Suite", function(){ var requestStub = sandbox.stub(request, 'get') requestStub.callsFake(function (options, callback) { + options.headers.should.have.property('User-Agent', 'talis-node/0.2.1'); callback(null, {statusCode: 400}, data); });