Skip to content

Commit 6b5cdb5

Browse files
committed
trigger delete fails when feed deletion fails
- add --force flag to force trigger deletion
1 parent d8a6735 commit 6b5cdb5

File tree

6 files changed

+108
-7
lines changed

6 files changed

+108
-7
lines changed

commands/flags.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ type FlagsStruct struct {
6767
detail bool
6868
format string
6969
nameSort bool // sorts list alphabetically by entity name
70+
force bool
7071
}
7172

7273
property struct {

commands/trigger.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package commands
2020
import (
2121
"errors"
2222
"fmt"
23+
"strings"
2324

2425
"github.com/apache/openwhisk-cli/wski18n"
2526
"github.com/apache/openwhisk-client-go/whisk"
@@ -286,6 +287,30 @@ var triggerDeleteCmd = &cobra.Command{
286287
err = configureFeed(qualifiedName.GetEntityName(), fullFeedName, getParameters(Flags.common.param, false, false))
287288
if err != nil {
288289
whisk.Debug(whisk.DbgError, "configureFeed(%s, %s) failed: %s\n", qualifiedName.GetEntityName(), fullFeedName, err)
290+
291+
// If the trigger feed does not exist, it's deleted! This error message will look like
292+
// "could not find trigger /NAMESPACE_ID/TRIGGER_NAME in the database"
293+
// OR if the feed action is not present, there's no way to clean up the feed
294+
// "The requested resource does not exist"
295+
// likewise, if the feed action has no code, there's no way to clean up the feed
296+
// "Missing main/no code to execute"
297+
if strings.Contains(err.Error(), "could not find trigger") {
298+
whisk.Debug(whisk.DbgWarn, "trigger feed is already deleted for trigger %s\n", qualifiedName.GetEntityName())
299+
} else if strings.Contains(err.Error(), "The requested resource does not exist") {
300+
whisk.Debug(whisk.DbgWarn, "trigger feed action '%s' does not exist\n", fullFeedName)
301+
} else if strings.Contains(err.Error(), "no code to execute") {
302+
whisk.Debug(whisk.DbgWarn, "trigger feed action '%s' does not contain valid code\n", fullFeedName)
303+
} else {
304+
errStr := wski18n.T("Unable to delete trigger '{{.name}}': {{.err}}",
305+
map[string]interface{}{"name": qualifiedName.GetEntityName(), "err": err})
306+
307+
if !Flags.common.force {
308+
werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
309+
return werr
310+
} else {
311+
whisk.Debug(whisk.DbgInfo, "trigger delete is forced despite feed deletion failure\n")
312+
}
313+
}
289314
}
290315

291316
Flags.common.param = origParams
@@ -370,7 +395,7 @@ func configureFeed(triggerName string, feedName string, parameters interface{})
370395
if err != nil {
371396
whisk.Debug(whisk.DbgError, "Invoke of action '%s' failed: %s\n", feedName, err)
372397
errStr := wski18n.T(FEED_CONFIGURATION_FAILURE, map[string]interface{}{"feedname": feedName, "trigname": triggerName, "err": err})
373-
err = whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
398+
err = whisk.MakeWskError(errors.New(errStr), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
374399
} else {
375400
whisk.Debug(whisk.DbgInfo, "Successfully configured trigger feed via feed action '%s'\n", feedName)
376401
}
@@ -405,6 +430,8 @@ func init() {
405430

406431
triggerGetCmd.Flags().BoolVarP(&Flags.trigger.summary, "summary", "s", false, wski18n.T("summarize trigger details; parameters with prefix \"*\" are bound"))
407432

433+
triggerDeleteCmd.Flags().BoolVarP(&Flags.common.force, "force", "f", false, wski18n.T("force trigger deletion even when feed deletion fails"))
434+
408435
triggerFireCmd.Flags().StringSliceVarP(&Flags.common.param, "param", "p", []string{}, wski18n.T("parameter values in `KEY VALUE` format"))
409436
triggerFireCmd.Flags().StringVarP(&Flags.common.paramFile, "param-file", "P", "", wski18n.T("`FILE` containing parameter values in JSON format"))
410437

@@ -477,6 +504,7 @@ func (t *Trigger) Create(Client *whisk.Client, args []string) error {
477504
printFailedBlockingInvocationResponse(*feedName, false, res, err)
478505

479506
reason := wski18n.T(FEED_CONFIGURATION_FAILURE, map[string]interface{}{"feedname": feedName.GetFullQualifiedName(), "err": err})
507+
480508
errStr := wski18n.T("Unable to create trigger '{{.name}}': {{.err}}",
481509
map[string]interface{}{"name": trigger.Name, "err": reason})
482510
werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
function main(params) {
18+
var bodyobj = params || {};
19+
var sc = params.statusCode || 412;
20+
bodystr = JSON.stringify(bodyobj);
21+
var resp = {}
22+
if (sc >=200 && sc <= 299) {
23+
return {
24+
statusCode: sc,
25+
headers: { 'Content-Type': 'application/json' },
26+
body: bodystr,
27+
};
28+
}
29+
return {
30+
error: {
31+
error: 'Some sort of error string',
32+
message: 'Some sort of error message',
33+
statusCode: sc,
34+
headers: { 'Content-Type': 'application/json' },
35+
}
36+
};
37+
}

tests/src/test/scala/org/apache/openwhisk/core/cli/test/WskCliBasicUsageTests.scala

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1561,6 +1561,37 @@ class WskCliBasicUsageTests extends TestHelpers with WskTestHelpers {
15611561
}
15621562
}
15631563

1564+
it should "not delete a trigger when feed deletion fails" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
1565+
val actionName = withTimestamp("feed-action-fails-delete")
1566+
val triggerName = withTimestamp("feedDeleteTest")
1567+
val feedActionCreateParams = Map("statusCode" -> JsNumber(200))
1568+
val feedActionPath = new File(".").getAbsolutePath() + "/src/dat/feed-action-fails-delete.js"
1569+
1570+
assetHelper.withCleaner(wsk.action, actionName) { (action, _) =>
1571+
action.create(actionName, Some(feedActionPath))
1572+
}
1573+
1574+
try {
1575+
wsk.trigger.create(triggerName, feed = Some(actionName), parameters = feedActionCreateParams)
1576+
wsk.trigger.delete(triggerName, expectedExitCode = ERROR_EXIT).stderr should include(
1577+
"""Unable to delete trigger""")
1578+
} finally {
1579+
wsk.cli(
1580+
Seq(
1581+
"trigger",
1582+
"delete",
1583+
s"$triggerName",
1584+
"--auth",
1585+
wskprops.authKey,
1586+
"--apihost",
1587+
wskprops.apihost,
1588+
"--apiversion",
1589+
wskprops.apiversion,
1590+
"-i",
1591+
"-f"))
1592+
}
1593+
}
1594+
15641595
it should "invoke a feed action with the correct lifecyle event when creating, retrieving and deleting a feed trigger" in withAssetCleaner(
15651596
wskprops) { (wp, assetHelper) =>
15661597
val actionName = withTimestamp("echo")

vendor/vendor.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
"ignore": "test",
44
"package": [
55
{
6-
"checksumSHA1": "upP6n3vm+l0xwq1EswdwVQSHDOg=",
6+
"checksumSHA1": "v0S6R6MWfslQgopOXRIhcd9OdHk=",
77
"path": "github.com/apache/openwhisk-client-go/whisk",
8-
"revision": "d8ccb1442651beee6a9245913e3ca0cb182888b1",
9-
"revisionTime": "2019-08-09T21:43:19Z"
8+
"revision": "d272b2b1129269d384c1dbba6c39156abc10ad3c",
9+
"revisionTime": "2019-12-11T16:53:14Z"
1010
},
1111
{
12-
"checksumSHA1": "uN1QmjP7Z6Rlkw73uOAQrtNKQR0=",
12+
"checksumSHA1": "wdSbAqtYatmuN3ckhnIfwLMJM0U=",
1313
"path": "github.com/apache/openwhisk-client-go/wski18n",
14-
"revision": "d8ccb1442651beee6a9245913e3ca0cb182888b1",
15-
"revisionTime": "2019-08-09T21:43:19Z"
14+
"revision": "d272b2b1129269d384c1dbba6c39156abc10ad3c",
15+
"revisionTime": "2019-12-11T16:53:14Z"
1616
},
1717
{
1818
"checksumSHA1": "jgCQbGeq+qGCWmBQOcl0LF6Dy0E=",

wski18n/resources/en_US.all.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,10 @@
682682
"id": "FEED_CONFIGURATION_FAILURE",
683683
"translation": "Unable to configure feed '{{.feedname}}': {{.err}}"
684684
},
685+
{
686+
"id": "force trigger deletion even when feed deletion fails",
687+
"translation": "force trigger deletion even when feed deletion fails"
688+
},
685689
{
686690
"note-to-translators": "DO NOT TRANSLATE THE 'yes' AND 'no'. THOSE ARE FIXED CLI ARGUMENT VALUES",
687691
"id": "trigger visibility `SCOPE`; yes = shared, no = private",

0 commit comments

Comments
 (0)