Unable to create action due to name clash but no existing action has this name? - openwhisk

Creating a new OpenWhisk action from the command-line, the following error is returned.
$ wsk action create hello index.js
error: Unable to create action 'hello': Resource by this name exists but is not in this collection. (code 4923976)
Run 'wsk --help' for usage.
Looking at the actions already deployed, I don't see another action with the same name.
$ wsk action list
actions
/user#email.com_dev/example private nodejs:6
/user#email.com_dev/hello_world private nodejs:6
/user#email.com_dev/testing private nodejs:6
What is responsible for this error message?

Action, trigger and rule names must be unique within a namespace and package.
If there are no actions with this identifer, check for triggers and rules with the hello name.
Here's an example showing that actions, triggers and rules will clash when using the same names.
$ wsk trigger create clash
ok: created trigger clash
[17:41:41 /private/tmp]$ wsk action create clash index.js
error: Unable to create action 'clash': Resource by this name exists but is not in this collection. (code 5000008)
Run 'wsk --help' for usage.
[17:41:54 /private/tmp]$ wsk trigger delete clash
ok: deleted trigger clash
[17:42:06 /private/tmp]$ wsk action create clash index.js
ok: created action clash
This error can be resolved by using a different identifier for the action name or renaming the clashing resource. Actions can also be moved within a package to stop clashing with a resource in the global workspace.

Related

Chef template resource to execute if the source template changes?

I'm deploying a package that requires a template be created in a specified directory every time a directory is unzipped.
A remote_file notifies my unzip action, that unzip action notifies the template resource, which in turn notifies other resources. This chain of notifications works as expected.
Below is my template resource:
template 'C:\\Program Files\\MyProgram\\program.yml' do
source "my_program-#{node['program']['version']}.yml.erb"
action :nothing
notifies :run, 'powershell_script[install-program]', :immediately
end
My question: Is there a way to have the template resource execute if I make a change to the source template? Right now it only executes the template resource if notified by my unzip action (due to my action :nothing).
However, it would be great to have a way for it to tell if the template itself has changed. Perhaps some kind of not_if or only_if statement?
sounds to me that you avoid all the notification chaining if you will have your resources defined in the same recipe.
back to your questions, it sounds that setting action :create, which is the default action, will do the trick. from the template resource documentation
action :create
Create a file. If a file already exists (but does not match), update that file to match.

getResource return null url in context of module

