UNPKG

19.1 kBMarkdownView Raw
1# OpenWhisk Client for JavaScript
2
3[![Build Status](https://travis-ci.org/apache/incubator-openwhisk-client-js.svg?branch=master)](https://travis-ci.org/apache/incubator-openwhisk-client-js)
4[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0)
5[![codecov](https://codecov.io/gh/apache/incubator-openwhisk-client-js/branch/master/graph/badge.svg)](https://codecov.io/gh/apache/incubator-openwhisk-client-js)
6
7JavaScript client library for the [Apache OpenWhisk](https://github.com/apache/incubator-openwhisk) platform.
8Provides a wrapper around the [OpenWhisk APIs](https://github.com/apache/incubator-openwhisk/blob/fb001afa237476eda0c0f6494ee92702e5986538/core/controller/src/main/resources/apiv1swagger.json) (Swagger JSON).
9
10## installation
11
12```bash
13$ npm install openwhisk
14```
15
16## usage
17
18### within openwhisk platform
19
20This client library can use environment parameters to automatically configure the authentication credentials, platform endpoint and namespace. These parameters are defined within the Node.js runtime environment in OpenWhisk. Unless you want to override these values, you can construct the client instance without further configuration.
21
22```javascript
23var openwhisk = require('openwhisk');
24
25function action() {
26 var ow = openwhisk();
27 return ow.actions.invoke('sample')
28}
29
30exports.main = action
31```
32
33_All methods return a Promise resolved asynchronously with the results. Failures are available through the catch method._
34
35```javascript
36ow.resource.operation().then(function () { // success! }).catch(function (err) { // failed! })
37```
38
39Users can override default constructor parameters by passing in explicit options as shown in the example below.
40
41_**Please note**: Due to [an issue](https://github.com/openwhisk/openwhisk/issues/1751) with the Node.js runtime in OpenWhisk, environment variables used by the constructor are not available until the invocation function handler is called. If you want to define the client instance outside this function, you will need to manually pass in the constructor options ._
42
43```javascript
44var openwhisk = require('openwhisk');
45// DOES NOT WORK! Environment parameters not set.
46var ow = openwhisk();
47
48function action() {
49 return ow.actions.invoke('sample')
50}
51
52exports.main = action
53```
54
55### outside openwhisk platform
56
57```javascript
58var openwhisk = require('openwhisk');
59var options = {apihost: 'openwhisk.ng.bluemix.net', api_key: '...'};
60var ow = openwhisk(options);
61ow.actions.invoke('sample').then(result => console.log(result))
62```
63
64### constructor options
65
66_Client constructor supports the following mandatory parameters:_
67
68- **apihost.** Hostname and optional port for openwhisk platform, e.g. `openwhisk.ng.bluemix.net` or `my_whisk_host:80`. Used with API URL template `${protocol}://${apihost}/api/v1/`. If port is missing or port value is 443 in the apihost string, protocol is HTTPS. Otherwise, protocol is HTTP.
69- **api_key.** Authorisation key for user account registered with OpenWhisk platform.
70
71*Client constructor supports the following optional parameters:*
72
73- **api.** Full API URL for OpenWhisk platform, e.g. `https://openwhisk.ng.bluemix.net/api/v1/`. This value overrides `apihost` if both are present.
74- **namespace**. Namespace for resource requests, defaults to `_`.
75- **ignore_certs**. Turns off server SSL/TLS certificate verification. This allows the client to be used against local deployments of OpenWhisk with a self-signed certificate. Defaults to false.
76- **apigw_token**. API Gateway service authentication token. This is mandatory for using an external API Gateway service, rather than the built-in api gateway.
77- **apigw_space_guid**. API Gateway space identifier. This is optional when using an API gateway service, defaults to the authentication uuid.
78
79### environment variables
80
81Client constructor will read values for the `apihost`, `namespace`, `api_key`, `apigw_token` and `apigw_space_guid` options from the environment if the following parameters are set. Explicit options have precedence over environment values.
82
83- *__OW_API_HOST*
84- *__OW_NAMESPACE*
85- *__OW_API_KEY*
86- *__OW_APIGW_TOKEN*
87- *__OW_APIGW_SPACE_SUID*
88
89
90
91## Examples
92
93### invoke action, blocking for result
94
95```javascript
96const name = 'reverseWords'
97const blocking = true, result = true
98const params = {msg: 'these are some words to reverse'}
99
100ow.actions.invoke({name, blocking, result, params}).then(result => {
101 console.log('here is the reversed string', result.reversed)
102}).catch(err => {
103 console.error('failed to invoke actions', err)
104})
105```
106
107### fire trigger
108
109```javascript
110const name = 'eventTrigger'
111const params = {msg: 'event trigger message string'}
112ow.triggers.invoke({name, params}).then(result => {
113 console.log('trigger fired!')
114}).catch(err => {
115 console.error('failed to fire trigger', err)
116})
117```
118
119### create action from source file
120
121```javascript
122const name = 'reverseWords'
123const action = fs.readFileSync('source.js', {encoding: 'utf8'})
124
125ow.actions.create({name, action}).then(result => {
126 console.log('action created!')
127}).catch(err => {
128 console.error('failed to create action', err)
129})
130```
131
132### create action from zip package
133
134```javascript
135const name = 'reverseWords'
136const action = fs.readFileSync('package.zip')
137
138ow.actions.create({name, action}).then(result => {
139 console.log('action created!')
140}).catch(err => {
141 console.error('failed to create action', err)
142})
143```
144
145### retrieve action resource
146
147```javascript
148const name = 'reverseWords'
149ow.actions.get(name).then(action => {
150 console.log('action resource', action)
151}).catch(err => {
152 console.error('failed to retrieve action', err)
153})
154```
155
156### chaining calls
157
158```javascript
159ow.actions.list()
160 .then(actions => ow.actions.invoke(actions))
161 .then(result => ...)
162```
163
164### list packages
165
166```javascript
167ow.packages.list().then(packages => {
168 packages.forEach(package => console.log(package.name))
169}).catch(err => {
170 console.error('failed to list packages', err)
171})
172```
173
174### update package parameters
175
176```javascript
177const name = 'myPackage'
178const package = {
179 parameters: [
180 {key: "colour", value: "green"},
181 {key: "name", value: "Freya"}
182 ]
183}
184
185ow.packages.update({name, package}).then(package => {
186 console.log('updated package:', package.name)
187}).catch(err => {
188 console.error('failed to update package', err)
189})
190```
191
192### create trigger feed from alarm package
193
194```javascript
195// alarmTrigger MUST already exist in default namespace
196const params = {cron: '*/8 * * * * *', trigger_payload: {name: 'James'}}
197const name = '/whisk.system/alarms/alarm'
198const trigger = 'alarmTrigger'
199ow.feeds.create({name, trigger, params}).then(package => {
200 console.log('alarm trigger feed created')
201}).catch(err => {
202 console.error('failed to create alarm trigger', err)
203})
204```
205
206
207
208## API Details
209
210### resource identifiers + namespaces
211
212When passing resource identifiers as parameters you can either use a short name, without an explicit namespace, or a fully-qualified identifier, including namespace and package details.
213
214If the namespace is missing from the resource identifier, the client will use the namespace from configuration options following this ordering.
215
216- `namespace` from method parameter options OR
217- `namespace` from options passed into client constructor OR
218- `namespace` from environment variable (`__OW_NAMESPACE`) OR
219- default namespace: `_`
220
221### list resources
222
223```javascript
224ow.actions.list()
225ow.activations.list()
226ow.triggers.list()
227ow.rules.list()
228ow.namespaces.list()
229ow.packages.list()
230```
231
232Query parameters for the API calls are supported (e.g. limit, skip, etc.) by passing an object with the named parameters as the first argument.
233
234```javascript
235ow.actions.list({skip: 100, limit: 50})
236```
237
238The following optional parameters are supported:
239- `namespace` - set custom namespace for endpoint
240
241### retrieve resource
242
243```javascript
244ow.actions.get({name: '...'})
245ow.activations.get({name: '...'})
246ow.triggers.get({name: '...'})
247ow.rules.get({name: '...'})
248ow.packages.get({name: '...'})
249ow.feeds.get({name: '...', trigger: '...'})
250```
251
252The following optional parameters are supported for all resource retrievals:
253- `namespace` - set custom namespace for endpoint
254
255Optional parameters for action resource retrievals are shown below:
256- `code` - set to `true` or `false` depending on whether action code should be included or excluded respectively
257
258This method also supports passing the `name` property directly without wrapping within an object.
259```javascript
260const name = "actionName"
261ow.actions.get(name)
262```
263
264If you pass in an array for the first parameter, the `get` call will be executed for each array item. The function returns a Promise which resolves with the results when all operations have finished.
265
266```javascript
267ow.actions.get(["a", {name: "b"}])
268```
269
270### delete resource
271
272```javascript
273ow.actions.delete({name: '...'})
274ow.triggers.delete({name: '...'})
275ow.rules.delete({name: '...'})
276ow.packages.delete({name: '...'})
277ow.feeds.delete({name: '...', trigger: '...'})
278```
279
280The following optional parameters are supported:
281- `namespace` - set custom namespace for endpoint
282
283This method also supports passing the `name` property directly without wrapping within an object.
284
285```javascript
286const name = "actionName"
287ow.actions.delete(name)
288```
289
290If you pass in an array for the first parameter, the `delete` call will be executed for each array item. The function returns a Promise which resolves with the results when all operations have finished.
291
292```javascript
293ow.actions.delete(["a", {name: "b"}])
294```
295
296### invoke action
297
298```javascript
299ow.actions.invoke({name: '...'})
300```
301
302The `actionName` parameter supports the following formats: `actionName`, `package/actionName`, `/namespace/actionName`, `/namespace/package/actionName`.
303
304If `actionName` includes a namespace, this overrides any other `namespace` properties.
305
306The following optional parameters are supported:
307- `blocking` - delay returning until action has finished executing (default: `false`)
308- `result` - return function result (`obj.response.result`) rather than entire API result (default: `false`)
309- `params` - JSON object containing parameters for the action being invoked (default: `{}`)
310- `namespace` - set custom namespace for endpoint
311
312This method also supports passing the `name` property directly without wrapping within an object.
313
314```javascript
315const name = "actionName"
316ow.actions.invoke(name)
317```
318
319If you pass in an array for the first parameter, the `invoke` call will be executed for each array item. The function returns a Promise which resolves with the results when all operations have finished.
320
321```javascript
322ow.actions.invoke(["a", {name: "b", blocking: true}])
323```
324
325### create & update action
326
327```javascript
328ow.actions.create({name: '...', action: 'function main() {};'})
329ow.actions.update({name: '...', action: 'function main() {};'})
330```
331
332The following mandatory parameters are supported:
333- `name` - action identifier
334- `action` - String containing JS function source code, Buffer [containing package action zip file](https://github.com/openwhisk/openwhisk/blob/master/docs/actions.md#packaging-an-action-as-a-nodejs-module) or JSON object containing full parameters for the action body
335
336The following optional parameters are supported:
337- `namespace` - set custom namespace for endpoint
338- `params` - object containing default parameters for the action (default: `{}`)
339- `annotations` - object containing annotations for the action (default: `{}`)
340- `limits` - object containing limits for the action (default: `{}`)
341- `kind` - runtime environment parameter, ignored when `action` is an object (default: `nodejs:default`)
342- `version` - set semantic version of the action. If parameter is empty when create new action openwisk generate 0.0.1 value when update an action increase the patch version.
343
344If you pass in an array for the first parameter, the `create` call will be executed for each array item. The function returns a Promise which resolves with the results when all operations have finished.
345
346```javascript
347ow.actions.create([{...}, {...}])
348```
349
350### fire trigger
351
352```javascript
353ow.triggers.invoke({name: '...'})
354```
355
356The following optional parameters are supported:
357- `params` - JSON object containing parameters for the trigger being fired (default: `{}`)
358- `namespace` - set custom namespace for endpoint
359
360This method also supports passing the `name` property directly without wrapping within an object.
361
362```javascript
363const name = "actionName"
364ow.triggers.invoke(name)
365```
366
367If you pass in an array for the first parameter, the `invoke` call will be executed for each array item. The function returns a Promise which resolves with the results when all operations have finished.
368
369```javascript
370ow.triggers.invoke(["a", {name: "b", blocking: true}])
371```
372
373### create & update trigger
374
375```javascript
376ow.triggers.create({name: '...'})
377ow.triggers.update({name: '...'})
378```
379
380The following optional parameters are supported:
381- `trigger` - JSON object containing parameters for the trigger body (default: `{}`)
382- `namespace` - set custom namespace for endpoint
383
384### create & update packages
385
386```javascript
387ow.packages.create({name: '...'})
388ow.packages.update({name: '...'})
389```
390
391The following optional parameters are supported:
392- `package` - JSON object containing parameters for the package body (default: `{}`)
393- `namespace` - set custom namespace for endpoint
394
395### create & update rule
396
397```javascript
398ow.rules.create({name: '...', action: '...', trigger: '...'})
399ow.rules.update({name: '...', action: '...', trigger: '...'})
400```
401
402`trigger` and `action` identifiers will have the default namespace (`/_/`)
403appended in the request, unless a fully qualified name is passed in
404(`/custom_ns/action_or_trigger_name`).
405
406The following optional parameters are supported:
407- `namespace` - set namespace for rule
408
409### enable & disable rule
410
411```javascript
412ow.rules.enable({name: '...'})
413ow.rules.disable({name: '...'})
414```
415
416The following optional parameters are supported:
417- `namespace` - set custom namespace for endpoint
418
419### create & update feeds
420
421```javascript
422ow.feeds.create({feedName: '...', trigger: '...'})
423ow.feeds.update({feedName: '...', trigger: '...'})
424```
425
426The following optional parameters are supported:
427- `namespace` - set custom namespace for endpoint
428- `params` - JSON object containing parameters for the feed being invoked (default: `{}`)
429
430## api gateway
431
432OpenWhisk supports a [built-in API gateway service](https://github.com/apache/incubator-openwhisk/blob/master/docs/apigateway.md) and external third-party providers.
433
434This client library defaults to using the platform service. If the `apigw_token` parameter is passed into the client constructor, the implementation will switch to the [IBM Bluemix API Gateway](https://console.ng.bluemix.net/docs/openwhisk/openwhisk_apigateway.html#openwhisk_apigateway).
435
436*The interface for managing routes through the library does not change between providers.*
437
438### retrieve route
439
440```javascript
441ow.routes.get({basepath: '...'})
442ow.routes.get({name: '...'})
443```
444
445*This method is a wrapper for the list method. It throws an error if the base path or name parameter is missing.*
446
447### list routes
448
449```javascript
450ow.routes.list()
451```
452
453The following optional parameters are supported to filter the result set:
454- `relpath` - relative URI path for endpoints
455- `basepath` - base URI path for endpoints
456- `name` - identifier for API
457- `operation` - HTTP methods
458- `limit` - limit result set size
459- `skip` - skip results from index
460
461*`relpath` is only valid when `basepath` is also specified. `name` and `basepath` cannot be used together.*
462
463### delete routes
464
465```javascript
466ow.routes.delete({basepath: '...'})
467ow.routes.delete({name: '...'})
468```
469
470The following optional parameters are supported to filter the result set:
471- `relpath` - relative URI path for endpoints
472- `operation` - HTTP methods
473
474### add route
475```javascript
476ow.routes.create({relpath: '...', operation: '...', action: '...'})
477```
478
479*`action` supports normal (actionName) and fully-qualified (/namespace/actionName) formats.*
480
481The following optional parameters are supported:
482- `responsetype` - content type returned by web action, possible values: `html`, `http`, `json`, `text` and `svg` (default: `json`).
483- `basepath` - base URI path for endpoints (default: `/`)
484- `name` - identifier for API (default: `basepath`)
485
486### add route (swagger)
487
488```javascript
489ow.routes.create({swagger: '{...}'})
490```
491
492Swagger 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).
493
494*No other parameters are supported when creating the route from a JSON Swagger document.*
495
496## Debugging
497
498Setting an environment parameter (`DEBUG=needle`) will dump the HTTP requests from the client library and responses received to `stderr`.
499
500```bash
501DEBUG=needle node script.js
502```
503
504This parameter can also be set dynamically at runtime, provided this happens before the `openwhisk` module is required.
505
506```javascript
507process.env.DEBUG='needle';
508var openwhisk = require('openwhisk');
509```
510
511## Development
512
513### unit tests
514
515```bash
516$ npm test
517```
518
519### integration tests
520
521*Please [see the instructions](https://github.com/openwhisk/openwhisk-client-js/tree/master/test/integration) for setting up the integration test environment prior to running these tests.*
522
523```bash
524$ npm run-script test-integration
525```
526
527**Note:** The test integration runs in secure mode by default, which means that all trusted signers must be present and available to the client process.
528If your local environment is using self-signed certificates, you can use the following command to start the script in insecure mode:
529
530`npm run test-integration -i`
531
532This will disable SSL/TLS verification for all SSL communication.
533
534Alternatively, you can run the `prepIntegrationTests.sh` script using guest credentials or by specifying specific credentials.
535Run the script with openwhisk credentials:
536```bash
537$ ./test/integration/prepIntegrationTests.sh <your key in the form of ABCD:EFGH> <openwhisk instance hostname> <openwhisk namespace> <api gatewaytoken>
538```
539The `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`
540
541## Code-Coverage:
542
543You can customize how comprehensive the tests are over the code, and generate reports to view the results by using
544the provided `code-coverage` commands below.
545
546**Note:** Ensure that you use guest credentials with the wsk CLI.
547
548To compile down to ECMA5 run the following command:
5491 `$ npm run code-coverage-build`
550
551To generate combined reports of both the unit and integration tests, run the following command:
5522 `$ npm run code-coverage-run <key> <host> <namespace> <token> <options>`
553
554The report is viewable under `/coverage`. Click **`/coverage/index.html`** to view the full report.