UNPKG

30.3 kBMarkdownView Raw
1# Serverless OpenWhisk Plugin
2[![Build Status](https://travis-ci.org/serverless/serverless-openwhisk.svg?branch=master)](https://travis-ci.org/serverless/serverless-openwhisk)
3[![codecov](https://codecov.io/gh/serverless/serverless-openwhisk/branch/master/graph/badge.svg)](https://codecov.io/gh/serverless/serverless-openwhisk)
4
5This plugin enables support for the [OpenWhisk platform](http://openwhisk.org/) within the Serverless Framework.
6
7## Getting Started
8
9### Register account with OpenWhisk
10
11Before you can deploy your service to OpenWhisk, you need to have an account registered with the platform.
12
13- *Want to run the platform locally?* Please read the project's [*Quick Start*](https://github.com/openwhisk/openwhisk#quick-start) guide for deploying it locally.
14- *Want to use a hosted provider?* Please sign up for an account with [IBM Bluemix](https://console.ng.bluemix.net/) and then follow the instructions for getting access to [OpenWhisk on Bluemix](https://console.ng.bluemix.net/openwhisk/).
15
16### Set up account credentials
17
18Account credentials for OpenWhisk can be provided through a configuration file or environment variables. This plugin requires the API endpoint, namespace and authentication credentials.
19
20**Do you want to use a configuration file for storing these values?** Please [follow the instructions](https://console.ng.bluemix.net/openwhisk/cli) for setting up the OpenWhisk command-line utility. This tool stores account credentials in the `.wskprops` file in the user's home directory. The plugin automatically extracts credentials from this file at runtime. No further configuration is needed.
21
22**Do you want to use environment variables for credentials?** Use the following environment variables to be pass in account credentials. These values override anything extracted from the configuration file.
23
24- *OW_APIHOST* - Platform endpoint, e.g. `openwhisk.ng.bluemix.net`
25- *OW_AUTH* - Authentication key, e.g. `xxxxxx:yyyyy`
26- *OW_APIGW_ACCESS_TOKEN* - API gateway access token (optional)
27
28### Install Framework & Dependencies
29
30*Due to an [outstanding issue](https://github.com/serverless/serverless/issues/2895) with provider plugins, the [OpenWhisk provider](https://github.com/serverless/serverless-openwhisk) must be installed as a global module.*
31
32```shell
33$ npm install --global serverless serverless-openwhisk
34```
35
36**_This framework plugin requires Node.js runtime version 6.0 or above._**
37
38### Create Service From Template
39
40Using the `create` command, you can create an example service from the [following template](https://github.com/serverless/serverless/tree/master/lib/plugins/create/templates/openwhisk-nodejs).
41
42```shell
43serverless create --template openwhisk-nodejs --path my_service
44cd my_service
45npm install
46```
47
48More service examples are available in the [`serverless-examples`](https://github.com/serverless/examples) repository.
49
50**Using a self-hosted version of the platform?**
51
52Ensure you set the `ignore_certs` option in the serverless.yaml prior to deployment.
53
54```
55provider:
56 name: openwhisk
57 ignore_certs: true
58```
59
60### Deploy Service
61
62The sample service from the template can be deployed without modification.
63
64```shell
65serverless deploy
66```
67
68If the deployment succeeds, the following messages will be printed to the console.
69
70```sh
71$ serverless deploy
72Serverless: Packaging service...
73Serverless: Compiling Functions...
74Serverless: Compiling API Gateway definitions...
75Serverless: Compiling Rules...
76Serverless: Compiling Triggers & Feeds...
77Serverless: Deploying Functions...
78Serverless: Deployment successful!
79
80Service Information
81platform: openwhisk.ng.bluemix.net
82namespace: _
83service: my_service
84
85actions:
86my_service-dev-hello
87
88triggers:
89**no triggers deployed***
90
91rules:
92**no rules deployed**
93
94endpoints:
95**no routes deployed**
96
97web-actions:
98**no web actions deployed**
99```
100
101### Test Service
102
103Use the `invoke` command to test your newly deployed service.
104
105```shell
106$ serverless invoke --function hello
107{
108 "payload": "Hello, World!"
109}
110$ serverless invoke --function hello --data '{"name": "OpenWhisk"}'
111{
112 "payload": "Hello, OpenWhisk!"
113}
114```
115
116## Writing Functions - Node.js
117
118Here's an `index.js` file containing an example handler function.
119
120```javascript
121function main(params) {
122 const name = params.name || 'World';
123 return {payload: 'Hello, ' + name + '!'};
124};
125
126exports.main = main;
127```
128
129Modules [should return the function handler](https://github.com/openwhisk/openwhisk/blob/master/docs/actions.md#packaging-an-action-as-a-nodejs-module) as a custom property on the global `exports` object.
130
131In the `serverless.yaml` file, the `handler` property is used to denote the source file and module property containing the serverless function.
132
133```yaml
134functions:
135 my_function:
136 handler: index.main
137```
138
139### Request Properties
140
141OpenWhisk executes the handler function for each request. This function is called with a single argument, an object [containing the request properties](https://github.com/openwhisk/openwhisk/blob/master/docs/actions.md#passing-parameters-to-an-action).
142
143```javascript
144function main(params) {
145 const parameter = params.parameter_name;
146 ...
147};
148```
149
150### Function Return Values
151
152The handler must return an object from the function call. Returning `undefined` or `null` will result in an error. If the handler is carrying out an [asynchronous task](https://github.com/openwhisk/openwhisk/blob/master/docs/actions.md#creating-asynchronous-actions), it can return a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).
153
154```javascript
155// synchronous return
156function main () {
157 return { payload: "..." }
158}
159
160// asychronous return
161function main(args) {
162 return new Promise(function(resolve, reject) {
163 setTimeout(function() {
164 resolve({ done: true });
165 }, 2000);
166 })
167}
168```
169
170If you want to return an error message, return an object with an `error` property with the message. Promise values that are rejected will be interpreted as runtime errors.
171
172```javascript
173// synchronous return
174function main () {
175 return { error: "..." }
176}
177
178// asychronous return
179function main(args) {
180 return new Promise(function(resolve, reject) {
181 setTimeout(function() {
182 reject("error message");
183 }, 2000);
184 })
185}
186```
187
188### Using NPM Modules
189
190NPM modules must be [installed locally](https://github.com/openwhisk/openwhisk/blob/master/docs/actions.md#packaging-an-action-as-a-nodejs-module) in the `node_modules` directory before deployment. This directory will be packaged up in the deployment artefact. Any dependencies included in `node_modules` will be available through `require()` in the runtime environment.
191
192OpenWhisk provides a number of popular NPM modules in the runtime environment. Using these modules doesn't require them to be included in the deployment package. See [this list](https://github.com/openwhisk/openwhisk/blob/master/docs/reference.md#javascript-runtime-environments) for full details of which modules are available.
193
194```javascript
195const leftPad = require("left-pad")
196
197function pad_lines(args) {
198 const lines = args.lines || [];
199 return { padded: lines.map(l => leftPad(l, 30, ".")) }
200};
201
202exports.handler = pad_lines;
203```
204
205## Writing Functions - PHP
206
207Here's an `index.php` file containing an example handler function.
208
209```php
210<?php
211function main(array $args) : array
212{
213 $name = $args["name"] ?? "stranger";
214 $greeting = "Hello $name!";
215 echo $greeting;
216 return ["greeting" => $greeting];
217}
218```
219
220In the `serverless.yaml` file, the `handler` property is used to denote the source file and function name of the serverless function.
221
222```yaml
223functions:
224 my_function:
225 handler: index.main
226 runtime: php
227```
228
229### Request Properties
230
231OpenWhisk executes the handler function for each request. This function is called with a single argument, an associative array [containing the request properties](https://github.com/openwhisk/openwhisk/blob/master/docs/actions.md#passing-parameters-to-an-action).
232
233```php
234function main(array $args) : array
235{
236 $name = $args["name"] ?? "stranger";
237 ...
238}
239```
240
241### Function Return Values
242
243The handler must return an associative array from the function call.
244
245```swift
246func main(args: [String:Any]) -> [String:Any] {
247 ...
248 return ["foo" => $bar];
249}
250```
251
252If you want to return an error message, return an object with an `error` property with the message.
253
254## Writing Functions - Python
255
256Here's an `index.py` file containing an example handler function.
257
258```python
259def endpoint(params):
260 name = params.get("name", "stranger")
261 greeting = "Hello " + name + "!"
262 print(greeting)
263 return {"greeting": greeting}
264```
265
266In the `serverless.yaml` file, the `handler` property is used to denote the source file and module property containing the serverless function.
267
268```yaml
269functions:
270 my_function:
271 handler: index.endpoint
272 runtime: python
273```
274
275### Request Properties
276
277OpenWhisk executes the handler function for each request. This function is called with a single argument, a dictionary [containing the request properties](https://github.com/openwhisk/openwhisk/blob/master/docs/actions.md#passing-parameters-to-an-action).
278
279```python
280def endpoint(params):
281 name = params.get("name", "stranger")
282 ...
283```
284
285### Function Return Values
286
287The handler must return a dictionary from the function call.
288
289```python
290def endpoint(params):
291 ...
292 return {"foo": "bar"}
293```
294
295If you want to return an error message, return an object with an `error` property with the message.
296
297## Writing Functions - Swift
298
299Here's an `index.swift` file containing an example handler function.
300
301```swift
302func main(args: [String:Any]) -> [String:Any] {
303 if let name = args["name"] as? String {
304 return [ "greeting" : "Hello \(name)!" ]
305 } else {
306 return [ "greeting" : "Hello stranger!" ]
307 }
308}
309```
310
311In the `serverless.yaml` file, the `handler` property is used to denote the source file and module property containing the serverless function.
312
313```yaml
314functions:
315 my_function:
316 handler: index.main
317 runtime: swift
318```
319
320### Request Properties
321
322OpenWhisk executes the handler function for each request. This function is called with a single argument, a dictionary [containing the request properties](https://github.com/openwhisk/openwhisk/blob/master/docs/actions.md#passing-parameters-to-an-action).
323
324```swift
325func main(args: [String:Any]) -> [String:Any] {
326 let prop = args["prop"] as? String
327}
328```
329
330### Function Return Values
331
332The handler must return a dictionary from the function call.
333
334```swift
335func main(args: [String:Any]) -> [String:Any] {
336 ...
337 return ["foo": "bar"]
338}
339```
340
341If you want to return an error message, return an object with an `error` property with the message.
342
343## Writing Functions - Pre-Compiled Swift Binaries
344
345OpenWhisk supports creating Swift actions from a pre-compiled binary. This reduces startup time for Swift actions by removing the need for a dynamic compilation step.
346
347In the `serverless.yaml` file, the `handler` property can refer to the compiled binary file produced by the build.
348
349```yaml
350functions:
351 hello:
352 handler: .build/release/Hello
353```
354
355This configuration will generate the deployment package for that function containing only this binary file. It will not include other local files, e.g. Swift source files.
356
357Pre-compiled Swift actions must be compatible with the platform runtime and architecture. There is an [open-source Swift package](https://packagecatalog.com/package/jthomas/OpenWhiskAction) (`OpenWhiskAction`) that handles wrapping functions within a shim to support runtime execution.
358
359```
360import OpenWhiskAction
361
362func hello(args: [String:Any]) -> [String:Any] {
363 if let name = args["name"] as? String {
364 return [ "greeting" : "Hello \(name)!" ]
365 } else {
366 return [ "greeting" : "Hello stranger!" ]
367 }
368}
369
370OpenWhiskAction(main: hello)
371```
372
373Binaries produced by the Swift build process must be generated for the correct platform architecture. This Docker command will compile Swift sources files using the relevant Swift environment.
374
375```
376docker run --rm -it -v $(pwd):/swift-package openwhisk/swift3action bash -e -c "cd /swift-package && swift build -v -c release"
377```
378
379## Writing Functions - Binary
380
381OpenWhisk supports executing a compiled binary for the function handler. Using a Python wrapper, the file will be invoked within the `openwhisk/dockerskeleton` Docker container.
382
383The binary must be compiled for the correct platform architecture and only link to shared libraries installed in the `openwhisk/dockerskeleton` runtime.
384
385In the `serverless.yaml` file, the `handler` property is used to denote the binary file to upload.
386
387```yaml
388functions:
389 my_function:
390 handler: bin_file
391 runtime: binary
392```
393
394### Request Properties
395
396OpenWhisk executes the binary file for each request. Event parameters are streamed to `stdio` as a JSON object string.
397
398### Function Return Values
399
400The handler must write a JSON object string with the response parameters to `stdout` before exiting.
401
402If you want to return an error message, return an object with an `error` property with the message.
403
404## Custom Runtime Images
405
406OpenWhisk actions can use [custom Docker images as the runtime environment](https://medium.com/openwhisk/large-applications-on-openwhisk-bcf15bff94ec). This allows extra packages, libraries or tools to be pre-installed in the runtime environment. Using a custom runtime image, with extra libraries and dependencies built-in, is useful for overcoming the [maximum deployment size](https://github.com/apache/incubator-openwhisk/blob/master/docs/reference.md#system-limits) on actions.
407
408*Images must implement the [API used by the platform](http://jamesthom.as/blog/2017/01/16/openwhisk-docker-actions/) to interact with runtime environments. Images must also be available on Docker Hub. OpenWhisk does not support private Docker registries.*
409
410OpenWhisk publishes the [existing runtime images on Docker Hub](https://hub.docker.com/r/openwhisk/). Using these images in the `FROM` directive in the `Dockerfile` is an easy way to [create new images](https://docs.docker.com/engine/reference/commandline/build/) compatible with the platform.
411
412In the `serverless.yaml` file, the `image` property is used to denote the custom runtime image.
413
414```yaml
415functions:
416 my_function:
417 handler: source.js
418 runtime: nodejs
419 image: dockerhub_user/image_name
420```
421
422*Node.js, Swift, Python and Binary runtimes support using a custom image property.*
423
424## Writing Functions - Docker
425
426OpenWhisk supports creating actions from public images on Docker Hub without handler files. These images are expected to support the platform API used to instantiate and invoke serverless functions.
427
428All necessary files for execution must be provided within the image. Local source files will not be uploaded to the runtime environment.
429
430In the `serverless.yaml` file, the `handler` property is used to denote the image label.
431
432```yaml
433functions:
434 my_function:
435 handler: repo/image_name
436 runtime: docker
437```
438
439## Runtime Configuration Properties
440
441The following OpenWhisk configuration properties are supported for functions defined in
442the `serverless.yaml` file.
443
444```yaml
445functions:
446 my_function:
447 handler: file_name.handler_func
448 runtime: 'runtime_label' // defaults to nodejs:default
449 namespace: "..." // defaults to user-provided credentials
450 memory: 256 // 128 to 512 (MB).
451 timeout: 60 // 0.1 to 600 (seconds)
452 parameters:
453 foo: bar // default parameters
454 anotations:
455 foo: bar // action annotations
456```
457
458## Writing Sequences
459
460OpenWhisk supports a special type of serverless function called [sequences](https://github.com/openwhisk/openwhisk/blob/master/docs/actions.md#creating-action-sequences).
461
462These functions are defined from a list of other serverless functions. Upon invocation, the platform executes each function in series. Request parameters are passed into the first function in the list. Each subsequent function call is passed the output from the previous step as input parameters. The last function's return value is returned as the response result.
463
464Here's an example of the configuration to define a sequence function, composed of three other functions.
465
466```yaml
467functions:
468 my_function:
469 sequence:
470 - parse_input
471 - do_some_algorithm
472 - construct_output
473```
474
475*Sequence functions do not have a handler file defined. If you want to refer to functions not defined in the serverless project, use the fully qualified identifier e.g. /namespace/package/action_name*
476
477## Connecting HTTP Endpoints
478
479Functions can be bound to public URL endpoints using the [API Gateway service](https://github.com/openwhisk/openwhisk/blob/master/docs/apigateway.md). HTTP requests to configured endpoints will invoke functions on-demand. Requests parameters are passed as function arguments. Function return values are serialised as the JSON response body.
480
481HTTP endpoints for functions can be configured through the `serverless.yaml` file.
482
483```yaml
484functions:
485 my_function:
486 handler: index.main
487 events:
488 - http: GET /api/greeting
489```
490
491HTTP event configuration also supports using explicit parameters.
492
493- `method` - HTTP method (mandatory).
494- `path` - URI path for API gateway (mandatory).
495- `resp` - controls [web action content type](https://github.com/apache/incubator-openwhisk/blob/master/docs/webactions.md#additional-features), values include: `json`, `html`, `http`, `svg`or `text` (optional, defaults to `json`).
496
497```yaml
498functions:
499 my_function:
500 handler: index.main
501 events:
502 - http:
503 method: GET
504 path: /api/http
505 resp: http
506```
507
508API Gateway hosts serving the API endpoints will be shown during deployment.
509
510```shell
511$ serverless deploy
512...
513endpoints:
514GET https://xxx-gws.api-gw.mybluemix.net/service_name/api/path --> service_name-dev-my_function
515```
516
517Calling the configured API endpoints will execute the deployed functions.
518
519````shell
520$ http get https://xxx-gws.api-gw.mybluemix.net/api/greeting?user="James Thomas"
521HTTP/1.1 200 OK
522Content-Type: application/json; charset=UTF-8
523Date: Mon, 19 Dec 2016 15:47:53 GMT
524
525{
526 "message": "Hello James Thomas!"
527}
528````
529
530
531
532## Exporting Web Actions
533
534Functions can be turned into "*web actions*" which return HTTP content without use of an API Gateway. This feature is enabled by setting an annotation (`web-export`) in the configuration file.
535
536```yaml
537functions:
538 my_function:
539 handler: index.main
540 annotations:
541 web-export: true
542```
543
544Functions with this annotation can be invoked through a URL template with the following parameters.
545
546```
547https://{APIHOST}/api/v1/experimental/web/{USER_NAMESPACE}/{PACKAGE}/{ACTION_NAME}.{TYPE}
548```
549
550- *APIHOST* - platform endpoint e.g. *openwhisk.ng.bluemix.net.*
551- *USER_NAMESPACE* - this must be an explicit namespace and cannot use the default namespace (_).
552- PACKAGE - action package or `default`.
553- *ACTION_NAME* - default form `${servicename}-${space}-${name}`.
554- *TYPE* - `.json``.html``.text` or `.http`.
555
556Return values from the function are used to construct the HTTP response. The following parameters are supported.
557
5581. `headers`: a JSON object where the keys are header-names and the values are string values for those headers (default is no headers).
5592. `code`: a valid HTTP status code (default is 200 OK).
5603. `body`: a string which is either plain text or a base64 encoded string (for binary data).
561
562Here is an example of returning HTML content:
563
564```
565function main(args) {
566 var msg = "you didn&#39;t tell me who you are."
567 if (args.name) {
568 msg = `hello ${args.name}!`
569 }
570 return {body:
571 `<html><body><h3><center>${msg}</center></h3></body></html>`}
572}
573```
574
575Here is an example of returning binary data:
576
577```
578function main() {
579 let png = <base 64 encoded string>
580 return {
581 headers: { "Content-Type": "image/png" },
582 body: png };
583}
584```
585
586Functions can access request parameters using the following environment variables.
587
5881. `**__ow_meta_verb:**` the HTTP method of the request.
5892. `**__ow_meta_headers:**` the request headers.
5903. `**__ow_meta_path:**` the unmatched path of the request.
591
592Full details on this new feature are available in this [blog post](https://medium.com/openwhisk/serverless-http-handlers-with-openwhisk-90a986cc7cdd#.2x09176m8).
593
594_**IMPORTANT: [Web Actions](https://github.com/openwhisk/openwhisk/blob/master/docs/actions.md) is currently experimental and may be subject to breaking changes.**_
595
596## Scheduled Invocations
597
598Functions can be set up to fire automatically using the [alarm package](https://github.com/openwhisk/openwhisk/blob/master/docs/catalog.md#using-the-alarm-package). This allows you to invoke functions with preset parameters at specific times (*12:00 each day*) or according to a schedule (*every ten minutes*).
599
600Scheduled invocation for functions can be configured through the `serverless.yaml` file.
601
602The `schedule` event configuration is controlled by a string, based on the UNIX crontab syntax, in the format `cron(X X X X X)`. This can either be passed in as a native string or through the `rate` parameter.
603
604```yaml
605functions:
606 my_function:
607 handler: index.main
608 events:
609 - schedule: cron(* * * * *) // fires each minute.
610```
611
612This above example generates a new trigger (`${service}_crawl_schedule_trigger`) and rule (`${service}_crawl_schedule_rule`) during deployment.
613
614Other `schedule` event parameters can be manually configured, e.g trigger or rule names.
615
616```yaml
617functions:
618 aggregate:
619 handler: statistics.handler
620 events:
621 - schedule:
622 rate: cron(0 * * * *) // call once an hour
623 trigger: triggerName
624 rule: ruleName
625 max: 10000 // max invocations, default: 1000, max: 10000
626 params: // event params for invocation
627 hello: world
628```
629
630## IBM Message Hub Events
631
632IBM Bluemix provides an "Apache Kafka"-as-a-Service called IBM Message Hub. Functions can be connected to fire when messages arrive on Kafka topics.
633
634IBM Message Hub instances can be provisioned through the IBM Bluemix platform. OpenWhisk on Bluemix will export Message Hub service credentials bound to a package with the following name:
635
636```
637/${BLUEMIX_ORG}_${BLUEMIX_SPACE}/Bluemix_${SERVICE_NAME}_Credentials-1
638```
639
640Rather than having to manually define all the properties needed by the Message Hub trigger feed, you can reference a package to use instead. Credentials from the referenced package will be used when executing the trigger feed.
641
642Developers only need to add the topic to listen to for each trigger.
643
644```yaml
645# serverless.yaml
646functions:
647 index:
648 handler: users.main
649 events:
650 - message_hub:
651 package: /${BLUEMIX_ORG}_${BLUEMIX_SPACE}/Bluemix_${SERVICE_NAME}_Credentials-1
652 topic: my_kafka_topic
653
654```
655
656The plugin will create a trigger called `${serviceName}_${fnName}_messagehub_${topic}` and a rule called `${serviceName}_${fnName}_messagehub_${topic}_rule` to bind the function to the message hub events.
657
658The trigger and rule names created can be set explicitly using the `trigger` and`rule` parameters.
659
660Other functions can bind to the same trigger using the inline `trigger` event referencing this trigger name.
661
662```yaml
663# serverless.yaml
664functions:
665 index:
666 handler: users.main
667 events:
668 - message_hub:
669 package: /${BLUEMIX_ORG}_${BLUEMIX_SPACE}/Bluemix_${SERVICE_NAME}_Credentials-1
670 topic: my_kafka_topic
671 trigger: log_events
672 rule: connect_index_to_kafka
673 another:
674 handler: users.another
675 events:
676 - trigger: log_events
677```
678
679### Using Manual Parameters
680
681Parameters for the Message Hub event source can be defined explicitly, rather than using pulling credentials from a package.
682
683```yaml
684# serverless.yaml
685functions:
686 index:
687 handler: users.main
688 events:
689 - message_hub:
690 topic: my_kafka_topic
691 brokers: afka01-prod01.messagehub.services.us-south.bluemix.net:9093
692 user: USERNAME
693 password: PASSWORD
694 admin_url: https://kafka-admin-prod01.messagehub.services.us-south.bluemix.net:443
695 json: true
696 binary_key: true
697 binary_value: true
698```
699
700`topic`, `brokers`, `user`, `password` and `admin_url` are mandatory parameters.
701
702## Cloudant DB Events
703
704IBM Cloudant provides a hosted NoSQL database, based upon CouchDB, running on IBM Bluemix. Functions can be connected to events fired when the database is updated. These events use the [CouchDB changes feed](http://guide.couchdb.org/draft/notifications.html) to follow database modifications.
705
706IBM Cloudant instances can be provisioned through the IBM Bluemix platform. OpenWhisk on Bluemix will export Cloudant service credentials bound to a package with the following name:
707
708```
709/${BLUEMIX_ORG}_${BLUEMIX_SPACE}/Bluemix_${SERVICE_NAME}_Credentials-1
710```
711
712Rather than having to manually define all the properties needed by the [Cloudant trigger feed](https://github.com/openwhisk/openwhisk-package-cloudant#using-the-cloudant-package), you can reference a package to use instead. Credentials from the referenced package will be used when executing the trigger feed.
713
714Developers only need to add the database name to follow for modifications.
715
716```yaml
717# serverless.yaml
718functions:
719 index:
720 handler: users.main
721 events:
722 - cloudant:
723 package: /${BLUEMIX_ORG}_${BLUEMIX_SPACE}/Bluemix_${SERVICE_NAME}_Credentials-1
724 db: my_db_name
725
726```
727
728The plugin will create a trigger called `${serviceName}_${fnName}_cloudant_${topic}` and a rule called `${serviceName}_${fnName}_cloudant_${topic}_rule` to bind the function to the Cloudant update events.
729
730The trigger and rule names created can be set explicitly using the `trigger` and`rule` parameters.
731
732Other functions can bind to the same trigger using the inline `trigger` event referencing this trigger name.
733
734### Using Manual Parameters
735
736Parameters for the Cloudant event source can be defined explicitly, rather than using pulling credentials from a package.
737
738```yaml
739# serverless.yaml
740functions:
741 index:
742 handler: users.main
743 events:
744 - cloudant:
745 host: xxx-yyy-zzz-bluemix.cloudant.com
746 username: USERNAME
747 password: PASSWORD
748 db: db_name
749```
750
751### Adding Optional Parameters
752
753The following optional feed parameters are also supported:
754
755* `max` - Maximum number of triggers to fire. Defaults to infinite.
756* `filter` - Filter function defined on a design document.
757* `query` - Optional query parameters for the filter function.
758
759```yaml
760# serverless.yaml
761functions:
762 index:
763 handler: users.main
764 events:
765 - cloudant:
766 ...
767 max: 10000
768 query:
769 status: new
770 filter: mailbox/by_status
771```
772
773## Custom Event Triggers
774
775Functions are connected to event sources in OpenWhisk [using triggers and rules](https://github.com/openwhisk/openwhisk/blob/master/docs/triggers_rules.md). Triggers create a named event stream within the system. Triggers can be fired manually or connected to external data sources, like databases or message queues.
776
777Rules set up a binding between triggers and serverless functions. With an active rule, each time a trigger is fired, the function will be executed with the trigger payload.
778
779Event binding for functions can be configured through the `serverless.yaml` file.
780
781```yaml
782functions:
783 my_function:
784 handler: index.main
785 events:
786 - trigger: my_trigger
787```
788This configuration will create a trigger called `servicename-my_trigger` with an active rule binding `my_function` to this event stream.
789
790### Customising Rules
791
792Rule names default to the following format `servicename-trigger-to-action`. These names be explicitly set through configuration.
793
794```yaml
795functions:
796 my_function:
797 handler: index.main
798 events:
799 - trigger:
800 name: "my_trigger"
801 rule: "rule_name"
802```
803
804### Customing Triggers
805
806Triggers can be defined as separate resources in the `serverless.yaml` file. This allows you to set up trigger properties like default parameters.
807
808```yaml
809functions:
810 my_function:
811 handler: index.main
812 events:
813 - trigger: my_trigger
814
815resources:
816 triggers:
817 my_trigger:
818 parameters:
819 hello: world
820```
821
822### Trigger Feeds
823
824Triggers can be bound to external event sources using the `feed` property. OpenWhisk [provides a catalogue](https://github.com/openwhisk/openwhisk/blob/master/docs/catalog.md) of third-party event sources bundled as [packages](https://github.com/openwhisk/openwhisk/blob/master/docs/packages.md#creating-and-using-trigger-feeds).
825
826This example demonstrates setting up a trigger which uses the `/whisk.system/alarms/alarm` feed. The `alarm` feed will fire a trigger according to a user-supplied cron schedule.
827
828```yaml
829resources:
830 triggers:
831 alarm_trigger:
832 parameters:
833 hello: world
834 feed: /whisk.system/alarms/alarm
835 feed_parameters:
836 cron: '*/8 * * * * *'
837```
838
839## Commands
840
841The following serverless commands are currently implemented for the OpenWhisk provider.
842
843- `deploy` - [Deploy functions, triggers and rules for service](https://serverless.com/framework/docs/providers/openwhisk/cli-reference/deploy/).
844- `invoke`- [Invoke deployed serverless function and show result](https://serverless.com/framework/docs/providers/openwhisk/cli-reference/invoke/).
845- `invokeLocal`- [Invoke serverless functions locally and show result](https://serverless.com/framework/docs/providers/openwhisk/cli-reference/invoke#invoke-local).
846- `remove` - [Remove functions, triggers and rules for service](https://serverless.com/framework/docs/providers/openwhisk/cli-reference/remove/).
847- `logs` - [Display activation logs for deployed function](https://serverless.com/framework/docs/providers/openwhisk/cli-reference/logs/).
848- `info` - [Display details on deployed functions, triggers and rules](https://serverless.com/framework/docs/providers/openwhisk/cli-reference/info/).