I am new to Java Modularity. I am using Java 9.
The program compiles without complaint. It also runs perfectly well from the "exploded module" folder, but with one exception: it throws an exception whose cause originates with the following line of code:
URL introURL = AboutPanel.class.getResource("help.html");
introURL is being assigned null.
When running the program in Eclipse, or from a jar file exported from Eclipse, the URL is populated correctly with the address of a resource file (help.html) that is in the same directory as the calling class.
Here is the command I use to run the program from the "exploded module" that is in the "out" folder:
java -p out/ -m moduleTCD/com.adonax.tanpura.TCDLaunch
The project consists of two packages that I am bundling together in a single module.
src/moduleTCD/com/adonax/tanpura
/pfaudio
The "main" class (entry point) is tanpura.TCDLaunch.
Here is the module-info.java class contents:
module moduleTCD {
exports com.adonax.tanpura;
requires java.base;
requires java.desktop;
}
The error statement, when trying to run from the command line:
java.io.IOException: invalid url
at java.desktop/javax.swing.JEditorPane.setPage(Unknown Source)
at moduleTCD/com.adonax.tanpura.documentation.AboutPanel.<init>(AboutPanel.java:28)
at moduleTCD/com.adonax.tanpura.panels.ControlPanel.initializeHelpPanel(ControlPanel.java:525)
at moduleTCD/com.adonax.tanpura.panels.ControlPanel.<init>(ControlPanel.java:163)
at moduleTCD/com.adonax.tanpura.TCDLaunch.main(TCDLaunch.java:43)
This exception is thrown in a try/catch for IOException at the point where the JEditorPane method setPage is called with null as an argument.
textArea.setPage(introURL);
At first, I didn't have an exports line in my module-info.java, but added it when I read the following from the API for Class.getResource:
Returns:
A URL object; null if no resource with this name is found, the resource cannot be located by a URL, the resource is in a package that
is not open to at least the caller module, or access to the resource
is denied by the security manager.
This raised the possibility that the package might be needed by Class in the module Java.base. The exports command there now is the broadest possible. But adding it did not change the error. I'm wondering if there is something wrong with how I did this, or if there is something else I am overlooking.
Classic error on my part. I made assumptions about the error being related to tech that is new and unfamiliar to me, rather than first verifying the obvious.
The fail was due to not realizing that the javac command did not move required resources into the target folder system.
I also verified that an "exports" statement is NOT needed in module-info in order to allow the loading of the resource.
So, in fact, this was not a java-module issue at all, just an oversight which I credit in part to a lack of chops using shell-level Java commands.
Big thank you to Alan Bateman!

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.
As you have a local build, guest is your default namespace name. The package is default (aka _) as you didn't specify one. You can find the name of your namespace using:
wsk namespace list
It's labelled private as it's yours and not published to the world.
You can invoke your action with:
wsk action invoke ProcessFuzzyMatch -r
If you wanted to put your action in a namespace, called say "demo", you'd use:
wsk package create demo
wsk action create demo/ProcessFuzzyMatch /vagrant/ildMicroServices-1.0.jar --main com.xxx.micro.services.ProcessFuzzyMatch
You can now invoke your action with:
wsk action invoke demo/ProcessFuzzyMatch -r
Finally running wsk activation poll in a separate terminal window is helpful to see what's going on when you invoke an action.
Have you tried using /guest/default/ProcessFuzzyMatch in your url instead of /guest/ProcessFuzzyMatch
The fully qualified name of the action must include its package name, which is "default" if the action is not in a named package.
In case of authentication errors, you need to pass the auth as header parameters using -H
curl -k -H "Authorization: Basic <encoded value>" https://<host>/api/v1/namespaces/guest/default/ProcessFuzzyMatch
You can also try to invoke action using wsk CLI and see if it is getting invoked or not.
wsk -i action invoke ProcessFuzzyMatch --result=true
You didn't create a package for your action. Actions in the default package which is what you created will not appear in the package listing.
Also you're listing a whisk.system namespace while creating the action in the guest namespace.
So if you want to put the action in the whisk.system package, you'll need to use that API key and create the package first.
wsk package create mypkg -u <whisk.system key>
wsk action create mypkg/ProcessFuzzyMatch ... -u <whisk.system key>
Otherwise you the guest key to get the action
wsk action get ProcessFuzzyMatch --summary
Or equally
wsk action get /guest/ProcessFuzzyMatch --summary
Note that summaries are currently not generated if an action does not have any annotations (see https://github.com/apache/incubator-openwhisk/issues/2270).
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.

Swift and terminal: Using Google Endpoints in an iOS Client

I am following the tutorial at
https://cloud.google.com/appengine/docs/java/endpoints/calling-from-ios
and when I get to step 5 and Open a new Terminal window to invoke ServiceGenerator. I get the error message in my terminal saying..
Barrys-MacBook-Pro:~ barrymadej$ /Users/barrymadej/Library/Developer/Xcode/DerivedData/ServiceGenerator-avaeguyitgyhxpcnaejpgzvxezei/Build/Products/Debug/ServiceGenerator \
/Users/barrymadej/Documents/AndroidStudioProjects/StudentProgressTrackerDatabaseAndCloud/backend/build/discovery-docs/myApi-v2-rpc.discovery /
ERROR: An output directory is required.
Usage: ServiceGenerator [FLAGS] [ARGS]
Required Flags:
--outputDir PATH
The destination directory for writing the generated files.
Optional Flags:
--discoveryService URL
Instead of discovery's default URL, use the specified URL as the
location to send the JSON-RPC requests. This is useful for running
against a custom or prerelease server.
--gtlFrameworkName NAME
Will generate sources that include GTL's headers as if they are in a
framework with the given name. If you are using GTL via CocoaPods,
you'll likely want to pass "GoogleAPIClient" as the value for this.
--apiLogDir DIR
Write out a file into DIR for each JSON API description processed. These
can be useful for reporting bugs if generation fails with an error.
--httpLogDir PATH
Turn on the HTTP fetcher logging and set it to write to PATH. This can
be useful for diagnosing errors on discovery fetches.
--generatePreferred
Causes the list of services to be collected, and all preferred services
to be generated.
--httpHeader NAME:VALUE
Causes the given NAME/VALUE pair to be added as an HTTP header on *all*
HTTP requests made by the generator. Can be used repeatedly to provide
additional header pairs.
--formattedName SERVICE:VERSION=NAME
Causes the given SERVICE:VERSION pair to override its service name in
files, classes, etc. with NAME. If :VERSION is omitted the override is
for any version of the service. Can be used repeatedly to provide
several maps when generating a few things in a single run.
--addServiceNameDir yes|no Default: no
Causes the generator to add a directory with the service name in the
outputDir for the files. This is useful for generating multiple
services.
--generatedDir yes|no Default: no
Causes a directory in outputDir called "Generated" to be created and
used to contain the generated files.
--removeUnknownFiles yes|no Default: no
By default, the generator will report unknown files in the output
directory, as commonly happens when classes go away in a new API
version. This option causes the generator to also remove the unknown
files.
--rootURLOverrides yes|no Default: yes
Causes any API root URL for a Google sandbox server to be replaced with
the googleapis.com root instead.
--verbose
Generate more verbose output. Can be used more than once.
Arguments:
Multiple arguments can be given on the command line.
service:version
The description of the given [service]/[version] pair is fetched and the
files for it are generated. When using --generatePreferred version can
be '-' to skip generating the name service.
http[s]://url/to/rpc_description_json
A URL to download containing the description of a service to generate.
path/to/rpc_description.json
The path to a text file containing the description of a service to
generate.
ServiceGenerator path:
/Users/barrymadej/Library/Developer/Xcode/DerivedData/ServiceGenerator-avaeguyitgyhxpcnaejpgzvxezei/Build/Products/Debug/ServiceGenerator
ERROR: There was one or more errors; check the full output for details.
Barrys-MacBook-Pro:~ barrymadej$ --outputDir
-bash: --outputDir: command not found
Barrys-MacBook-Pro:~ barrymadej$ /Users/barrymadej/Documents/AndroidStudioProjects/StudentProgressTrackerDatabaseAndCloud/API
You should generate a REST discovery document and use the new Objective C client instead. The client library you're trying to use is deprecated anyway. It looks like it didn't work because you specified the flag without the rest of the command, though.

Changing play default package

I am using play 1.2.4 version and I am trying to change controllers package name to controllers.com.app.
I am getting error saying
"Error raised is Controller controllers.app not found"
Is there any problem if I change the package name???
If your controllers package name is:
controllers.com.app
Then you will need to change your routes file and append com.app to all your route Controller class references.
ie:
GET /something Something
To
GET /something com.app.Something

Resources