csantanapr closed pull request #85: Add new features to routes methods.
URL: https://github.com/apache/incubator-openwhisk-client-js/pull/85
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/README.md b/README.md
index 159b3e3..089d7ed 100644
--- a/README.md
+++ b/README.md
@@ -272,6 +272,7 @@ ow.actions.delete({name: '...'})
 ow.triggers.delete({name: '...'})
 ow.rules.delete({name: '...'})
 ow.packages.delete({name: '...'})
+ow.feeds.delete({name: '...', trigger: '...'})
 ```
 
 The following optional parameters are supported:
@@ -413,11 +414,10 @@ ow.rules.disable({name: '...'})
 The following optional parameters are supported:
 - `namespace` - set custom namespace for endpoint
 
-### create & delete feeds
+### create feeds
 
 ```javascript
 ow.feeds.create({feedName: '...', trigger: '...'})
-ow.feeds.delete({feedName: '...', trigger: '...'})
 ```
 
 The following optional parameters are supported:
@@ -432,6 +432,15 @@ This client library defaults to using the platform 
service. If the `apigw_token`
 
 *The interface for managing routes through the library does not change between 
providers.*
 
+### retrieve route
+
+```javascript
+ow.routes.get({basepath: '...'})
+ow.routes.get({name: '...'})
+```
+
+*This method is a wrapper for the list method. It throws an error if the base 
path or name parameter is missing.*
+
 ### list routes
 
 ```javascript
@@ -441,16 +450,18 @@ ow.routes.list()
 The following optional parameters are supported to filter the result set:
 - `relpath` - relative URI path for endpoints
 - `basepath` - base URI path for endpoints
+- `name` - identifier for API
 - `operation` - HTTP methods
 - `limit` - limit result set size
 - `skip` - skip results from index
 
-*`relpath` is only valid when `basepath` is also specified.*
+*`relpath` is only valid when `basepath` is also specified. `name` and 
`basepath` cannot be used together.*
 
 ### delete routes
 
 ```javascript
 ow.routes.delete({basepath: '...'})
+ow.routes.delete({name: '...'})
 ```
 
 The following optional parameters are supported to filter the result set:
@@ -467,6 +478,17 @@ ow.routes.create({relpath: '...', operation: '...', 
action: '...'})
 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`)
+
+### add route (swagger)
+
+```javascript
+ow.routes.create({swagger: '{...}'})
+```
+
+Swagger parameter must be a well-formed JSON string, containing a valid 
Swagger API definition, which follows the [OpenWhisk API Gateway route 
schema](https://github.com/apache/incubator-openwhisk-apigateway/blob/master/doc/v2/management_interface_v2.md#post-v2tenant_idapis).
+
+*No other parameters are supported when creating the route from a JSON Swagger 
document.*
 
 ## Debugging
 
@@ -510,7 +532,7 @@ Alternatively, you can run the `prepIntegrationTests.sh` 
script using guest cred
 Run the script with openwhisk credentials:  
 ```bash
 $ ./test/integration/prepIntegrationTests.sh <your key in the form of 
ABCD:EFGH> <openwhisk instance hostname> <openwhisk namespace> <api 
gatewaytoken>
-```  
+```
 The `prepIntegrationTests.sh` script is designed to give you feedback if it 
detects a setting that is not correct on your machine. ex: `node 6 or above is 
not detected`
 
 ## Code-Coverage:
diff --git a/lib/messages.js b/lib/messages.js
index 909721f..a1873f9 100644
--- a/lib/messages.js
+++ b/lib/messages.js
@@ -18,5 +18,6 @@ module.exports = {
   MISSING_PACKAGE_BODY_ERROR: 'Missing mandatory package parameter from 
options.',
   MISSING_NAMESPACE_ERROR: 'Missing namespace from options, please set a 
default namespace or pass one in the options.',
   INVALID_OPTIONS_ERROR: 'Invalid constructor options.',
-  MISSING_BASEPATH_ERROR: 'Missing mandatory basepath parameter from options.'
+  MISSING_BASEPATH_ERROR: 'Missing mandatory parameters: basepath or name.',
+  INVALID_BASEPATH_ERROR: 'Invalid parameters: use basepath or name, not both.'
 }
diff --git a/lib/routes.js b/lib/routes.js
index edb5f60..eb55026 100644
--- a/lib/routes.js
+++ b/lib/routes.js
@@ -13,8 +13,19 @@ class Routes extends BaseOperation {
     return `web/whisk.system/apimgmt/${path}.http`
   }
 
+  get (options) {
+    options = options || {}
+    options.basepath = this.basepath(options)
+
+    return this.list(this.qs(options, ['basepath']))
+  }
+
   list (options) {
     options = options || {}
+    if (this.has_basepath(options)) {
+      options.basepath = this.calculate_basepath(options)
+    }
+
     const qs = this.qs(options, ['relpath', 'basepath', 'operation', 'limit', 
'skip'])
     return this.client.request('GET', this.routeMgmtApiPath('getApi'), { qs })
   }
