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

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


The following commit(s) were added to refs/heads/master by this push:
     new c5daef0  Trigger parameter issue (#479)
c5daef0 is described below

commit c5daef0c036930e7f0c05b2dc65d3fba89c6dca0
Author: steven0711dong <[email protected]>
AuthorDate: Tue Feb 25 12:35:16 2020 -0500

    Trigger parameter issue (#479)
    
    * allow trigger feed and trigger parameters
---
 commands/commands.go                               |  38 ++-
 commands/flags.go                                  |   4 +-
 commands/trigger.go                                | 260 ++++++++++++++++++---
 .../test/scala/system/basic/WskCliBasicTests.scala |  97 ++++++++
 wski18n/resources/en_US.all.json                   |  16 ++
 5 files changed, 379 insertions(+), 36 deletions(-)

diff --git a/commands/commands.go b/commands/commands.go
index cbc1ce5..f6b2ab0 100644
--- a/commands/commands.go
+++ b/commands/commands.go
@@ -131,9 +131,11 @@ func getValueFromArgs(args []string, argIndex int, 
parsedArgs []string) ([]strin
        return parsedArgs, args, whiskErr
 }
 
-func parseArgs(args []string) ([]string, []string, []string, error) {
+func parseArgs(args []string) ([]string, []string, []string, []string, 
[]string, error) {
        var paramArgs []string
        var annotArgs []string
+       var feedParamArgs []string
+       var triggerParamArgs []string
        var whiskErr error
 
        i := 0
@@ -147,14 +149,14 @@ func parseArgs(args []string) ([]string, []string, 
[]string, error) {
                                        map[string]interface{}{"err": whiskErr})
                                whiskErr = 
whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL, 
whisk.DISPLAY_MSG,
                                        whisk.DISPLAY_USAGE)
-                               return nil, nil, nil, whiskErr
+                               return nil, nil, nil, nil, nil, whiskErr
                        }
 
                        filename := paramArgs[len(paramArgs)-1]
                        paramArgs[len(paramArgs)-1], whiskErr = 
ReadFile(filename)
                        if whiskErr != nil {
                                whisk.Debug(whisk.DbgError, "readFile(%s) 
error: %s\n", filename, whiskErr)
-                               return nil, nil, nil, whiskErr
+                               return nil, nil, nil, nil, nil, whiskErr
                        }
                } else if args[i] == "-A" || args[i] == "--annotation-file" {
                        annotArgs, args, whiskErr = getValueFromArgs(args, i, 
annotArgs)
@@ -164,14 +166,14 @@ func parseArgs(args []string) ([]string, []string, 
[]string, error) {
                                        map[string]interface{}{"err": whiskErr})
                                whiskErr = 
whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL, 
whisk.DISPLAY_MSG,
                                        whisk.DISPLAY_USAGE)
-                               return nil, nil, nil, whiskErr
+                               return nil, nil, nil, nil, nil, whiskErr
                        }
 
                        filename := annotArgs[len(annotArgs)-1]
                        annotArgs[len(annotArgs)-1], whiskErr = 
ReadFile(filename)
                        if whiskErr != nil {
                                whisk.Debug(whisk.DbgError, "readFile(%s) 
error: %s\n", filename, whiskErr)
-                               return nil, nil, nil, whiskErr
+                               return nil, nil, nil, nil, nil, whiskErr
                        }
                } else if args[i] == "-p" || args[i] == "--param" {
                        paramArgs, args, whiskErr = getKeyValueArgs(args, i, 
paramArgs)
@@ -181,7 +183,7 @@ func parseArgs(args []string) ([]string, []string, 
[]string, error) {
                                        map[string]interface{}{"err": whiskErr})
                                whiskErr = 
whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL, 
whisk.DISPLAY_MSG,
                                        whisk.DISPLAY_USAGE)
-                               return nil, nil, nil, whiskErr
+                               return nil, nil, nil, nil, nil, whiskErr
                        }
                } else if args[i] == "-a" || args[i] == "--annotation" {
                        annotArgs, args, whiskErr = getKeyValueArgs(args, i, 
annotArgs)
@@ -191,7 +193,23 @@ func parseArgs(args []string) ([]string, []string, 
[]string, error) {
                                        map[string]interface{}{"err": whiskErr})
                                whiskErr = 
whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL, 
whisk.DISPLAY_MSG,
                                        whisk.DISPLAY_USAGE)
