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 2f1996c  adding support to create api gateway based on sequences (#858)
2f1996c is described below

commit 2f1996ca3fb53514fee10ed05975ada3084d16b0
Author: Priti Desai <pde...@us.ibm.com>
AuthorDate: Fri Apr 6 12:19:05 2018 -0700

    adding support to create api gateway based on sequences (#858)
---
 parsers/manifest_parser.go                       | 92 ++++++++++++++----------
 parsers/manifest_parser_test.go                  |  6 +-
 tests/dat/manifest_data_compose_api_records.yaml |  5 ++
 tests/src/integration/apigateway/manifest.yml    |  4 ++
 utils/webaction.go                               |  4 ++
 wski18n/i18n_ids.go                              | 40 ++++++-----
 wski18n/i18n_resources.go                        |  4 +-
 wski18n/resources/en_US.all.json                 |  8 ++-
 8 files changed, 100 insertions(+), 63 deletions(-)

diff --git a/parsers/manifest_parser.go b/parsers/manifest_parser.go
index b46f73a..c63e4dd 100644
--- a/parsers/manifest_parser.go
+++ b/parsers/manifest_parser.go
@@ -1027,13 +1027,7 @@ func (dm *YAMLParser) ComposeApiRecords(client 
*whisk.Config, packageName string
                                }
                                for actionName, gatewayMethod := range 
gatewayRelPathMap {
                                        // verify that the action is defined 
under actions sections
-                                       if _, ok := pkg.Actions[actionName]; 
!ok {
-                                               return nil, 
wskderrors.NewYAMLFileFormatError(manifestPath,
-                                                       
wski18n.T(wski18n.ID_ERR_API_MISSING_ACTION_X_action_X_api_X,
-                                                               
map[string]interface{}{
-                                                                       
wski18n.KEY_ACTION: actionName,
-                                                                       
wski18n.KEY_API:    apiName}))
-                                       } else {
+                                       if _, ok := pkg.Actions[actionName]; ok 
{
                                                // verify that the action is 
defined as web action
                                                // web or web-export set to any 
of [true, yes, raw]
                                                a := pkg.Actions[actionName]
@@ -1049,38 +1043,62 @@ func (dm *YAMLParser) ComposeApiRecords(client 
*whisk.Config, packageName string
                                                        
a.Annotations[utils.WEB_EXPORT_ANNOT] = true
                                                        pkg.Actions[actionName] 
= a
                                                }
-                                               request := 
new(whisk.ApiCreateRequest)
-                                               request.ApiDoc = new(whisk.Api)
-                                               request.ApiDoc.GatewayBasePath 
= gatewayBasePath
-                                               // is API verb is valid, it 
must be one of (GET, PUT, POST, DELETE)
-                                               request.ApiDoc.GatewayRelPath = 
gatewayRelPath
-                                               if _, ok := 
whisk.ApiVerbs[strings.ToUpper(gatewayMethod)]; !ok {
-                                                       return nil, 
wskderrors.NewInvalidAPIGatewayMethodError(manifestPath,
-                                                               
gatewayBasePath+gatewayRelPath,
-                                                               gatewayMethod,
-                                                               
dm.getGatewayMethods())
-                                               }
-                                               request.ApiDoc.GatewayMethod = 
strings.ToUpper(gatewayMethod)
-                                               request.ApiDoc.Namespace = 
client.Namespace
-                                               request.ApiDoc.ApiName = apiName
-                                               request.ApiDoc.Id = 
strings.Join([]string{API, request.ApiDoc.Namespace, 
request.ApiDoc.GatewayRelPath}, ":")
-                                               // set action of an API Doc
-                                               request.ApiDoc.Action = 
new(whisk.ApiAction)
-                                               if packageName == 
DEFAULT_PACKAGE {
-                                                       
request.ApiDoc.Action.Name = actionName
-                                               } else {
-                                                       
request.ApiDoc.Action.Name = packageName + PATH_SEPARATOR + actionName
+                                               // verify that the sequence is 
defined under sequences sections
+                                       } else if _, ok := 
pkg.Sequences[actionName]; ok {
+                                               // verify that the sequence is 
defined as web sequence
+                                               // web set to any of [true, 
yes, raw]
+                                               a := pkg.Sequences[actionName]
+                                               if !utils.IsWebSequence(a.Web) {
+                                                       warningString := 
wski18n.T(wski18n.ID_WARN_API_MISSING_WEB_SEQUENCE_X_sequence_X_api_X,
+                                                               
map[string]interface{}{
+                                                                       
wski18n.KEY_SEQUENCE: actionName,
+                                                                       
wski18n.KEY_API:      apiName})
+                                                       
wskprint.PrintOpenWhiskWarning(warningString)
+                                                       if a.Annotations == nil 
{
+                                                               a.Annotations = 
make(map[string]interface{}, 0)
+                                                       }
+                                                       
a.Annotations[utils.WEB_EXPORT_ANNOT] = true
+                                                       
pkg.Sequences[actionName] = a
                                                }
-                                               url := []string{HTTPS + 
client.Host, strings.ToLower(API),
-                                                       API_VERSION, WEB, 
client.Namespace, packageName,
-                                                       actionName + "." + 
utils.HTTP_FILE_EXTENSION}
-                                               request.ApiDoc.Action.Namespace 
= client.Namespace
-                                               
request.ApiDoc.Action.BackendUrl = strings.Join(url, PATH_SEPARATOR)
-                                               
request.ApiDoc.Action.BackendMethod = gatewayMethod
-                                               request.ApiDoc.Action.Auth = 
client.AuthToken
-                                               // add a newly created 
ApiCreateRequest object to a list of requests
-                                               requests = append(requests, 
request)
+                                               // return failure since action 
or sequence are not defined in the manifest
+                                       } else {
+                                               return nil, 
wskderrors.NewYAMLFileFormatError(manifestPath,
+                                                       
wski18n.T(wski18n.ID_ERR_API_MISSING_ACTION_OR_SEQUENCE_X_action_or_sequence_X_api_X,
+                                                               
map[string]interface{}{
+                                                                       
wski18n.KEY_ACTION: actionName,
+                                                                       
wski18n.KEY_API:    apiName}))
+                                       }
+                                       request := new(whisk.ApiCreateRequest)
+                                       request.ApiDoc = new(whisk.Api)
+                                       request.ApiDoc.GatewayBasePath = 
gatewayBasePath
+                                       // is API verb is valid, it must be one 
of (GET, PUT, POST, DELETE)
+                                       request.ApiDoc.GatewayRelPath = 
gatewayRelPath
+                                       if _, ok := 
whisk.ApiVerbs[strings.ToUpper(gatewayMethod)]; !ok {
+                                               return nil, 
wskderrors.NewInvalidAPIGatewayMethodError(manifestPath,
+                                                       
gatewayBasePath+gatewayRelPath,
+                                                       gatewayMethod,
+                                                       dm.getGatewayMethods())
+                                       }
+                                       request.ApiDoc.GatewayMethod = 
strings.ToUpper(gatewayMethod)
+                                       request.ApiDoc.Namespace = 
client.Namespace
+                                       request.ApiDoc.ApiName = apiName
+                                       request.ApiDoc.Id = 
strings.Join([]string{API, request.ApiDoc.Namespace, 
request.ApiDoc.GatewayRelPath}, ":")
+                                       // set action of an API Doc
+                                       request.ApiDoc.Action = 
new(whisk.ApiAction)
+                                       if packageName == DEFAULT_PACKAGE {
+                                               request.ApiDoc.Action.Name = 
actionName
+                                       } else {
+                                               request.ApiDoc.Action.Name = 
packageName + PATH_SEPARATOR + actionName
                                        }
+                                       url := []string{HTTPS + client.Host, 
strings.ToLower(API),
+                                               API_VERSION, WEB, 
client.Namespace, packageName,
+                                               actionName + "." + 
utils.HTTP_FILE_EXTENSION}
+                                       request.ApiDoc.Action.Namespace = 
client.Namespace
+                                       request.ApiDoc.Action.BackendUrl = 
strings.Join(url, PATH_SEPARATOR)
+                                       request.ApiDoc.Action.BackendMethod = 
gatewayMethod
+                                       request.ApiDoc.Action.Auth = 
client.AuthToken
+                                       // add a newly created ApiCreateRequest 
object to a list of requests
+                                       requests = append(requests, request)
                                }
                        }
                }
diff --git a/parsers/manifest_parser_test.go b/parsers/manifest_parser_test.go
index c3d62d4..113049c 100644
--- a/parsers/manifest_parser_test.go
+++ b/parsers/manifest_parser_test.go
@@ -1305,8 +1305,6 @@ func TestComposeRules(t *testing.T) {
        }
 }
 
