Action Proxy Single Entrypoint Interface

The typical endpoints used by the OpenWhisk control plane are not used in single entrypoint execution environments such as Knative. Initialization and running are still essential to how OpenWhisk runtimes function, but they are done in a different methodology than /init and /run endpoints. The proxy that shapes how the calls are preprocessed and postprocessed to emulate some of the functionality provided by the OpenWhisk control plane. In single entrypoint supported runtime proxy implementations, both initailization and running are done via the / root endpoint. The sections below explain the interface the runtime proxy must adhere to initialize and run via a single entrypoint execution environment.

Init

To initialize an undifferintiated stem cell, the interface is to pass a JSON object containing the key init to the / endpoint. The value corresponding to the init key is the same JSON object as the initialization of standard OpenWhisk actions. For example:

{
  "init": {
    "name" : "hello",
    "main" : "main",
    "code" : "function main(params) {return { payload: 'Hello ' + params.name + ' from ' + params.place +  '!' };}",
    "binary": false,
    "env": {}
  }
}

Just as with the OpenWhisk control plane, specialized function containers need no explicit initialization.

Run

To run an action, the interface is to pass a JSON object containing the key activation to the / endpoint. The value corresponding to the activation key is largely the same JSON object as the activation of standard OpenWhisk actions. The key difference is that value is not used under the activation key to pass parameters to the underlying function. To see the interface for passing keys to the underlying functions see section below. Example of an activation:

{
  "activation": {
    "namespace": "",
    "action_name": "hello",
    "api_host": "",
    "api_key": "",
    "activation_id": "",
    "transaction_id": "",
    "deadline": 1000000
  },
  "value": {
    "name": "Alan Turing",
    "place": "England"
  }
}

One thing to note is when these values are present outside of the context of the OpenWhisk control plane, they may not actually be used for anything. However, the activation key is still necessary to signal the intent to run the function.

Passing parameters

Similar to the description of the value key in the activation object during the activation of standard OpenWhisk actions, a top level value key in the JSON object passed to the / endpoint (with a corresponding top level activation key) is how parameters are passed to the underlying function being run. In the following example:

{
  "activation": {
    "namespace": "",
    "action_name": "hello",
    "api_host": "",
    "api_key": "",
    "activation_id": "",
    "transaction_id": "",
    "deadline": 1000000
  },
  "value": {
    "name": "Alan Turing",
    "location": "England"
  }
}

The underlying function would receive a parameters map with the keys name and location with the values Alan Turing and England respectively.

Init/Run

OpenWhisk stem cell runtimes being executed in a single entrypoint execution environment can be both initialized and activated at the same time by passing both init and activation keys in the same JSON object to the / endpoint. This will first initialize the runtime, following the same procedures described above, and then subsequently activate the same runtime. For example:

{
  "init": {
    "name" : "hello",
    "main" : "main",
    "code" : "function main(params) {return { payload: 'Hello ' + params.name + ' from ' + params.place +  '!' };}",
    "binary": false,
    "env": {}
  },
  "activation": {
    "namespace": "",
    "action_name": "hello",
    "api_host": "",
    "api_key": "",
    "activation_id": "",
    "transaction_id": "",
    "deadline": 1000000
  },
  "value": {
    "name": "Alan Turing",
    "location": "England"
  }
}

The above JSON object would instruct the runtime to be initialized with the function under init.code and be run with the function being passed the object {name: "Alan Turing", location: "England"}. It would then return the JSON object

{
  "payload": "Hello Alan Turing from England!"
}

Example Cases

Below is a table outlining the standardized behaviors that any action proxy implementation needs to fulfill. NodeJS was the sample language used, but corresponding example cases could be written in the language of the corresponding runtime it is showcasing.

Implementations

NodeJS


The links below will point to the OpenWhisk Test repo where the example cases are being stored.

Action CodeInitRunInit/RunOutput
Hello Worldhello_world-inithello_world-runhello_world-init-runhello_world
Hello World with Paramshello_world_with_params-inithello_world_with_params-runhello_world_with_params-init-runhello_world_with_params
Web Action Hello Worldweb_action_hello_world-initweb_action_hello_world-runweb_action_hello_world-init-runweb_action_hello_world
Web Action Hello World (no input)web_action_hello_world_no_input-initweb_action_hello_world_no_input-runweb_action_hello_world_no_input-init-runweb_action_hello_world_no_input
Web Action Rawweb_action_raw-initweb_action_raw-runweb_action_raw-init-runweb_action_raw