-                               return nil, nil, nil, whiskErr
+                               return nil, nil, nil, nil, nil, whiskErr
+                       }
+               } else if args[i] == "-F" || args[i] == "--feed-param" {
+                       feedParamArgs, args, whiskErr = getKeyValueArgs(args, 
i, feedParamArgs)
+                       if whiskErr != nil {
+                               whisk.Debug(whisk.DbgError, 
"getKeyValueArgs(%#v, %d) failed: %s\n", args, i, whiskErr)
+                               whiskErr = whisk.MakeWskError(whiskErr, 
whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG,
+                                       whisk.DISPLAY_USAGE)
+                               return nil, nil, nil, nil, nil, whiskErr
+                       }
+               } else if args[i] == "-T" || args[i] == "--trigger-param" {
+                       triggerParamArgs, args, whiskErr = 
getKeyValueArgs(args, i, triggerParamArgs)
+                       if whiskErr != nil {
+                               whisk.Debug(whisk.DbgError, 
"getKeyValueArgs(%#v, %d) failed: %s\n", args, i, whiskErr)
+                               whiskErr = whisk.MakeWskError(whiskErr, 
whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG,
+                                       whisk.DISPLAY_USAGE)
+                               return nil, nil, nil, nil, nil, whiskErr
                        }
                } else {
                        i++
@@ -200,16 +218,18 @@ func parseArgs(args []string) ([]string, []string, 
[]string, error) {
 
        whisk.Debug(whisk.DbgInfo, "Found param args '%s'.\n", paramArgs)
        whisk.Debug(whisk.DbgInfo, "Found annotations args '%s'.\n", annotArgs)
+       whisk.Debug(whisk.DbgInfo, "Found feed param args '%s'.\n", 
feedParamArgs)
+       whisk.Debug(whisk.DbgInfo, "Found trigger param args '%s'.\n", 
triggerParamArgs)
        whisk.Debug(whisk.DbgInfo, "Arguments with param args removed '%s'.\n", 
args)
 
-       return args, paramArgs, annotArgs, nil
+       return args, paramArgs, annotArgs, feedParamArgs, triggerParamArgs, nil
 }
 
 func Execute() error {
        var err error
 
        whisk.Debug(whisk.DbgInfo, "wsk args: %#v\n", os.Args)
-       os.Args, Flags.common.param, Flags.common.annotation, err = 
parseArgs(os.Args)
+       os.Args, Flags.common.param, Flags.common.annotation, 
Flags.trigger.feedParam, Flags.trigger.triggerParam, err = parseArgs(os.Args)
 
        if err != nil {
                whisk.Debug(whisk.DbgError, "parseParams(%s) failed: %s\n", 
os.Args, err)
diff --git a/commands/flags.go b/commands/flags.go
index 25c9b96..b48058c 100644
--- a/commands/flags.go
+++ b/commands/flags.go
@@ -112,7 +112,9 @@ type FlagsStruct struct {
 
        // trigger
        trigger struct {
-               summary bool
+               summary      bool
+               feedParam    []string
+               triggerParam []string
        }
 
        //sdk
diff --git a/commands/trigger.go b/commands/trigger.go
index 86b18da..c5cec1d 100644
--- a/commands/trigger.go
+++ b/commands/trigger.go
@@ -397,11 +397,15 @@ func init() {
        triggerCreateCmd.Flags().StringSliceVarP(&Flags.common.param, "param", 
"p", []string{}, wski18n.T("parameter values in `KEY VALUE` format"))
        triggerCreateCmd.Flags().StringVarP(&Flags.common.paramFile, 
"param-file", "P", "", wski18n.T("`FILE` containing parameter values in JSON 
format"))
        triggerCreateCmd.Flags().StringVarP(&Flags.common.feed, "feed", "f", 
"", wski18n.T("trigger feed `ACTION_NAME`"))
+       triggerCreateCmd.Flags().StringSliceVarP(&Flags.trigger.feedParam, 
"feed-param", "F", []string{}, wski18n.T("feed parameter values in `KEY VALUE` 
format"))
+       triggerCreateCmd.Flags().StringSliceVarP(&Flags.trigger.triggerParam, 
"trigger-param", "T", []string{}, wski18n.T("trigger parameter values in `KEY 
VALUE` format"))
 
        triggerUpdateCmd.Flags().StringSliceVarP(&Flags.common.annotation, 
"annotation", "a", []string{}, wski18n.T("annotation values in `KEY VALUE` 
format"))
        triggerUpdateCmd.Flags().StringVarP(&Flags.common.annotFile, 
"annotation-file", "A", "", wski18n.T("`FILE` containing annotation values in 
JSON format"))
        triggerUpdateCmd.Flags().StringSliceVarP(&Flags.common.param, "param", 
"p", []string{}, wski18n.T("parameter values in `KEY VALUE` format"))
        triggerUpdateCmd.Flags().StringVarP(&Flags.common.paramFile, 
"param-file", "P", "", wski18n.T("`FILE` containing parameter values in JSON 
format"))
+       triggerUpdateCmd.Flags().StringSliceVarP(&Flags.trigger.feedParam, 
"feed-param", "F", []string{}, wski18n.T("feed parameter values in `KEY VALUE` 
format"))
+       triggerUpdateCmd.Flags().StringSliceVarP(&Flags.trigger.triggerParam, 
"trigger-param", "T", []string{}, wski18n.T("trigger parameter values in `KEY 
VALUE` format"))
 
        triggerGetCmd.Flags().BoolVarP(&Flags.trigger.summary, "summary", "s", 
false, wski18n.T("summarize trigger details; parameters with prefix \"*\" are 
bound"))
 
@@ -431,52 +435,140 @@ func (t *Trigger) Create(Client *whisk.Client, args 
[]string) error {
                return whiskErr
        }
 
+       //1. if the command line arguments user provides contains only --param 
flags
+       //2. if the command line arguments user provides contains no --param 
flags at all
+       //we should process the trigger create command in the old way.
+       if userIndicatesToUseOldTriggerCommand() {
+               triggerName, err := NewQualifiedName(args[0])
+               if err != nil {
+                       return NewQualifiedNameError(args[0], err)
+               }
+
+               //if user also issued new trigger command then we stop execution
+               if triggerUsageErr := userIssuedNewTriggerCmd(); 
triggerUsageErr != nil {
+                       return triggerUsageErr
+               }
+
+               annotationArray := Flags.common.annotation
+               authToken := Client.Config.AuthToken
+
+               // if a feed is specified, create additional parameters which 
must be passed to the feed
+               feedQualifiedName, additionalFeedParams := 
feedParameters(Flags.common.feed, FEED_CREATE, triggerName, authToken)
+
+               // if a feed is specified, add feed annotation the annotations 
declared on the command line
+               // TODO: add test to ensure that generated annotation has 
precedence
+               if feedQualifiedName != nil {
+                       annotationArray = append(annotationArray, 
getFormattedJSON("feed", feedQualifiedName.GetFullQualifiedName()))
+               }
+               annotations := getParameters(annotationArray, true, true)
+
+               // the feed receives all the parameters that are specified on 
the command line so we merge
+               // the feed lifecycle parameters with the command line ones
+               parameters := getParameters(append(Flags.common.param, 
additionalFeedParams...), feedQualifiedName == nil, false)
+
+               trigger := &whisk.Trigger{
+                       Name:        triggerName.GetEntityName(),
+                       Annotations: annotations.(whisk.KeyValueArr),
+               }
+
+               if feedQualifiedName == nil {
+                       // parameters are only attached to the trigger in there 
is no feed, otherwise
+                       // parameters are passed to the feed instead
+                       trigger.Parameters = parameters.(whisk.KeyValueArr)
+               }
+
+               createOrUpdate(Client, triggerName, trigger, false)
+
+               // Invoke the specified feed action to configure the trigger 
feed
+               if feedQualifiedName != nil {
+                       res, err := invokeAction(*feedQualifiedName, 
parameters, true, false)
+                       if err != nil {
+                               whisk.Debug(whisk.DbgError, "Failed configuring 
feed '%s' failed: %s\n", feedQualifiedName.GetFullQualifiedName(), err)
+
+                               // TODO: should we do this at all? Keeping for 
now.
+                               
printFailedBlockingInvocationResponse(*feedQualifiedName, false, res, err)
+
+                               reason := wski18n.T(FEED_CONFIGURATION_FAILURE, 
map[string]interface{}{"feedname": feedQualifiedName.GetFullQualifiedName(), 
"err": err})
+                               errStr := wski18n.T("Unable to create trigger 
'{{.name}}': {{.err}}",
+                                       map[string]interface{}{"name": 
trigger.Name, "err": reason})
+                               werr := 
whisk.MakeWskErrorFromWskError(errors.New(errStr), err, 
whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
+
+                               // Delete trigger that was created for this feed
+                               err = deleteTrigger(triggerName.GetEntityName())
+                               if err != nil {
+                                       whisk.Debug(whisk.DbgWarn, "Ignoring 
deleteTrigger(%s) failure: %s\n", triggerName.GetEntityName(), err)
+                               }
+
+                               return werr
+                       } else {
+                               whisk.Debug(whisk.DbgInfo, "Successfully 
configured trigger feed via feed action '%s'\n", Flags.common.feed)
+
+                               // preserve existing behavior where output of 
feed activation is emitted to console
+                               printInvocationMsg(*feedQualifiedName, true, 
true, res, color.Output)
+                       }
+               }
+
+               fmt.Fprintf(color.Output,
+                       wski18n.T("{{.ok}} created trigger {{.name}}\n",
+                               map[string]interface{}{"ok": 
color.GreenString("ok:"), "name": boldString(trigger.Name)}))
+               return nil
+       }
+       //1. if user's input command line argument contains either --feed-param 
or --trigger-param
+       //2. if user's input command line argument contains both --feed-param 
and --trigger-param
+       //then we process trigger create command in a different way
+       return CreateExtendedVersion(Client, args)
+}
+
+//CreateExtendedVersion only executes when users indicate to create triggers 
with --feed-param
+//or --trigger-param flags.
+func CreateExtendedVersion(Client *whisk.Client, args []string) error {
        triggerName, err := NewQualifiedName(args[0])
        if err != nil {
                return NewQualifiedNameError(args[0], err)
        }
 
-       paramArray := Flags.common.param
        annotationArray := Flags.common.annotation
-       feedParam := Flags.common.feed
        authToken := Client.Config.AuthToken
 
        // if a feed is specified, create additional parameters which must be 
passed to the feed
-       feedName, feedParams := feedParameters(feedParam, FEED_CREATE, 
triggerName, authToken)
-       // the feed receives all the parameters that are specified on the 
command line so we merge
-       // the feed lifecycle parameters with the command line ones
-       parameters := getParameters(append(paramArray, feedParams...), feedName 
== nil, false)
+       feedQualifiedName, additionalFeedParams := 
feedParameters(Flags.common.feed, FEED_CREATE, triggerName, authToken)
 
        // if a feed is specified, add feed annotation the annotations declared 
on the command line
        // TODO: add test to ensure that generated annotation has precedence
-       if feedName != nil {
-               annotationArray = append(annotationArray, 
getFormattedJSON("feed", feedName.GetFullQualifiedName()))
+       if feedQualifiedName != nil {
+               annotationArray = append(annotationArray, 
getFormattedJSON("feed", feedQualifiedName.GetFullQualifiedName()))
        }
+
        annotations := getParameters(annotationArray, true, true)
 
+       //if trigger contains no feed but user tries to update feed parameter, 
then we issue error.
+       if feedQualifiedName == nil && len(Flags.trigger.feedParam) > 0 {
+               errStr := wski18n.T("Incorrect usage. Trigger without a feed 
cannot have feed parameters")
+               return whisk.MakeWskError(errors.New(errStr), 
whisk.NOT_ALLOWED, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
+       }
+
+       triggerParams := getParameters(Flags.trigger.triggerParam, true, false)
+       //if a feed is specified, add feed annotation the annotations declared 
on the command line
+       //TODO: add test to ensure that generated annotation has precedence
+       feedParams := getParameters(append(Flags.trigger.feedParam, 
additionalFeedParams...), feedQualifiedName == nil, false)
+
        trigger := &whisk.Trigger{
                Name:        triggerName.GetEntityName(),
                Annotations: annotations.(whisk.KeyValueArr),
-       }
-
-       if feedName == nil {
-               // parameters are only attached to the trigger in there is no 
feed, otherwise
-               // parameters are passed to the feed instead
-               trigger.Parameters = parameters.(whisk.KeyValueArr)
+               Parameters:  triggerParams.(whisk.KeyValueArr),
        }
 
        createOrUpdate(Client, triggerName, trigger, false)
-
        // Invoke the specified feed action to configure the trigger feed
-       if feedName != nil {
-               res, err := invokeAction(*feedName, parameters, true, false)
+       if feedQualifiedName != nil {
+               res, err := invokeAction(*feedQualifiedName, feedParams, true, 
false)
                if err != nil {
-                       whisk.Debug(whisk.DbgError, "Failed configuring feed 
'%s' failed: %s\n", feedName.GetFullQualifiedName(), err)
+                       whisk.Debug(whisk.DbgError, "Failed configuring feed 
'%s' failed: %s\n", feedQualifiedName.GetFullQualifiedName(), err)
 
                        // TODO: should we do this at all? Keeping for now.
-                       printFailedBlockingInvocationResponse(*feedName, false, 
res, err)
+                       
printFailedBlockingInvocationResponse(*feedQualifiedName, false, res, err)
 
-                       reason := wski18n.T(FEED_CONFIGURATION_FAILURE, 
map[string]interface{}{"feedname": feedName.GetFullQualifiedName(), "err": err})
+                       reason := wski18n.T(FEED_CONFIGURATION_FAILURE, 
map[string]interface{}{"feedname": feedQualifiedName.GetFullQualifiedName(), 
"err": err})
                        errStr := wski18n.T("Unable to create trigger 
'{{.name}}': {{.err}}",
                                map[string]interface{}{"name": trigger.Name, 
"err": reason})
                        werr := 
whisk.MakeWskErrorFromWskError(errors.New(errStr), err, 
whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
@@ -488,17 +580,17 @@ func (t *Trigger) Create(Client *whisk.Client, args 
[]string) error {
                        }
 
                        return werr
-               } else {
-                       whisk.Debug(whisk.DbgInfo, "Successfully configured 
trigger feed via feed action '%s'\n", feedName)
-
-                       // preserve existing behavior where output of feed 
activation is emitted to console
-                       printInvocationMsg(*feedName, true, true, res, 
color.Output)
                }
+               whisk.Debug(whisk.DbgInfo, "Successfully configured trigger 
feed via feed action '%s'\n", Flags.common.feed)
+               // preserve existing behavior where output of feed activation 
is emitted to console
+               printInvocationMsg(*feedQualifiedName, true, true, res, 
color.Output)
+
        }
 
        fmt.Fprintf(color.Output,
                wski18n.T("{{.ok}} created trigger {{.name}}\n",
                        map[string]interface{}{"ok": color.GreenString("ok:"), 
"name": boldString(trigger.Name)}))
+
        return nil
 }
 
@@ -547,7 +639,10 @@ func (t *Trigger) Update(Client *whisk.Client, args 
[]string) error {
        retTrigger, httpResp, err := 
Client.Triggers.Get(qualifiedName.GetEntityName())
 
        if err != nil && httpResp.StatusCode == 404 {
-               t.Create(Client, args)
+               if createErr := t.Create(Client, args); createErr != nil {
+                       return createErr
+               }
+               return nil
        } else if err != nil {
                whisk.Debug(whisk.DbgError, "Client.Triggers.Get(%s) failed: 
%s\n", qualifiedName.GetEntityName(), err)
                errStr := wski18n.T("Unable to get trigger '{{.name}}': 
{{.err}}",
@@ -555,7 +650,13 @@ func (t *Trigger) Update(Client *whisk.Client, args 
[]string) error {
                werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, 
whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
                return werr
        } else {
+               if !userIndicatesToUseOldTriggerCommand() {
+                       return UpdateExtendedVersion(Client, args, retTrigger)
+               }
 
+               if triggerUsageErr := userIssuedNewTriggerCmd(); 
triggerUsageErr != nil {
+                       return triggerUsageErr
+               }
                // Get full feed name from trigger get request as it is needed 
to get the feed
                if retTrigger != nil && retTrigger.Annotations != nil {
                        fullFeedName = getValueString(retTrigger.Annotations, 
"feed")
@@ -601,3 +702,110 @@ func (t *Trigger) Update(Client *whisk.Client, args 
[]string) error {
 
        return nil
 }
+
+//UpdateExtendedVersion only executes when users indicate to update triggers 
with --feed-param
+//or --trigger-param flags.
+func UpdateExtendedVersion(Client *whisk.Client, args []string, retTrigger 
*whisk.Trigger) error {
+       var fullFeedName string
+       var qualifiedName = new(QualifiedName)
+       var err error
+
+       if qualifiedName, err = NewQualifiedName(args[0]); err != nil {
+               return NewQualifiedNameError(args[0], err)
+       }
+
+       whisk.Debug(whisk.DbgInfo, "Parsing parameters: %#v\n", 
Flags.trigger.triggerParam)
+       triggerParameters, err := 
getJSONFromStrings(Flags.trigger.triggerParam, true)
+       if err != nil {
+               whisk.Debug(whisk.DbgError, "getJSONFromStrings(%#v, true) 
failed: %s\n", Flags.common.param, err)
+               errStr := wski18n.T("Invalid parameter argument '{{.param}}': 
{{.err}}",
+                       map[string]interface{}{"param": fmt.Sprintf("%#v", 
Flags.common.param), "err": err})
+               werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, 
whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
+               return werr
+       }
+
+       whisk.Debug(whisk.DbgInfo, "Parsing annotations: %#v\n", 
Flags.common.annotation)
+       annotations, err := getJSONFromStrings(Flags.common.annotation, true)
+       if err != nil {
+               whisk.Debug(whisk.DbgError, "getJSONFromStrings(%#v, true) 
failed: %s\n", Flags.common.annotation, err)
+               errStr := wski18n.T("Invalid annotation argument 
'{{.annotation}}': {{.err}}",
+                       map[string]interface{}{"annotation": fmt.Sprintf("%#v", 
Flags.common.annotation), "err": err})
+               werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, 
whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
+               return werr
+       }
+
+       trigger := &whisk.Trigger{
+               Name:        qualifiedName.GetEntityName(),
+               Parameters:  triggerParameters.(whisk.KeyValueArr),
+               Annotations: annotations.(whisk.KeyValueArr),
+       }
+
+       // Get full feed name from trigger get request as it is needed to get 
the feed
+       if retTrigger != nil && retTrigger.Annotations != nil {
+               fullFeedName = getValueString(retTrigger.Annotations, "feed")
+       }
+
+       _, _, err = Client.Triggers.Insert(trigger, true)
+       if err != nil {
+               whisk.Debug(whisk.DbgError, "Client.Triggers.Insert(%+v,true) 
failed: %s\n", trigger, err)
+               errStr := wski18n.T("Unable to update trigger '{{.name}}': 
{{.err}}",
+                       map[string]interface{}{"name": trigger.Name, "err": 
err})
+               werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, 
whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
+               return werr
+       }
+       //if there is no feed attached to this trigger
+       if len(fullFeedName) < 1 {
+               //but user indicate feed parameter change, we issue error 
message.
+               if len(Flags.trigger.feedParam) > 0 {
+                       whisk.Debug(whisk.DbgError, "trigger %+v is found but 
it does not contain a feed. \n", trigger)
+                       err := errors.New("this trigger does not contain a 
feed")
+                       errStr := wski18n.T(FEED_CONFIGURATION_FAILURE, 
map[string]interface{}{"feedname": qualifiedName.GetEntityName(), "err": err})
+                       werr := 
whisk.MakeWskErrorFromWskError(errors.New(errStr), err, 
whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
+                       return werr
+               }
+       }
+
+       if len(fullFeedName) > 0 && 
feedParameterChanged(Flags.trigger.feedParam) {
+               //if there is feed, we invoke the action to configure the feed 
regardless any changes on feed parameters
+               fullTriggerName := fmt.Sprintf("/%s/%s", 
qualifiedName.GetNamespace(), qualifiedName.GetEntityName())
+               Flags.trigger.feedParam = append(Flags.trigger.feedParam, 
getFormattedJSON(FEED_LIFECYCLE_EVENT, FEED_UPDATE))
+               Flags.trigger.feedParam = append(Flags.trigger.feedParam, 
getFormattedJSON(FEED_TRIGGER_NAME, fullTriggerName))
+               Flags.trigger.feedParam = append(Flags.trigger.feedParam, 
getFormattedJSON(FEED_AUTH_KEY, Client.Config.AuthToken))
+
+               // Invoke the specified feed action to configure the trigger 
feed
+               err = configureFeed(qualifiedName.GetEntityName(), 
fullFeedName, getParameters(Flags.trigger.feedParam, false, false))
+               if err != nil {
+                       whisk.Debug(whisk.DbgError, "configureFeed(%s, %s) 
failed: %s\n", qualifiedName.GetEntityName(), Flags.common.feed, err)
+                       errStr := wski18n.T("Unable to create trigger 
'{{.name}}': {{.err}}",
+                               map[string]interface{}{"name": 
qualifiedName.GetEntityName(), "err": err})
+                       werr := 
whisk.MakeWskErrorFromWskError(errors.New(errStr), err, 
whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
+                       return werr
+               }
+       }
+
+       fmt.Fprintf(color.Output,
+               wski18n.T("{{.ok}} updated trigger {{.name}}\n",
+                       map[string]interface{}{"ok": color.GreenString("ok:"), 
"name": boldString(qualifiedName.GetEntityName())}))
+
+       return nil
+}
+
+func feedParameterChanged(triggerParam []string) bool {
+       return len(triggerParam) > 0
+}
+
+//if users are 1. creating a trigger without any feed or parameters
+//             2. creating a trigger using --param flag
+//then we use the old way to create the trigger.
+func userIndicatesToUseOldTriggerCommand() bool {
+       return len(Flags.common.param) > 0 || (len(Flags.trigger.feedParam) == 
0 && len(Flags.common.param) == 0 && len(Flags.trigger.triggerParam) == 0)
+}
+
+func userIssuedNewTriggerCmd() error {
+       if len(Flags.trigger.feedParam) > 0 || len(Flags.trigger.triggerParam) 
> 0 {
+               whisk.Debug(whisk.DbgError, "User tries to mix use of --param 
or --param-file flags with --feed-param or --trigger-param")
+               errStr := wski18n.T("Incorrect usage. Cannot combine 
--feed-param or --trigger-param flag with neither --param nor --param-file 
flag")
+               return whisk.MakeWskError(errors.New(errStr), 
whisk.NOT_ALLOWED, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
+       }
+       return nil
+}
diff --git a/tests/src/test/scala/system/basic/WskCliBasicTests.scala 
b/tests/src/test/scala/system/basic/WskCliBasicTests.scala
index c3a7cf7..a892bba 100644
--- a/tests/src/test/scala/system/basic/WskCliBasicTests.scala
+++ b/tests/src/test/scala/system/basic/WskCliBasicTests.scala
@@ -491,6 +491,103 @@ class WskCliBasicTests extends TestHelpers with 
WskTestHelpers {
     wsk.trigger.list().stdout should include(triggerName)
   }
 
+  it should "return error message when updating feed param on trigger that 
contains no feed param" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val triggerName = withTimestamp("t1tor1")
+    val ns = wsk.namespace.whois()
+    val params = Map("a" -> "A".toJson)
+
+    assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, _) =>
+      trigger.create(triggerName, parameters = params)
+    }
+    wsk
+      .cli(
+        Seq("trigger", "update", triggerName, "-F", "feedParam", 
"feedParamVal", "--auth", wskprops.authKey) ++ wskprops.overrides,
+        expectedExitCode = ERROR_EXIT)
+      .stderr should include("this trigger does not contain a feed")
+  }
+
+  it should "return error message when creating feed with both --param and 
--trigger-param/--feed-param flags" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val triggerName = withTimestamp("t1tor1")
+    val ns = wsk.namespace.whois()
+
+    var stderr =
+      wsk
+        .cli(
+          Seq(
+            "trigger",
+            "create",
+            triggerName,
+            "-p",
+            "a",
+            "A",
+            "-F",
+            "feedParam",
+            "feedParamVal",
+            "--auth",
+            wskprops.authKey) ++ wskprops.overrides,
+          expectedExitCode = NOT_ALLOWED)
+        .stderr
+    stderr should include(
+      "Incorrect usage. Cannot combine --feed-param or --trigger-param flag 
with neither --param nor --param-file flag")
+  }
+
+  it should "return error message when updating feed with both --param and 
--trigger-param/--feed-param flags" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val triggerName = withTimestamp("t1tor1")
+    val ns = wsk.namespace.whois()
+
+    var stderr =
+      wsk
+        .cli(
+          Seq(
+            "trigger",
+            "update",
+            triggerName,
+            "-p",
+            "a",
+            "A",
+            "-T",
+            "feedParam",
+            "feedParamVal",
+            "--auth",
+            wskprops.authKey) ++ wskprops.overrides,
+          expectedExitCode = NOT_ALLOWED)
+        .stderr
+    stderr should include(
+      "Incorrect usage. Cannot combine --feed-param or --trigger-param flag 
with neither --param nor --param-file flag")
+  }
+
+  it should "return error message when creating feed with both --param-file 
and --trigger-param/--feed-param flags" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val triggerName = withTimestamp("t1tor1")
+    val ns = wsk.namespace.whois()
+    val filePathString = TestUtils.getTestActionFilename("argCheck.js")
+
+    var stderr =
+      wsk
+        .cli(
+          Seq(
+            "trigger",
+            "create",
+            triggerName,
+            "--param-file",
+            filePathString,
+            "-F",
+            "feedParam",
+            "feedParamVal",
+            "-T",
+            "triggerParam",
+            "triggerParamVal",
+            "--auth",
+            wskprops.authKey) ++ wskprops.overrides,
+          expectedExitCode = NOT_ALLOWED)
+        .stderr
+    stderr should include(
+      "Incorrect usage. Cannot combine --feed-param or --trigger-param flag 
with neither --param nor --param-file flag")
+  }
+
   it should "create, and get a trigger summary" in withAssetCleaner(wskprops) 
{ (wp, assetHelper) =>
     val name = "triggerName"
     val annots = Map(
diff --git a/wski18n/resources/en_US.all.json b/wski18n/resources/en_US.all.json
index fbcdfb8..a887e03 100644
--- a/wski18n/resources/en_US.all.json
+++ b/wski18n/resources/en_US.all.json
@@ -1594,5 +1594,21 @@
   {
     "id": "CMD_DESC_LONG_EXPORT",
     "translation": "Exports managed project assets from OpenWhisk to manifest 
and function files.\n\nThe most common way to run export:\n$ wsk project export 
--projectname PROJECT --manifest path/to/exported-manifest.yaml"
+  },
+  {
+    "id": "Incorrect usage. Cannot combine --feed-param or --trigger-param 
flag with neither --param nor --param-file flag", 
+    "translation": "Incorrect usage. Cannot combine --feed-param or 
--trigger-param flag with neither --param nor --param-file flag"
+  },
+  {
+    "id": "trigger parameter values in `KEY VALUE` format", 
+    "translation": "trigger parameter values in `KEY VALUE` format"
+  },
+  {
+    "id": "feed parameter values in `KEY VALUE` format", 
+    "translation": "feed parameter values in `KEY VALUE` format"
+  },
+  {
+    "id": "Incorrect usage. Trigger without a feed cannot have feed 
parameters", 
+    "translation": "Incorrect usage. Trigger without a feed cannot have feed 
parameters"
   }
 ]

Reply via email to