Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 6BC50200D2F for ; Wed, 1 Nov 2017 22:17:24 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 6A6D2160BFA; Wed, 1 Nov 2017 21:17:24 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 98AF8160BEA for ; Wed, 1 Nov 2017 22:17:22 +0100 (CET) Received: (qmail 7877 invoked by uid 500); 1 Nov 2017 21:17:21 -0000 Mailing-List: contact commits-help@openwhisk.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@openwhisk.apache.org Delivered-To: mailing list commits@openwhisk.apache.org Received: (qmail 7864 invoked by uid 99); 1 Nov 2017 21:17:21 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 01 Nov 2017 21:17:21 +0000 Received: by gitbox.apache.org (ASF Mail Server at gitbox.apache.org, from userid 33) id 2329E81C57; Wed, 1 Nov 2017 21:17:21 +0000 (UTC) Date: Wed, 01 Nov 2017 21:17:21 +0000 To: "commits@openwhisk.apache.org" Subject: [incubator-openwhisk-wskdeploy] branch master updated: Adding Action Annotations (#631) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Message-ID: <150957104105.13995.12398432595226503436@gitbox.apache.org> From: mrutkowski@apache.org X-Git-Host: gitbox.apache.org X-Git-Repo: incubator-openwhisk-wskdeploy X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: 0a569116c9e5aeedfa0b1e6fe103888990eb3d70 X-Git-Newrev: 2d400be898f2400c38fa6107b1e8245be9cc8333 X-Git-Rev: 2d400be898f2400c38fa6107b1e8245be9cc8333 X-Git-NotificationType: ref_changed_plus_diff X-Git-Multimail-Version: 1.5.dev Auto-Submitted: auto-generated archived-at: Wed, 01 Nov 2017 21:17:24 -0000 This is an automated email from the ASF dual-hosted git repository. mrutkowski pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-wskdeploy.git The following commit(s) were added to refs/heads/master by this push: new 2d400be Adding Action Annotations (#631) 2d400be is described below commit 2d400be898f2400c38fa6107b1e8245be9cc8333 Author: Priti Desai AuthorDate: Wed Nov 1 14:17:19 2017 -0700 Adding Action Annotations (#631) * fixing annotation on actions * adding better unit test * adding integration test * Adding a new line * adding similar precedence order for package and trigger annotations * Adding translatable error message and fixing few grammatical errors --- deployers/deploymentreader.go | 118 ++++++++----- deployers/deploymentreader_test.go | 183 ++++++++++++++------- deployers/servicedeployer.go | 8 +- parsers/manifest_parser.go | 38 ++++- parsers/manifest_parser_test.go | 34 ++++ .../deployment_validate_action_annotations.yaml | 31 ++++ .../dat/manifest_validate_action_annotations.yaml | 65 ++++++++ .../validate-action-annotations/actions/hello.js | 26 +++ .../deployment-with-invalid-annotations.yaml | 22 +++ .../validate-action-annotations/deployment.yaml | 31 ++++ .../validate-action-annotations/manifest.yaml | 65 ++++++++ .../validate-action-annotations_test.go | 48 ++++++ .../deployment.yaml | 53 +++--- .../manifest.yaml | 25 +++ .../validate-bind-inputs-anno_test.go | 73 ++++++-- utils/misc.go | 71 -------- utils/webaction.go | 94 +++++++++++ 17 files changed, 753 insertions(+), 232 deletions(-) diff --git a/deployers/deploymentreader.go b/deployers/deploymentreader.go index d9e5759..21dd39e 100644 --- a/deployers/deploymentreader.go +++ b/deployers/deploymentreader.go @@ -21,6 +21,7 @@ import ( "github.com/apache/incubator-openwhisk-client-go/whisk" "github.com/apache/incubator-openwhisk-wskdeploy/parsers" "github.com/apache/incubator-openwhisk-wskdeploy/utils" + "github.com/apache/incubator-openwhisk-wskdeploy/wski18n" ) type DeploymentReader struct { @@ -51,15 +52,20 @@ func (reader *DeploymentReader) HandleYaml() error { // Update entities with deployment settings func (reader *DeploymentReader) BindAssets() error { - reader.bindPackageInputsAndAnnotations() - reader.bindActionInputsAndAnnotations() - reader.bindTriggerInputsAndAnnotations() + if err := reader.bindPackageInputsAndAnnotations(); err != nil { + return err + } + if err := reader.bindActionInputsAndAnnotations(); err != nil { + return err + } + if err := reader.bindTriggerInputsAndAnnotations(); err != nil { + return err + } return nil - } -func (reader *DeploymentReader) bindPackageInputsAndAnnotations() { +func (reader *DeploymentReader) bindPackageInputsAndAnnotations() error { packMap := make(map[string]parsers.Package) @@ -121,25 +127,33 @@ func (reader *DeploymentReader) bindPackageInputsAndAnnotations() { serviceDeployPack.Package.Parameters = keyValArr } - keyValArr = make(whisk.KeyValueArr, 0) - if len(pack.Annotations) > 0 { + // iterate over each annotation from deployment file for name, input := range pack.Annotations { - var keyVal whisk.KeyValue - - keyVal.Key = name - keyVal.Value = utils.GetEnvVar(input) - - keyValArr = append(keyValArr, keyVal) + // check if annotation key in deployment file exists in manifest file + // setting a bool flag to false assuming key does not exist in manifest + keyExistsInManifest := false + // iterate over each annotation from manifest file + for i, a := range serviceDeployPack.Package.Annotations { + if name == a.Key { + // annotation key is found in manifest + keyExistsInManifest = true + // overwrite annotation in manifest file with deployment file + serviceDeployPack.Package.Annotations[i].Value = input + break + } + } + if !keyExistsInManifest { + err := wski18n.T("Annotation key \"" + name + "\" does not exist in manifest file but specified in deployment file.") + return utils.NewYAMLFormatError(err) + } } - - serviceDeployPack.Package.Annotations = keyValArr } - } + return nil } -func (reader *DeploymentReader) bindActionInputsAndAnnotations() { +func (reader *DeploymentReader) bindActionInputsAndAnnotations() error { packMap := make(map[string]parsers.Package) @@ -202,28 +216,34 @@ func (reader *DeploymentReader) bindActionInputsAndAnnotations() { } } - keyValArr = make(whisk.KeyValueArr, 0) - - if len(action.Annotations) > 0 { + if wskAction, exists := serviceDeployPack.Actions[actionName]; exists { + // iterate over each annotation from deployment file for name, input := range action.Annotations { - var keyVal whisk.KeyValue - - keyVal.Key = name - keyVal.Value = input - - keyValArr = append(keyValArr, keyVal) - } - - if wskAction, exists := serviceDeployPack.Actions[actionName]; exists { - wskAction.Action.Annotations = keyValArr + // check if annotation key in deployment file exists in manifest file + // setting a bool flag to false assuming key does not exist in manifest + keyExistsInManifest := false + // iterate over each annotation from manifest file + for i, a := range wskAction.Action.Annotations { + if name == a.Key { + // annotation key is found in manifest + keyExistsInManifest = true + // overwrite annotation in manifest file with deployment file + wskAction.Action.Annotations[i].Value = input + break + } + } + if !keyExistsInManifest { + err := wski18n.T("Annotation key \"" + name + "\" does not exist in manifest file but specified in deployment file.") + return utils.NewYAMLFormatError(err) + } } } } - } + return nil } -func (reader *DeploymentReader) bindTriggerInputsAndAnnotations() { +func (reader *DeploymentReader) bindTriggerInputsAndAnnotations() error { packMap := make(map[string]parsers.Package) @@ -282,23 +302,31 @@ func (reader *DeploymentReader) bindTriggerInputsAndAnnotations() { } } - keyValArr = make(whisk.KeyValueArr, 0) - - if len(trigger.Annotations) > 0 { + if wskTrigger, exists := serviceDeployment.Triggers[triggerName]; exists { + // iterate over each annotation from deployment file for name, input := range trigger.Annotations { - var keyVal whisk.KeyValue - - keyVal.Key = name - keyVal.Value = input - - keyValArr = append(keyValArr, keyVal) - } - - if wskTrigger, exists := serviceDeployment.Triggers[triggerName]; exists { - wskTrigger.Annotations = keyValArr + // check if annotation key in deployment file exists in manifest file + // setting a bool flag to false assuming key does not exist in manifest + keyExistsInManifest := false + // iterate over each annotation from manifest file + for i, a := range wskTrigger.Annotations { + if name == a.Key { + // annotation key is found in manifest + keyExistsInManifest = true + // overwrite annotation in manifest file with deployment file + wskTrigger.Annotations[i].Value = input + break + } + } + if !keyExistsInManifest { + err := wski18n.T("Annotation key \"" + name + "\" does not exist in manifest file but specified in deployment file.") + return utils.NewYAMLFormatError(err) + } } } + } } + return nil } diff --git a/deployers/deploymentreader_test.go b/deployers/deploymentreader_test.go index 53e326b..a4a518e 100644 --- a/deployers/deploymentreader_test.go +++ b/deployers/deploymentreader_test.go @@ -20,9 +20,10 @@ package deployers import ( + "github.com/apache/incubator-openwhisk-client-go/whisk" "github.com/stretchr/testify/assert" "testing" - "github.com/apache/incubator-openwhisk-client-go/whisk" + "reflect" ) var sd *ServiceDeployer @@ -87,70 +88,124 @@ func TestDeploymentReader_bindTrigger(t *testing.T) { } func TestDeploymentReader_bindTrigger_packages(t *testing.T) { - //init variables - sDeployer := NewServiceDeployer() - sDeployer.DeploymentPath = "../tests/dat/deployment-deploymentreader-test-packages.yml" - sDeployer.Deployment.Triggers["locationUpdate"] = new(whisk.Trigger) - - //parse deployment and bind triggers input and annotation - dReader := NewDeploymentReader(sDeployer) - dReader.HandleYaml() - dReader.bindTriggerInputsAndAnnotations() - - trigger := sDeployer.Deployment.Triggers["locationUpdate"] - for _, param := range trigger.Parameters { - switch param.Key { - case "name": - assert.Equal(t, "Bernie", param.Value, "Failed to set inputs") - case "place": - assert.Equal(t, "DC", param.Value, "Failed to set inputs") - default: - assert.Fail(t, "Failed to get inputs key") - - } - } - for _, annos := range trigger.Annotations { - switch annos.Key { - case "bbb": - assert.Equal(t, "this is an annotation", annos.Value, "Failed to set annotations") - default: - assert.Fail(t, "Failed to get annotation key") - - } - } + //init variables + sDeployer := NewServiceDeployer() + sDeployer.DeploymentPath = "../tests/dat/deployment-deploymentreader-test-packages.yml" + sDeployer.Deployment.Triggers["locationUpdate"] = new(whisk.Trigger) + + //parse deployment and bind triggers input and annotation + dReader := NewDeploymentReader(sDeployer) + dReader.HandleYaml() + dReader.bindTriggerInputsAndAnnotations() + + trigger := sDeployer.Deployment.Triggers["locationUpdate"] + for _, param := range trigger.Parameters { + switch param.Key { + case "name": + assert.Equal(t, "Bernie", param.Value, "Failed to set inputs") + case "place": + assert.Equal(t, "DC", param.Value, "Failed to set inputs") + default: + assert.Fail(t, "Failed to get inputs key") + + } + } + for _, annos := range trigger.Annotations { + switch annos.Key { + case "bbb": + assert.Equal(t, "this is an annotation", annos.Value, "Failed to set annotations") + default: + assert.Fail(t, "Failed to get annotation key") + + } + } } func TestDeploymentReader_bindTrigger_package(t *testing.T) { - //init variables - sDeployer := NewServiceDeployer() - sDeployer.DeploymentPath = "../tests/dat/deployment-deploymentreader-test-package.yml" - sDeployer.Deployment.Triggers["locationUpdate"] = new(whisk.Trigger) - - //parse deployment and bind triggers input and annotation - dReader := NewDeploymentReader(sDeployer) - dReader.HandleYaml() - dReader.bindTriggerInputsAndAnnotations() - - assert.Equal(t, "triggerrule", dReader.DeploymentDescriptor.Package.Packagename) - trigger := sDeployer.Deployment.Triggers["locationUpdate"] - for _, param := range trigger.Parameters { - switch param.Key { - case "name": - assert.Equal(t, "Bernie", param.Value, "Failed to set inputs") - case "place": - assert.Equal(t, "DC", param.Value, "Failed to set inputs") - default: - assert.Fail(t, "Failed to get inputs key") - - } - } - for _, annos := range trigger.Annotations { - switch annos.Key { - case "bbb": - assert.Equal(t, "this is an annotation", annos.Value, "Failed to set annotations") - default: - assert.Fail(t, "Failed to get annotation key") - - } - } + //init variables + sDeployer := NewServiceDeployer() + sDeployer.DeploymentPath = "../tests/dat/deployment-deploymentreader-test-package.yml" + sDeployer.Deployment.Triggers["locationUpdate"] = new(whisk.Trigger) + + //parse deployment and bind triggers input and annotation + dReader := NewDeploymentReader(sDeployer) + dReader.HandleYaml() + dReader.bindTriggerInputsAndAnnotations() + + assert.Equal(t, "triggerrule", dReader.DeploymentDescriptor.Package.Packagename) + trigger := sDeployer.Deployment.Triggers["locationUpdate"] + for _, param := range trigger.Parameters { + switch param.Key { + case "name": + assert.Equal(t, "Bernie", param.Value, "Failed to set inputs") + case "place": + assert.Equal(t, "DC", param.Value, "Failed to set inputs") + default: + assert.Fail(t, "Failed to get inputs key") + + } + } + for _, annos := range trigger.Annotations { + switch annos.Key { + case "bbb": + assert.Equal(t, "this is an annotation", annos.Value, "Failed to set annotations") + default: + assert.Fail(t, "Failed to get annotation key") + + } + } +} + +func TestDeploymentReader_BindAssets_ActionAnnotations(t *testing.T) { + sDeployer := NewServiceDeployer() + sDeployer.DeploymentPath = "../tests/dat/deployment_validate_action_annotations.yaml" + sDeployer.ManifestPath = "../tests/dat/manifest_validate_action_annotations.yaml" + + //parse deployment and bind triggers input and annotation + dReader := NewDeploymentReader(sDeployer) + dReader.HandleYaml() + err := dReader.bindActionInputsAndAnnotations() + + assert.Nil(t, err, "Failed to bind action annotations") + + pkg_name := "packageActionAnnotations" + pkg := dReader.DeploymentDescriptor.Packages[pkg_name] + assert.NotNil(t, pkg, "Could not find package with name " + pkg_name) + action_name := "helloworld" + action := dReader.DeploymentDescriptor.GetProject().Packages[pkg_name].Actions[action_name] + assert.NotNil(t, action, "Could not find action with name " + action_name) + actual_annotations := action.Annotations + expected_annotations := map[string]interface{}{ + "action_annotation_1": "this is annotation 1", + "action_annotation_2": "this is annotation 2", + } + assert.Equal(t, len(actual_annotations), len(expected_annotations), "Could not find expected number of annotations specified in manifest file") + eq := reflect.DeepEqual(actual_annotations, expected_annotations) + assert.True(t, eq, "Expected list of annotations does not match with actual list, expected annotations: %v actual annotations: %v", expected_annotations, actual_annotations) + + pkg_name = "packageActionAnnotationsWithWebAction" + pkg = dReader.DeploymentDescriptor.Packages[pkg_name] + assert.NotNil(t, pkg, "Could not find package with name " + pkg_name) + action = dReader.DeploymentDescriptor.GetProject().Packages[pkg_name].Actions[action_name] + assert.NotNil(t, action, "Could not find action with name " + action_name) + actual_annotations = action.Annotations + expected_annotations["web-export"] = true + assert.Equal(t, len(actual_annotations), len(expected_annotations), "Could not find expected number of annotations specified in manifest file") + eq = reflect.DeepEqual(actual_annotations, expected_annotations) + assert.True(t, eq, "Expected list of annotations does not match with actual list, expected annotations: %v actual annotations: %v", expected_annotations, actual_annotations) + + pkg_name = "packageActionAnnotationsFromDeployment" + pkg = dReader.DeploymentDescriptor.Packages[pkg_name] + assert.NotNil(t, pkg, "Could not find package with name " + pkg_name) + action = dReader.DeploymentDescriptor.GetProject().Packages[pkg_name].Actions[action_name] + assert.NotNil(t, action, "Could not find action with name " + action_name) + actual_annotations = action.Annotations + expected_annotations = map[string]interface{}{ + "action_annotation_1": "this is annotation 1 from deployment", + "action_annotation_2": "this is annotation 2 from deployment", + } + assert.Equal(t, len(actual_annotations), len(expected_annotations), "Could not find expected number of annotations specified in manifest file") + eq = reflect.DeepEqual(actual_annotations, expected_annotations) + assert.True(t, eq, "Expected list of annotations does not match with actual list, expected annotations: %v actual annotations: %v", expected_annotations, actual_annotations) } + diff --git a/deployers/servicedeployer.go b/deployers/servicedeployer.go index 15ce427..57b1c64 100644 --- a/deployers/servicedeployer.go +++ b/deployers/servicedeployer.go @@ -175,7 +175,9 @@ func (deployer *ServiceDeployer) ConstructDeploymentPlan() error { return utils.NewYAMLFormatError(errorString) } } - deploymentReader.BindAssets() + if err := deploymentReader.BindAssets(); err != nil { + return err + } } return err @@ -250,7 +252,9 @@ func (deployer *ServiceDeployer) ConstructUnDeploymentPlan() (*DeploymentProject } } - deploymentReader.BindAssets() + if err := deploymentReader.BindAssets(); err != nil { + return deployer.Deployment, err + } } verifiedPlan := deployer.Deployment diff --git a/parsers/manifest_parser.go b/parsers/manifest_parser.go index 771b4f7..7028831 100644 --- a/parsers/manifest_parser.go +++ b/parsers/manifest_parser.go @@ -277,6 +277,19 @@ func (dm *YAMLParser) ComposePackage(pkg Package, packageName string, filePath s if len(keyValArr) > 0 { pag.Parameters = keyValArr } + + // set Package Annotations + listOfAnnotations := make(whisk.KeyValueArr, 0) + for name, value := range pkg.Annotations { + var keyVal whisk.KeyValue + keyVal.Key = name + keyVal.Value = utils.GetEnvVar(value) + listOfAnnotations = append(listOfAnnotations, keyVal) + } + if len(listOfAnnotations) > 0 { + pag.Annotations = append(pag.Annotations, listOfAnnotations...) + } + return pag, nil } @@ -523,24 +536,22 @@ func (dm *YAMLParser) ComposeActions(filePath string, actions map[string]Action, /* * Action.Annotations */ - keyValArr = make(whisk.KeyValueArr, 0) + listOfAnnotations := make(whisk.KeyValueArr, 0) for name, value := range action.Annotations { var keyVal whisk.KeyValue keyVal.Key = name keyVal.Value = utils.GetEnvVar(value) - keyValArr = append(keyValArr, keyVal) - // TODO{} Fix Annottions; they are not added to Action if web-export key is not present - // Need to assure annotations are added/set even if web-export is not set on the action. + listOfAnnotations = append(listOfAnnotations, keyVal) + } + if len(listOfAnnotations) > 0 { + wskaction.Annotations = append(wskaction.Annotations, listOfAnnotations...) } /* * Web Export */ - // only set the webaction when the annotations are not empty. if action.Webexport == "true" { - // TODO() why is this commented out? we should now support annotations... - //wskaction.Annotations = keyValArr - wskaction.Annotations, errorParser = utils.WebAction("yes", keyValArr, action.Name, false) + wskaction.Annotations, errorParser = utils.WebAction("yes", listOfAnnotations, false) if errorParser != nil { return s1, errorParser } @@ -668,6 +679,17 @@ func (dm *YAMLParser) ComposeTriggers(filePath string, pkg Package) ([]*whisk.Tr wsktrigger.Parameters = keyValArr } + listOfAnnotations := make(whisk.KeyValueArr, 0) + for name, value := range trigger.Annotations { + var keyVal whisk.KeyValue + keyVal.Key = name + keyVal.Value = utils.GetEnvVar(value) + listOfAnnotations = append(listOfAnnotations, keyVal) + } + if len(listOfAnnotations) > 0 { + wsktrigger.Annotations = append(wsktrigger.Annotations, listOfAnnotations...) + } + t1 = append(t1, wsktrigger) } return t1, nil diff --git a/parsers/manifest_parser_test.go b/parsers/manifest_parser_test.go index 3037a6f..19ebc07 100644 --- a/parsers/manifest_parser_test.go +++ b/parsers/manifest_parser_test.go @@ -1595,3 +1595,37 @@ func TestPackageName_Env_Var(t *testing.T) { assert.Equal(t, "Apache-2.0", pkg.License, "Get the wrong license.") } } + +func TestComposeActionForAnnotations(t *testing.T) { + manifestFile := "../tests/dat/manifest_validate_action_annotations.yaml" + mm := NewYAMLParser() + manifest, _ := mm.ParseManifest(manifestFile) + pkg_name := "packageActionAnnotations" + pkg := manifest.Packages[pkg_name] + assert.NotNil(t, pkg, "Could not find package with name " + pkg_name) + action_name := "helloworld" + action := pkg.Actions[action_name] + assert.NotNil(t, action, "Could not find action with name " + action_name) + actual_annotations := action.Annotations + expected_annotations := map[string]interface{} { + "action_annotation_1": "this is annotation 1", + "action_annotation_2": "this is annotation 2", + "action_annotation_3": "this is annotation 3", + "action_annotation_4": "this is annotation 4", + } + assert.Equal(t, len(actual_annotations), len(expected_annotations), "Could not find expected number of annotations specified in manifest file") + eq := reflect.DeepEqual(actual_annotations, expected_annotations) + assert.True(t, eq, "Expected list of annotations does not match with actual list, expected annotations: %v actual annotations: %v", expected_annotations, actual_annotations) + + pkg_name = "packageActionAnnotationsWithWebAction" + pkg = manifest.Packages[pkg_name] + assert.NotNil(t, pkg, "Could not find package with name " + pkg_name) + action = pkg.Actions[action_name] + assert.NotNil(t, action, "Could not find action with name " + action_name) + actual_annotations = action.Annotations + expected_annotations["web-export"] = true + assert.Equal(t, len(actual_annotations), len(expected_annotations), "Could not find expected number of annotations specified in manifest file") + eq = reflect.DeepEqual(actual_annotations, expected_annotations) + assert.True(t, eq, "Expected list of annotations does not match with actual list, expected annotations: %v actual annotations: %v", expected_annotations, actual_annotations) +} + diff --git a/tests/dat/deployment_validate_action_annotations.yaml b/tests/dat/deployment_validate_action_annotations.yaml new file mode 100644 index 0000000..a76e48f --- /dev/null +++ b/tests/dat/deployment_validate_action_annotations.yaml @@ -0,0 +1,31 @@ +project: + name: TestActionAnnotations + packages: + packageActionAnnotations: + actions: + helloworld: + inputs: + name: Amy + place: New York + annotations: + action_annotation_1: this is annotation 1 + action_annotation_2: this is annotation 2 + packageActionAnnotationsFromDeployment: + actions: + helloworld: + inputs: + name: Amy + place: New York + annotations: + action_annotation_1: this is annotation 1 from deployment + action_annotation_2: this is annotation 2 from deployment + packageActionAnnotationsWithWebAction: + actions: + helloworld: + inputs: + name: Amy + place: New York + annotations: + action_annotation_1: this is annotation 1 + action_annotation_2: this is annotation 2 + web-export: true diff --git a/tests/dat/manifest_validate_action_annotations.yaml b/tests/dat/manifest_validate_action_annotations.yaml new file mode 100644 index 0000000..030fb6a --- /dev/null +++ b/tests/dat/manifest_validate_action_annotations.yaml @@ -0,0 +1,65 @@ +packages: + packageActionAnnotations: + actions: + helloworld: + function: actions/hello.js + runtime: nodejs:6 + inputs: + name: + type: string + description: name of a person + place: + type: string + description: location of a person + outputs: + payload: + type: string + description: a simple greeting message, Hello World! + annotations: + action_annotation_1: this is annotation 1 + action_annotation_2: this is annotation 2 + action_annotation_3: this is annotation 3 + action_annotation_4: this is annotation 4 + packageActionAnnotationsFromDeployment: + actions: + helloworld: + function: actions/hello.js + runtime: nodejs:6 + inputs: + name: + type: string + description: name of a person + place: + type: string + description: location of a person + outputs: + payload: + type: string + description: a simple greeting message, Hello World! + annotations: + action_annotation_1: this is annotation 1 + action_annotation_2: this is annotation 2 + action_annotation_3: this is annotation 3 + action_annotation_4: this is annotation 4 + packageActionAnnotationsWithWebAction: + actions: + helloworld: + function: actions/hello.js + runtime: nodejs:6 + inputs: + name: + type: string + description: name of a person + place: + type: string + description: location of a person + outputs: + payload: + type: string + description: a simple greeting message, Hello World! + annotations: + action_annotation_1: this is annotation 1 + action_annotation_2: this is annotation 2 + action_annotation_3: this is annotation 3 + action_annotation_4: this is annotation 4 + web-export: true diff --git a/tests/src/integration/validate-action-annotations/actions/hello.js b/tests/src/integration/validate-action-annotations/actions/hello.js new file mode 100644 index 0000000..25fdafb --- /dev/null +++ b/tests/src/integration/validate-action-annotations/actions/hello.js @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Return a simple greeting message for the whole world. + */ +function main(params) { + msg = "Hello, " + params.name + " from " + params.place; + console.log(msg) + return { payload: msg }; +} + diff --git a/tests/src/integration/validate-action-annotations/deployment-with-invalid-annotations.yaml b/tests/src/integration/validate-action-annotations/deployment-with-invalid-annotations.yaml new file mode 100644 index 0000000..b551e8f --- /dev/null +++ b/tests/src/integration/validate-action-annotations/deployment-with-invalid-annotations.yaml @@ -0,0 +1,22 @@ +project: + name: TestActionAnnotations + packages: + packageActionAnnotations: + actions: + helloworld: + inputs: + name: Amy + place: New York + annotations: + action_annotation_5: this is annotation 5 + action_annotation_6: this is annotation 6 + packageActionAnnotationsWithWebAction: + actions: + helloworld: + inputs: + name: Amy + place: New York + annotations: + action_annotation_5: this is annotation 5 + action_annotation_6: this is annotation 6 + web-export: true diff --git a/tests/src/integration/validate-action-annotations/deployment.yaml b/tests/src/integration/validate-action-annotations/deployment.yaml new file mode 100644 index 0000000..a76e48f --- /dev/null +++ b/tests/src/integration/validate-action-annotations/deployment.yaml @@ -0,0 +1,31 @@ +project: + name: TestActionAnnotations + packages: + packageActionAnnotations: + actions: + helloworld: + inputs: + name: Amy + place: New York + annotations: + action_annotation_1: this is annotation 1 + action_annotation_2: this is annotation 2 + packageActionAnnotationsFromDeployment: + actions: + helloworld: + inputs: + name: Amy + place: New York + annotations: + action_annotation_1: this is annotation 1 from deployment + action_annotation_2: this is annotation 2 from deployment + packageActionAnnotationsWithWebAction: + actions: + helloworld: + inputs: + name: Amy + place: New York + annotations: + action_annotation_1: this is annotation 1 + action_annotation_2: this is annotation 2 + web-export: true diff --git a/tests/src/integration/validate-action-annotations/manifest.yaml b/tests/src/integration/validate-action-annotations/manifest.yaml new file mode 100644 index 0000000..030fb6a --- /dev/null +++ b/tests/src/integration/validate-action-annotations/manifest.yaml @@ -0,0 +1,65 @@ +packages: + packageActionAnnotations: + actions: + helloworld: + function: actions/hello.js + runtime: nodejs:6 + inputs: + name: + type: string + description: name of a person + place: + type: string + description: location of a person + outputs: + payload: + type: string + description: a simple greeting message, Hello World! + annotations: + action_annotation_1: this is annotation 1 + action_annotation_2: this is annotation 2 + action_annotation_3: this is annotation 3 + action_annotation_4: this is annotation 4 + packageActionAnnotationsFromDeployment: + actions: + helloworld: + function: actions/hello.js + runtime: nodejs:6 + inputs: + name: + type: string + description: name of a person + place: + type: string + description: location of a person + outputs: + payload: + type: string + description: a simple greeting message, Hello World! + annotations: + action_annotation_1: this is annotation 1 + action_annotation_2: this is annotation 2 + action_annotation_3: this is annotation 3 + action_annotation_4: this is annotation 4 + packageActionAnnotationsWithWebAction: + actions: + helloworld: + function: actions/hello.js + runtime: nodejs:6 + inputs: + name: + type: string + description: name of a person + place: + type: string + description: location of a person + outputs: + payload: + type: string + description: a simple greeting message, Hello World! + annotations: + action_annotation_1: this is annotation 1 + action_annotation_2: this is annotation 2 + action_annotation_3: this is annotation 3 + action_annotation_4: this is annotation 4 + web-export: true diff --git a/tests/src/integration/validate-action-annotations/validate-action-annotations_test.go b/tests/src/integration/validate-action-annotations/validate-action-annotations_test.go new file mode 100644 index 0000000..f48aa29 --- /dev/null +++ b/tests/src/integration/validate-action-annotations/validate-action-annotations_test.go @@ -0,0 +1,48 @@ +// +build integration + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package tests + +import ( + "github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/common" + "github.com/stretchr/testify/assert" + "os" + "testing" +) + +var path = "/src/github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/validate-action-annotations/" + +func TestActionAnnotations(t *testing.T) { + manifestPath := os.Getenv("GOPATH") + path + "manifest.yaml" + deploymentPath := os.Getenv("GOPATH") + path + "deployment.yaml" + wskdeploy := common.NewWskdeploy() + _, err := wskdeploy.Deploy(manifestPath, deploymentPath) + assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") + _, err = wskdeploy.Undeploy(manifestPath, deploymentPath) + assert.Equal(t, nil, err, "Failed to undeploy based on the manifest and deployment files.") +} + +func TestInvalidActionAnnotations(t *testing.T) { + manifestPath := os.Getenv("GOPATH") + path + "manifest.yaml" + deploymentPath := os.Getenv("GOPATH") + path + "deployment-with-invalid-annotations.yaml" + wskdeploy := common.NewWskdeploy() + _, err := wskdeploy.Deploy(manifestPath, deploymentPath) + assert.NotNil(t, err, "Failed to validate invalid annotations in deployment file") +} + diff --git a/tests/src/integration/validate-binding-inputs-annotations/deployment.yaml b/tests/src/integration/validate-binding-inputs-annotations/deployment.yaml index ec0526d..bf51b00 100644 --- a/tests/src/integration/validate-binding-inputs-annotations/deployment.yaml +++ b/tests/src/integration/validate-binding-inputs-annotations/deployment.yaml @@ -1,27 +1,28 @@ project: - name: BindingTest - packages: - packagebinding: - inputs: - name: daisy - city: Beijing - annotations: - tag: hello - aaa: this is an annotation - actions: - helloworld: - inputs: - name: Amy - place: Paris - annotations: - tag: hello - aaa: this is an annotation - triggers: - dbtrigger: - inputs: - dbname: cats - docid: 1234567 - annotations: - tag: hello - aaa: this is an annotation - + name: BindingTest + packages: + packagebinding: + inputs: + name: daisy + city: Beijing + actions: + helloworld: + inputs: + name: Amy + place: Paris + triggers: + dbtrigger: + inputs: + dbname: cats + docid: 1234567 + packageBindingFromDeployment: + annotations: + package_annotation_1: this is a package annotation 1 from deployment + actions: + helloworld: + annotations: + action_annotation_1: this is an action annotation 1 from deployment + triggers: + dbtrigger1: + annotations: + trigger_annotation_1: this is a trigger annotation 1 from deployment diff --git a/tests/src/integration/validate-binding-inputs-annotations/manifest.yaml b/tests/src/integration/validate-binding-inputs-annotations/manifest.yaml index 5ecc86f..f2a6b6e 100644 --- a/tests/src/integration/validate-binding-inputs-annotations/manifest.yaml +++ b/tests/src/integration/validate-binding-inputs-annotations/manifest.yaml @@ -1,5 +1,8 @@ packages: packagebinding: + annotations: + package_annotation_1: this is a package annotation 1 + package_annotation_2: this is a package annotation 2 actions: helloworld: function: actions/helloworld.js @@ -15,6 +18,9 @@ packages: payload: type: string description: a simple greeting message, Hello World! + annotations: + action_annotation_1: this is an action annotation 1 + action_annotation_2: this is an action annotation 2 triggers: dbtrigger: inputs: @@ -24,4 +30,23 @@ packages: docid: type: string description: doc ID + annotations: + trigger_annotation_1: this is a trigger annotation 1 + trigger_annotation_2: this is a trigger annotation 2 + packageBindingFromDeployment: + annotations: + package_annotation_1: this is a package annotation 1 + package_annotation_2: this is a package annotation 2 + actions: + helloworld: + function: actions/helloworld.js + runtime: nodejs:6 + annotations: + action_annotation_1: this is an action annotation 1 + action_annotation_2: this is an action annotation 2 + triggers: + dbtrigger1: + annotations: + trigger_annotation_1: this is a trigger annotation 1 + trigger_annotation_2: this is a trigger annotation 2 diff --git a/tests/src/integration/validate-binding-inputs-annotations/validate-bind-inputs-anno_test.go b/tests/src/integration/validate-binding-inputs-annotations/validate-bind-inputs-anno_test.go index 40184fd..8e0d159 100644 --- a/tests/src/integration/validate-binding-inputs-annotations/validate-bind-inputs-anno_test.go +++ b/tests/src/integration/validate-binding-inputs-annotations/validate-bind-inputs-anno_test.go @@ -26,7 +26,13 @@ import ( "testing" ) +var PATH = "/src/github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/validate-binding-inputs-annotations/" + func TestBindingInputsAnnotations(t *testing.T) { + + manifestPath := os.Getenv("GOPATH") + PATH + "manifest.yaml" + deploymentPath := os.Getenv("GOPATH") + PATH + "deployment.yaml" + wskdeploy := common.NewWskdeploy() // verify the inputs & annotations are set deploymentObjects, err := wskdeploy.GetDeploymentObjects(manifestPath, deploymentPath) @@ -47,10 +53,10 @@ func TestBindingInputsAnnotations(t *testing.T) { } for _, annos := range wskpkg.Annotations { switch annos.Key { - case "tag": - assert.Equal(t, "hello", annos.Value, "Failed to get package annotations") - case "aaa": - assert.Equal(t, "this is an annotation", annos.Value, "Failed to get package annotations") + case "package_annotation_1": + assert.Equal(t, "this is a package annotation 1", annos.Value, "Failed to get package annotations") + case "package_annotation_2": + assert.Equal(t, "this is a package annotation 2", annos.Value, "Failed to get package annotations") default: assert.Fail(t, "Failed to get package annotation key") } @@ -70,10 +76,10 @@ func TestBindingInputsAnnotations(t *testing.T) { } for _, annos := range wskaction.Annotations { switch annos.Key { - case "tag": - assert.Equal(t, "hello", annos.Value, "Failed to get action annotations") - case "aaa": - assert.Equal(t, "this is an annotation", annos.Value, "Failed to get action annotations") + case "action_annotation_1": + assert.Equal(t, "this is an action annotation 1", annos.Value, "Failed to get action annotations") + case "action_annotation_2": + assert.Equal(t, "this is an action annotation 2", annos.Value, "Failed to get action annotations") default: assert.Fail(t, "Failed to get action annotation key") } @@ -93,15 +99,54 @@ func TestBindingInputsAnnotations(t *testing.T) { } for _, annos := range wsktrigger.Annotations { switch annos.Key { - case "tag": - assert.Equal(t, "hello", annos.Value, "Failed to get trigger annotations") - case "aaa": - assert.Equal(t, "this is an annotation", annos.Value, "Failed to get trigger annotations") + case "trigger_annotation_1": + assert.Equal(t, "this is a trigger annotation 1", annos.Value, "Failed to get action annotations") + case "trigger_annotation_2": + assert.Equal(t, "this is a trigger annotation 2", annos.Value, "Failed to get action annotations") default: assert.Fail(t, "Failed to get annotation key") } } + // verify the annotations of a package + pkgobj = deploymentObjects.Packages["packageBindingFromDeployment"] + wskpkg = pkgobj.Package + for _, annos := range wskpkg.Annotations { + switch annos.Key { + case "package_annotation_1": + assert.Equal(t, "this is a package annotation 1 from deployment", annos.Value, "Failed to get package annotations") + case "package_annotation_2": + assert.Equal(t, "this is a package annotation 2", annos.Value, "Failed to get package annotations") + default: + assert.Fail(t, "Failed to get package annotation key") + } + } + // verify the annotations of action + wskaction = pkgobj.Actions["helloworld"].Action + for _, annos := range wskaction.Annotations { + switch annos.Key { + case "action_annotation_1": + assert.Equal(t, "this is an action annotation 1 from deployment", annos.Value, "Failed to get action annotations") + case "action_annotation_2": + assert.Equal(t, "this is an action annotation 2", annos.Value, "Failed to get action annotations") + default: + assert.Fail(t, "Failed to get action annotation key") + } + } + // verify the inputs & annotations of trigger + wsktrigger = deploymentObjects.Triggers["dbtrigger1"] + for _, annos := range wsktrigger.Annotations { + switch annos.Key { + case "trigger_annotation_1": + assert.Equal(t, "this is a trigger annotation 1 from deployment", annos.Value, "Failed to get action annotations") + case "trigger_annotation_2": + assert.Equal(t, "this is a trigger annotation 2", annos.Value, "Failed to get action annotations") + default: + assert.Fail(t, "Failed to get annotation key") + } + } + + // testing deploy and undeploy _, err = wskdeploy.Deploy(manifestPath, deploymentPath) assert.NoError(t, err, "Failed to deploy based on the manifest and deployment files.") @@ -109,7 +154,3 @@ func TestBindingInputsAnnotations(t *testing.T) { assert.NoError(t, err, "Failed to undeploy based on the manifest and deployment files.") } -var ( - manifestPath = os.Getenv("GOPATH") + "/src/github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/validate-binding-inputs-annotations/manifest.yaml" - deploymentPath = os.Getenv("GOPATH") + "/src/github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/validate-binding-inputs-annotations/deployment.yaml" -) diff --git a/utils/misc.go b/utils/misc.go index b37b059..b9d862e 100644 --- a/utils/misc.go +++ b/utils/misc.go @@ -331,77 +331,6 @@ func javaEntryError() error { return errors.New(errMsg) } -//for web action support, code from wsk cli with tiny adjustments -const WEB_EXPORT_ANNOT = "web-export" -const RAW_HTTP_ANNOT = "raw-http" -const FINAL_ANNOT = "final" - -func WebAction(webMode string, annotations whisk.KeyValueArr, entityName string, fetch bool) (whisk.KeyValueArr, error) { - switch strings.ToLower(webMode) { - case "yes": - fallthrough - case "true": - return webActionAnnotations(fetch, annotations, entityName, addWebAnnotations) - case "no": - fallthrough - case "false": - return webActionAnnotations(fetch, annotations, entityName, deleteWebAnnotations) - case "raw": - return webActionAnnotations(fetch, annotations, entityName, addRawAnnotations) - default: - return nil, errors.New(webMode) - } -} - -type WebActionAnnotationMethod func(annotations whisk.KeyValueArr) whisk.KeyValueArr - -func webActionAnnotations( - fetchAnnotations bool, - annotations whisk.KeyValueArr, - entityName string, - webActionAnnotationMethod WebActionAnnotationMethod) (whisk.KeyValueArr, error) { - if annotations != nil || !fetchAnnotations { - annotations = webActionAnnotationMethod(annotations) - } - - return annotations, nil -} - -func addWebAnnotations(annotations whisk.KeyValueArr) whisk.KeyValueArr { - annotations = deleteWebAnnotationKeys(annotations) - annotations = addKeyValue(WEB_EXPORT_ANNOT, true, annotations) - annotations = addKeyValue(RAW_HTTP_ANNOT, false, annotations) - annotations = addKeyValue(FINAL_ANNOT, true, annotations) - - return annotations -} - -func deleteWebAnnotations(annotations whisk.KeyValueArr) whisk.KeyValueArr { - annotations = deleteWebAnnotationKeys(annotations) - annotations = addKeyValue(WEB_EXPORT_ANNOT, false, annotations) - annotations = addKeyValue(RAW_HTTP_ANNOT, false, annotations) - annotations = addKeyValue(FINAL_ANNOT, false, annotations) - - return annotations -} - -func addRawAnnotations(annotations whisk.KeyValueArr) whisk.KeyValueArr { - annotations = deleteWebAnnotationKeys(annotations) - annotations = addKeyValue(WEB_EXPORT_ANNOT, true, annotations) - annotations = addKeyValue(RAW_HTTP_ANNOT, true, annotations) - annotations = addKeyValue(FINAL_ANNOT, true, annotations) - - return annotations -} - -func deleteWebAnnotationKeys(annotations whisk.KeyValueArr) whisk.KeyValueArr { - annotations = deleteKey(WEB_EXPORT_ANNOT, annotations) - annotations = deleteKey(RAW_HTTP_ANNOT, annotations) - annotations = deleteKey(FINAL_ANNOT, annotations) - - return annotations -} - func deleteKey(key string, keyValueArr whisk.KeyValueArr) whisk.KeyValueArr { for i := 0; i < len(keyValueArr); i++ { if keyValueArr[i].Key == key { diff --git a/utils/webaction.go b/utils/webaction.go new file mode 100644 index 0000000..f9f6e4e --- /dev/null +++ b/utils/webaction.go @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package utils + +import ( + "errors" + "github.com/apache/incubator-openwhisk-client-go/whisk" + "strings" +) + +//for web action support, code from wsk cli with tiny adjustments +const WEB_EXPORT_ANNOT = "web-export" +const RAW_HTTP_ANNOT = "raw-http" +const FINAL_ANNOT = "final" + +func WebAction(webMode string, annotations whisk.KeyValueArr, fetch bool) (whisk.KeyValueArr, error) { + switch strings.ToLower(webMode) { + case "yes": + fallthrough + case "true": + return webActionAnnotations(fetch, annotations, addWebAnnotations) + case "no": + fallthrough + case "false": + return webActionAnnotations(fetch, annotations, deleteWebAnnotations) + case "raw": + return webActionAnnotations(fetch, annotations, addRawAnnotations) + default: + return nil, errors.New(webMode) + } +} + +type WebActionAnnotationMethod func(annotations whisk.KeyValueArr) whisk.KeyValueArr + +func webActionAnnotations( + fetchAnnotations bool, + annotations whisk.KeyValueArr, + webActionAnnotationMethod WebActionAnnotationMethod) (whisk.KeyValueArr, error) { + if annotations != nil || !fetchAnnotations { + annotations = webActionAnnotationMethod(annotations) + } + + return annotations, nil +} + +func addWebAnnotations(annotations whisk.KeyValueArr) whisk.KeyValueArr { + annotations = deleteWebAnnotationKeys(annotations) + annotations = addKeyValue(WEB_EXPORT_ANNOT, true, annotations) + annotations = addKeyValue(RAW_HTTP_ANNOT, false, annotations) + annotations = addKeyValue(FINAL_ANNOT, true, annotations) + + return annotations +} + +func deleteWebAnnotations(annotations whisk.KeyValueArr) whisk.KeyValueArr { + annotations = deleteWebAnnotationKeys(annotations) + annotations = addKeyValue(WEB_EXPORT_ANNOT, false, annotations) + annotations = addKeyValue(RAW_HTTP_ANNOT, false, annotations) + annotations = addKeyValue(FINAL_ANNOT, false, annotations) + + return annotations +} + +func addRawAnnotations(annotations whisk.KeyValueArr) whisk.KeyValueArr { + annotations = deleteWebAnnotationKeys(annotations) + annotations = addKeyValue(WEB_EXPORT_ANNOT, true, annotations) + annotations = addKeyValue(RAW_HTTP_ANNOT, true, annotations) + annotations = addKeyValue(FINAL_ANNOT, true, annotations) + + return annotations +} + +func deleteWebAnnotationKeys(annotations whisk.KeyValueArr) whisk.KeyValueArr { + annotations = deleteKey(WEB_EXPORT_ANNOT, annotations) + annotations = deleteKey(RAW_HTTP_ANNOT, annotations) + annotations = deleteKey(FINAL_ANNOT, annotations) + + return annotations +} -- To stop receiving notification emails like this one, please contact ['"commits@openwhisk.apache.org" '].