This is an automated email from the ASF dual-hosted git repository.

houshengbo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-cli.git


The following commit(s) were added to refs/heads/master by this push:
     new 72bc486  Refactor action invoke functions  (#319)
72bc486 is described below

commit 72bc4862db7188b669fdf8e82851f9dadf8f49fb
Author: rodric rabbah <rod...@gmail.com>
AuthorDate: Mon Jun 18 12:37:23 2018 -0400

    Refactor action invoke functions  (#319)
    
    * Refactor invoke functions.
    
    This permits invoking an action without access to global pamareters and 
bypassing parameter passing. Caller will be responsible for passing in the 
appropriate paramters, as in the case of a feed.
    
    * Strip references to Flags.common in utility methods for actions.
    
    * Add exit on error utility function.
    
    * update git ignore for tests/out.
    
    * Use refactored action invoke function but preserve semantics.
    
    * Pull out getParameters method to utils and use it in action invoke and 
trigger feed.
    
    * Refactor method printing activation response.
---
 .gitignore          |   1 +
 commands/action.go  | 120 +++++++++++++++++++++++++++++-----------------------
 commands/trigger.go |  29 ++++++++-----
 commands/util.go    |  96 +++++++++++++++++++++++++++++++++++++++++
 main.go             |  46 +-------------------
 5 files changed, 182 insertions(+), 110 deletions(-)

diff --git a/.gitignore b/.gitignore
index 55423b3..717c0b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,4 @@ incubator-openwhisk-cli.iml
 wski18n/i18n_resources.go
 bin/
 tests/build/
+tests/out/
diff --git a/commands/action.go b/commands/action.go
index bce0bf2..c21d946 100644
--- a/commands/action.go
+++ b/commands/action.go
@@ -155,9 +155,8 @@ var actionInvokeCmd = &cobra.Command{
        PreRunE:       SetupClientConfig,
        RunE: func(cmd *cobra.Command, args []string) error {
                var err error
-               var parameters interface{}
                var qualifiedName = new(QualifiedName)
-               var paramArgs []string
+               var parameters interface{}
 
                if whiskErr := CheckArgs(
                        args,
@@ -172,65 +171,79 @@ var actionInvokeCmd = &cobra.Command{
                        return NewQualifiedNameError(args[0], err)
                }
 
-               Client.Namespace = qualifiedName.GetNamespace()
-               paramArgs = Flags.common.param
+               parameters = getParameters(Flags.common.param, false, false)
+               blocking := Flags.common.blocking || Flags.action.result
+               resultOnly := Flags.action.result
+               header := !resultOnly
 
-               if len(paramArgs) > 0 {
-                       if parameters, err = getJSONFromStrings(paramArgs, 
false); err != nil {
-                               return getJSONFromStringsParamError(paramArgs, 
false, err)
-                       }
-               }
-               if Flags.action.result {
-                       Flags.common.blocking = true
-               }
-
-               res, _, err := Client.Actions.Invoke(
-                       qualifiedName.GetEntityName(),
+               res, err := invokeAction(
+                       *qualifiedName,
                        parameters,
-                       Flags.common.blocking,
-                       Flags.action.result)
+                       blocking,
+                       resultOnly)
 
-               return handleInvocationResponse(*qualifiedName, parameters, 
res, err)
+               return printInvocationResponse(*qualifiedName, blocking, 
header, res, err)
        },
 }
 
-func handleInvocationResponse(
+func invokeAction(
        qualifiedName QualifiedName,
        parameters interface{},
+       blocking bool,
+       result bool) (map[string]interface{}, error) {
+       // TODO remove all global modifiers
+       Client.Namespace = qualifiedName.GetNamespace()
+       res, _, err := Client.Actions.Invoke(
+               qualifiedName.GetEntityName(),
+               parameters,
+               blocking,
+               result)
+       return res, err
+}
+
+func printInvocationResponse(
+       qualifiedName QualifiedName,
+       blocking bool,
+       header bool,
        result map[string]interface{},
        err error) error {
        if err == nil {
-               printInvocationMsg(
-                       qualifiedName.GetNamespace(),
-                       qualifiedName.GetEntityName(),
-                       getValueFromJSONResponse(ACTIVATION_ID, result),
-                       result,
-                       color.Output)
+               printInvocationMsg(qualifiedName, blocking, header, result, 
color.Output)
        } else {
-               if !Flags.common.blocking {
-                       return handleInvocationError(err, 
qualifiedName.GetEntityName(), parameters)
+               if !blocking {
+                       return handleInvocationError(err, 
qualifiedName.GetEntityName())
                } else {
-                       if isBlockingTimeout(err) {
-                               printBlockingTimeoutMsg(
-                                       qualifiedName.GetNamespace(),
-                                       qualifiedName.GetEntityName(),
-                                       getValueFromJSONResponse(ACTIVATION_ID, 
result))
-                       } else if isApplicationError(err) {
-                               printInvocationMsg(
-                                       qualifiedName.GetNamespace(),
-                                       qualifiedName.GetEntityName(),
-                                       getValueFromJSONResponse(ACTIVATION_ID, 
result),
-                                       result,
-                                       colorable.NewColorableStderr())
-                       } else {
-                               return handleInvocationError(err, 
qualifiedName.GetEntityName(), parameters)
-                       }
+                       return 
printFailedBlockingInvocationResponse(qualifiedName, header, result, err)
                }
        }
 
        return err
 }
 
+func printFailedBlockingInvocationResponse(
+       qualifiedName QualifiedName,
+       header bool,
+       result map[string]interface{},
+       err error) error {
+       if isBlockingTimeout(err) {
+               printBlockingTimeoutMsg(
+                       qualifiedName.GetNamespace(),
+                       qualifiedName.GetEntityName(),
+                       getValueFromJSONResponse(ACTIVATION_ID, result))
+               return err
+       } else if isApplicationError(err) {
+               printInvocationMsg(
+                       qualifiedName,
+                       true,
+                       header,
+                       result,
+                       colorable.NewColorableStderr())
+               return err
+       } else {
+               return handleInvocationError(err, qualifiedName.GetEntityName())
+       }
+}
+
 var actionGetCmd = &cobra.Command{
        Use:           "get ACTION_NAME [FIELD_FILTER | --summary | --url]",
        Short:         wski18n.T("get action"),
@@ -987,12 +1000,11 @@ func actionGetError(entityName string, fetchCode bool, 
err error) error {
        return nestedError(errMsg, err)
 }
 
-func handleInvocationError(err error, entityName string, parameters 
interface{}) error {
+func handleInvocationError(err error, entityName string) error {
        whisk.Debug(
                whisk.DbgError,
-               "Client.Actions.Invoke(%s, %s, %t) error: %s\n",
-               entityName, parameters,
-               Flags.common.blocking,
+               "Client.Actions.Invoke(%s, %t) error: %s\n",
+               entityName,
                err)
 
        errMsg := wski18n.T(
@@ -1113,25 +1125,25 @@ func printBlockingTimeoutMsg(namespace string, 
entityName string, activationID i
 }
 
 func printInvocationMsg(
-       namespace string,
-       entityName string,
-       activationID interface{},
+       qualifiedName QualifiedName,
+       blocking bool,
+       header bool,
        response map[string]interface{},
        outputStream io.Writer) {
-       if !Flags.action.result {
+       if header {
                fmt.Fprintf(
                        outputStream,
                        wski18n.T(
                                "{{.ok}} invoked /{{.namespace}}/{{.name}} with 
id {{.id}}\n",
                                map[string]interface{}{
                                        "ok":        color.GreenString("ok:"),
-                                       "namespace": boldString(namespace),
-                                       "name":      boldString(entityName),
-                                       "id":        boldString(activationID),
+                                       "namespace": 
boldString(qualifiedName.GetNamespace()),
+                                       "name":      
boldString(qualifiedName.GetEntityName()),
+                                       "id":        
boldString(getValueFromJSONResponse(ACTIVATION_ID, response)),
                                }))
        }
 
-       if Flags.common.blocking {
+       if blocking {
                printJSON(response, outputStream)
        }
 }
diff --git a/commands/trigger.go b/commands/trigger.go
index fb50161..9aa0825 100644
--- a/commands/trigger.go
+++ b/commands/trigger.go
@@ -193,7 +193,7 @@ var triggerCreateCmd = &cobra.Command{
 
                // Invoke the specified feed action to configure the trigger 
feed
                if feedArgPassed {
-                       err := configureFeed(trigger.Name, fullFeedName)
+                       err := configureFeed(trigger.Name, fullFeedName, 
getParameters(Flags.common.param, false, false))
                        if err != nil {
                                whisk.Debug(whisk.DbgError, "configureFeed(%s, 
%s) failed: %s\n", trigger.Name, Flags.common.feed,
                                        err)
@@ -286,7 +286,7 @@ var triggerUpdateCmd = &cobra.Command{
                        Flags.common.param = append(Flags.common.param, 
getFormattedJSON(FEED_AUTH_KEY, Client.Config.AuthToken))
 
                        // Invoke the specified feed action to configure the 
trigger feed
-                       err = configureFeed(qualifiedName.GetEntityName(), 
fullFeedName)
+                       err = configureFeed(qualifiedName.GetEntityName(), 
fullFeedName, getParameters(Flags.common.param, false, false))
                        if err != nil {
                                whisk.Debug(whisk.DbgError, "configureFeed(%s, 
%s) failed: %s\n", qualifiedName.GetEntityName(), Flags.common.feed,
                                        err)
@@ -372,7 +372,7 @@ var triggerGetCmd = &cobra.Command{
                        Flags.common.param = append(Flags.common.param, 
getFormattedJSON(FEED_TRIGGER_NAME, fullTriggerName))
                        Flags.common.param = append(Flags.common.param, 
getFormattedJSON(FEED_AUTH_KEY, Client.Config.AuthToken))
 
-                       err = configureFeed(qualifiedName.GetEntityName(), 
fullFeedName)
+                       err = configureFeed(qualifiedName.GetEntityName(), 
fullFeedName, getParameters(Flags.common.param, false, false))
                        if err != nil {
                                whisk.Debug(whisk.DbgError, "configureFeed(%s, 
%s) failed: %s\n", qualifiedName.GetEntityName(), fullFeedName, err)
                        }
@@ -441,7 +441,7 @@ var triggerDeleteCmd = &cobra.Command{
                                Flags.common.param = append(Flags.common.param, 
getFormattedJSON(FEED_TRIGGER_NAME, fullTriggerName))
                                Flags.common.param = append(Flags.common.param, 
getFormattedJSON(FEED_AUTH_KEY, Client.Config.AuthToken))
 
-                               err = 
configureFeed(qualifiedName.GetEntityName(), fullFeedName)
+                               err = 
configureFeed(qualifiedName.GetEntityName(), fullFeedName, 
getParameters(Flags.common.param, false, false))
                                if err != nil {
                                        whisk.Debug(whisk.DbgError, 
"configureFeed(%s, %s) failed: %s\n", qualifiedName.GetEntityName(), 
fullFeedName, err)
                                }
@@ -515,17 +515,24 @@ var triggerListCmd = &cobra.Command{
        },
 }
 
-func configureFeed(triggerName string, FullFeedName string) error {
-       feedArgs := []string{FullFeedName}
-       Flags.common.blocking = true
-       err := actionInvokeCmd.RunE(nil, feedArgs)
+func configureFeed(triggerName string, feedName string, parameters 
interface{}) error {
+       var fullFeedName *QualifiedName
+       var err error
+
+       if fullFeedName, err = NewQualifiedName(feedName); err != nil {
+               return NewQualifiedNameError(feedName, err)
+       }
+
+       res, err := invokeAction(*fullFeedName, parameters, true, false)
+       err = printInvocationResponse(*fullFeedName, true, false, res, err)
+
        if err != nil {
-               whisk.Debug(whisk.DbgError, "Invoke of action '%s' failed: 
%s\n", FullFeedName, err)
+               whisk.Debug(whisk.DbgError, "Invoke of action '%s' failed: 
%s\n", feedName, err)
                errStr := wski18n.T("Unable to invoke trigger '{{.trigname}}' 
feed action '{{.feedname}}'; feed is not configured: {{.err}}",
-                       map[string]interface{}{"trigname": triggerName, 
"feedname": FullFeedName, "err": err})
+                       map[string]interface{}{"trigname": triggerName, 
"feedname": feedName, "err": err})
                err = whisk.MakeWskErrorFromWskError(errors.New(errStr), err, 
whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
        } else {
-               whisk.Debug(whisk.DbgInfo, "Successfully configured trigger 
feed via feed action '%s'\n", FullFeedName)
+               whisk.Debug(whisk.DbgInfo, "Successfully configured trigger 
feed via feed action '%s'\n", feedName)
        }
 
        return err
diff --git a/commands/util.go b/commands/util.go
index a33ad23..775989b 100644
--- a/commands/util.go
+++ b/commands/util.go
@@ -27,6 +27,8 @@ import (
        "github.com/apache/incubator-openwhisk-client-go/whisk"
 
        "github.com/fatih/color"
+       "github.com/mattn/go-colorable"
+
        //prettyjson "github.com/hokaccha/go-prettyjson"  // See prettyjson 
comment below
        "archive/tar"
        "archive/zip"
@@ -51,6 +53,45 @@ func csvToQualifiedActions(artifacts string) []string {
        return res
 }
 
+/**
+ * Processes command line to retrieve pairs of key-value pairs, where the 
value must be valid JSON.
+ *
+ * Parameters and annotations are handled the same way. The flag here is only 
for generating an error messages
+ * specific to one or the other.
+ *
+ * NOTE: this function will exit in case of a processing error since it 
indicates a problem parsing parameters.
+ *
+ * @return either an array or a JSON object (map) formatted representation of 
the key-value pairs.
+ */
+func getParameters(params []string, keyValueFormat bool, annotation bool) 
interface{} {
+       var parameters interface{}
+       var err error
+
+       if !annotation {
+               whisk.Debug(whisk.DbgInfo, "Parsing parameters: %#v\n", params)
+       } else {
+               whisk.Debug(whisk.DbgInfo, "Parsing annotations: %#v\n", params)
+       }
+
+       parameters, err = getJSONFromStrings(params, keyValueFormat)
+       if err != nil {
+               whisk.Debug(whisk.DbgError, "getJSONFromStrings(%#v, %s) 
failed: %s\n", params, keyValueFormat, err)
+               var errStr string
+
+               if !annotation {
+                       errStr = wski18n.T("Invalid parameter argument 
'{{.param}}': {{.err}}",
+                               map[string]interface{}{"param": 
fmt.Sprintf("%#v", params), "err": err})
+               } else {
+                       errStr = wski18n.T("Invalid annotation argument 
'{{.annotation}}': {{.err}}",
+                               map[string]interface{}{"annotation": 
fmt.Sprintf("%#v", params), "err": err})
+               }
+               werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, 
whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
+               ExitOnError(werr)
+       }
+
+       return parameters
+}
+
 func getJSONFromStrings(content []string, keyValueFormat bool) (interface{}, 
error) {
        var data map[string]interface{}
        var res interface{}
@@ -68,6 +109,10 @@ func getJSONFromStrings(content []string, keyValueFormat 
bool) (interface{}, err
                whisk.Debug(whisk.DbgInfo, "Created map '%v' from '%v'\n", 
data, content[i])
        }
 
+       if data == nil {
+               data = make(map[string]interface{})
+       }
+
        if keyValueFormat {
                res = getKeyValueFormattedJSON(data)
        } else {
@@ -1133,3 +1178,54 @@ func contains(arr []string, element string) bool {
        }
        return false
 }
+
+func ExitOnError(err error) {
+       if err == nil {
+               return
+       }
+
+       whisk.Debug(whisk.DbgInfo, "err object type: %s\n", 
reflect.TypeOf(err).String())
+
+       T := wski18n.T
+       var exitCode int = 0
+       var displayUsage bool = false
+       var displayMsg bool = false
+       var msgDisplayed bool = true
+       var displayPrefix bool = true
+
+       werr, isWskError := err.(*whisk.WskError) // Is the err a WskError?
+       if isWskError {
+               whisk.Debug(whisk.DbgError, "Got a *whisk.WskError error: 
%#v\n", werr)
+               displayUsage = werr.DisplayUsage
+               displayMsg = werr.DisplayMsg
+               msgDisplayed = werr.MsgDisplayed
+               displayPrefix = werr.DisplayPrefix
+               exitCode = werr.ExitCode
+       } else {
+               whisk.Debug(whisk.DbgError, "Got some other error: %s\n", err)
+               fmt.Fprintf(os.Stderr, "%s\n", err)
+
+               displayUsage = false // Cobra already displayed the usage 
message
+               exitCode = 1
+       }
+
+       outputStream := colorable.NewColorableStderr()
+
+       // If the err msg should be displayed to the console and it has not 
already been
+       // displayed, display it now.
+       if displayMsg && !msgDisplayed && displayPrefix && exitCode != 0 {
+               fmt.Fprintf(outputStream, "%s%s\n", color.RedString(T("error: 
")), err)
+       } else if displayMsg && !msgDisplayed && !displayPrefix && exitCode != 
0 {
+               fmt.Fprintf(outputStream, "%s\n", err)
+       } else if displayMsg && !msgDisplayed && exitCode == 0 {
+               fmt.Fprintf(outputStream, "%s\n", err)
+       }
+
+       // Displays usage
+       if displayUsage {
+               fmt.Fprintf(outputStream, T("Run '{{.Name}} --help' for 
usage.\n",
+                       map[string]interface{}{"Name": WskCmd.CommandPath()}))
+       }
+
+       os.Exit(exitCode)
+}
diff --git a/main.go b/main.go
index 526c505..343f6c6 100644
--- a/main.go
+++ b/main.go
@@ -19,15 +19,12 @@ package main
 
 import (
        "fmt"
-       "github.com/fatih/color"
        goi18n "github.com/nicksnyder/go-i18n/i18n"
        "os"
-       "reflect"
 
        "github.com/apache/incubator-openwhisk-cli/commands"
        "github.com/apache/incubator-openwhisk-cli/wski18n"
        "github.com/apache/incubator-openwhisk-client-go/whisk"
-       "github.com/mattn/go-colorable"
 )
 
 // CLI_BUILD_TIME holds the time of the CLI build.  During gradle builds,
@@ -51,12 +48,6 @@ func init() {
 }
 
 func main() {
-       var exitCode int = 0
-       var displayUsage bool = false
-       var displayMsg bool = false
-       var msgDisplayed bool = true
-       var displayPrefix bool = true
-
        defer func() {
                if r := recover(); r != nil {
                        fmt.Println(r)
@@ -65,42 +56,7 @@ func main() {
        }()
 
        if err := commands.Execute(); err != nil {
-               whisk.Debug(whisk.DbgInfo, "err object type: %s\n", 
reflect.TypeOf(err).String())
-
-               werr, isWskError := err.(*whisk.WskError) // Is the err a 
WskError?
-               if isWskError {
-                       whisk.Debug(whisk.DbgError, "Got a *whisk.WskError 
error: %#v\n", werr)
-                       displayUsage = werr.DisplayUsage
-                       displayMsg = werr.DisplayMsg
-                       msgDisplayed = werr.MsgDisplayed
-                       displayPrefix = werr.DisplayPrefix
-                       exitCode = werr.ExitCode
-               } else {
-                       whisk.Debug(whisk.DbgError, "Got some other error: 
%s\n", err)
-                       fmt.Fprintf(os.Stderr, "%s\n", err)
-
-                       displayUsage = false // Cobra already displayed the 
usage message
-                       exitCode = 1
-               }
-
-               outputStream := colorable.NewColorableStderr()
-
-               // If the err msg should be displayed to the console and it has 
not already been
-               // displayed, display it now.
-               if displayMsg && !msgDisplayed && displayPrefix && exitCode != 
0 {
-                       fmt.Fprintf(outputStream, "%s%s\n", 
color.RedString(T("error: ")), err)
-               } else if displayMsg && !msgDisplayed && !displayPrefix && 
exitCode != 0 {
-                       fmt.Fprintf(outputStream, "%s\n", err)
-               } else if displayMsg && !msgDisplayed && exitCode == 0 {
-                       fmt.Fprintf(outputStream, "%s\n", err)
-               }
-
-               // Displays usage
-               if displayUsage {
-                       fmt.Fprintf(outputStream, T("Run '{{.Name}} --help' for 
usage.\n",
-                               map[string]interface{}{"Name": 
commands.WskCmd.CommandPath()}))
-               }
+               commands.ExitOnError(err)
        }
-       os.Exit(exitCode)
        return
 }

-- 
To stop receiving notification emails like this one, please contact
houshen...@apache.org.

Reply via email to