Search code examples
openwhisk

Created openwhisk action but shows in guest as private java so can't call it


Trying to follow directions, I created an action in the vagrant image (e.g., after vagrant ssh) using this command:

wsk action create ProcessFuzzyMatch /vagrant/ildMicroServices-1.0.jar --main com.xxx.micro.services.ProcessFuzzyMatch

and I could see it was created:

wsk action list
actions
/guest/ProcessFuzzyMatch                                               private java

however guest isn't listed as a package:

wsk package list /whisk.system
packages
/whisk.system/weather                                                  shared
/whisk.system/combinators                                              shared
/whisk.system/websocket                                                shared
/whisk.system/watson-translator                                        shared
/whisk.system/samples                                                  shared
/whisk.system/watson-speechToText                                      shared
/whisk.system/watson-textToSpeech                                      shared
/whisk.system/slack                                                    shared
/whisk.system/github                                                   shared
/whisk.system/utils                                                    shared

and attempts to call the action via curl fail with authentication errors but this doesn't seem to be related to the request headers. Instead I guess it is related to the private java nature of the action I registered. I believe this because I can't use the wsk command to show the summary information for the action I'd registered:

wsk package get --summary /whisk.system/guest/ProcessFuzzyMatch
error: Unable to get package 'guest/ProcessFuzzyMatch': The requested resource could not be found. (code 364)

Is the proper sequence to first create a package then use that package when registering my action?

Thanks for any advice you can provide.


Solution

  • This answer turned out as a result of following all the other posts recommendations and trying different approaches. It took a while because I had to port all the file based functions to call Cloudant instead and because of the size of artifacts to be loaded and an issue with their attachments API in Java I had to use a workaround (because the data field returned empty).

    I tried using the --web=true to avoid the security issues and that got me very close. However, while I got back a reply with 200 response code, the payload was empty (Content-Length: 0). So, I used the wsk invoke action with -v I was able to see how the call was being made locally within the vagrant VM, and was then able to get it to work from outside the VM.

    Basically, these were the steps I followed: wsk package create ild to create my own package which becomes a child of /guest as shown with the command:

    wsk package list
    /guest/ild
    

    Then I created my action based on the jar build using gradle (so it includes all dependent classes other than gson.JsonObject since that is already in the runtime environment).

    wsk action create /guest/ild/ProcessFuzzyMatch /vagrant/ildMicroServices-1.0.jar --main com.xxx.ild.micro.services.ProcessFuzzyMatch --web true
    

    Because my service expected a JsonObject containing text and workspaceID I ran the following command in the vagrant VM:

     wsk action invoke -v -br ild/ProcessFuzzyMatch -p "text" "borken window" -p "workspaceID" "bc3d43ab-1529-41c8-8571-b7155e53e3ff"
    

    And this showed the correct response. By examining the request headers I could see how the action was being referenced so I could then create a shell script to point to the host 192.168.33.13 from outside the VM.

    The working shell scripts is shown below:

    #! /bin/bash
    curl -s -v -k https://192.168.33.13/api/v1/namespaces/guest/actions/ild/ProcessFuzzyMatch?blocking=true \
    -H "Authorization: Basic MjNiYzQ2YjEtNzFmNi00ZWQ1LThjNTQtODE2YWE0ZjhjNTAyOjEyM3pPM3haQ0xyTU42djJCS0sxZFhZRnBYbFBrY2NPRnFtMTJDZEFzTWdSVTRWck5aOWx5R1ZDR3VNREdJd1A=" \
    -X POST -H "Content-Type: application/json" \
    -d '{"text":"borken window","workspaceID":"bc3d43ab-1529-41c8-8571-b7155e53e3ff"}' 
    

    The -X POST is not needed as POST is assumed. The Authorization was copied from what I'd seen in the headers from the version run on the localhost (in the VM) but it is the Base64 encoding of the ~/openwhisk/ansible/files/auth.guest content (when in the VM via "vagrant ssh" command). This could also have been passed as is using the -u parameter to curl.

    In theory, the authentication should not have been required since the --web=true was used when registering the action, but I found it was needed when calling into the VM from outside. Without the header, it returns this error:

    {
        "error": "The resource requires authentication, which was not supplied with the request",
        "code": 2259
        * Connection #0 to host 192.168.33.13 left intact
     }
    

    I believe the key to getting the external call to work was providing the proper URI before the package/action name and ensuring the blocking=true parameter was passed:

    https://192.168.33.13/api/v1/namespaces/guest/actions/
    

    I will up vote all the other replies as they all helped me figure out what was required.