apache / openwhisk-wskdeploy

Apache OpenWhisk utility for deploying and managing OpenWhisk projects and packages
https://openwhisk.apache.org/
Apache License 2.0
77 stars 74 forks source link

Trigger Feed vs Non-Feed inputs apply differently #1077

Open dpsommer opened 5 years ago

dpsommer commented 5 years ago

I've run into the following issue trying to deploy triggers/rules to IBM Cloud Functions.

Trigger inputs seem to have different behaviour depending on whether or not a feed parameter is specified. Without a feed parameter, the inputs array is sent as an object to the Parameters object in Functions, which is then passed to triggered actions as part of the input payload. When given a feed parameter, in this case /whisk.system/alarms/alarm, the expected feed parameters work (cron, timezone) and correctly configure the trigger, but any additional parameters aren't passed to the Parameters object as above.

The trigger_payload parameter seems like it would be the way to go in this case, but when setting it as documented (see below screenshot of the created trigger's spec from a GET) it does seem to apply but isn't passed along to the actions as is the case with the Parameters object.

Is there a different syntax I should be using for the payload value?

Alternatively, is there a way to define a separate set of inputs that will be parsed differently so I can populate both the feed inputs and the Parameters object?

Screen Shot 2019-10-18 at 4 40 05 PM

I've attached the manifest and deployment files below (as txt due to GH restrictions).

Note that using typed bindings for parameters in the manifest doesn't seem to make a difference.

deployment.txt manifest.txt

@mrutkows

style95 commented 5 years ago

Yes, this is an old issue.

When you create a trigger with wsk, seemingly it just creates the trigger, but it actually creates a trigger and executes a feed action with the given trigger name. And when you execute the feed, the trigger_payload is passed as a request body. We can easily figure out this with -v option.

$ wsk trigger create trigger-with-wsk   --feed /whisk.system/alarms/alarm   --param cron "*/2 * * * *"   --param trigger_payload "{\"name\":\"Odin\",\"place\":\"Asgard\"}" -v
REQUEST:
[PUT]   https://localhost/api/v1/namespaces/_/triggers/trigger-with-wsk?overwrite=false

...

Req Body
{"name":"trigger-with-wsk","annotations":[{"key":"feed","value":"/whisk.system/alarms/alarm"}]}

...

Response body received:
{"annotations":[{"key":"feed","value":"/whisk.system/alarms/alarm"}],"limits":{},"name":"trigger-with-wsk","namespace":"style95","parameters":[],"publish":false,"version":"0.0.1"}

REQUEST:
[POST]  https://localhost/api/v1/namespaces/whisk.system/actions/alarms/alarm?blocking=true&result=false

...

Req Body
{...,"cron":"*/2 * * * *","lifecycleEvent":"CREATE","triggerName":"/_/trigger-with-wsk","trigger_payload":{"name":"Odin","place":"Asgard"}}

...

{"activationId":"d1607ba22ffb4744a07ba22ffb47443a","annotations":[{"key":"path","value":"whisk.system/alarms/alarm"},{"key":"waitTime","value":10},{"key":"kind","value":"nodejs:6"},{"key":"timeout","value":false},{"key":"limits","value":{"concurrency":1,"logs":1,"memory":256,"timeout":60000}},{"key":"initTime","value":273}],"duration":1038,"end":1571700653323,"logs":[],"name":"alarm","namespace":"style95","publish":false,"response":{"result":{"status":"success"},"status":"success","success":true},"start":1571700652285,"subject":"style95","version":"0.0.68"}

Also, when you get the trigger information, it fetches data from the feed using READ lifecycle event.

REQUEST:
[POST]  https://localhost/api/v1/namespaces/whisk.system/actions/alarms/alarm?blocking=true&result=false
...
{...,"lifecycleEvent":"READ","triggerName":"/_/trigger-with-wsk"}

So there is no given parameter stored in the trigger infromation. The payload is stored together while creating "cron" data. AFAIK, we are unable to change this behavior with CLI tool.

Alternatively, you can directly configure trigger payload in the trigger with REST API. If you directly create a trigger with the feed annotation and trigger parameters and execute the feed action using REST API, you can see payload is stored in the trigger side,

$ wsk trigger get trigger-with-api -v
REQUEST:
[GET]   https://localhost/api/v1/namespaces/_/triggers/trigger-with-api

...

{"annotations":[{"key":"feed","value":"/whisk.system/alarms/alarm"}] ... ,"parameters":[{"key":"name","value":"hello"}],...,"version":"0.0.1"}

while there is no parameter configured in the feed side.

    "response": {
        "result": {
            "config": {
                "cron": "*/1 * * * *",
                "name": "trigger-with-api",
                "namespace": "style95",
                "payload": {
                    "payload": "" // nothing configured here.
                }
            },
            "status": {
                "active": true,
                "dateChanged": 1571701532663,
                "dateChangedISO": "2019-10-21T23:45:32Z"
            }
        },

The invocation is also slightly different.

The empty "payload" is also passed as a trigger parameter.

{
  "params": {
    "name": "hello",
    "payload": ""
  }
}

The current behavior is generally not a problem. But it introduces some inconsistency in some cases. For example, when we need to visualize trigger payload in UI, we should differently deal with a trigger and a trigger with a feed.

dpsommer commented 5 years ago

@style95

Ok, there are still two unanswered questions though (correct me if I'm wrong):

  1. Despite the parameters being set and passed to the alarm feed action, the payload value (from triggered_payload being set) is not sent to the triggered action. This is the main issue.
  2. There doesn't seem to be a way, as far as I can tell, to set arbitrary key-value pairs in the params object you're describing through wskdeploy while using a feed-based trigger.

Note also that I'm using wskdeploy - if you can provide yaml examples that would be helpful.

mrutkows commented 5 years ago

@style95 I had interacted with @dpsommer and asked him to open this issue. After speaking with Priti, it seems that last year (May 2018) that we found that the Go Client was not accepting/forwarding the "payload" annotation (key and value map)...

At the time, James Dubee ack'ed the problem and thought he would work to address this in the Go Client and wskdeploy would then work. Apparently, the "ball was dropped" and no issue was opened and no fix was made to the Go Client code. Adding @pritidesai as she has the first-hand story, as I have just relayed above what she told me. My belief is we should open an issue for Go client for the actual "fix" and provide detailed information and attempt to record the history as well. Then link that issue to this one where we would then add another testcase to verify the payload annotation works.

KeonHee commented 5 years ago

@dpsommer How about changing this way? It works well to me

inputs:
  timezone: America/Toronto
  cron: * * * * *
  trigger_payload:
    service_name: planning-analytics

Your way is also passed to the action, but it looks like the payload is not json, it's a string, so it's possible you've mistaken it for not being delivered.

dpsommer commented 5 years ago

@KeonHee

Updating manifest.yaml with your change does update the values I'm seeing in the trigger payload:

Screen Shot 2019-10-22 at 7 30 52 AM

but as @mrutkows mentioned, the payload itself still isn't forwarded at all to the triggered actions.

As a side note, when I try to put the same markup in deployment.yaml I get the following error:

servicedeployer.go [1656]: [ERROR_WHISK_CLIENT_ERROR]: Error code: 1: Unable to create HTTP request for POST 'actions/alarms/alarm?blocking=true&result=false': Error encoding request body: json: unsupported type: map[interface {}]interface {}
pritidesai commented 5 years ago

The same issue is raised multiple places:

https://github.com/apache/openwhisk-wskdeploy/issues/884 https://github.com/apache/openwhisk-client-go/issues/122 https://github.com/apache/openwhisk-cli/issues/293

Looks like it has not been resolved yet. @jasonpet @dubee @eweiter any more info/updates on this?

pritidesai commented 5 years ago

Hey @steven0711dong any insight into this? @jasonpet sent me your way

style95 commented 5 years ago

@dpsommer While there is some inconsistency between feed parameters and trigger parameters, I could still pass payloads to a triggered action as expected.

We are checking on the version we used to see the difference.

style95 commented 5 years ago

@dpsommer Kindly clarify one thing. Did you manually fire the trigger or fire it via an alarm cron job?

dpsommer commented 5 years ago

@style95

I was firing it manually to test. Checking the logs this morning, the parameters updated based on @KeonHee 's feedback were passed when the cron jobs fired.

Thanks for your help.

style95 commented 5 years ago

@dpsommer Thank you for the confirmation.

So the main issue is that trigger parameters are stored in the alarm package stack rather than a trigger itself.

pritidesai commented 5 years ago

@steven0711dong is looking into this and will start fixing it next week ... thanks @steven0711dong!

pritidesai commented 5 years ago

@KeonHee @dpsommer yes the trigger_payload does get to the action when the trigger invokes it, but the params doesnt reach to the associated action which could be sent via --param or -p.