You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by ra...@apache.org on 2017/10/20 17:53:49 UTC
[incubator-openwhisk-client-js] branch master updated: switch from
request-promise to needle (#78)
This is an automated email from the ASF dual-hosted git repository.
rabbah pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-client-js.git
The following commit(s) were added to refs/heads/master by this push:
new 8f0e241 switch from request-promise to needle (#78)
8f0e241 is described below
commit 8f0e241da581c9186e8635df3fb1aaf7d2e8979e
Author: Nick Mitchell <st...@users.noreply.github.com>
AuthorDate: Fri Oct 20 13:53:46 2017 -0400
switch from request-promise to needle (#78)
Switch from request-promise to needle, for an initialization performance boost. Fixes #77
Also adds test coverage for 404 and 409 cases. Fixes #79
* switch from request-promise to needle
* remove needless clause
* handle errors for needle
* improve comments of rp facade code
* improve error handling test coverage
* fix for 409 test
---
lib/client.js | 48 ++++++++++++++++++++++++++++++++++++++-
package.json | 2 +-
test/integration/actions.test.js | 23 +++++++++++++++++++
test/integration/packages.test.js | 7 ++++++
test/integration/rules.test.js | 7 ++++++
test/integration/triggers.test.js | 7 ++++++
6 files changed, 92 insertions(+), 2 deletions(-)
diff --git a/lib/client.js b/lib/client.js
index b6666e8..73dfe4a 100644
--- a/lib/client.js
+++ b/lib/client.js
@@ -5,10 +5,56 @@
const messages = require('./messages')
const OpenWhiskError = require('./openwhisk_error')
-const rp = require('request-promise')
+const needle = require('needle')
const url = require('url')
const http = require('http')
+/**
+ * This implements a request-promise-like facade over the needle
+ * library. There are two gaps between needle and rp that need to be
+ * bridged: 1) convert `qs` into a query string; and 2) convert
+ * needle's non-excepting >=400 statusCode responses into exceptions
+ *
+ */
+const rp = opts => {
+ if (opts.qs) {
+ // we turn the qs struct into a query string over the url
+ let first = true
+ for (let key in opts.qs) {
+ const str = `${encodeURIComponent(key)}=${encodeURIComponent(opts.qs[key])}`
+ if (first) {
+ opts.url += `?${str}`
+ first = false
+ } else {
+ opts.url += `&${str}`
+ }
+ }
+ }
+
+ // it appears that certain call paths from our code do not set the
+ // opts.json field to true; rp is apparently more resilient to
+ // this situation than needle
+ opts.json = true
+
+ return needle(opts.method.toLowerCase(), // needle takes e.g. 'put' not 'PUT'
+ opts.url,
+ opts.body || opts.params,
+ opts)
+ .then(resp => {
+ if (resp.statusCode >= 400) {
+ // we turn >=400 statusCode responses into exceptions
+ const error = new Error(resp.body.error || resp.statusMessage)
+ error.statusCode = resp.statusCode // the http status code
+ error.options = opts // the code below requires access to the input opts
+ error.error = resp.body // the error body
+ throw error
+ } else {
+ // otherwise, the response body is the expected return value
+ return resp.body
+ }
+ })
+}
+
class Client {
constructor (options) {
this.options = this.parse_options(options || {})
diff --git a/package.json b/package.json
index 105f154..e856296 100644
--- a/package.json
+++ b/package.json
@@ -42,7 +42,7 @@
"proxyquire": "1.7.4"
},
"dependencies": {
- "request-promise": "^2.0.1",
+ "needle": "^2.0.1",
"@types/node": "^8.0.26",
"@types/swagger-schema-official": "^2.0.6"
},
diff --git a/test/integration/actions.test.js b/test/integration/actions.test.js
index b1e98e2..d61bd94 100644
--- a/test/integration/actions.test.js
+++ b/test/integration/actions.test.js
@@ -50,6 +50,29 @@ test('list all actions using options namespace', t => {
})
})
+test('get a non-existing action, expecting 404', async t => {
+ const actions = new Actions(new Client(options))
+ await actions.get({name: 'glorfindel'}).catch(err => {
+ t.is(err.statusCode, 404)
+ })
+})
+
+test('delete a non-existing action, expecting 404', async t => {
+ const actions = new Actions(new Client(options))
+ await actions.delete({name: 'glorfindel'}).catch(err => {
+ t.is(err.statusCode, 404)
+ })
+})
+
+test('create with an existing action, expecting 409', async t => {
+ const actions = new Actions(new Client(options))
+ await actions.create({name: 'glorfindel2', action: 'x=>x'})
+ .then(() => actions.create({name: 'glorfindel2', action: 'x=>x'}))
+ .catch(err => {
+ t.is(err.statusCode, 409)
+ })
+})
+
test('create, get and delete an action', t => {
const errors = err => {
console.log(err)
diff --git a/test/integration/packages.test.js b/test/integration/packages.test.js
index 7bb7ffe..d0a66e0 100644
--- a/test/integration/packages.test.js
+++ b/test/integration/packages.test.js
@@ -49,6 +49,13 @@ test('list all packages using options namespace', t => {
})
})
+test('get a non-existing package, expecting 404', async t => {
+ const packages = new Packages(new Client(options))
+ await packages.get({name: 'glorfindel'}).catch(err => {
+ t.is(err.statusCode, 404)
+ })
+})
+
test('create, get and delete an package', t => {
const errors = err => {
console.log(err)
diff --git a/test/integration/rules.test.js b/test/integration/rules.test.js
index b1e5f84..434bab9 100644
--- a/test/integration/rules.test.js
+++ b/test/integration/rules.test.js
@@ -51,6 +51,13 @@ test('list all rules using options namespace', t => {
})
})
+test('get a non-existing rule, expecting 404', async t => {
+ const rules = new Rules(new Client(options))
+ await rules.get({name: 'glorfindel'}).catch(err => {
+ t.is(err.statusCode, 404)
+ })
+})
+
// Running update tests conconcurrently leads to resource conflict errors.
test.serial('create, get and delete a rule', t => {
const errors = err => {
diff --git a/test/integration/triggers.test.js b/test/integration/triggers.test.js
index d49f08c..4b68e2b 100644
--- a/test/integration/triggers.test.js
+++ b/test/integration/triggers.test.js
@@ -49,6 +49,13 @@ test('list all triggers using options namespace', t => {
})
})
+test('get a non-existing trigger, expecting 404', async t => {
+ const triggers = new Triggers(new Client(options))
+ await triggers.get({name: 'glorfindel'}).catch(err => {
+ t.is(err.statusCode, 404)
+ })
+})
+
test('create, get and delete an trigger', t => {
const errors = err => {
console.log(err)
--
To stop receiving notification emails like this one, please contact
['"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>'].