-// TODO(752) We SHOULD automatically add "web-export" to each Action 
referenced in the "apis" section
-// as this is implied.  The user should not have to do this manually
 func TestComposeApiRecords(t *testing.T) {
 
        p, m, _ := testLoadParseManifest(t, 
"../tests/dat/manifest_data_compose_api_records.yaml")
@@ -1323,7 +1321,7 @@ func TestComposeApiRecords(t *testing.T) {
        if err != nil {
                assert.Fail(t, "Failed to compose api records: "+err.Error())
        }
-       assert.Equal(t, 6, len(apiList), "Failed to get api records")
+       assert.Equal(t, 7, len(apiList), "Failed to get api records")
        for _, apiRecord := range apiList {
                apiDoc := apiRecord.ApiDoc
                action := apiDoc.Action
@@ -1354,10 +1352,12 @@ func TestComposeApiRecords(t *testing.T) {
                        assert.Equal(t, "/books2", apiDoc.GatewayRelPath, 
"Failed to set api rel path")
                        assert.Equal(t, "post", action.BackendMethod, "Failed 
to set api backend method")
                case "apiTest/listMembers2":
+               case "apiTest/listAllMembers":
                        assert.Equal(t, "book-club2", apiDoc.ApiName, "Failed 
to set api name")
                        assert.Equal(t, "/club2", apiDoc.GatewayBasePath, 
"Failed to set api base path")
                        assert.Equal(t, "/members2", apiDoc.GatewayRelPath, 
"Failed to set api rel path")
                        assert.Equal(t, "get", action.BackendMethod, "Failed to 
set api backend method")
+
                default:
                        assert.Fail(t, "Failed to get api action name")
                }
diff --git a/tests/dat/manifest_data_compose_api_records.yaml 
b/tests/dat/manifest_data_compose_api_records.yaml
index 385c8e9..6191a1f 100644
--- a/tests/dat/manifest_data_compose_api_records.yaml
+++ b/tests/dat/manifest_data_compose_api_records.yaml
@@ -30,6 +30,10 @@ packages:
         function: ../tests/src/integration/helloworld/actions/hello.js
       listMembers2:
         function: ../tests/src/integration/helloworld/actions/hello.js
+    sequences:
+      listAllMembers:
+        actions: listMembers, listMembers2
+        web: true
     apis:
       book-club:
         club:
@@ -45,3 +49,4 @@ packages:
             postBooks2: post
           members2:
             listMembers2: get
+            listAllMembers: get
diff --git a/tests/src/integration/apigateway/manifest.yml 
b/tests/src/integration/apigateway/manifest.yml
index e2b26f5..5c22af2 100644
--- a/tests/src/integration/apigateway/manifest.yml
+++ b/tests/src/integration/apigateway/manifest.yml
@@ -34,6 +34,9 @@ packages:
                 function: src/delete-books.js
             listMembers:
                 function: src/list-members.js
+        sequences:
+            listAllMembers:
+                actions: listMembers
         # new top-level key for defining groups of named APIs
         apis:
             hello-world:
@@ -49,3 +52,4 @@ packages:
                         deleteBooks: DELETE
                     members:
                         listMembers: GET
+                        listAllMembers: GET
diff --git a/utils/webaction.go b/utils/webaction.go
index 087a773..64fe346 100644
--- a/utils/webaction.go
+++ b/utils/webaction.go
@@ -121,3 +121,7 @@ func IsWebAction(webexport string) bool {
        }
        return false
 }
+
+func IsWebSequence(webexport string) bool {
+       return IsWebAction(webexport)
+}
diff --git a/wski18n/i18n_ids.go b/wski18n/i18n_ids.go
index 1ede72a..eae4a0b 100644
--- a/wski18n/i18n_ids.go
+++ b/wski18n/i18n_ids.go
@@ -77,6 +77,7 @@ const (
        KEY_BINDINGS        = "bindings"
        KEY_DEPENDENCY      = "dependency"
        KEY_LOCATION        = "location"
+       KEY_SEQUENCE        = "sequence"
 )
 
 // DO NOT TRANSLATE
@@ -162,25 +163,25 @@ const (
        ID_MSG_MANAGED_FOUND_DELETED_X_key_X_name_X_project_X = 
"msg_managed_found_deleted_entity"
 
        // Errors
-       ID_ERR_DEPENDENCY_UNKNOWN_TYPE                                   = 
"msg_err_dependency_unknown_type"
-       ID_ERR_ENTITY_CREATE_X_key_X_err_X_code_X                        = 
"msg_err_entity_create"
-       ID_ERR_ENTITY_DELETE_X_key_X_err_X_code_X                        = 
"msg_err_entity_delete"
-       ID_ERR_FEED_INVOKE_X_err_X_code_X                                = 
"msg_err_feed_invoke"
-       ID_ERR_KEY_MISSING_X_key_X                                       = 
"msg_err_key_missing_mandatory"
-       ID_ERR_MANIFEST_FILE_NOT_FOUND_X_path_X                          = 
"msg_err_manifest_not_found"
-       ID_ERR_NAME_MISMATCH_X_key_X_dname_X_dpath_X_mname_X_moath_X     = 
"msg_err_name_mismatch"
-       ID_ERR_RUNTIME_INVALID_X_runtime_X_action_X                      = 
"msg_err_runtime_invalid"
-       ID_ERR_RUNTIME_MISMATCH_X_runtime_X_ext_X_action_X               = 
"msg_err_runtime_mismatch"
-       ID_ERR_RUNTIMES_GET_X_err_X                                      = 
"msg_err_runtimes_get"
-       ID_ERR_RUNTIME_ACTION_SOURCE_NOT_SUPPORTED_X_ext_X_action_X      = 
"msg_err_runtime_action_source_not_supported"
-       ID_ERR_URL_INVALID_X_urltype_X_url_X_filetype_X                  = 
"msg_err_url_invalid"
-       ID_ERR_URL_MALFORMED_X_urltype_X_url_X                           = 
"msg_err_url_malformed"
-       ID_ERR_API_MISSING_ACTION_X_action_X_api_X                       = 
"msg_err_api_missing_action"
-       ID_ERR_ACTION_INVALID_X_action_X                                 = 
"msg_err_action_invalid"
-       ID_ERR_ACTION_MISSING_RUNTIME_WITH_CODE_X_action_X               = 
"msg_err_action_missing_runtime_with_code"
-       ID_ERR_ACTION_FUNCTION_REMOTE_DIR_NOT_SUPPORTED_X_action_X_url_X = 
"msg_err_action_function_remote_dir_not_supported"
-       ID_ERR_CANT_SAVE_DOCKER_RUNTIME                                  = 
"msg_err_cant_save_docker"
-       ID_ERR_FILE_ALREADY_EXISTS                                       = 
"msg_err_file_already_exists"
+       ID_ERR_DEPENDENCY_UNKNOWN_TYPE                                     = 
"msg_err_dependency_unknown_type"
+       ID_ERR_ENTITY_CREATE_X_key_X_err_X_code_X                          = 
"msg_err_entity_create"
+       ID_ERR_ENTITY_DELETE_X_key_X_err_X_code_X                          = 
"msg_err_entity_delete"
+       ID_ERR_FEED_INVOKE_X_err_X_code_X                                  = 
"msg_err_feed_invoke"
+       ID_ERR_KEY_MISSING_X_key_X                                         = 
"msg_err_key_missing_mandatory"
+       ID_ERR_MANIFEST_FILE_NOT_FOUND_X_path_X                            = 
"msg_err_manifest_not_found"
+       ID_ERR_NAME_MISMATCH_X_key_X_dname_X_dpath_X_mname_X_moath_X       = 
"msg_err_name_mismatch"
+       ID_ERR_RUNTIME_INVALID_X_runtime_X_action_X                        = 
"msg_err_runtime_invalid"
+       ID_ERR_RUNTIME_MISMATCH_X_runtime_X_ext_X_action_X                 = 
"msg_err_runtime_mismatch"
+       ID_ERR_RUNTIMES_GET_X_err_X                                        = 
"msg_err_runtimes_get"
+       ID_ERR_RUNTIME_ACTION_SOURCE_NOT_SUPPORTED_X_ext_X_action_X        = 
"msg_err_runtime_action_source_not_supported"
+       ID_ERR_URL_INVALID_X_urltype_X_url_X_filetype_X                    = 
"msg_err_url_invalid"
+       ID_ERR_URL_MALFORMED_X_urltype_X_url_X                             = 
"msg_err_url_malformed"
+       ID_ERR_API_MISSING_ACTION_OR_SEQUENCE_X_action_or_sequence_X_api_X = 
"msg_err_api_missing_action_or_sequence"
+       ID_ERR_ACTION_INVALID_X_action_X                                   = 
"msg_err_action_invalid"
+       ID_ERR_ACTION_MISSING_RUNTIME_WITH_CODE_X_action_X                 = 
"msg_err_action_missing_runtime_with_code"
+       ID_ERR_ACTION_FUNCTION_REMOTE_DIR_NOT_SUPPORTED_X_action_X_url_X   = 
"msg_err_action_function_remote_dir_not_supported"
+       ID_ERR_CANT_SAVE_DOCKER_RUNTIME                                    = 
"msg_err_cant_save_docker"
+       ID_ERR_FILE_ALREADY_EXISTS                                         = 
"msg_err_file_already_exists"
 
        // Server-side Errors (wskdeploy as an Action)
        ID_ERR_JSON_MISSING_KEY_CMD = "msg_err_json_missing_cmd_key"
@@ -207,6 +208,7 @@ const (
        ID_WARN_PACKAGE_IS_PUBLIC_X_package_X                     = 
"msg_warn_package_is_public"
        ID_WARN_ACTION_WEB_X_action_X                             = 
"msg_warn_action_web_export_ignored"
        ID_WARN_API_MISSING_WEB_ACTION_X_action_X_api_X           = 
"msg_warn_api_missing_web_action"
+       ID_WARN_API_MISSING_WEB_SEQUENCE_X_sequence_X_api_X       = 
"msg_warn_api_missing_web_sequence"
 
        // Verbose (Debug/Trace) messages
        ID_DEBUG_PROJECT_SEARCH_X_path_X_key_X                = 
"msg_dbg_searching_project_directory"
diff --git a/wski18n/i18n_resources.go b/wski18n/i18n_resources.go
index 7bc2343..e77a8f5 100644
--- a/wski18n/i18n_resources.go
+++ b/wski18n/i18n_resources.go
@@ -97,7 +97,7 @@ func wski18nResourcesDe_deAllJson() (*asset, error) {
        return a, nil
 }
 
-var _wski18nResourcesEn_usAllJson = 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x5b\x6d\x8f\xdb\x36\xf2\x7f\x9f\x4f\x31\x08\xfe\x40\x5a\xc0\x51\xd2\xfe\x71\xc0\x21\xc0\xbe\xc8\x75\xd3\x76\xaf\x4d\x36\xd8\xcd\x5e\x50\xe4\x16\x0a\x2d\x8d\x6d\xd6\x12\x29\x90\x94\x1d\x77\xe1\xef\x7e\x98\x21\xf5\x60\xef\x52\xd2\x3a\xed\x5d\xdf\xd4\x09\x87\x33\xbf\x19\x0e\xe7\x89\xca\xa7\x27\x00\x77\x4f\x00\x00\x9e\xca\xfc\xe9\x2b\x78\x5a\xda\x65\x5a\x19\x5c\xc8\x2f\x29\x1a\xa3\xcd\xd3\x99\x5f\x75\x46
 [...]
+var _wski18nResourcesEn_usAllJson = 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x5b\x6f\x8f\xdb\x36\xd2\x7f\x9f\x4f\x31\x08\x1e\x20\x2d\xe0\x28\x69\x1f\x3c\xc0\x83\x00\x79\x91\x6b\xd2\x76\xaf\x4d\x36\xd8\xcd\x5e\x50\xe4\x16\x0a\x2d\x8d\x6d\xd6\x12\xa9\x23\x29\x3b\xae\xe1\xef\x7e\x98\x21\xf5\xc7\xde\xa5\xa4\x75\xda\xbb\xbe\xa9\xbb\x1c\xce\xfc\x66\x38\x9c\x7f\x54\x3f\x3d\x02\xd8\x3f\x02\x00\x78\x2c\xf3\xc7\x2f\xe0\x71\x69\x97\x69\x65\x70\x21\xbf\xa4\x68\x8c\x36\x8f\x67\x7e\xd5\x19
 [...]
 
 func wski18nResourcesEn_usAllJsonBytes() ([]byte, error) {
        return bindataRead(
@@ -112,7 +112,7 @@ func wski18nResourcesEn_usAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 
14019, mode: os.FileMode(420), modTime: time.Unix(1522283010, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 
14286, mode: os.FileMode(420), modTime: time.Unix(1523039220, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
diff --git a/wski18n/resources/en_US.all.json b/wski18n/resources/en_US.all.json
index b03692a..f765820 100644
--- a/wski18n/resources/en_US.all.json
+++ b/wski18n/resources/en_US.all.json
@@ -292,8 +292,8 @@
     "translation": "JSON input data Missing 'cmd' key"
   },
   {
-    "id": "msg_err_api_missing_action",
-    "translation": "Action [{{.action}}] is missing from manifest file, API 
[{{.api}}] can only be created based on the action from manifest file. Please 
update manifest file to include [{{.action}}] as a web action.\n"
+    "id": "msg_err_api_missing_action_or_sequence",
+    "translation": "Action/Sequence [{{.action}}] is missing from manifest 
file, API [{{.api}}] can only be created based on the action/sequence from 
manifest file. Please update manifest file to include [{{.action}}] as a web 
action/sequence.\n"
   },
   {
     "id": "msg_err_action_invalid",
@@ -404,6 +404,10 @@
     "translation": "Action [{{.action}}] is not a web action, API [{{.api}}] 
can only be created using web action. Converting [{{.action}}] to a web 
action.\n"
   },
   {
+    "id": "msg_warn_api_missing_web_sequence",
+    "translation": "Sequence [{{.sequence}}] is not a web sequence, API 
[{{.api}}] can only be created using web sequence. Converting [{{.sequence}}] 
to a web sequence.\n"
+  },
+  {
     "id": "DEBUG",
     "translation": "================= DEBUG ==================="
   },

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

Reply via email to