Action basics

Creating Actions - Helloworld

  1. Create a JavaScript file named 'hello.js' with these contents:

     function main(params) {
         return {payload:  'Hello, ' + params.name + ' from ' + params.place};
     }

    The JavaScript file might contain additional functions. However, by convention, a function called main is the default entry point for the action.

  2. Create an action from the 'hello.js' JavaScript function naming it hello:

     ibmcloud fn action create hello hello.js
  3. List all actions; it should show the hello action you just created:

     ibmcloud fn action list
     actions
     <NAMESPACE>/hello       private    nodejs10

    You can see the hello action you just created under your default NAMESPACE with implied access control provided by the platform.

Takeaways

  • No special code needed, developer just the codes their favorite language

    • Convention: "Main" entrypoint assumed (can alias "main" to any function)

  • No build step: Runtimes for all supported languages already resident in "invoker" clusters for immediate function "injection".

  • NodeJS inferred (latest runtime version); can explicitly set with --kind flag

  • Namespaced: (default) installed into; allows underlying platform to apply IAM access control to any entity (Package, Action, Trigger, etc.)

  • Note: "update" action subcommand will update internal version of source code (allowing existing actions to complete with source code version in-flight)

Invoking Actions

You may invoke your action in one of two modes:

  • blocking - which will wait for the result (i.e., request/response style) by specifying the blocking flag on the command-line.

  • non-blocking - which will invoke the action immediately, but not wait for a response.

Regardless, invocations always provide an Activation ID which can be used later to lookup the action's response.

Blocking Invocations

A blocking invocation request will wait for the activation result to be available.

  1. Invoke the hello action using the command-line as a blocking activation.

    ibmcloud fn action invoke --blocking hello
    ok: invoked /_/hello with id 4479...
    ...
    "response": {
         "result": {
             "payload": "Hello, undefined from undefined"
         },
         "size": 45,
         "status": "success",
         "success": true
     },
     ...

    Notes

    • The wait period is the lesser of 60 seconds or the action's configured time limit.

    • The Activation ID can always be used later to lookup the response.

Non-blocking invocations (Async)

A non-blocking invocation will invoke the action immediately, but not wait for a response.

If you don't need the action result right away, you can omit the --blocking flag to make a non-blocking invocation. You can get the result later by using the Activation ID.

  1. Invoke the hello Action using the command-line as a non-blocking activation.

    ibmcloud fn action invoke hello
    ok: invoked /_/hello with id 6bf1f670ee614a7eb5af3c9fde813043
  2. Retrieve the activation result

    ibmcloud fn activation result 6bf1...
    {
        "payload": "Hello, undefined from undefined"
    }
  3. Alternatively, retrieve the --last or -l activation result

    ibmcloud fn activation result --last
    {
       "payload": "Hello, undefined from undefined"
    }
  4. Retrieve the full activation record

    ibmcloud fn activation get 6bf1..
    ok: got activation 6bf1..
    {
     ...
     "response": {
         "result": {
             "payload": "Hello world"
         },
         "size": 25,
         "status": "success",
         "success": true
     },
     ...
    }
  5. Retrieve activation list

ibmcloud fn activation list -l 2
Datetime   Activation ID  Kind      Start Duration Status  Entity
y:m:d:hm:s 44794bd6...    nodejs:10 cold  34s      success <NAMESPACE>/hello:0.0.1
y:m:d:hm:s 6bf1f670...    nodejs:10 warm  2ms      success <NAMESPACE>/hello:0.0.1

Takeaways

  • Actions can be invoked directly using CLI

    • asynchronously: by default

    • synchronously: --block flag

  • System tracks each action invocation with as an "Activation" (record)

    • Lots of information about execution time/params, etc.

Passing Action Parameters

Event parameters can be passed to the action when it is invoked. Let's look at a sample action which uses the parameters to calculate the return values.

From command line using the --param flag

  1. Invoke the hello action using explicit command-line parameters using the --param flag.

     ibmcloud fn action invoke --result hello --param name Elrond --param place Rivendell

    or using the -p short form:

     ibmcloud fn action invoke --result hello -p name Elrond -p place Rivendell
     {
         "payload": "Hello, Elrond from Rivendell"
     }

Note We used the --result option above. It implies a blocking invocation where the CLI waits for the activation to complete and then displays only the function's output as the payload value.

From parameter file using the --param-file flag

  1. Create a file named parameters.json containing the following JSON.

     {
         "name": "Frodo",
         "place": "the Shire"
     }
  2. Invoke the hello action using parameters from a JSON file.

     ibmcloud fn action invoke --result hello --param-file parameters.json -p name Bilbo
     {
         "payload": "Hello, Bilbo from the Shire"
     }

"Binding" parameter defaults to Action

Rather than pass all the parameters to an action every time, you can bind default parameters. Default parameters are stored in the platform and automatically passed in during each invocation.

Let's use the hello action from our previous example and bind a default value for the place parameter.

From command line using --param

Update the action by using the --param option to bind default parameter values.

ibmcloud fn action update hello --param place Rivendell

From parameter file using --param-file

Passing parameters from a file requires the creation of a file containing the desired content in JSON format. The filename must then be passed to the --param-file flag:

Example: parameter file parameters2.json:

{
    "place": "Rivendell"
}
ibmcloud fn action update hello --param-file parameters2.json

Invoke the action, passing only the name parameter this time.

ibmcloud fn action invoke --result hello --param name Elrond
{
    "payload": "Hello, Elrond from Rivendell"
}
  • Notice that you did not need to specify the place parameter when you invoked the action.

Bound parameters can still be overwritten by specifying the parameter value at invocation time.

Command Line overrides defaults (binding values)

Invoke the action, passing both name and place values. The latter overwrites the value that is bound to the action.

ibmcloud fn action invoke --result hello --param name Elrond --param place "the Lonely Mountain"
{
    "payload": "Hello, Elrond from the Lonely Mountain"
}

Actions calling other Actions

Proxy example

Let's look an example of creating a "proxy" action which invokes another action (i.e, our hello action) if a "password" is present in the input parameters.

  1. Create the following new action named proxy from the following source files.

     var openwhisk = require('openwhisk');
    
     function main(params) {
         if (params.password !== 'secret') {
         throw new Error("Password incorrect!")
         }
    
         var ow = openwhisk();
         return ow.actions.invoke({name: "hello", blocking: true, result: true, params: params})
     }
     ibmcloud fn action create proxy proxy.js
  2. Invoke the proxy with an incorrect password.

     ibmcloud fn action invoke proxy -p password wrong -r
     {
         "error": "An error has occurred: Error: Password incorrect!"
     }

Note On the invoke call above, we used the short form for the --result flag which is -r.

  1. Invoke the proxy with the correct password.

     ibmcloud fn action invoke proxy -p password secret -p name Bernie -p place Vermont -r
     {
         "greeting": "Hello Bernie from Vermont"
     }
  2. Review the activations list to show both actions were invoked.

    ibmcloud fn activation list -l 2
     Activation ID                    Kind      Start Duration   Status  Entity
     8387302c81dc4d2d87302c81dc4d2dc6 nodejs:10 cold  35ms       success hello:0.0.4
     e0c603c242c646978603c242c6c6977f nodejs:10 cold  438ms      success proxy:0.0.1

Tip On the invoke call above, we used the short form for the -l with a parameter to only list the last 2 activations.

Note The Start values for each indicate if each Action was "cold" (slower, function reloaded) or "warm" (already loaded) started.

Takeaways

  • Platform functions simplified:

    • Simple import of NPM package (NodeJS developer familiar)

    • Actions call other actions

Last updated

Was this helpful?