This is an automated email from the ASF dual-hosted git repository. pdesai pushed a commit to branch whisk-system-utils in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-wskdeploy.git
commit 52a1167f6bd87023d3b9f37e9f41e2eb5b9e06f3 Author: Priti Desai <[email protected]> AuthorDate: Thu Apr 19 14:05:05 2018 -0700 adding annotation parsing/encoding --- parsers/annotations.go | 75 +++++++++++++++++++ parsers/manifest_parser.go | 27 +------ parsers/manifest_parser_test.go | 83 ++++++++++++++++++++++ ...ifest_data_compose_actions_for_annotations.yaml | 39 ++++++++++ 4 files changed, 198 insertions(+), 26 deletions(-) diff --git a/parsers/annotations.go b/parsers/annotations.go new file mode 100644 index 0000000..16dc220 --- /dev/null +++ b/parsers/annotations.go @@ -0,0 +1,75 @@ +/* + * 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 parsers + +import ( + "fmt" + "reflect" +) + +func encodeBoolAnnotations(annotation interface{}) interface{} { + return annotation.(bool) +} + +func encodeIntAnnotations(annotation interface{}) interface{} { + return annotation.(int) +} + +func encodeFloatAnnotations(annotation interface{}) interface{} { + return annotation.(float64) +} + +func encodeListAnnotations(annotation interface{}) interface{} { + list := make([]interface{}, 0) + annotationList := annotation.([]interface{}) + for _, s := range annotationList { + l := EncodeAnnotations(s) + list = append(list, l) + } + return list +} + +func encodeMapAnnotations(annotation interface{}) interface{} { + mapValue := make(map[string]interface{}) + for k, v := range annotation.(map[interface{}]interface{}) { + key := fmt.Sprintf("%v", k) + value := EncodeAnnotations(v) + mapValue[key] = value + } + return mapValue +} + +func EncodeAnnotations(annotation interface{}) interface{} { + var annotationValue interface{} + if reflect.ValueOf(annotation).Kind() == reflect.Bool { + annotationValue = encodeBoolAnnotations(annotation) + } else if reflect.ValueOf(annotation).Kind() == reflect.Int { + annotationValue = encodeIntAnnotations(annotation) + } else if reflect.ValueOf(annotation).Kind() == reflect.Float32 { + annotationValue = encodeFloatAnnotations(annotation) + } else if reflect.ValueOf(annotation).Kind() == reflect.Float64 { + annotationValue = encodeFloatAnnotations(annotation) + } else if reflect.ValueOf(annotation).Kind() == reflect.Slice { + annotationValue = encodeListAnnotations(annotation) + } else if reflect.ValueOf(annotation).Kind() == reflect.Map { + annotationValue = encodeMapAnnotations(annotation) + } else { + annotationValue = fmt.Sprintf("%v", annotation) + } + return annotationValue +} diff --git a/parsers/manifest_parser.go b/parsers/manifest_parser.go index a3375ad..5c50730 100644 --- a/parsers/manifest_parser.go +++ b/parsers/manifest_parser.go @@ -20,13 +20,11 @@ package parsers import ( "encoding/base64" "errors" - "fmt" "gopkg.in/yaml.v2" "io/ioutil" "os" "path" "path/filepath" - "reflect" "strings" "github.com/apache/incubator-openwhisk-client-go/whisk" @@ -131,35 +129,12 @@ func (dm *YAMLParser) composeInputsOrOutputs(inputs map[string]Parameter, manife return keyValArr, nil } -func (dm *YAMLParser) encodeJSONAnnotations(annotation interface{}) interface{} { - mapString := make(map[string]interface{}) - if reflect.ValueOf(annotation).Kind() == reflect.Map { - for k, v := range annotation.(map[interface{}]interface{}) { - strKey := fmt.Sprintf("%v", k) - var strValue interface{} - if reflect.ValueOf(v).Kind() == reflect.Slice { - strValue = v.([]interface{}) - } else if reflect.ValueOf(v).Kind() == reflect.String { - strValue = fmt.Sprintf("%v", v) - } else if reflect.ValueOf(v).Kind() == reflect.Map { - strValue = dm.encodeJSONAnnotations(v) - } - mapString[strKey] = strValue - } - } - return mapString -} - func (dm *YAMLParser) composeAnnotations(annotations map[string]interface{}) whisk.KeyValueArr { listOfAnnotations := make(whisk.KeyValueArr, 0) for name, value := range annotations { var keyVal whisk.KeyValue keyVal.Key = name - if reflect.ValueOf(value).Kind() == reflect.String { - keyVal.Value = fmt.Sprintf("%v", value) - } else { - keyVal.Value = dm.encodeJSONAnnotations(value) - } + keyVal.Value = EncodeAnnotations(value) listOfAnnotations = append(listOfAnnotations, keyVal) } return listOfAnnotations diff --git a/parsers/manifest_parser_test.go b/parsers/manifest_parser_test.go index 113049c..087edb1 100644 --- a/parsers/manifest_parser_test.go +++ b/parsers/manifest_parser_test.go @@ -52,6 +52,7 @@ const ( TEST_MSG_ACTION_DOCKER_KIND_MISMATCH = "Docker action kind is set to [%s] instead of " + utils.BLACKBOX TEST_MSG_ACTION_DOCKER_IMAGE_MISMATCH = "Docker action image had a value mismatch." TEST_MSG_ACTION_CODE_MISSING = "Action code is missing." + TEST_MSG_INVALID_ACTION_ANNOTATION = "Action annotations are invalid" // local error messages TEST_ERROR_MANIFEST_PARSE_FAILURE = "Manifest [%s]: Failed to parse." @@ -1068,6 +1069,88 @@ func TestComposeActionsForWebAndWebExport(t *testing.T) { } } +func TestYAMLParser_ComposeActionsForAnnotations(t *testing.T) { + file := "../tests/dat/manifest_data_compose_actions_for_annotations.yaml" + p, m, _ := testLoadParseManifest(t, file) + + actions, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{}) + assert.Nil(t, err, fmt.Sprintf(TEST_ERROR_COMPOSE_ACTION_FAILURE, file)) + + for _, action := range actions { + if action.Action.Name == "hello" { + for _, a := range action.Action.Annotations { + switch a.Key { + // annotation_string: this is a string annotations + case "annotation_string": + assert.Equal(t, "this is a string annotations", + a.Value.(string), TEST_MSG_INVALID_ACTION_ANNOTATION) + //annotation_int: 100 + case "annotation_int": + assert.Equal(t, 100, + a.Value.(int), TEST_MSG_INVALID_ACTION_ANNOTATION) + //annotation_float: 99.99 + case "annotation_float": + assert.Equal(t, 99.99, + a.Value.(float64), TEST_MSG_INVALID_ACTION_ANNOTATION) + //annotation_bool: true + case "annotation_bool": + assert.Equal(t, true, + a.Value.(bool), TEST_MSG_INVALID_ACTION_ANNOTATION) + // annotation_list_1: [1, 2, 3, 4] + case "annotation_list_1": + assert.Equal(t, []interface{}{1, 2, 3, 4}, + a.Value.([]interface{}), TEST_MSG_INVALID_ACTION_ANNOTATION) + //annotation_list_2: [{ "payload": "one,two,three" }, { "payload": "one,two,three", "separator": "," }] + case "annotation_list_2": + assert.Equal(t, []interface{}{map[string]interface{}{"payload": "one,two,three"}, map[string]interface{}{"payload": "one,two,three", "separator": ","}}, + a.Value.([]interface{}), TEST_MSG_INVALID_ACTION_ANNOTATION) + // annotation_json_1: { "payload": "one,two,three" } + case "annotation_json_1": + assert.Equal(t, map[string]interface{}{"payload": "one,two,three"}, + a.Value.(map[string]interface{}), TEST_MSG_INVALID_ACTION_ANNOTATION) + // annotation_json_2: { "payload": "one,two,three", "separator": "," } + case "annotation_json_2": + assert.Equal(t, map[string]interface{}{"payload": "one,two,three", "separator": ","}, + a.Value.(map[string]interface{}), TEST_MSG_INVALID_ACTION_ANNOTATION) + // annotation_json_3: { "payload": "one,two,three", "lines": ["one", "two", "three"] } + case "annotation_json_3": + assert.Equal(t, map[string]interface{}{"payload": "one,two,three", "lines": []interface{}{"one", "two", "three"}}, + a.Value.(map[string]interface{}), TEST_MSG_INVALID_ACTION_ANNOTATION) + //annotation_json_4: { "p": { "a": 1 } } + case "annotation_json_4": + assert.Equal(t, map[string]interface{}{"p": map[string]interface{}{"a": 1}}, + a.Value.(map[string]interface{}), TEST_MSG_INVALID_ACTION_ANNOTATION) + //annotation_json_5: { "p": { "a": 1, "b": 2 } } + case "annotation_json_5": + assert.Equal(t, map[string]interface{}{"p": map[string]interface{}{"a": 1, "b": 2}}, + a.Value.(map[string]interface{}), TEST_MSG_INVALID_ACTION_ANNOTATION) + //annotation_json_6: { "p": { "a": 1, "b": { "c": 2 } } } + case "annotation_json_6": + assert.Equal(t, map[string]interface{}{"p": map[string]interface{}{"a": 1, "b": map[string]interface{}{"c": 2}}}, + a.Value.(map[string]interface{}), TEST_MSG_INVALID_ACTION_ANNOTATION) + //annotation_json_7: { "p": { "a": 1, "b": { "c": 2, "d": 3 } } } + case "annotation_json_7": + assert.Equal(t, map[string]interface{}{"p": map[string]interface{}{"a": 1, "b": map[string]interface{}{"c": 2, "d": 3}}}, + a.Value.(map[string]interface{}), TEST_MSG_INVALID_ACTION_ANNOTATION) + //annotation_json_8: { "p": { "a": 1, "b": { "c": 2, "d": [3, 4] } } } + case "annotation_json_8": + assert.Equal(t, map[string]interface{}{"p": map[string]interface{}{"a": 1, "b": map[string]interface{}{"c": 2, "d": []interface{}{3, 4}}}}, + a.Value.(map[string]interface{}), TEST_MSG_INVALID_ACTION_ANNOTATION) + //annotation_json_9: { "p": { "a": 99.99 } } + case "annotation_json_9": + assert.Equal(t, map[string]interface{}{"p": map[string]interface{}{"a": 99.99}}, + a.Value.(map[string]interface{}), TEST_MSG_INVALID_ACTION_ANNOTATION) + //annotation_json_10: { "p": { "a": true } } + case "annotation_json_10": + assert.Equal(t, map[string]interface{}{"p": map[string]interface{}{"a": true}}, + a.Value.(map[string]interface{}), TEST_MSG_INVALID_ACTION_ANNOTATION) + + } + } + } + } +} + // Test 16: validate manifest_parser.ResolveParameter() method func TestResolveParameterForMultiLineParams(t *testing.T) { paramName := "name" diff --git a/tests/dat/manifest_data_compose_actions_for_annotations.yaml b/tests/dat/manifest_data_compose_actions_for_annotations.yaml new file mode 100644 index 0000000..5bd44e4 --- /dev/null +++ b/tests/dat/manifest_data_compose_actions_for_annotations.yaml @@ -0,0 +1,39 @@ +# +# 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. +# + +packages: + helloworld: + actions: + hello: + function: ../src/integration/helloworld/actions/hello.js + annotations: + annotation_string: this is a string annotations + annotation_int: 100 + annotation_float: 99.99 + annotation_bool: true + annotation_list_1: [1, 2, 3, 4] + annotation_list_2: [{ "payload": "one,two,three" }, { "payload": "one,two,three", "separator": "," }] + annotation_json_1: { "payload": "one,two,three" } + annotation_json_2: { "payload": "one,two,three", "separator": "," } + annotation_json_3: { "payload": "one,two,three", "lines": ["one", "two", "three"] } + annotation_json_4: { "p": { "a": 1 } } + annotation_json_5: { "p": { "a": 1, "b": 2 } } + annotation_json_6: { "p": { "a": 1, "b": { "c": 2 } } } + annotation_json_7: { "p": { "a": 1, "b": { "c": 2, "d": 3 } } } + annotation_json_8: { "p": { "a": 1, "b": { "c": 2, "d": [3, 4] } } } + annotation_json_9: { "p": { "a": 99.99 } } + annotation_json_10: { "p": { "a": true } } + -- To stop receiving notification emails like this one, please contact [email protected].