@@ -30,26 +41,57 @@ class Routes extends BaseOperation {
     return result
   }
 
-  delete (options) {
-    if (!options || !options.hasOwnProperty('basepath')) {
+  has_basepath (options) {
+    return !!(options.name || options.basepath)
+  }
+
+  basepath (options) {
+    if (!this.has_basepath(options)) {
       throw new Error(messages.MISSING_BASEPATH_ERROR)
     }
 
+    return this.calculate_basepath(options)
+  }
+
+  calculate_basepath (options) {
+    if (options.name && options.basepath) {
+      throw new Error(messages.INVALID_BASEPATH_ERROR)
+    }
+
+    return options.basepath || options.name
+  }
+
+  missing_basepath (options) {
+    return !(options.name || options.basepath)
+  }
+
+  delete (options) {
+    options = options || {}
+    options.basepath = this.basepath(options)
+
     const qs = this.qs(options, ['relpath', 'basepath', 'operation'])
     qs.force = true
     return this.client.request('DELETE', this.routeMgmtApiPath('deleteApi'), { 
qs })
   }
 
   create (options) {
+    const body = this.create_body(options || {})
+    const qs = this.qs(options, ['responsetype'])
+    return this.client.request('POST', this.routeMgmtApiPath('createApi'), { 
body, qs })
+  }
+
+  create_body (options) {
+    if (options.swagger) {
+      return { apidoc: { namespace: '_', swagger: options.swagger } }
+    }
+
     const missing = CREATE_PARAMS.filter(param => !(options || 
{}).hasOwnProperty(param))
 
     if (missing.length) {
       throw new Error(`Missing mandatory parameters: ${missing.join(', ')}`)
     }
 
-    const body = this.route_swagger_definition(options)
-    const qs = this.qs(options, ['responsetype'])
-    return this.client.request('POST', this.routeMgmtApiPath('createApi'), { 
body, qs })
+    return this.route_swagger_definition(options)
   }
 
   route_swagger_definition (params) {
@@ -60,7 +102,11 @@ class Routes extends BaseOperation {
       gatewayMethod: params.operation,
       id: `API:_:${this.route_base_path(params)}`,
       action: this.route_swagger_action(params)
-   }
+    }
+
+    if (params.name) {
+      apidoc.apiName = params.name
+    }
 
     return { apidoc }
   }
diff --git a/test/unit/routes.test.js b/test/unit/routes.test.js
index 0d25c36..9d039e4 100644
--- a/test/unit/routes.test.js
+++ b/test/unit/routes.test.js
@@ -6,6 +6,73 @@
 const test = require('ava')
 const Routes = require('../../lib/routes')
 
+test('should retrieve routes from name', t => {
+  t.plan(3)
+  const client = { options: {} }
+  client.request = (method, path, options) => {
+    t.is(method, 'GET')
+    t.is(path, routes.routeMgmtApiPath('getApi'))
+    t.deepEqual(options.qs, { basepath: 'testing' })
+  }
+
+  const routes = new Routes(client)
+  return routes.get({name: 'testing'})
+})
+
+test('should retrieve routes from basepath', t => {
+  t.plan(3)
+  const client = { options: {} }
+  client.request = (method, path, options) => {
+    t.is(method, 'GET')
+    t.is(path, routes.routeMgmtApiPath('getApi'))
+    t.deepEqual(options.qs, { basepath: 'testing' })
+  }
+
+  const routes = new Routes(client)
+  return routes.get({basepath: 'testing'})
+})
+
+test('should retrieve routes with apigw_token and name', t => {
+  t.plan(3)
+  const client = { options: {
+    apigw_token: 'token',
+    apigw_space_guid: 'space'
+  } }
+  client.request = (method, path, options) => {
+    t.is(method, 'GET')
+    t.is(path, routes.routeMgmtApiPath('getApi'))
+    t.deepEqual(options.qs, { basepath: 'testing', spaceguid: 'space', 
accesstoken: 'token'})
+  }
+
+  const routes = new Routes(client)
+  return routes.get({name: 'testing'})
+})
+
+test('should retrieve routes with apigw_token and basepath', t => {
+  t.plan(3)
+  const client = { options: {
+    apigw_token: 'token',
+    apigw_space_guid: 'space'
+  } }
+  client.request = (method, path, options) => {
+    t.is(method, 'GET')
+    t.is(path, routes.routeMgmtApiPath('getApi'))
+    t.deepEqual(options.qs, { basepath: 'testing', spaceguid: 'space', 
accesstoken: 'token'})
+  }
+
+  const routes = new Routes(client)
+  return routes.get({basepath: 'testing'})
+})
+
+test('get routes with incorrect parameters', t => {
+  const routes = new Routes({options: {}})
+  t.throws(() => { routes.get() }, /Missing mandatory parameters: basepath or 
name/)
+  t.throws(() => { routes.get({}) }, /Missing mandatory parameters: basepath 
or name/)
+  t.throws(() => { routes.get({basepath: 'id', name: 'id'}) }, /Invalid 
parameters: use basepath or name, not both/)
+})
+
+// ADD NAME TO OTHER METHODS
+
 test('should list all routes', t => {
   t.plan(2)
   const client = { options: {} }
@@ -35,7 +102,7 @@ test('should list all routes with apigw_token', t => {
 })
 
 
-test('should list all routes with parameters', t => {
+test('should list all routes with parameters including basepath', t => {
   t.plan(3)
   const client = { options: {} }
   const options = {basepath: '/hello', relpath: '/foo/bar', operation: 'GET', 
limit: 10, skip: 10}
@@ -49,7 +116,28 @@ test('should list all routes with parameters', t => {
   return routes.list(options)
 })
 
-test('should delete a route', t => {
+test('should list all routes with parameters including name', t => {
+  t.plan(3)
+  const client = { options: {} }
+  const options = {name: '/hello', relpath: '/foo/bar', operation: 'GET', 
limit: 10, skip: 10}
+  const qs_options = {basepath: '/hello', relpath: '/foo/bar', operation: 
'GET', limit: 10, skip: 10}
+  client.request = (method, path, _options) => {
+    t.is(method, 'GET')
+    t.is(path, routes.routeMgmtApiPath('getApi'))
+    t.deepEqual(_options.qs, qs_options)
+  }
+
+  const routes = new Routes(client)
+  return routes.list(options)
+})
+
+test('list routes providing basepath and name', t => {
+  const client = { options: {} }
+  const routes = new Routes(client)
+  return t.throws(() => { routes.list({basepath: 'bp', name: 'nm'}) }, 
/Invalid parameters: use basepath or name, not both/)
+})
+
+test('should delete a route with basepath', t => {
   t.plan(3)
   const client = { options: {} }
   const options = {force: true, basepath: '/hello'}
@@ -64,6 +152,21 @@ test('should delete a route', t => {
   return routes.delete({basepath: '/hello'})
 })
 
+test('should delete a route with name', t => {
+  t.plan(3)
+  const client = { options: {} }
+  const options = {force: true, basepath: '/hello'}
+
+  client.request = (method, path, _options) => {
+    t.is(method, 'DELETE')
+    t.is(path, routes.routeMgmtApiPath('deleteApi'))
+    t.deepEqual(_options.qs, options)
+  }
+
+  const routes = new Routes(client)
+  return routes.delete({name: '/hello'})
+})
+
 test('should delete a route with apigw token', t => {
   t.plan(3)
   const client = { options: {
@@ -96,10 +199,16 @@ test('should delete a route with parameters', t => {
   return routes.delete({basepath: '/hello', relpath: '/bar/1', operation: 
'GET'})
 })
 
-test('delete routes without providing basepath', t => {
+test('delete routes without providing basepath or name', t => {
   const client = { options: {} }
   const routes = new Routes(client)
-  return t.throws(() => { routes.delete() }, /Missing mandatory basepath/)
+  return t.throws(() => { routes.delete() }, /Missing mandatory parameters: 
basepath or name/)
+})
+
+test('delete routes providing basepath and name', t => {
+  const client = { options: {} }
+  const routes = new Routes(client)
+  return t.throws(() => { routes.delete({basepath: 'bp', name: 'nm'}) }, 
/Invalid parameters: use basepath or name, not both/)
 })
 
 test('should create a route', t => {
@@ -136,6 +245,65 @@ test('should create a route', t => {
   return routes.create({relpath: '/hello', operation: 'GET', action: 
'helloAction'})
 })
 
+test('should create a route from swagger file', t => {
+  t.plan(3)
+  const path_url = path => `https://openwhisk.ng.bluemix.net/api/v1/${path}`
+  const api_key = 'username:password'
+  const client_options = { api_key }
+  const client = { path_url, options: client_options }
+
+  const body = {
+    apidoc: {
+      namespace: '_',
+      swagger: '{"hello": "world"}'
+    }
+  }
+
+  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({swagger: '{"hello": "world"}'})
+})
+
+test('should create a route with api name', t => {
+  t.plan(3)
+  const path_url = path => `https://openwhisk.ng.bluemix.net/api/v1/${path}`
+  const api_key = 'username:password'
+  const client_options = { api_key }
+  const client = { path_url, options: client_options }
+  const options = {force: true, basepath: '/hello', relpath: '/bar/1', 
operation: 'GET'}
+
+  const body = {
+    apidoc: {
+      namespace: '_',
+      apiName: 'SOME_NAME',
+      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: api_key }
+    }
+  }
+
+  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', name: 'SOME_NAME'})
+})
+
 test('should create a route with apigw_token', t => {
   t.plan(4)
   const path_url = path => `https://openwhisk.ng.bluemix.net/api/v1/${path}`
@@ -446,7 +614,6 @@ test('should create a route using action name with ns 
overriding defaults', t =>
   return routes.create({relpath: '/hello', operation: 'GET', action: 
'/test/helloAction'})
 })
 
-
 test('create routes missing mandatory parameters', t => {
   const routes = new Routes()
   t.throws(() => { routes.create() }, /Missing mandatory parameters: relpath, 
operation, action/)


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to