openwhisk-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From csantan...@apache.org
Subject [incubator-openwhisk-client-js] branch master updated: Support route creation with path parameters and secure keys. (#114)
Date Sat, 28 Apr 2018 18:42:33 GMT
This is an automated email from the ASF dual-hosted git repository.

csantanapr 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 895d632  Support route creation with path parameters and secure keys. (#114)
895d632 is described below

commit 895d632cf1411e611258e7e007d2937eeb70ae86
Author: James Thomas <jthomas.uk@gmail.com>
AuthorDate: Sat Apr 28 19:42:31 2018 +0100

    Support route creation with path parameters and secure keys. (#114)
    
    * 3.11.0
    
    * 3.12.0
    
    * Fixing #100
    
    Connect echo action to trigger with rule to ensure result has
    activation identifier.
    
    * 3.13.1
    
    * Support route creation with path parameters and secure keys.
    
    Parse path parameters from route options and generate correct swagger.
    New creation parameter to pass authentication key for secured web actions.
---
 README.md                |   1 +
 lib/routes.js            |  45 ++++++++++++++++++++-
 test/unit/routes.test.js | 102 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 147 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 280440f..65671b3 100644
--- a/README.md
+++ b/README.md
@@ -490,6 +490,7 @@ The following optional parameters are supported:
 - `responsetype` - content type returned by web action, possible values: `html`, `http`,
`json`, `text` and `svg` (default: `json`).
 - `basepath` - base URI path for endpoints (default: `/`)
 - `name` - identifier for API (default: `basepath`)
+- `secure_key` - auth key for secure web action
 
 ### add route (swagger)
 
diff --git a/lib/routes.js b/lib/routes.js
index a40e85e..6c1eaf1 100644
--- a/lib/routes.js
+++ b/lib/routes.js
@@ -104,6 +104,12 @@ class Routes extends BaseOperation {
       action: this.routeSwaggerAction(params)
     }
 
+    const pathParameters = this.parsePathParameters(params.relpath)
+
+    if (pathParameters.length) {
+      apidoc.pathParameters = pathParameters.map(this.createPathParameter)
+    }
+
     if (params.name) {
       apidoc.apiName = params.name
     }
@@ -117,13 +123,20 @@ class Routes extends BaseOperation {
     if (params.action.startsWith('/')) {
       namespace = names.parseNamespace(params.action)
     }
-    return {
+
+    const body = {
       name: id,
       namespace: namespace,
       backendMethod: `GET`,
       backendUrl: this.actionUrlPath(id, namespace),
       authkey: this.client.options.apiKey
     }
+
+    if (params.secure_key) {
+      body.secureKey = params.secure_key
+    }
+
+    return body
   }
 
   routeBasepath (params) {
@@ -143,6 +156,36 @@ class Routes extends BaseOperation {
   hasAccessToken () {
     return !!this.client.options.apigwToken
   }
+
+  // return list of path parameters from paths
+  // e.g. /book/{id}
+  // Multiple parameters are supported.
+  parsePathParameters (path) {
+    const regex = /{([^}]+)\}/g
+    const findAllParams = p => {
+      const ids = []
+      let id = regex.exec(p)
+      while (id) {
+        ids.push(id[1])
+        id = regex.exec(p)
+      }
+      return ids
+    }
+
+    return path.split('/')
+      .map(findAllParams)
+      .reduce((sum, el) => sum.concat(el), [])
+  }
+
+  createPathParameter (name) {
+    return {
+      name: name,
+      in: 'path',
+      description: `Default description for '${name}'`,
+      required: true,
+      type: 'string'
+    }
+  }
 }
 
 module.exports = Routes
diff --git a/test/unit/routes.test.js b/test/unit/routes.test.js
index 30eab78..e813a99 100644
--- a/test/unit/routes.test.js
+++ b/test/unit/routes.test.js
@@ -391,6 +391,42 @@ test('should create a route with response type', t => {
   return routes.create({relpath: '/hello', operation: 'GET', action: 'helloAction', responsetype:
'http'})
 })
 
+test('should create a route with secure key', t => {
+  t.plan(3)
+  const pathUrl = path => `https://openwhisk.ng.bluemix.net/api/v1/${path}`
+  const apiKey = 'username:password'
+  const secureKey = 'some_key'
+  const clientOptions = {apiKey}
+  const client = {pathUrl, options: clientOptions}
+
+  const body = {
+    apidoc: {
+      namespace: '_',
+      gatewayBasePath: '/',
+      gatewayPath: '/hello',
+      gatewayMethod: 'GET',
+      id: 'API:_:/',
+      action: {
+        name: 'helloAction',
+        namespace: '_',
+        backendMethod: 'GET',
+        backendUrl: 'https://openwhisk.ng.bluemix.net/api/v1/web/_/default/helloAction.http',
+        authkey: apiKey,
+        secureKey: secureKey
+      }
+    }
+  }
+
+  client.request = (method, path, _options) => {
+    t.is(method, 'POST')
+    t.is(path, routes.routeMgmtApiPath('createApi'))
+    t.deepEqual(_options.body, body)
+  }
+
+  const routes = new Routes(client)
+  return routes.create({relpath: '/hello', operation: 'GET', action: 'helloAction', secure_key:
secureKey})
+})
+
 test('should create a route with apigwToken and action with package', t => {
   t.plan(4)
   const pathUrl = path => `https://openwhisk.ng.bluemix.net/api/v1/${path}`
@@ -631,6 +667,72 @@ test('should create a route using action name with ns overriding defaults',
t =>
   return routes.create({relpath: '/hello', operation: 'GET', action: '/test/helloAction'})
 })
 
+test('should create a route with path parameters', t => {
+  t.plan(3)
+  const pathUrl = path => `https://openwhisk.ng.bluemix.net/api/v1/${path}`
+  const apiKey = 'username:password'
+  const clientOptions = {apiKey}
+  const client = {pathUrl, options: clientOptions}
+
+  const body = {
+    apidoc: {
+      namespace: '_',
+      gatewayBasePath: '/',
+      gatewayPath: '/foo/{bar}/{baz}',
+      gatewayMethod: 'GET',
+      id: 'API:_:/',
+      action: {
+        name: 'helloAction',
+        namespace: '_',
+        backendMethod: 'GET',
+        backendUrl: 'https://openwhisk.ng.bluemix.net/api/v1/web/_/default/helloAction.http',
+        authkey: apiKey
+      },
+      pathParameters: [
+        {
+          name: 'bar',
+          in: 'path',
+          description: "Default description for 'bar'",
+          required: true,
+          type: 'string'
+        },
+        {
+          name: 'baz',
+          in: 'path',
+          description: "Default description for 'baz'",
+          required: true,
+          type: 'string'
+        }
+      ]
+    }
+  }
+
+  client.request = (method, path, _options) => {
+    t.is(method, 'POST')
+    t.is(path, routes.routeMgmtApiPath('createApi'))
+    t.deepEqual(_options.body, body)
+  }
+
+  const routes = new Routes(client)
+  return routes.create({relpath: '/foo/{bar}/{baz}', operation: 'GET', action: 'helloAction'})
+})
+
+test('should parse path parameters', t => {
+  const routes = new Routes()
+  t.deepEqual(routes.parsePathParameters('/foo/{bar}'), ['bar'])
+  t.deepEqual(routes.parsePathParameters('/{foo}/bar'), ['foo'])
+  t.deepEqual(routes.parsePathParameters('/{foo}/{bar}'), ['foo', 'bar'])
+
+  t.deepEqual(routes.parsePathParameters('/{foo}bar}'), ['foo'])
+  t.deepEqual(routes.parsePathParameters('/{foo}{bar}'), ['foo', 'bar'])
+  t.deepEqual(routes.parsePathParameters('/a{foo}c{bar}b'), ['foo', 'bar'])
+
+  t.deepEqual(routes.parsePathParameters('/foo/bar'), [])
+  t.deepEqual(routes.parsePathParameters('/{foo/bar}'), [])
+  t.deepEqual(routes.parsePathParameters('/foo/bar}'), [])
+  t.deepEqual(routes.parsePathParameters('/{foo/bar'), [])
+})
+
 test('create routes missing mandatory parameters', t => {
   const routes = new Routes()
   t.throws(() => { routes.create() }, /Missing mandatory parameters: relpath, operation,
action/)

-- 
To stop receiving notification emails like this one, please contact
csantanapr@apache.org.

Mime
View raw message