diff --git a/docs/actions.md b/docs/actions.md index fa3ff896f4f..5288d01c003 100644 --- a/docs/actions.md +++ b/docs/actions.md @@ -648,7 +648,7 @@ docker run --rm -it -v "$(pwd):/owexec" openwhisk/swift3action bash - Copy the source code and prepare to build it ``` - cp /owexec/hello.swift /swift3Action/spm-build/main.swift + cp /owexec/hello.swift /swift3Action/spm-build/main.swift ``` ``` @@ -677,16 +677,16 @@ docker run --rm -it -v "$(pwd):/owexec" openwhisk/swift3action bash exit ``` -This has created hello.zip in the same directory as hello.swift. +This has created hello.zip in the same directory as hello.swift. -Upload it to OpenWhisk with the action name helloSwifty: ``` wsk action update helloSwiftly hello.zip --kind swift:3 ``` -- To check how much faster it is, run +- To check how much faster it is, run ``` wsk action invoke helloSwiftly --blocking - ``` + ``` The time it took for the action to run is in the "duration" property and compare to the time it takes to run with a compilation step in the hello action. @@ -917,13 +917,13 @@ You can list all the actions that you have created using: wsk action list ``` -By default, listed actions will be sorted alphabetically, first by namespaces, then [packages](./packages.md), and finally by action name. To filter your list of actions to just the those within a specific pacakge, you can use: +By default, listed actions will be sorted alphabetically, first by namespaces, then [packages](./packages.md), and finally by action name. To filter your list of actions to just the those within a specific pacakge, you can use: ``` wsk action list [PACKAGE NAME] ``` -Side Note: Listing works the same way for actions as it does for [packages](./packages.md), [APIs](./apigateway.md), [triggers and rules](./triggers_rules.md). +*Note:* Listing works the same way for actions as it does for [packages](./packages.md), [APIs](./apigateway.md), [triggers and rules](./triggers_rules.md). ## Deleting actions diff --git a/docs/apigateway.md b/docs/apigateway.md index 802ea8fcfa6..386fe62b4f2 100644 --- a/docs/apigateway.md +++ b/docs/apigateway.md @@ -22,18 +22,18 @@ Follow the instructions in [Configure CLI](./README.md#setting-up-the-openwhisk- return {payload: `Hello world ${name}`}; } ``` - + 2. Create a web action from the following JavaScript function. For this example, the action is called 'hello'. Make sure to add the flag `--web true` - + ``` wsk action create hello hello.js --web true ``` ``` ok: created action hello ``` - + 3. Create an API with base path `/hello`, path `/world` and method `get` with response type `json` - + ``` wsk api create /hello /world get hello --response-type json ``` @@ -42,9 +42,9 @@ Follow the instructions in [Configure CLI](./README.md#setting-up-the-openwhisk- https://${APIHOST}:9001/api/21ef035/hello/world ``` A new URL is generated exposing the `hello` action via a __GET__ HTTP method. - + 4. Let's give it a try by sending a HTTP request to the URL. - + ``` $ curl https://${APIHOST}:9001/api/21ef035/hello/world?name=OpenWhisk ``` @@ -54,11 +54,11 @@ Follow the instructions in [Configure CLI](./README.md#setting-up-the-openwhisk- } ``` The web action `hello` was invoked, returning back a JSON object including the parameter `name` sent via query parameter. You can pass parameters to the action via simple query parameters, or via the request body. Web actions allow you to invoke an action in a public way without the OpenWhisk authorization API key. - + ### Full control over the HTTP response - - The `--response-type` flag controls the target URL of the web action to be proxied by the API Gateway. Using `--response-type json` as above returns the full result of the action in JSON format and automatically sets the Content-Type header to `application/json` which enables you to easily get started. - + + The `--response-type` flag controls the target URL of the web action to be proxied by the API Gateway. Using `--response-type json` as above returns the full result of the action in JSON format and automatically sets the Content-Type header to `application/json` which enables you to easily get started. + Once you get started you want to have full control over the HTTP response properties like `statusCode`, `headers` and return different content types in the `body`. You can do this by using `--response-type http`, this will configure the target URL of the web action with the `http` extension. You can choose to change the code of the action to comply with the return of web actions with `http` extension or include the action in a sequence passing its result to a new action that transforms the result to be properly formatted for an HTTP response. You can read more about response types and web actions extensions in the [Web Actions](webactions.md) documentation. @@ -67,14 +67,14 @@ Follow the instructions in [Configure CLI](./README.md#setting-up-the-openwhisk- ```javascript function main({name:name='Serverless API'}) { return { - body: new Buffer(JSON.stringify({payload:`Hello world ${name}`})).toString('base64'), - statusCode:200, + body: new Buffer(JSON.stringify({payload:`Hello world ${name}`})).toString('base64'), + statusCode:200, headers:{ 'Content-Type': 'application/json'} }; } ``` Notice that the body needs to be return encoded in `base64` and not a string. - + Update the action with the modified result ``` wsk action update hello hello.js --web true @@ -149,7 +149,7 @@ Action: putBooks URL: https://${APIHOST}:9001/api/21ef035/club/books ``` -Side Note: APIs will be sorted alphabetically by default, first by Base path, then by Path (relative path), then by Verb. If we need to sort alphabetically by Action name, we can add the `-n` or `--sort-action` flags to do so. +*Note:* APIs will be sorted alphabetically by default, first by Base path, then by Path (relative path), then by Verb. If we need to sort alphabetically by Action name, we can add the `-n` or `--sort-action` flags to do so. Now just for fun let's add a new book `JavaScript: The Good Parts` with a HTTP __POST__ ``` @@ -172,7 +172,7 @@ curl -X GET https://${APIHOST}:9001/api/21ef035/club/books ``` ### Exporting the configuration -Let's export API named `Book Club` into a file that we can use as a base to to re-create the APIs using a file as input. +Let's export API named `Book Club` into a file that we can use as a base to to re-create the APIs using a file as input. ``` wsk api get "Book Club" > club-swagger.json ``` diff --git a/docs/packages.md b/docs/packages.md index 61137baff3b..8bbe28f3a32 100644 --- a/docs/packages.md +++ b/docs/packages.md @@ -22,17 +22,17 @@ Several packages are registered with OpenWhisk. You can get a list of packages i ``` ``` packages - /whisk.system/alarms shared - /whisk.system/cloudant shared - /whisk.system/github shared - /whisk.system/pushnotifications shared - /whisk.system/samples shared - /whisk.system/slack shared - /whisk.system/system shared - /whisk.system/utils shared - /whisk.system/watson shared - /whisk.system/weather shared - /whisk.system/websocket shared + /whisk.system/alarms shared + /whisk.system/cloudant shared + /whisk.system/github shared + /whisk.system/pushnotifications shared + /whisk.system/samples shared + /whisk.system/slack shared + /whisk.system/system shared + /whisk.system/utils shared + /whisk.system/watson shared + /whisk.system/weather shared + /whisk.system/websocket shared ``` 2. Get a list of entities in the `/whisk.system/cloudant` package. diff --git a/docs/triggers_rules.md b/docs/triggers_rules.md index ffefd22f6b1..7fe83a8461e 100644 --- a/docs/triggers_rules.md +++ b/docs/triggers_rules.md @@ -56,7 +56,7 @@ As an example, create a trigger to send user location updates, and manually fire ok: created trigger locationUpdate ``` -2. Check that you created the trigger by listing the set of triggers. (Side note: triggers and rules will be listed alphabetically when using the `list` command.) +2. Check that you created the trigger by listing the set of triggers. ``` $ wsk trigger list diff --git a/tests/src/test/scala/apigw/healthtests/ApiGwEndToEndTests.scala b/tests/src/test/scala/apigw/healthtests/ApiGwEndToEndTests.scala index afecd8f2da4..c1231b27829 100644 --- a/tests/src/test/scala/apigw/healthtests/ApiGwEndToEndTests.scala +++ b/tests/src/test/scala/apigw/healthtests/ApiGwEndToEndTests.scala @@ -87,34 +87,28 @@ class ApiGwEndToEndTests try { //Create Actions for apiexperimentals val file = TestUtils.getTestActionFilename(s"echo-web-http.js") - println("Create Action: " + actionName1) assetHelper.withCleaner(wsk.action, actionName1) { (action, name) => action.create(name, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) } - println("Create Action: " + actionName2) assetHelper.withCleaner(wsk.action, actionName2) { (action, name) => action.create(name, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) } - println("Create Action: " + actionName3) assetHelper.withCleaner(wsk.action, actionName3) { (action, name) => action.create(name, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) } - //Create apiexperimentals - println("Create api-experimental: Base Path " + base2) + // Create apiexperimentals wsk.apiexperimental.create( basepath = Some(base2), relpath = Some("/relPath1"), operation = Some("get"), action = Some(actionName2) ) - println("Create api-experimental: Base Path " + base1) wsk.apiexperimental.create( basepath = Some(base1), relpath = Some("/relPath2"), operation = Some("delete"), action = Some(actionName1) ) - println("Create api-experimental: Base Path " + base3) wsk.apiexperimental.create( basepath = Some(base3), relpath = Some("/relPath3"), @@ -131,11 +125,8 @@ class ApiGwEndToEndTests scalaSorted.toString shouldEqual listFull.toString } finally { //Clean up apiexperimentals - println("Delete api-experimental: Base Path " + base1) wsk.apiexperimental.delete(base1, expectedExitCode = DONTCARE_EXIT) - println("Delete api-experimental: Base Path " + base2) wsk.apiexperimental.delete(base2, expectedExitCode = DONTCARE_EXIT) - println("Delete api-experimental: Base Path " + base3) wsk.apiexperimental.delete(base3, expectedExitCode = DONTCARE_EXIT) } } @@ -151,36 +142,30 @@ class ApiGwEndToEndTests val base3 = "/BaseTestPath3" try { - //Create Actions for api-experimentals + // Create Actions for api-experimentals val file = TestUtils.getTestActionFilename(s"echo-web-http.js") - println("Create Action: " + actionName1) assetHelper.withCleaner(wsk.action, actionName1) { (action, name) => action.create(name, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) } - println("Create Action: " + actionName2) assetHelper.withCleaner(wsk.action, actionName2) { (action, name) => action.create(name, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) } - println("Create Action: " + actionName3) assetHelper.withCleaner(wsk.action, actionName3) { (action, name) => action.create(name, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) } - //Create api-experimentals - println("Create api-experimental: Base Path " + base2) + // Create api-experimentals wsk.apiexperimental.create( basepath = Some(base2), relpath = Some("/relPath1"), operation = Some("get"), action = Some(actionName2) ) - println("Create apiexperimental: Base Path " + base1) wsk.apiexperimental.create( basepath = Some(base1), relpath = Some("/relPath2"), operation = Some("delete"), action = Some(actionName1) ) - println("Create apiexperimental: Base Path " + base3) wsk.apiexperimental.create( basepath = Some(base3), relpath = Some("/relPath3"), @@ -196,12 +181,9 @@ class ApiGwEndToEndTests scalaSorted.toString shouldEqual list.toString scalaSorted.toString shouldEqual listFull.toString } finally { - //Clean up apiexperimentals - println("Delete apiexperimental: Base Path " + base1) + // Clean up apiexperimentals wsk.apiexperimental.delete(base1, expectedExitCode = DONTCARE_EXIT) - println("Delete apiexperimental: Base Path " + base2) wsk.apiexperimental.delete(base2, expectedExitCode = DONTCARE_EXIT) - println("Delete apiexperimental: Base Path " + base3) wsk.apiexperimental.delete(base3, expectedExitCode = DONTCARE_EXIT) } } @@ -287,22 +269,18 @@ class ApiGwEndToEndTests val base3 = "/BaseTestPath3" try { - //Create Actions for Apis + // Create Actions for Apis val file = TestUtils.getTestActionFilename(s"echo-web-http.js") - println("Create Action: " + actionName1) assetHelper.withCleaner(wsk.action, actionName1) { (action, name) => action.create(name, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) } - println("Create Action: " + actionName2) assetHelper.withCleaner(wsk.action, actionName2) { (action, name) => action.create(name, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) } - println("Create Action: " + actionName3) assetHelper.withCleaner(wsk.action, actionName3) { (action, name) => action.create(name, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) } - //Create Apis - println("Create API: Base Path " + base2) + // Create Apis wsk.api.create( basepath = Some(base2), relpath = Some("/relPath1"), @@ -310,7 +288,6 @@ class ApiGwEndToEndTests action = Some(actionName2), cliCfgFile = Some(cliWskPropsFile.getCanonicalPath()) ) - println("Create API: Base Path " + base1) wsk.api.create( basepath = Some(base1), relpath = Some("/relPath2"), @@ -318,7 +295,6 @@ class ApiGwEndToEndTests action = Some(actionName1), cliCfgFile = Some(cliWskPropsFile.getCanonicalPath()) ) - println("Create API: Base Path " + base3) wsk.api.create( basepath = Some(base3), relpath = Some("/relPath3"), @@ -335,12 +311,9 @@ class ApiGwEndToEndTests scalaSorted.toString shouldEqual list.toString scalaSorted.toString shouldEqual listFull.toString } finally { - //Clean up Apis - println("Delete API: Base Path " + base1) + // Clean up Apis wsk.api.delete(base1, expectedExitCode = DONTCARE_EXIT, cliCfgFile = Some(cliWskPropsFile.getCanonicalPath())) - println("Delete API: Base Path " + base2) wsk.api.delete(base2, expectedExitCode = DONTCARE_EXIT, cliCfgFile = Some(cliWskPropsFile.getCanonicalPath())) - println("Delete API: Base Path " + base3) wsk.api.delete(base3, expectedExitCode = DONTCARE_EXIT, cliCfgFile = Some(cliWskPropsFile.getCanonicalPath())) } } @@ -356,22 +329,18 @@ class ApiGwEndToEndTests val base3 = "/BaseTestPath3" try { - //Create Actions for Apis + // Create Actions for Apis val file = TestUtils.getTestActionFilename(s"echo-web-http.js") - println("Create Action: " + actionName1) assetHelper.withCleaner(wsk.action, actionName1) { (action, name) => action.create(name, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) } - println("Create Action: " + actionName2) assetHelper.withCleaner(wsk.action, actionName2) { (action, name) => action.create(name, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) } - println("Create Action: " + actionName3) assetHelper.withCleaner(wsk.action, actionName3) { (action, name) => action.create(name, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) } - //Create Apis - println("Create API: Base Path " + base2) + // Create Apis wsk.api.create( basepath = Some(base2), relpath = Some("/relPath1"), @@ -379,7 +348,6 @@ class ApiGwEndToEndTests action = Some(actionName2), cliCfgFile = Some(cliWskPropsFile.getCanonicalPath()) ) - println("Create API: Base Path " + base1) wsk.api.create( basepath = Some(base1), relpath = Some("/relPath2"), @@ -387,7 +355,6 @@ class ApiGwEndToEndTests action = Some(actionName1), cliCfgFile = Some(cliWskPropsFile.getCanonicalPath()) ) - println("Create API: Base Path " + base3) wsk.api.create( basepath = Some(base3), relpath = Some("/relPath3"), @@ -406,12 +373,9 @@ class ApiGwEndToEndTests scalaSorted.toString shouldEqual list.toString scalaSorted.toString shouldEqual listFull.toString } finally { - //Clean up Apis - println("Delete API: Base Path " + base1) + // Clean up Apis wsk.api.delete(base1, expectedExitCode = DONTCARE_EXIT, cliCfgFile = Some(cliWskPropsFile.getCanonicalPath())) - println("Delete API: Base Path " + base2) wsk.api.delete(base2, expectedExitCode = DONTCARE_EXIT, cliCfgFile = Some(cliWskPropsFile.getCanonicalPath())) - println("Delete API: Base Path " + base3) wsk.api.delete(base3, expectedExitCode = DONTCARE_EXIT, cliCfgFile = Some(cliWskPropsFile.getCanonicalPath())) } } diff --git a/tests/src/test/scala/system/basic/WskBasicTests.scala b/tests/src/test/scala/system/basic/WskBasicTests.scala index 9789e8f6baa..e99c6d4e386 100644 --- a/tests/src/test/scala/system/basic/WskBasicTests.scala +++ b/tests/src/test/scala/system/basic/WskBasicTests.scala @@ -51,7 +51,7 @@ class WskBasicTests it should "return a list of alphabetized packages" in withAssetCleaner(wskprops) { (wp, assetHelper) => - //Declare 4 actions, create them out of alphabetical order + // Declare 4 actions, create them out of alphabetical order val nameA = "activationBasicTestingA1" val nameB = "activationBasicTestingA2" val nameC = "activationBasicTestingB1" @@ -69,11 +69,11 @@ class WskBasicTests } val original = wsk.pkg.list().stdout - //Create list with action names in correct order + // Create list with action names in correct order val scalaSorted = List(nameA, nameB, nameC) - //Filter out everything not previously created + // Filter out everything not previously created val regex = "activationBasicTesting[A,B][1,2]".r - //Retrieve action names into list as found in original + // Retrieve action names into list as found in original val list = (regex.findAllMatchIn(original)).toList scalaSorted.toString shouldEqual list.toString } @@ -91,7 +91,7 @@ class WskBasicTests assetHelper.withCleaner(wsk.action, actionName) { (action, name) => action.create(name, defaultAction) } - //Declare 4 actions, create them out of alphabetical order + // Declare 4 actions, create them out of alphabetical order val nameA = "activationBasicTestingA1" val nameB = "activationBasicTestingA2" val nameC = "activationBasicTestingB1" @@ -109,18 +109,18 @@ class WskBasicTests } val original = wsk.rule.list().stdout - //Create list with action names in correct order + // Create list with action names in correct order val scalaSorted = List(nameA, nameB, nameC) - //Filter out everything not previously created + // Filter out everything not previously created val regex = "activationBasicTesting[A,B][1,2]".r - //Retrieve action names into list as found in original + // Retrieve action names into list as found in original val list = (regex.findAllMatchIn(original)).toList scalaSorted.toString shouldEqual list.toString } it should "return a list of alphabetized actions" in withAssetCleaner(wskprops) { (wp, assetHelper) => - //Declare 4 actions, create them out of alphabetical order + // Declare 4 actions, create them out of alphabetical order val nameA = "activationBasicTestingA1" val nameB = "activationBasicTestingA2" val nameC = "activationBasicTestingB1" @@ -134,18 +134,18 @@ class WskBasicTests (action, _) => action.create(nameA, Some(TestUtils.getTestActionFilename("empty.js"))) } val original = wsk.action.list().stdout - //Create list with action names in correct order + // Create list with action names in correct order val scalaSorted = List(nameA, nameB, nameC) - //Filter out everything not previously created + // Filter out everything not previously created val regex = "activationBasicTesting[A,B][1,2]".r - //Retrieve action names into list as found in original + // Retrieve action names into list as found in original val list = (regex.findAllMatchIn(original)).toList scalaSorted.toString shouldEqual list.toString } it should "return a list of alphabetized triggers" in withAssetCleaner(wskprops) { (wp, assetHelper) => - //Declare 4 actions, create them out of alphabetical order + // Declare 4 actions, create them out of alphabetical order val nameA = "activationBasicTestingA1" val nameB = "activationBasicTestingA2" val nameC = "activationBasicTestingB1" @@ -159,11 +159,11 @@ it should "return a list of alphabetized triggers" in withAssetCleaner(wskprops) (trigger, _) => trigger.create(nameA) } val original = wsk.trigger.list().stdout - //Create list with action names in correct order + // Create list with action names in correct order val scalaSorted = List(nameA, nameB, nameC) - //Filter out everything not previously created + // Filter out everything not previously created val regex = "activationBasicTesting[A,B][1,2]".r - //Retrieve action names into list as found in original + // Retrieve action names into list as found in original val list = (regex.findAllMatchIn(original)).toList scalaSorted.toString shouldEqual list.toString } diff --git a/tools/cli/go-whisk-cli/commands/action.go b/tools/cli/go-whisk-cli/commands/action.go index 3eb5a7a7d48..405590ca813 100644 --- a/tools/cli/go-whisk-cli/commands/action.go +++ b/tools/cli/go-whisk-cli/commands/action.go @@ -312,6 +312,7 @@ var actionListCmd = &cobra.Command{ if actions, _, err = client.Actions.List(qualifiedName.entityName, options); err != nil { return actionListError(qualifiedName.entityName, options, err) } + if (len(actions) != 0) { whisk.Debug(whisk.DbgInfo, "Sending actions to be printed") printList(actions) diff --git a/tools/cli/go-whisk-cli/commands/api.go b/tools/cli/go-whisk-cli/commands/api.go index 0d308fadde8..f0d5376d9b0 100644 --- a/tools/cli/go-whisk-cli/commands/api.go +++ b/tools/cli/go-whisk-cli/commands/api.go @@ -40,6 +40,8 @@ const ( formatOptionYaml = "yaml" formatOptionJson = "json" + + sortActionFlag = "a" ) ////////////// @@ -299,7 +301,7 @@ var apiDeleteCmd = &cobra.Command{ if err != nil { whisk.Debug(whisk.DbgError, "client.Apis.Delete(%#v, %#v) error: %s\n", apiDeleteReq, apiDeleteReqOptions, err) errMsg := wski18n.T("Unable to delete API: {{.err}}", map[string]interface{}{"err": err}) - whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, + whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXITCODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) return whiskErr } @@ -409,9 +411,9 @@ var apiListCmd = &cobra.Command{ // Cast to a common type to allow for code to print out apilist response or apiget response retApiArray = (*whisk.RetApiArray)(retApi) } - //Checks for any sort flags being passed + // Checks for any sort flags being passed if flags.api.sortAction { - flagType = "a" + flagType = sortActionFlag } // Display the APIs - applying any specified filtering if (flags.common.full) { @@ -443,7 +445,7 @@ var apiListCmd = &cobra.Command{ })) fmt.Printf(fmtString, "Action", "Verb", "API Name", "URL") for i:=0; i