You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by mr...@apache.org on 2018/02/05 22:24:41 UTC

[incubator-openwhisk-wskdeploy] branch master updated: Adding support for raw HTTP web actions (#707)

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 e87c98a  Adding support for raw HTTP web actions (#707)
e87c98a is described below

commit e87c98ab7b5d0ce662119988042b6fe4242217c5
Author: Priti Desai <pd...@us.ibm.com>
AuthorDate: Mon Feb 5 14:24:39 2018 -0800

    Adding support for raw HTTP web actions (#707)
    
    * Adding support for raw HTTP web actions
    
    * fixing integration test
    
    * adding error type for invalid web-export
    
    * formatting with gofmt
    
    * fixing integration test
---
 parsers/manifest_parser.go                   |  9 ++-
 parsers/manifest_parser_test.go              | 86 +++++++++++++++++++++++++++-
 tests/src/integration/webaction/manifest.yml | 51 +++++++++++------
 utils/webaction.go                           | 32 ++++++++---
 wskderrors/wskdeployerror.go                 | 54 ++++++++++++-----
 5 files changed, 186 insertions(+), 46 deletions(-)

diff --git a/parsers/manifest_parser.go b/parsers/manifest_parser.go
index d913c1c..c5eb0c8 100644
--- a/parsers/manifest_parser.go
+++ b/parsers/manifest_parser.go
@@ -652,9 +652,12 @@ func (dm *YAMLParser) ComposeActions(filePath string, actions map[string]Action,
 		/*
 		 *  Web Export
 		 */
-		// TODO() add boolean value const
-		if action.Webexport == "true" {
-			wskaction.Annotations, errorParser = utils.WebAction("yes", listOfAnnotations, false)
+		// Treat ACTION as a web action, a raw HTTP web action, or as a standard action based on web-export;
+		// when web-export is set to yes | true, treat action as a web action,
+		// when web-export is set to raw, treat action as a raw HTTP web action,
+		// when web-export is set to no | false, treat action as a standard action
+		if len(action.Webexport) != 0 {
+			wskaction.Annotations, errorParser = utils.WebAction(filePath, action.Name, action.Webexport, listOfAnnotations, false)
 			if errorParser != nil {
 				return s1, errorParser
 			}
diff --git a/parsers/manifest_parser_test.go b/parsers/manifest_parser_test.go
index 5b45dc1..ae64033 100644
--- a/parsers/manifest_parser_test.go
+++ b/parsers/manifest_parser_test.go
@@ -949,9 +949,21 @@ func TestComposeActionsForWebActions(t *testing.T) {
 		`package:
   name: helloworld
   actions:
-    hello:
+    hello1:
+      function: ../tests/src/integration/helloworld/actions/hello.js
+      web-export: true
+    hello2:
       function: ../tests/src/integration/helloworld/actions/hello.js
-      web-export: true`
+      web-export: yes
+    hello3:
+      function: ../tests/src/integration/helloworld/actions/hello.js
+      web-export: raw
+    hello4:
+      function: ../tests/src/integration/helloworld/actions/hello.js
+      web-export: false
+    hello5:
+      function: ../tests/src/integration/helloworld/actions/hello.js
+      web-export: no`
 	dir, _ := os.Getwd()
 	tmpfile, err := ioutil.TempFile(dir, "manifest_parser_validate_web_actions_")
 	if err == nil {
@@ -963,7 +975,7 @@ func TestComposeActionsForWebActions(t *testing.T) {
 			actions, err := p.ComposeActionsFromAllPackages(m, tmpfile.Name(), whisk.KeyValue{})
 			if err == nil {
 				for i := 0; i < len(actions); i++ {
-					if actions[i].Action.Name == "hello" {
+					if actions[i].Action.Name == "hello1" {
 						for _, a := range actions[i].Action.Annotations {
 							switch a.Key {
 							case "web-export":
@@ -974,6 +986,50 @@ func TestComposeActionsForWebActions(t *testing.T) {
 								assert.Equal(t, true, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
 							}
 						}
+					} else if actions[i].Action.Name == "hello2" {
+						for _, a := range actions[i].Action.Annotations {
+							switch a.Key {
+							case "web-export":
+								assert.Equal(t, true, a.Value, "Expected true for web-export but got "+strconv.FormatBool(a.Value.(bool)))
+							case "raw-http":
+								assert.Equal(t, false, a.Value, "Expected false for raw-http but got "+strconv.FormatBool(a.Value.(bool)))
+							case "final":
+								assert.Equal(t, true, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
+							}
+						}
+					} else if actions[i].Action.Name == "hello3" {
+						for _, a := range actions[i].Action.Annotations {
+							switch a.Key {
+							case "web-export":
+								assert.Equal(t, true, a.Value, "Expected true for web-export but got "+strconv.FormatBool(a.Value.(bool)))
+							case "raw-http":
+								assert.Equal(t, true, a.Value, "Expected false for raw-http but got "+strconv.FormatBool(a.Value.(bool)))
+							case "final":
+								assert.Equal(t, true, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
+							}
+						}
+					} else if actions[i].Action.Name == "hello4" {
+						for _, a := range actions[i].Action.Annotations {
+							switch a.Key {
+							case "web-export":
+								assert.Equal(t, false, a.Value, "Expected true for web-export but got "+strconv.FormatBool(a.Value.(bool)))
+							case "raw-http":
+								assert.Equal(t, false, a.Value, "Expected false for raw-http but got "+strconv.FormatBool(a.Value.(bool)))
+							case "final":
+								assert.Equal(t, false, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
+							}
+						}
+					} else if actions[i].Action.Name == "hello5" {
+						for _, a := range actions[i].Action.Annotations {
+							switch a.Key {
+							case "web-export":
+								assert.Equal(t, false, a.Value, "Expected true for web-export but got "+strconv.FormatBool(a.Value.(bool)))
+							case "raw-http":
+								assert.Equal(t, false, a.Value, "Expected false for raw-http but got "+strconv.FormatBool(a.Value.(bool)))
+							case "final":
+								assert.Equal(t, false, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
+							}
+						}
 					}
 				}
 			}
@@ -983,6 +1039,30 @@ func TestComposeActionsForWebActions(t *testing.T) {
 	}
 }
 
+// Test 15-1: validate manifest_parser.ComposeActions() method
+func TestComposeActionsForInvalidWebActions(t *testing.T) {
+	data :=
+		`package:
+  name: helloworld
+  actions:
+    hello:
+      function: ../tests/src/integration/helloworld/actions/hello.js
+      web-export: raw123`
+	dir, _ := os.Getwd()
+	tmpfile, err := ioutil.TempFile(dir, "manifest_parser_validate_invalid_web_actions_")
+	if err == nil {
+		defer os.Remove(tmpfile.Name()) // clean up
+		if _, err := tmpfile.Write([]byte(data)); err == nil {
+			// read and parse manifest.yaml file
+			p := NewYAMLParser()
+			m, _ := p.ParseManifest(tmpfile.Name())
+			_, err := p.ComposeActionsFromAllPackages(m, tmpfile.Name(), whisk.KeyValue{})
+			assert.NotNil(t, err, "Expected error for invalid web-export.")
+		}
+		tmpfile.Close()
+	}
+}
+
 // Test 16: validate manifest_parser.ResolveParameter() method
 func TestResolveParameterForMultiLineParams(t *testing.T) {
 	paramName := "name"
diff --git a/tests/src/integration/webaction/manifest.yml b/tests/src/integration/webaction/manifest.yml
index 5d71023..44568d0 100644
--- a/tests/src/integration/webaction/manifest.yml
+++ b/tests/src/integration/webaction/manifest.yml
@@ -1,20 +1,35 @@
 packages:
-  IntegrationTestWebAction:
-      actions:
-        greeting:
-          web-export: true
-          version: 1.0
-          function: src/greeting.js
-          runtime: nodejs:6
-          inputs:
-            name: string
-            place: string
-          outputs:
-            payload: string
-      triggers:
-        webActionTrigger:
-      rules:
-        webActionRule:
-          trigger: webActionTrigger
-          action: greeting
+    IntegrationTestWebAction:
+        actions:
+            greeting-web-action:
+                web-export: true
+                version: 1.0
+                function: src/greeting.js
+                runtime: nodejs:6
+                inputs:
+                    name: string
+                    place: string
+                outputs:
+                    payload: string
+            greeting-web-action-1:
+                web-export: yes
+                version: 1.0
+                function: src/greeting.js
+                runtime: nodejs:6
+                inputs:
+                    name: string
+                    place: string
+                outputs:
+                    payload: string
+            greeting-with-raw-http:
+                web-export: raw
+                version: 1.0
+                function: src/greeting.js
+                runtime: nodejs:6
+        triggers:
+            webActionTrigger:
+        rules:
+            webActionRule:
+                trigger: webActionTrigger
+                action: greeting-web-action
 
diff --git a/utils/webaction.go b/utils/webaction.go
index f9f6e4e..ed05ad3 100644
--- a/utils/webaction.go
+++ b/utils/webaction.go
@@ -18,8 +18,8 @@
 package utils
 
 import (
-	"errors"
 	"github.com/apache/incubator-openwhisk-client-go/whisk"
+	"github.com/apache/incubator-openwhisk-wskdeploy/wskderrors"
 	"strings"
 )
 
@@ -28,20 +28,28 @@ 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) {
+var webexport map[string]string = map[string]string{
+	"TRUE":  "true",
+	"FALSE": "false",
+	"NO":    "no",
+	"YES":   "yes",
+	"RAW":   "raw",
+}
+
+func WebAction(filePath string, action string, webMode string, annotations whisk.KeyValueArr, fetch bool) (whisk.KeyValueArr, error) {
 	switch strings.ToLower(webMode) {
-	case "yes":
+	case webexport["TRUE"]:
 		fallthrough
-	case "true":
+	case webexport["YES"]:
 		return webActionAnnotations(fetch, annotations, addWebAnnotations)
-	case "no":
+	case webexport["NO"]:
 		fallthrough
-	case "false":
+	case webexport["FALSE"]:
 		return webActionAnnotations(fetch, annotations, deleteWebAnnotations)
-	case "raw":
+	case webexport["RAW"]:
 		return webActionAnnotations(fetch, annotations, addRawAnnotations)
 	default:
-		return nil, errors.New(webMode)
+		return nil, wskderrors.NewInvalidWebExportError(filePath, action, webMode, getValidWebExports())
 	}
 }
 
@@ -92,3 +100,11 @@ func deleteWebAnnotationKeys(annotations whisk.KeyValueArr) whisk.KeyValueArr {
 
 	return annotations
 }
+
+func getValidWebExports() []string {
+	var validWebExports []string
+	for _, v := range webexport {
+		validWebExports = append(validWebExports, v)
+	}
+	return validWebExports
+}
diff --git a/wskderrors/wskdeployerror.go b/wskderrors/wskdeployerror.go
index fa375f8..1667ce2 100644
--- a/wskderrors/wskdeployerror.go
+++ b/wskderrors/wskdeployerror.go
@@ -28,20 +28,22 @@ import (
 
 const (
 	// Error message compositional strings
-	STR_UNKNOWN_VALUE      = "Unknown value"
-	STR_COMMAND            = "Command"
-	STR_ERROR_CODE         = "Error code"
-	STR_FILE               = "File"
-	STR_PARAMETER          = "Parameter"
-	STR_TYPE               = "Type"
-	STR_EXPECTED           = "Expected"
-	STR_ACTUAL             = "Actual"
-	STR_NEWLINE            = "\n"
-	STR_ACTION             = "Action"
-	STR_RUNTIME            = "Runtime"
-	STR_SUPPORTED_RUNTIMES = "Supported Runtimes"
-	STR_HTTP_STATUS        = "HTTP Response Status"
-	STR_HTTP_BODY          = "HTTP Response Body"
+	STR_UNKNOWN_VALUE         = "Unknown value"
+	STR_COMMAND               = "Command"
+	STR_ERROR_CODE            = "Error code"
+	STR_FILE                  = "File"
+	STR_PARAMETER             = "Parameter"
+	STR_TYPE                  = "Type"
+	STR_EXPECTED              = "Expected"
+	STR_ACTUAL                = "Actual"
+	STR_NEWLINE               = "\n"
+	STR_ACTION                = "Action"
+	STR_RUNTIME               = "Runtime"
+	STR_SUPPORTED_RUNTIMES    = "Supported Runtimes"
+	STR_HTTP_STATUS           = "HTTP Response Status"
+	STR_HTTP_BODY             = "HTTP Response Body"
+	STR_SUPPORTED_WEB_EXPORTS = "Supported Web Exports"
+	STR_WEB_EXPORT            = "web-export"
 
 	// Formatting
 	STR_INDENT_1 = "==>"
@@ -57,6 +59,7 @@ const (
 	ERROR_YAML_PARAMETER_TYPE_MISMATCH = "ERROR_YAML_PARAMETER_TYPE_MISMATCH"
 	ERROR_YAML_INVALID_PARAMETER_TYPE  = "ERROR_YAML_INVALID_PARAMETER_TYPE"
 	ERROR_YAML_INVALID_RUNTIME         = "ERROR_YAML_INVALID_RUNTIME"
+	ERROR_YAML_INVALID_WEB_EXPORT      = "ERROR_YAML_INVALID_WEB_EXPORT"
 )
 
 /*
@@ -381,6 +384,29 @@ func NewInvalidRuntimeError(errMessage string, fpath string, action string, runt
 	return err
 }
 
+/*
+ * InvalidWebExport
+ */
+type InvalidWebExportError struct {
+	FileError
+	Webexport           string
+	SupportedWebexports []string
+}
+
+func NewInvalidWebExportError(fpath string, action string, webexport string, supportedWebexports []string) *InvalidWebExportError {
+	var err = &InvalidWebExportError{
+		SupportedWebexports: supportedWebexports,
+	}
+	err.SetErrorFilePath(fpath)
+	err.SetErrorType(ERROR_YAML_INVALID_WEB_EXPORT)
+	err.SetCallerByStackFrameSkip(2)
+	str := fmt.Sprintf("%s [%s]: %s [%s]: %s [%s]",
+		STR_ACTION, action,
+		STR_WEB_EXPORT, webexport,
+		STR_SUPPORTED_WEB_EXPORTS, strings.Join(supportedWebexports, ", "))
+	err.SetMessage(str)
+	return err
+}
 func IsCustomError(err error) bool {
 
 	switch err.(type) {

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