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 86f8078  API Gateway deployment/undeployment (#717)
86f8078 is described below

commit 86f8078f57cf0e35910c3158c06e541435932c58
Author: Priti Desai <pde...@us.ibm.com>
AuthorDate: Fri Feb 9 12:11:16 2018 -0800

    API Gateway deployment/undeployment (#717)
    
    * Adding support for API Gateway creation
    
    * adding more test files
    
    * adding undeploy api
    
    * Adding getApi method
    
    * fixing deleteApi
    
    * updating unit test
    
    * fixing Whisk Client unit test
    
    * removing debug messages
    
    * go fmt whiskclient
    
    * fixing syntax error delete-books
    
    * fixing error reportings
    
    * removing todo comment as its addressed here
    
    * running go fmt on changed files
    
    * one more go fmt
    
    * fixing syntax error
    
    * fixing syntax error
    
    * fixing action name
    
    * updating go client dependency version
    
    * adding check if token is set
    
    * go fmt resources
    
    * fixing unit test
    
    * trying to fix integration test
    
    * removing apihost from manifest
    
    * changing apigw host
    
    * disabling integration test for now
---
 Godeps/Godeps.json                                 |   4 +-
 deployers/manifestreader.go                        |   9 +-
 deployers/servicedeployer.go                       |  80 +++++++-
 deployers/whiskclient.go                           | 215 +++++++++++++--------
 parsers/manifest_parser.go                         | 127 ++++++++++--
 parsers/manifest_parser_test.go                    | 102 ++++++----
 parsers/yamlparser.go                              |  36 ++--
 .../src/integration/apigateway/apigateway_test.go  |   2 +-
 tests/src/integration/apigateway/manifest.yml      |  71 ++++---
 .../src/integration/apigateway/src/delete-books.js |  23 +++
 tests/src/integration/apigateway/src/get-books.js  |  13 ++
 .../src/integration/apigateway/src/list-members.js |  13 ++
 tests/src/integration/apigateway/src/post-books.js |  24 +++
 tests/src/integration/apigateway/src/put-books.js  |  30 +++
 utils/flags.go                                     |  37 ++--
 utils/webaction.go                                 |  24 ++-
 wskderrors/wskdeployerror.go                       |  51 +++--
 wski18n/i18n_ids.go                                | 115 +++++------
 wski18n/i18n_resources.go                          |  39 ++--
 wski18n/resources/en_US.all.json                   |  12 ++
 20 files changed, 731 insertions(+), 296 deletions(-)

diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json
index 4576bf6..1758c5d 100644
--- a/Godeps/Godeps.json
+++ b/Godeps/Godeps.json
@@ -105,11 +105,11 @@
                },
                {
                        "ImportPath": 
"github.com/apache/incubator-openwhisk-client-go/whisk",
-                       "Rev": "cef179c81f07f86413c720623995c17bd1bddd7d"
+                       "Rev": "d7cab4297a25e2cc25492b85b64e7ec000da9ffb"
                },
                {
                        "ImportPath": 
"github.com/apache/incubator-openwhisk-client-go/wski18n",
-                       "Rev": "cef179c81f07f86413c720623995c17bd1bddd7d"
+                       "Rev": "d7cab4297a25e2cc25492b85b64e7ec000da9ffb"
                },
                {
                        "ImportPath": "github.com/pelletier/go-buffruneio",
diff --git a/deployers/manifestreader.go b/deployers/manifestreader.go
index 06fbdce..0442abc 100644
--- a/deployers/manifestreader.go
+++ b/deployers/manifestreader.go
@@ -93,7 +93,7 @@ func (deployer *ManifestReader) HandleYaml(sdeployer 
*ServiceDeployer, manifestP
                return wskderrors.NewYAMLFileFormatError(manifestName, err)
        }
 
-       apis, err := manifestParser.ComposeApiRecordsFromAllPackages(manifest)
+       apis, err := 
manifestParser.ComposeApiRecordsFromAllPackages(deployer.serviceDeployer.ClientConfig,
 manifest)
        if err != nil {
                return wskderrors.NewYAMLFileFormatError(manifestName, err)
        }
@@ -373,17 +373,16 @@ func (reader *ManifestReader) SetRules(rules 
[]*whisk.Rule) error {
 
 func (reader *ManifestReader) SetApis(ar []*whisk.ApiCreateRequest) error {
        dep := reader.serviceDeployer
-       var apis []*whisk.ApiCreateRequest = make([]*whisk.ApiCreateRequest, 0)
 
        dep.mt.Lock()
        defer dep.mt.Unlock()
 
-       for _, api := range apis {
-               existApi, exist := dep.Deployment.Apis[api.ApiDoc.ApiName]
+       for _, api := range ar {
+               existApi, exist := dep.Deployment.Apis[api.ApiDoc.Action.Name]
                if exist {
                        existApi.ApiDoc.ApiName = api.ApiDoc.ApiName
                } else {
-                       dep.Deployment.Apis[api.ApiDoc.ApiName] = api
+                       dep.Deployment.Apis[api.ApiDoc.Action.Name] = api
                }
 
        }
diff --git a/deployers/servicedeployer.go b/deployers/servicedeployer.go
index 8861619..14fc1c8 100644
--- a/deployers/servicedeployer.go
+++ b/deployers/servicedeployer.go
@@ -927,14 +927,20 @@ func (deployer *ServiceDeployer) createAction(pkgname 
string, action *whisk.Acti
 // create api (API Gateway functionality)
 func (deployer *ServiceDeployer) createApi(api *whisk.ApiCreateRequest) error {
 
-       displayPreprocessingInfo(parsers.YAML_KEY_API, api.ApiDoc.ApiName, true)
+       apiPath := api.ApiDoc.ApiName + " " + api.ApiDoc.GatewayBasePath +
+               api.ApiDoc.GatewayRelPath + " " + api.ApiDoc.GatewayMethod
+       displayPreprocessingInfo(parsers.YAML_KEY_API, apiPath, true)
 
        var err error
        var response *http.Response
 
-       // TODO() Is there an api delete function? could not find it
+       apiCreateReqOptions := new(whisk.ApiCreateRequestOptions)
+       apiCreateReqOptions.SpaceGuid = 
strings.Split(deployer.Client.Config.AuthToken, ":")[0]
+       apiCreateReqOptions.AccessToken = 
deployer.Client.Config.ApigwAccessToken
+       // TODO() Add Response type apiCreateReqOptions.ResponseType
+
        err = retry(DEFAULT_ATTEMPTS, DEFAULT_INTERVAL, func() error {
-               _, response, err = deployer.Client.Apis.Insert(api, nil, true)
+               _, response, err = deployer.Client.Apis.Insert(api, 
apiCreateReqOptions, true)
                return err
        })
 
@@ -942,7 +948,7 @@ func (deployer *ServiceDeployer) createApi(api 
*whisk.ApiCreateRequest) error {
                return createWhiskClientError(err.(*whisk.WskError), response, 
parsers.YAML_KEY_API, true)
        }
 
-       displayPostprocessingInfo(parsers.YAML_KEY_API, api.ApiDoc.ApiName, 
true)
+       displayPostprocessingInfo(parsers.YAML_KEY_API, apiPath, true)
        return nil
 }
 
@@ -990,6 +996,9 @@ func (deployer *ServiceDeployer) UnDeploy(verifiedPlan 
*DeploymentProject) error
 }
 
 func (deployer *ServiceDeployer) unDeployAssets(verifiedPlan 
*DeploymentProject) error {
+       if err := deployer.UnDeployApis(verifiedPlan); err != nil {
+               return err
+       }
 
        if err := deployer.UnDeployRules(verifiedPlan); err != nil {
                return err
@@ -1147,6 +1156,17 @@ func (deployer *ServiceDeployer) 
UnDeployRules(deployment *DeploymentProject) er
        return nil
 }
 
+func (deployer *ServiceDeployer) UnDeployApis(deployment *DeploymentProject) 
error {
+
+       for _, api := range deployment.Apis {
+               err := deployer.deleteApi(api)
+               if err != nil {
+                       return err
+               }
+       }
+       return nil
+}
+
 func (deployer *ServiceDeployer) deletePackage(packa *whisk.Package) error {
 
        displayPreprocessingInfo(parsers.YAML_KEY_PACKAGE, packa.Name, false)
@@ -1255,6 +1275,58 @@ func (deployer *ServiceDeployer) deleteRule(rule 
*whisk.Rule) error {
        return nil
 }
 
+func (deployer *ServiceDeployer) isApi(api *whisk.ApiCreateRequest) bool {
+       apiReqOptions := new(whisk.ApiGetRequestOptions)
+       apiReqOptions.AccessToken = deployer.Client.Config.ApigwAccessToken
+       apiReqOptions.ApiBasePath = api.ApiDoc.GatewayBasePath
+       apiReqOptions.SpaceGuid = 
strings.Split(deployer.Client.Config.AuthToken, ":")[0]
+
+       a := new(whisk.ApiGetRequest)
+
+       retApi, _, err := deployer.Client.Apis.Get(a, apiReqOptions)
+       if err == nil {
+               if retApi.Apis != nil && len(retApi.Apis) > 0 &&
+                       retApi.Apis[0].ApiValue != nil {
+                       return true
+               }
+
+       }
+       return false
+}
+
+// delete api (API Gateway functionality)
+func (deployer *ServiceDeployer) deleteApi(api *whisk.ApiCreateRequest) error {
+
+       apiPath := api.ApiDoc.ApiName + " " + api.ApiDoc.GatewayBasePath +
+               api.ApiDoc.GatewayRelPath + " " + api.ApiDoc.GatewayMethod
+       displayPreprocessingInfo(parsers.YAML_KEY_API, apiPath, false)
+
+       if deployer.isApi(api) {
+               var err error
+               var response *http.Response
+
+               apiDeleteReqOptions := new(whisk.ApiDeleteRequestOptions)
+               apiDeleteReqOptions.AccessToken = 
deployer.Client.Config.ApigwAccessToken
+               apiDeleteReqOptions.SpaceGuid = 
strings.Split(deployer.Client.Config.AuthToken, ":")[0]
+               apiDeleteReqOptions.ApiBasePath = api.ApiDoc.GatewayBasePath
+               apiDeleteReqOptions.ApiRelPath = api.ApiDoc.GatewayRelPath
+               apiDeleteReqOptions.ApiVerb = api.ApiDoc.GatewayMethod
+
+               a := new(whisk.ApiDeleteRequest)
+
+               err = retry(DEFAULT_ATTEMPTS, DEFAULT_INTERVAL, func() error {
+                       response, err = deployer.Client.Apis.Delete(a, 
apiDeleteReqOptions)
+                       return err
+               })
+
+               if err != nil {
+                       return createWhiskClientError(err.(*whisk.WskError), 
response, parsers.YAML_KEY_API, false)
+               }
+       }
+       displayPostprocessingInfo(parsers.YAML_KEY_API, apiPath, false)
+       return nil
+}
+
 // Utility function to call go-whisk framework to make action
 func (deployer *ServiceDeployer) deleteAction(pkgname string, action 
*whisk.Action) error {
        // call ActionService through Client
diff --git a/deployers/whiskclient.go b/deployers/whiskclient.go
index 83d2380..4935b81 100644
--- a/deployers/whiskclient.go
+++ b/deployers/whiskclient.go
@@ -42,6 +42,15 @@ const (
        SOURCE_DEFAULT_VALUE     = "wskdeploy default" // TODO() i18n?
 )
 
+var (
+       credential       = PropertyValue{}
+       namespace        = PropertyValue{}
+       apiHost          = PropertyValue{}
+       key              = PropertyValue{}
+       cert             = PropertyValue{}
+       apigwAccessToken = PropertyValue{}
+)
+
 type PropertyValue struct {
        Value  string
        Source string
@@ -63,8 +72,8 @@ var GetWskPropFromWhiskProperty = func(pi whisk.Properties) 
(*whisk.Wskprops, er
        return whisk.GetWskPropFromWhiskProperty(pi)
 }
 
-var GetCommandLineFlags = func() (string, string, string, string, string) {
-       return utils.Flags.ApiHost, utils.Flags.Auth, utils.Flags.Namespace, 
utils.Flags.Key, utils.Flags.Cert
+var GetCommandLineFlags = func() (string, string, string, string, string, 
string) {
+       return utils.Flags.ApiHost, utils.Flags.Auth, utils.Flags.Namespace, 
utils.Flags.Key, utils.Flags.Cert, utils.Flags.ApigwAccessToken
 }
 
 var CreateNewClient = func(config_input *whisk.Config) (*whisk.Client, error) {
@@ -74,106 +83,80 @@ var CreateNewClient = func(config_input *whisk.Config) 
(*whisk.Client, error) {
        return whisk.NewClient(netClient, config_input)
 }
 
-// we are reading openwhisk credentials (apihost, namespace, and auth) in the 
following precedence order:
-// (1) wskdeploy command line `wskdeploy --apihost --namespace --auth`
-// (2) deployment file
-// (3) manifest file
-// (4) .wskprops
-// (5) prompt for values in interactive mode if any of them are missing
-func NewWhiskConfig(proppath string, deploymentPath string, manifestPath 
string, isInteractive bool) (*whisk.Config, error) {
-       // struct to store credential, namespace, and host with their 
respective source
-       credential := PropertyValue{}
-       namespace := PropertyValue{}
-       apiHost := PropertyValue{}
-       key := PropertyValue{}
-       cert := PropertyValue{}
-
-       // read credentials from command line
-       apihost, auth, ns, keyfile, certfile := GetCommandLineFlags()
+func resetWhiskConfig() {
+       credential = PropertyValue{}
+       namespace = PropertyValue{}
+       apiHost = PropertyValue{}
+       key = PropertyValue{}
+       cert = PropertyValue{}
+       apigwAccessToken = PropertyValue{}
+}
+
+func readFromCLI() {
+       // read credentials, namespace, API host, key file, cert file, and 
APIGW access token from command line
+       apihost, auth, ns, keyfile, certfile, accessToken := 
GetCommandLineFlags()
        credential = GetPropertyValue(credential, auth, wski18n.COMMAND_LINE)
        namespace = GetPropertyValue(namespace, ns, wski18n.COMMAND_LINE)
        apiHost = GetPropertyValue(apiHost, apihost, wski18n.COMMAND_LINE)
        key = GetPropertyValue(key, keyfile, wski18n.COMMAND_LINE)
        cert = GetPropertyValue(cert, certfile, wski18n.COMMAND_LINE)
+       apigwAccessToken = GetPropertyValue(apigwAccessToken, accessToken, 
wski18n.COMMAND_LINE)
+}
 
-       // TODO() i18n
-       // Print all flags / values if verbose
-       wskprint.PrintlnOpenWhiskVerbose(utils.Flags.Verbose, 
wski18n.CONFIGURATION+":\n"+utils.Flags.Format())
+func setWhiskConfig(cred string, ns string, host string, token string, source 
string) {
+       credential = GetPropertyValue(credential, cred, source)
+       namespace = GetPropertyValue(namespace, ns, source)
+       apiHost = GetPropertyValue(apiHost, host, source)
+       apigwAccessToken = GetPropertyValue(apigwAccessToken, token, source)
+}
 
-       // TODO() split this logic into its own function
-       // TODO() merge with the same logic used against manifest file (below)
-       // now, read them from deployment file if not found on command line
+func readFromDeploymentFile(deploymentPath string) {
        if len(credential.Value) == 0 || len(namespace.Value) == 0 || 
len(apiHost.Value) == 0 {
                if utils.FileExists(deploymentPath) {
                        mm := parsers.NewYAMLParser()
                        deployment, _ := mm.ParseDeployment(deploymentPath)
-                       credential = GetPropertyValue(credential,
-                               deployment.GetProject().Credential,
-                               path.Base(deploymentPath))
-                       namespace = GetPropertyValue(namespace,
-                               deployment.GetProject().Namespace,
-                               path.Base(deploymentPath))
-                       apiHost = GetPropertyValue(apiHost,
-                               deployment.GetProject().ApiHost,
-                               path.Base(deploymentPath))
+                       p := deployment.GetProject()
+                       setWhiskConfig(p.Credential, p.Namespace, p.ApiHost, 
p.ApigwAccessToken, path.Base(deploymentPath))
                }
        }
+}
 
-       // TODO() split this logic into its own function
-       // TODO() merge with the same logic used against deployment file (above)
-       // read credentials from manifest file as didn't find them on command 
line and in deployment file
+func readFromManifestFile(manifestPath string) {
        if len(credential.Value) == 0 || len(namespace.Value) == 0 || 
len(apiHost.Value) == 0 {
                if utils.FileExists(manifestPath) {
                        mm := parsers.NewYAMLParser()
                        manifest, _ := mm.ParseManifest(manifestPath)
+                       var p = parsers.Package{}
                        if manifest.Package.Packagename != "" {
-                               credential = GetPropertyValue(credential,
-                                       manifest.Package.Credential,
-                                       path.Base(manifestPath))
-                               namespace = GetPropertyValue(namespace,
-                                       manifest.Package.Namespace,
-                                       path.Base(manifestPath))
-                               apiHost = GetPropertyValue(apiHost,
-                                       manifest.Package.ApiHost,
-                                       path.Base(manifestPath))
+                               p = manifest.Package
                        } else if manifest.Packages != nil {
                                if len(manifest.Packages) == 1 {
                                        for _, pkg := range manifest.Packages {
-                                               credential = 
GetPropertyValue(credential,
-                                                       pkg.Credential,
-                                                       path.Base(manifestPath))
-                                               namespace = 
GetPropertyValue(namespace,
-                                                       pkg.Namespace,
-                                                       path.Base(manifestPath))
-                                               apiHost = 
GetPropertyValue(apiHost,
-                                                       pkg.ApiHost,
-                                                       path.Base(manifestPath))
+                                               p = pkg
                                        }
                                }
                        }
+                       setWhiskConfig(p.Credential, p.Namespace, p.ApiHost, 
p.ApigwAccessToken, path.Base(manifestPath))
                }
        }
+}
 
-       // Third, we need to look up the variables in .wskprops file.
-       pi := whisk.PropertiesImp{
-               OsPackage: whisk.OSPackageImp{},
-       }
-
-       // The error raised here can be neglected, because we will handle it in 
the end of this function.
+func readFromWskprops(pi whisk.PropertiesImp, proppath string) {
+       // The error raised here can be neglected, because we will handle it in 
the end of its calling function.
        wskprops, _ := GetWskPropFromWskprops(pi, proppath)
        credential = GetPropertyValue(credential, wskprops.AuthKey, 
SOURCE_WSKPROPS)
        namespace = GetPropertyValue(namespace, wskprops.Namespace, 
SOURCE_WSKPROPS)
        apiHost = GetPropertyValue(apiHost, wskprops.APIHost, SOURCE_WSKPROPS)
        key = GetPropertyValue(key, wskprops.Key, SOURCE_WSKPROPS)
        cert = GetPropertyValue(cert, wskprops.Cert, SOURCE_WSKPROPS)
+       apigwAccessToken = GetPropertyValue(apigwAccessToken, 
wskprops.AuthAPIGWKey, SOURCE_WSKPROPS)
+}
 
-       // TODO() see if we can split the following whisk prop logic into a 
separate function
+func readFromWhiskProperty(pi whisk.PropertiesImp) {
        // now, read credentials from whisk.properties but this is only 
acceptable within Travis
        // whisk.properties will soon be deprecated and should not be used for 
any production deployment
        whiskproperty, _ := GetWskPropFromWhiskProperty(pi)
-
        var warnMsg string
-
        credential = GetPropertyValue(credential, whiskproperty.AuthKey, 
SOURCE_WHISK_PROPERTIES)
        if credential.Source == SOURCE_WHISK_PROPERTIES {
                warnMsg = wski18n.T(wski18n.ID_WARN_WHISK_PROPS_DEPRECATED,
@@ -192,29 +175,26 @@ func NewWhiskConfig(proppath string, deploymentPath 
string, manifestPath string,
                        map[string]interface{}{wski18n.KEY_KEY: 
wski18n.API_HOST})
                wskprint.PrintlnOpenWhiskWarning(warnMsg)
        }
-
-       // set namespace to default namespace if not yet found
-       if len(apiHost.Value) != 0 && len(credential.Value) != 0 && 
len(namespace.Value) == 0 {
-               namespace.Value = whisk.DEFAULT_NAMESPACE
-               namespace.Source = SOURCE_DEFAULT_VALUE
+       apigwAccessToken = GetPropertyValue(apigwAccessToken, 
whiskproperty.AuthAPIGWKey, SOURCE_WHISK_PROPERTIES)
+       if apigwAccessToken.Source == SOURCE_WHISK_PROPERTIES {
+               warnMsg = wski18n.T(wski18n.ID_WARN_WHISK_PROPS_DEPRECATED,
+                       map[string]interface{}{wski18n.KEY_KEY: 
wski18n.APIGW_ACCESS_TOKEN})
+               wskprint.PrintlnOpenWhiskWarning(warnMsg)
        }
+}
 
-       // TODO() See if we can split off the interactive logic into a separate 
function
-       // If we still can not find the values we need, check if it is 
interactive mode.
-       // If so, we prompt users for the input.
-       // The namespace is set to a default value at this point if not 
provided.
-       if len(apiHost.Value) == 0 && isInteractive == true {
+func readInteractivly() {
+       if len(apiHost.Value) == 0 {
                host := promptForValue(wski18n.T(wski18n.ID_MSG_PROMPT_APIHOST))
                if host == "" {
                        // TODO() programmatically tell caller that we are 
using this default
                        // TODO() make this configurable or remove
                        host = "openwhisk.ng.bluemix.net"
                }
-               apiHost.Value = host
-               apiHost.Source = SOURCE_INTERACTIVE_INPUT
+               apiHost = GetPropertyValue(apiHost, host, 
SOURCE_INTERACTIVE_INPUT)
        }
 
-       if len(credential.Value) == 0 && isInteractive == true {
+       if len(credential.Value) == 0 {
                cred := promptForValue(wski18n.T(wski18n.ID_MSG_PROMPT_AUTHKEY))
                credential.Value = cred
                credential.Source = SOURCE_INTERACTIVE_INPUT
@@ -230,24 +210,83 @@ func NewWhiskConfig(proppath string, deploymentPath 
string, manifestPath string,
                                source = SOURCE_DEFAULT_VALUE
                        }
 
-                       namespace.Value = tempNamespace
-                       namespace.Source = source
+                       namespace = GetPropertyValue(namespace, tempNamespace, 
source)
                }
        }
 
+       if len(apigwAccessToken.Value) == 0 {
+               accessToken := 
promptForValue(wski18n.T(wski18n.APIGW_ACCESS_TOKEN))
+               apigwAccessToken = GetPropertyValue(apigwAccessToken, 
accessToken, SOURCE_INTERACTIVE_INPUT)
+       }
+}
+
+// we are reading openwhisk credentials (apihost, namespace, and auth) in the 
following precedence order:
+// (1) wskdeploy command line `wskdeploy --apihost --namespace --auth`
+// (2) deployment file
+// (3) manifest file
+// (4) .wskprops
+// (5) prompt for values in interactive mode if any of them are missing
+// we are following the same precedence order for APIGW_ACCESS_TOKEN
+// but as a separate thread as APIGW_ACCESS_TOKEN only needed for APIs
+func NewWhiskConfig(proppath string, deploymentPath string, manifestPath 
string, isInteractive bool) (*whisk.Config, error) {
+       // reset credential, apiHost, namespace, etc to avoid any conflicts as 
they initialized globally
+       resetWhiskConfig()
+
+       // initialize APIGW_ACCESS_TOKEN to "DUMMY TOKEN" for Travis builds
+       if strings.ToLower(os.Getenv("TRAVIS")) == "true" {
+               apigwAccessToken.Value = "DUMMY TOKEN"
+               apigwAccessToken.Source = SOURCE_DEFAULT_VALUE
+       }
+
+       // read from command line
+       readFromCLI()
+
+       // TODO() i18n
+       // Print all flags / values if verbose
+       wskprint.PrintlnOpenWhiskVerbose(utils.Flags.Verbose, 
wski18n.CONFIGURATION+":\n"+utils.Flags.Format())
+
+       // now, read them from deployment file if not found on command line
+       readFromDeploymentFile(deploymentPath)
+
+       // read credentials from manifest file as didn't find them on command 
line and in deployment file
+       readFromManifestFile(manifestPath)
+
+       // Third, we need to look up the variables in .wskprops file.
+       pi := whisk.PropertiesImp{
+               OsPackage: whisk.OSPackageImp{},
+       }
+
+       readFromWskprops(pi, proppath)
+
+       readFromWhiskProperty(pi)
+
+       // set namespace to default namespace if not yet found
+       if len(apiHost.Value) != 0 && len(credential.Value) != 0 && 
len(namespace.Value) == 0 {
+               namespace.Value = whisk.DEFAULT_NAMESPACE
+               namespace.Source = SOURCE_DEFAULT_VALUE
+       }
+
+       // If we still can not find the values we need, check if it is 
interactive mode.
+       // If so, we prompt users for the input.
+       // The namespace is set to a default value at this point if not 
provided.
+       if isInteractive {
+               readInteractivly()
+       }
+
        mode := true
        if len(cert.Value) != 0 && len(key.Value) != 0 {
                mode = false
        }
 
        clientConfig = &whisk.Config{
-               AuthToken: credential.Value, //Authtoken
-               Namespace: namespace.Value,  //Namespace
-               Host:      apiHost.Value,
-               Version:   "v1", // TODO() should not be hardcoded, should 
prompt/warn user of default
-               Cert:      cert.Value,
-               Key:       key.Value,
-               Insecure:  mode, // true if you want to ignore certificate 
signing
+               AuthToken:        credential.Value, //Authtoken
+               Namespace:        namespace.Value,  //Namespace
+               Host:             apiHost.Value,
+               Version:          "v1", // TODO() should not be hardcoded, 
should prompt/warn user of default
+               Cert:             cert.Value,
+               Key:              key.Value,
+               Insecure:         mode, // true if you want to ignore 
certificate signing
+               ApigwAccessToken: apigwAccessToken.Value,
        }
 
        // validate we have credential, apihost and namespace
@@ -288,6 +327,12 @@ func validateClientConfig(credential PropertyValue, 
apiHost PropertyValue, names
                map[string]interface{}{wski18n.KEY_NAMESPACE: namespace.Value, 
wski18n.KEY_SOURCE: namespace.Source})
        wskprint.PrintOpenWhiskInfo(stdout)
 
+       if len(apigwAccessToken.Value) != 0 {
+               stdout = 
wski18n.T(wski18n.ID_MSG_CONFIG_INFO_APIGE_ACCESS_TOKEN_X_source_X,
+                       map[string]interface{}{wski18n.KEY_SOURCE: 
apigwAccessToken.Source})
+               wskprint.PrintOpenWhiskInfo(stdout)
+       }
+
        return nil
 }
 
diff --git a/parsers/manifest_parser.go b/parsers/manifest_parser.go
index c5eb0c8..87d76b3 100644
--- a/parsers/manifest_parser.go
+++ b/parsers/manifest_parser.go
@@ -35,6 +35,15 @@ import (
        "github.com/apache/incubator-openwhisk-wskdeploy/wskprint"
 )
 
+const (
+       PATH_SEPERATOR = "/"
+       API            = "API"
+       HTTPS          = "https"
+       HTTP           = "http"
+       API_VERSION    = "v1"
+       WEB            = "web"
+)
+
 // Read existing manifest file or create new if none exists
 func ReadOrCreateManifest() (*YAML, error) {
        maniyaml := YAML{}
@@ -858,12 +867,18 @@ func (dm *YAMLParser) ComposeRules(pkg Package, 
packageName string) ([]*whisk.Ru
        return r1, nil
 }
 
-func (dm *YAMLParser) ComposeApiRecordsFromAllPackages(manifest *YAML) 
([]*whisk.ApiCreateRequest, error) {
+func (dm *YAMLParser) ComposeApiRecordsFromAllPackages(client *whisk.Config, 
manifest *YAML) ([]*whisk.ApiCreateRequest, error) {
        var requests []*whisk.ApiCreateRequest = 
make([]*whisk.ApiCreateRequest, 0)
        manifestPackages := make(map[string]Package)
 
+       // verify APIGW_ACCESS_TOKEN is set before composing APIs
+       // until this point, we dont know whether APIs are specified in 
manifest or not
+       if len(client.ApigwAccessToken) == 0 {
+               return nil, 
wskderrors.NewWhiskClientInvalidConfigError(wski18n.ID_MSG_CONFIG_MISSING_APIGW_ACCESS_TOKEN)
+       }
+
        if manifest.Package.Packagename != "" {
-               return dm.ComposeApiRecords(manifest.Package)
+               return dm.ComposeApiRecords(client, 
manifest.Package.Packagename, manifest.Package, manifest.Filepath)
        } else {
                if len(manifest.Packages) != 0 {
                        manifestPackages = manifest.Packages
@@ -872,8 +887,8 @@ func (dm *YAMLParser) 
ComposeApiRecordsFromAllPackages(manifest *YAML) ([]*whisk
                }
        }
 
-       for _, p := range manifestPackages {
-               r, err := dm.ComposeApiRecords(p)
+       for packageName, p := range manifestPackages {
+               r, err := dm.ComposeApiRecords(client, packageName, p, 
manifest.Filepath)
                if err == nil {
                        requests = append(requests, r...)
                } else {
@@ -883,14 +898,102 @@ func (dm *YAMLParser) 
ComposeApiRecordsFromAllPackages(manifest *YAML) ([]*whisk
        return requests, nil
 }
 
-func (dm *YAMLParser) ComposeApiRecords(pkg Package) 
([]*whisk.ApiCreateRequest, error) {
-       var acq []*whisk.ApiCreateRequest = make([]*whisk.ApiCreateRequest, 0)
-       apis := pkg.GetApis()
+/*
+ * read API section from manifest file:
+ * apis: # List of APIs
+ *     hello-world: #API name
+ *     /hello: #gateway base path
+ *         /world:   #gateway rel path
+ *             greeting: get #action name: gateway method
+ *
+ * compose APIDoc structure from the manifest:
+ * {
+ *     "apidoc":{
+ *             "namespace":<namespace>,
+ *             "gatewayBasePath":"/hello",
+ *             "gatewayPath":"/world",
+ *             "gatewayMethod":"GET",
+ *             "action":{
+ *                     "name":"hello",
+ *                     "namespace":"guest",
+ *                     "backendMethod":"GET",
+ *                     "backendUrl":<url>,
+ *                     "authkey":<auth>
+ *             }
+ *     }
+ * }
+ */
+func (dm *YAMLParser) ComposeApiRecords(client *whisk.Config, packageName 
string, pkg Package, manifestPath string) ([]*whisk.ApiCreateRequest, error) {
+       var requests []*whisk.ApiCreateRequest = 
make([]*whisk.ApiCreateRequest, 0)
+
+       for apiName, apiDoc := range pkg.Apis {
+               for gatewayBasePath, gatewayBasePathMap := range apiDoc {
+                       // append "/" to the gateway base path if its missing
+                       if !strings.HasPrefix(gatewayBasePath, PATH_SEPERATOR) {
+                               gatewayBasePath = PATH_SEPERATOR + 
gatewayBasePath
+                       }
+                       for gatewayRelPath, gatewayRelPathMap := range 
gatewayBasePathMap {
+                               // append "/" to the gateway relative path if 
its missing
+                               if !strings.HasPrefix(gatewayRelPath, 
PATH_SEPERATOR) {
+                                       gatewayRelPath = PATH_SEPERATOR + 
gatewayRelPath
+                               }
+                               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 {
+                                               // verify that the action is 
defined as web action
+                                               // web-export set to any of 
[true, yes, raw]
+                                               if 
!utils.IsWebAction(pkg.Actions[actionName].Webexport) {
+                                                       return nil, 
wskderrors.NewYAMLFileFormatError(manifestPath,
+                                                               
wski18n.T(wski18n.ID_ERR_API_MISSING_WEB_ACTION_X_action_X_api_X,
+                                                                       
map[string]interface{}{
+                                                                               
wski18n.KEY_ACTION: actionName,
+                                                                               
wski18n.KEY_API:    apiName}))
+                                               } else {
+                                                       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)
+                                                       
request.ApiDoc.Action.Name = packageName + PATH_SEPERATOR + actionName
+                                                       
request.ApiDoc.Action.Namespace = client.Namespace
+                                                       url := []string{HTTPS + 
":" + PATH_SEPERATOR, client.Host, strings.ToLower(API),
+                                                               API_VERSION, 
WEB, client.Namespace, packageName, actionName + "." + HTTP}
+                                                       
request.ApiDoc.Action.BackendUrl = strings.Join(url, PATH_SEPERATOR)
+                                                       
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 requests, nil
+}
 
-       for _, api := range apis {
-               acr := new(whisk.ApiCreateRequest)
-               acr.ApiDoc = api
-               acq = append(acq, acr)
+func (dm *YAMLParser) getGatewayMethods() []string {
+       methods := []string{}
+       for k := range whisk.ApiVerbs {
+               methods = append(methods, k)
        }
-       return acq, nil
+       return methods
 }
diff --git a/parsers/manifest_parser_test.go b/parsers/manifest_parser_test.go
index a55566c..cd07c5c 100644
--- a/parsers/manifest_parser_test.go
+++ b/parsers/manifest_parser_test.go
@@ -1345,23 +1345,43 @@ func TestComposeRules(t *testing.T) {
 }
 
 func TestComposeApiRecords(t *testing.T) {
-       data := `package:
-  name: helloworld
-  apis:
-    book-club:
-      club:
-        books:
-           putBooks: put
-           deleteBooks: delete
-        members:
-           listMembers: get
-    book-club2:
-      club2:
-        books2:
-           getBooks2: get
-           postBooks2: post
-        members2:
-           listMembers2: get`
+       data := `
+packages:
+  apiTest:
+    actions:
+      putBooks:
+        function: ../tests/src/integration/helloworld/actions/hello.js
+        web-export: true
+      deleteBooks:
+        function: ../tests/src/integration/helloworld/actions/hello.js
+        web-export: true
+      listMembers:
+        function: ../tests/src/integration/helloworld/actions/hello.js
+        web-export: true
+      getBooks2:
+        function: ../tests/src/integration/helloworld/actions/hello.js
+        web-export: true
+      postBooks2:
+        function: ../tests/src/integration/helloworld/actions/hello.js
+        web-export: true
+      listMembers2:
+        function: ../tests/src/integration/helloworld/actions/hello.js
+        web-export: true
+    apis:
+      book-club:
+        club:
+          books:
+            putBooks: put
+            deleteBooks: delete
+          members:
+            listMembers: get
+      book-club2:
+        club2:
+          books2:
+            getBooks2: get
+            postBooks2: post
+          members2:
+            listMembers2: get`
        tmpfile, err := _createTmpfile(data, "manifest_parser_test_")
        if err != nil {
                assert.Fail(t, "Failed to create temp file")
@@ -1373,44 +1393,52 @@ func TestComposeApiRecords(t *testing.T) {
        // read and parse manifest.yaml file
        p := NewYAMLParser()
        m, _ := p.ParseManifest(tmpfile.Name())
-       apiList, err := p.ComposeApiRecordsFromAllPackages(m)
+
+       config := whisk.Config{
+               Namespace:        "test",
+               AuthToken:        "user:pass",
+               Host:             "host",
+               ApigwAccessToken: "token",
+       }
+
+       apiList, err := p.ComposeApiRecordsFromAllPackages(&config, m)
        if err != nil {
-               assert.Fail(t, "Failed to compose api records")
+               assert.Fail(t, "Failed to compose api records: "+err.Error())
        }
        assert.Equal(t, 6, len(apiList), "Failed to get api records")
        for _, apiRecord := range apiList {
                apiDoc := apiRecord.ApiDoc
                action := apiDoc.Action
                switch action.Name {
-               case "putBooks":
+               case "apiTest/putBooks":
                        assert.Equal(t, "book-club", apiDoc.ApiName, "Failed to 
set api name")
-                       assert.Equal(t, "club", apiDoc.GatewayBasePath, "Failed 
to set api base path")
-                       assert.Equal(t, "books", apiDoc.GatewayRelPath, "Failed 
to set api rel path")
+                       assert.Equal(t, "/club", apiDoc.GatewayBasePath, 
"Failed to set api base path")
+                       assert.Equal(t, "/books", apiDoc.GatewayRelPath, 
"Failed to set api rel path")
                        assert.Equal(t, "put", action.BackendMethod, "Failed to 
set api backend method")
-               case "deleteBooks":
+               case "apiTest/deleteBooks":
                        assert.Equal(t, "book-club", apiDoc.ApiName, "Failed to 
set api name")
-                       assert.Equal(t, "club", apiDoc.GatewayBasePath, "Failed 
to set api base path")
-                       assert.Equal(t, "books", apiDoc.GatewayRelPath, "Failed 
to set api rel path")
+                       assert.Equal(t, "/club", apiDoc.GatewayBasePath, 
"Failed to set api base path")
+                       assert.Equal(t, "/books", apiDoc.GatewayRelPath, 
"Failed to set api rel path")
                        assert.Equal(t, "delete", action.BackendMethod, "Failed 
to set api backend method")
-               case "listMembers":
+               case "apiTest/listMembers":
                        assert.Equal(t, "book-club", apiDoc.ApiName, "Failed to 
set api name")
-                       assert.Equal(t, "club", apiDoc.GatewayBasePath, "Failed 
to set api base path")
-                       assert.Equal(t, "members", apiDoc.GatewayRelPath, 
"Failed to set api rel path")
+                       assert.Equal(t, "/club", apiDoc.GatewayBasePath, 
"Failed to set api base path")
+                       assert.Equal(t, "/members", apiDoc.GatewayRelPath, 
"Failed to set api rel path")
                        assert.Equal(t, "get", action.BackendMethod, "Failed to 
set api backend method")
-               case "getBooks2":
+               case "apiTest/getBooks2":
                        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, "books2", apiDoc.GatewayRelPath, 
"Failed to set api rel path")
+                       assert.Equal(t, "/club2", apiDoc.GatewayBasePath, 
"Failed to set api base path")
+                       assert.Equal(t, "/books2", apiDoc.GatewayRelPath, 
"Failed to set api rel path")
                        assert.Equal(t, "get", action.BackendMethod, "Failed to 
set api backend method")
-               case "postBooks2":
+               case "apiTest/postBooks2":
                        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, "books2", apiDoc.GatewayRelPath, 
"Failed to set api rel path")
+                       assert.Equal(t, "/club2", apiDoc.GatewayBasePath, 
"Failed to set api base path")
+                       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 "listMembers2":
+               case "apiTest/listMembers2":
                        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, "/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/parsers/yamlparser.go b/parsers/yamlparser.go
index b0b35fe..7e51714 100644
--- a/parsers/yamlparser.go
+++ b/parsers/yamlparser.go
@@ -191,28 +191,30 @@ type Package struct {
        Repositories []Repository          `yaml:"repositories,omitempty"`
        Dependencies map[string]Dependency `yaml: dependencies` //used in 
manifest.yaml
        //mapping to wsk.SentPackageNoPublish.Namespace
-       Namespace   string                 `yaml:"namespace"`  //used in both 
manifest.yaml and deployment.yaml
-       Credential  string                 `yaml:"credential"` //used in both 
manifest.yaml and deployment.yaml
-       ApiHost     string                 `yaml:"apiHost"`    //used in both 
manifest.yaml and deployment.yaml
-       Actions     map[string]Action      `yaml:"actions"`    //used in both 
manifest.yaml and deployment.yaml
-       Triggers    map[string]Trigger     `yaml:"triggers"`   //used in both 
manifest.yaml and deployment.yaml
-       Feeds       map[string]Feed        `yaml:"feeds"`      //used in both 
manifest.yaml and deployment.yaml
-       Rules       map[string]Rule        `yaml:"rules"`      //used in both 
manifest.yaml and deployment.yaml
-       Inputs      map[string]Parameter   `yaml:"inputs"`     //deprecated, 
used in deployment.yaml
-       Sequences   map[string]Sequence    `yaml:"sequences"`
-       Annotations map[string]interface{} `yaml:"annotations,omitempty"`
+       Namespace        string                 `yaml:"namespace"`  //used in 
both manifest.yaml and deployment.yaml
+       Credential       string                 `yaml:"credential"` //used in 
both manifest.yaml and deployment.yaml
+       ApiHost          string                 `yaml:"apiHost"`    //used in 
both manifest.yaml and deployment.yaml
+       ApigwAccessToken string                 `yaml:"apigwAccessToken"`
+       Actions          map[string]Action      `yaml:"actions"`  //used in 
both manifest.yaml and deployment.yaml
+       Triggers         map[string]Trigger     `yaml:"triggers"` //used in 
both manifest.yaml and deployment.yaml
+       Feeds            map[string]Feed        `yaml:"feeds"`    //used in 
both manifest.yaml and deployment.yaml
+       Rules            map[string]Rule        `yaml:"rules"`    //used in 
both manifest.yaml and deployment.yaml
+       Inputs           map[string]Parameter   `yaml:"inputs"`   //deprecated, 
used in deployment.yaml
+       Sequences        map[string]Sequence    `yaml:"sequences"`
+       Annotations      map[string]interface{} `yaml:"annotations,omitempty"`
        //Parameters  map[string]interface{} `yaml: parameters` // used in 
manifest.yaml
        Apis map[string]map[string]map[string]map[string]string `yaml:"apis"` 
//used in manifest.yaml
 }
 
 type Project struct {
-       Name       string             `yaml:"name"`      //used in 
deployment.yaml
-       Namespace  string             `yaml:"namespace"` //used in 
deployment.yaml
-       Credential string             `yaml:"credential"`
-       ApiHost    string             `yaml:"apiHost"`
-       Version    string             `yaml:"version"`
-       Packages   map[string]Package `yaml:"packages"` //used in 
deployment.yaml
-       Package    Package            `yaml:"package"`  // being deprecated, 
used in deployment.yaml
+       Name             string             `yaml:"name"`      //used in 
deployment.yaml
+       Namespace        string             `yaml:"namespace"` //used in 
deployment.yaml
+       Credential       string             `yaml:"credential"`
+       ApiHost          string             `yaml:"apiHost"`
+       ApigwAccessToken string             `yaml:"apigwAccessToken"`
+       Version          string             `yaml:"version"`
+       Packages         map[string]Package `yaml:"packages"` //used in 
deployment.yaml
+       Package          Package            `yaml:"package"`  // being 
deprecated, used in deployment.yaml
 }
 
 type YAML struct {
diff --git a/tests/src/integration/apigateway/apigateway_test.go 
b/tests/src/integration/apigateway/apigateway_test.go
index 6bc3355..a75a033 100644
--- a/tests/src/integration/apigateway/apigateway_test.go
+++ b/tests/src/integration/apigateway/apigateway_test.go
@@ -1,4 +1,4 @@
-// +build integration
+// +build skip_integration
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
diff --git a/tests/src/integration/apigateway/manifest.yml 
b/tests/src/integration/apigateway/manifest.yml
index 62f4dd0..407347a 100644
--- a/tests/src/integration/apigateway/manifest.yml
+++ b/tests/src/integration/apigateway/manifest.yml
@@ -15,35 +15,42 @@
 #
 
 packages:
-  api-gateway-test:
-      version: 1.0
-      license: Apache-2.0
-      actions:
-          greeting:
-            version: 1.0
-            function: src/greeting.js
-            runtime: nodejs:6
-            inputs:
-              name: string
-              place: string
-            outputs:
-              payload: string
-      apis: # new top-level key for defining groups of named APIs
-        book-club: #api name
-          club: # shared base path
-            books:   #path
-               getBooks: get #action name:verb
-               postBooks: post
-               putBooks: put
-               deleteBooks: delete
-            members: #path
-               listMembers: get #action name:verb
-        book-club2: #api name, added for multi api definition test
-              club2: # shared base path
-                books2:   #path
-                   getBooks2: get #action name:verb
-                   postBooks2: post
-                   putBooks2: put
-                   deleteBooks2: delete
-                members2: #path
-                   listMembers2: get #action name:verb
+    api-gateway-test:
+        version: 1.0
+        license: Apache-2.0
+        actions:
+            greeting:
+                web-export: true
+                version: 1.0
+                function: src/greeting.js
+                runtime: nodejs:6
+            getBooks:
+                web-export: true
+                function: src/get-books.js
+            postBooks:
+                web-export: true
+                function: src/post-books.js
+            putBooks:
+                web-export: true
+                function: src/put-books.js
+            deleteBooks:
+                web-export: true
+                function: src/delete-books.js
+            listMembers:
+                web-export: true
+                function: src/list-members.js
+        # new top-level key for defining groups of named APIs
+        apis:
+            hello-world:
+                hello:
+                    world:
+                        greeting: GET
+            book-club:
+                club:
+                    books:
+                        getBooks: GET
+                        postBooks: POST
+                        putBooks: PUT
+                        deleteBooks: DELETE
+                    members:
+                        listMembers: GET
diff --git a/tests/src/integration/apigateway/src/delete-books.js 
b/tests/src/integration/apigateway/src/delete-books.js
new file mode 100644
index 0000000..d2047a5
--- /dev/null
+++ b/tests/src/integration/apigateway/src/delete-books.js
@@ -0,0 +1,23 @@
+/**
+ * Return success saying a book was deleted from the book store.
+ */
+function main(params) {
+    return new Promise(function(resolve, reject) {
+        console.log(params.name);
+
+        if (!params.name) {
+            console.error('name parameter not set.');
+            reject({
+                'error': 'name parameter not set.'
+            });
+            return;
+        } else {
+            var message = 'A book ' + params.name + ' was deleted from the 
book store.';
+            console.log(message);
+            resolve({
+                result: message
+            });
+            return;
+        }
+    });
+}
diff --git a/tests/src/integration/apigateway/src/get-books.js 
b/tests/src/integration/apigateway/src/get-books.js
new file mode 100644
index 0000000..e72f70d
--- /dev/null
+++ b/tests/src/integration/apigateway/src/get-books.js
@@ -0,0 +1,13 @@
+/**
+ * Return a list of books in the book store.
+ */
+function main(params) {
+    return new Promise(function(resolve, reject) {
+        var message = 'List of books in the book store: '
+        console.log(message);
+        resolve({
+            result: {"name":"JavaScript: The Good Parts", 
"ISBN":"978-0596517748"}
+        });
+        return;
+    });
+}
diff --git a/tests/src/integration/apigateway/src/list-members.js 
b/tests/src/integration/apigateway/src/list-members.js
new file mode 100644
index 0000000..7396fd2
--- /dev/null
+++ b/tests/src/integration/apigateway/src/list-members.js
@@ -0,0 +1,13 @@
+/**
+ * Return a list of members in the book store.
+ */
+function main(params) {
+    return new Promise(function(resolve, reject) {
+        var message = 'List of members in the book store: '
+        console.log(message);
+        resolve({
+            result: {"name":"Anne Li", "name":"Bob Young"}
+        });
+        return;
+    });
+}
diff --git a/tests/src/integration/apigateway/src/post-books.js 
b/tests/src/integration/apigateway/src/post-books.js
new file mode 100644
index 0000000..0b30575
--- /dev/null
+++ b/tests/src/integration/apigateway/src/post-books.js
@@ -0,0 +1,24 @@
+/**
+ * Return success saying a book was added into the book store.
+ */
+function main(params) {
+    return new Promise(function(resolve, reject) {
+        console.log(params.name);
+        console.log(params.isbn);
+
+        if (!params.name) {
+            console.error('name parameter not set.');
+            reject({
+                'error': 'name parameter not set.'
+            });
+            return;
+        } else {
+            var message = 'A book ' + params.name + ' was added to the book 
store with ISBN ' + params.isbn;
+            console.log(message);
+            resolve({
+                result: message
+            });
+            return;
+        }
+    });
+}
diff --git a/tests/src/integration/apigateway/src/put-books.js 
b/tests/src/integration/apigateway/src/put-books.js
new file mode 100644
index 0000000..611c04a
--- /dev/null
+++ b/tests/src/integration/apigateway/src/put-books.js
@@ -0,0 +1,30 @@
+/**
+ * Return success saying a book was updated into the book store.
+ */
+function main(params) {
+    return new Promise(function(resolve, reject) {
+        console.log(params.name);
+        console.log(params.isbn);
+
+        if (!params.name) {
+            console.error('name parameter not set.');
+            reject({
+                'error': 'name parameter not set.'
+            });
+            return;
+        } else if (!params.isbn) {
+            console.error('isbn parameter not set.');
+            reject({
+                'error': 'isbn parameter not set.'
+            });
+            return;
+        } else {
+            var message = 'A book ' + params.name + ' was updated to a new 
ISBN ' + params.isbn;
+            console.log(message);
+            resolve({
+                result: message
+            });
+            return;
+        }
+    });
+}
diff --git a/utils/flags.go b/utils/flags.go
index 1f61cbb..4ec1a62 100644
--- a/utils/flags.go
+++ b/utils/flags.go
@@ -23,24 +23,25 @@ import (
 )
 
 type WskDeployFlags struct {
-       WithinOpenWhisk bool   // is this running within an OpenWhisk action?
-       ApiHost         string // OpenWhisk API host
-       Auth            string // OpenWhisk API key
-       Namespace       string
-       ApiVersion      string // OpenWhisk version
-       CfgFile         string
-       CliVersion      string
-       CliBuild        string
-       Verbose         bool
-       ProjectPath     string
-       DeploymentPath  string
-       ManifestPath    string
-       UseDefaults     bool
-       UseInteractive  bool
-       Strict          bool // strict flag to support user defined runtime 
version.
-       Key             string
-       Cert            string
-       Managed         bool // OpenWhisk Managed Deployments
+       WithinOpenWhisk  bool   // is this running within an OpenWhisk action?
+       ApiHost          string // OpenWhisk API host
+       Auth             string // OpenWhisk API key
+       Namespace        string
+       ApiVersion       string // OpenWhisk version
+       CfgFile          string
+       CliVersion       string
+       CliBuild         string
+       Verbose          bool
+       ProjectPath      string
+       DeploymentPath   string
+       ManifestPath     string
+       UseDefaults      bool
+       UseInteractive   bool
+       Strict           bool // strict flag to support user defined runtime 
version.
+       Key              string
+       Cert             string
+       Managed          bool // OpenWhisk Managed Deployments
+       ApigwAccessToken string
 }
 
 func (flags *WskDeployFlags) Format() string {
diff --git a/utils/webaction.go b/utils/webaction.go
index ed05ad3..0d6c9c6 100644
--- a/utils/webaction.go
+++ b/utils/webaction.go
@@ -28,7 +28,7 @@ const WEB_EXPORT_ANNOT = "web-export"
 const RAW_HTTP_ANNOT = "raw-http"
 const FINAL_ANNOT = "final"
 
-var webexport map[string]string = map[string]string{
+var webExport map[string]string = map[string]string{
        "TRUE":  "true",
        "FALSE": "false",
        "NO":    "no",
@@ -38,15 +38,15 @@ var webexport map[string]string = map[string]string{
 
 func WebAction(filePath string, action string, webMode string, annotations 
whisk.KeyValueArr, fetch bool) (whisk.KeyValueArr, error) {
        switch strings.ToLower(webMode) {
-       case webexport["TRUE"]:
+       case webExport["TRUE"]:
                fallthrough
-       case webexport["YES"]:
+       case webExport["YES"]:
                return webActionAnnotations(fetch, annotations, 
addWebAnnotations)
-       case webexport["NO"]:
+       case webExport["NO"]:
                fallthrough
-       case webexport["FALSE"]:
+       case webExport["FALSE"]:
                return webActionAnnotations(fetch, annotations, 
deleteWebAnnotations)
-       case webexport["RAW"]:
+       case webExport["RAW"]:
                return webActionAnnotations(fetch, annotations, 
addRawAnnotations)
        default:
                return nil, wskderrors.NewInvalidWebExportError(filePath, 
action, webMode, getValidWebExports())
@@ -103,8 +103,18 @@ func deleteWebAnnotationKeys(annotations 
whisk.KeyValueArr) whisk.KeyValueArr {
 
 func getValidWebExports() []string {
        var validWebExports []string
-       for _, v := range webexport {
+       for _, v := range webExport {
                validWebExports = append(validWebExports, v)
        }
        return validWebExports
 }
+
+func IsWebAction(webexport string) bool {
+       webexport = strings.ToLower(webexport)
+       if len(webexport) != 0 {
+               if webexport == webExport["TRUE"] || webexport == 
webExport["YES"] || webexport == webExport["RAW"] {
+                       return true
+               }
+       }
+       return false
+}
diff --git a/wskderrors/wskdeployerror.go b/wskderrors/wskdeployerror.go
index 1667ce2..e3c87c7 100644
--- a/wskderrors/wskdeployerror.go
+++ b/wskderrors/wskdeployerror.go
@@ -44,22 +44,26 @@ const (
        STR_HTTP_BODY             = "HTTP Response Body"
        STR_SUPPORTED_WEB_EXPORTS = "Supported Web Exports"
        STR_WEB_EXPORT            = "web-export"
+       STR_API                   = "API"
+       STR_API_METHOD            = "API gateway method"
+       STR_API_SUPPORTED_METHODS = "API gateway supported methods"
 
        // Formatting
        STR_INDENT_1 = "==>"
 
        // Error Types
-       ERROR_COMMAND_FAILED               = "ERROR_COMMAND_FAILED"
-       ERROR_WHISK_CLIENT_ERROR           = "ERROR_WHISK_CLIENT_ERROR"
-       ERROR_WHISK_CLIENT_INVALID_CONFIG  = "ERROR_WHISK_CLIENT_INVALID_CONFIG"
-       ERROR_FILE_READ_ERROR              = "ERROR_FILE_READ_ERROR"
-       ERROR_MANIFEST_FILE_NOT_FOUND      = "ERROR_MANIFEST_FILE_NOT_FOUND"
-       ERROR_YAML_FILE_FORMAT_ERROR       = "ERROR_YAML_FILE_FORMAT_ERROR"
-       ERROR_YAML_PARSER_ERROR            = "ERROR_YAML_PARSER_ERROR"
-       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"
+       ERROR_COMMAND_FAILED                  = "ERROR_COMMAND_FAILED"
+       ERROR_WHISK_CLIENT_ERROR              = "ERROR_WHISK_CLIENT_ERROR"
+       ERROR_WHISK_CLIENT_INVALID_CONFIG     = 
"ERROR_WHISK_CLIENT_INVALID_CONFIG"
+       ERROR_FILE_READ_ERROR                 = "ERROR_FILE_READ_ERROR"
+       ERROR_MANIFEST_FILE_NOT_FOUND         = "ERROR_MANIFEST_FILE_NOT_FOUND"
+       ERROR_YAML_FILE_FORMAT_ERROR          = "ERROR_YAML_FILE_FORMAT_ERROR"
+       ERROR_YAML_PARSER_ERROR               = "ERROR_YAML_PARSER_ERROR"
+       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"
+       ERROR_YAML_INVALID_API_GATEWAY_METHOD = 
"ERROR_YAML_INVALID_API_GATEWAY_METHOD"
 )
 
 /*
@@ -407,6 +411,31 @@ func NewInvalidWebExportError(fpath string, action string, 
webexport string, sup
        err.SetMessage(str)
        return err
 }
+
+/*
+ * Invalid API Gateway Method
+ */
+type InvalidAPIGatewayMethodError struct {
+       FileError
+       method           string
+       SupportedMethods []string
+}
+
+func NewInvalidAPIGatewayMethodError(fpath string, api string, method string, 
supportedMethods []string) *InvalidAPIGatewayMethodError {
+       var err = &InvalidAPIGatewayMethodError{
+               SupportedMethods: supportedMethods,
+       }
+       err.SetErrorFilePath(fpath)
+       err.SetErrorType(ERROR_YAML_INVALID_API_GATEWAY_METHOD)
+       err.SetCallerByStackFrameSkip(2)
+       str := fmt.Sprintf("%s [%s]: %s [%s]: %s [%s]",
+               STR_API, api,
+               STR_API_METHOD, method,
+               STR_API_SUPPORTED_METHODS, strings.Join(supportedMethods, ", "))
+       err.SetMessage(str)
+       return err
+}
+
 func IsCustomError(err error) bool {
 
        switch err.(type) {
diff --git a/wski18n/i18n_ids.go b/wski18n/i18n_ids.go
index d2f4be3..3ce8f21 100644
--- a/wski18n/i18n_ids.go
+++ b/wski18n/i18n_ids.go
@@ -20,34 +20,35 @@ package wski18n
 // descriptive key names
 // DO NOT TRANSLATE
 const (
-       ACTION_CODE     = "Action source"
-       ACTIONS         = "Actions"
-       ACTIVATIONS     = "Activations"
-       API_HOST        = "API host"
-       AUTH_KEY        = "authentication key"
-       COMMAND_LINE    = "wskdeploy command line"
-       DEPLOYMENT      = "deployment"
-       CONFIGURATION   = "Configuration"
-       MANIFEST        = "manifest"
-       NAME_ACTION     = "Action Name"
-       NAME_FEED       = "Feed Name"
-       NAME_RULE       = "Rule Name"
-       NAME_RUNTIME    = "Runtime Name"
-       NAME_TRIGGER    = "Trigger Name"
-       NAMESPACES      = "Namespaces"
-       PACKAGE_BINDING = "package binding"
-       PACKAGE_LICENSE = "package license"
-       PACKAGE_NAME    = "package name"
-       PACKAGE_VERSION = "package version"
-       PACKAGES        = "Packages"
-       PROJECT_NAME    = "project name"
-       REGISTRY        = "registry"
-       REGISTRY_URL    = "registry URL"
-       REPOSITORY      = "repository"
-       RULES           = "Rules"
-       TRIGGER_FEED    = "trigger feed"
-       TRIGGERS        = "Triggers"
-       WHISK_PROPS     = "wskprops"
+       ACTION_CODE        = "Action source"
+       ACTIONS            = "Actions"
+       ACTIVATIONS        = "Activations"
+       API_HOST           = "API host"
+       AUTH_KEY           = "authentication key"
+       COMMAND_LINE       = "wskdeploy command line"
+       DEPLOYMENT         = "deployment"
+       CONFIGURATION      = "Configuration"
+       MANIFEST           = "manifest"
+       NAME_ACTION        = "Action Name"
+       NAME_FEED          = "Feed Name"
+       NAME_RULE          = "Rule Name"
+       NAME_RUNTIME       = "Runtime Name"
+       NAME_TRIGGER       = "Trigger Name"
+       NAMESPACES         = "Namespaces"
+       PACKAGE_BINDING    = "package binding"
+       PACKAGE_LICENSE    = "package license"
+       PACKAGE_NAME       = "package name"
+       PACKAGE_VERSION    = "package version"
+       PACKAGES           = "Packages"
+       PROJECT_NAME       = "project name"
+       REGISTRY           = "registry"
+       REGISTRY_URL       = "registry URL"
+       REPOSITORY         = "repository"
+       RULES              = "Rules"
+       TRIGGER_FEED       = "trigger feed"
+       TRIGGERS           = "Triggers"
+       WHISK_PROPS        = "wskprops"
+       APIGW_ACCESS_TOKEN = "API Gateway Access Token"
 )
 
 // i18n Identifiers
@@ -92,9 +93,11 @@ const (
        ID_MSG_CONFIG_MISSING_AUTHKEY                       = 
"msg_config_missing_authkey"
        ID_MSG_CONFIG_MISSING_APIHOST                       = 
"msg_config_missing_apihost"
        ID_MSG_CONFIG_MISSING_NAMESPACE                     = 
"msg_config_missing_namespace"
+       ID_MSG_CONFIG_MISSING_APIGW_ACCESS_TOKEN            = 
"msg_config_missing_apigw_access_token"
        ID_MSG_CONFIG_INFO_APIHOST_X_host_X_source_X        = 
"msg_config_apihost_info"
        ID_MSG_CONFIG_INFO_AUTHKEY_X_source_X               = 
"msg_config_authkey_info"
        ID_MSG_CONFIG_INFO_NAMESPACE_X_namespace_X_source_X = 
"msg_config_namespace_info"
+       ID_MSG_CONFIG_INFO_APIGE_ACCESS_TOKEN_X_source_X    = 
"msg_config_apigw_access_token_info"
 
        // YAML marshall / unmarshall
        ID_MSG_UNMARSHAL_LOCAL   = "msg_unmarshall_local"
@@ -150,6 +153,8 @@ const (
        ID_ERR_RUNTIMES_GET_X_err_X                                  = 
"msg_err_runtimes_get"
        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_WEB_ACTION_X_action_X_api_X               = 
"msg_err_api_missing_web_action"
+       ID_ERR_API_MISSING_ACTION_X_action_X_api_X                   = 
"msg_err_api_missing_action"
 
        // Server-side Errors (wskdeploy as an Action)
        ID_ERR_JSON_MISSING_KEY_CMD = "msg_err_json_missing_cmd_key"
@@ -180,32 +185,34 @@ const (
 
 // Known keys used for text replacement in i18n translated strings
 const (
-       KEY_ACTION          = "action"
-       KEY_CMD             = "cmd"
-       KEY_CODE            = "code"
-       KEY_DEPLOYMENT_NAME = "dname"
-       KEY_DEPLOYMENT_PATH = "dpath"
-       KEY_ERR             = "err"
-       KEY_EXTENTION       = "ext"
-       KEY_FILE_TYPE       = "filetype"
-       KEY_HOST            = "host"
-       KEY_KEY             = "key"
-       KEY_LIMIT           = "limit"
-       KEY_MANIFEST_NAME   = "mname"
-       KEY_MANIFEST_PATH   = "mpath"
-       KEY_NAME            = "name"
-       KEY_NAMESPACE       = "namespace"
-       KEY_NEW             = "newkey"
-       KEY_OLD             = "oldkey"
-       KEY_PATH            = "path"
-       KEY_PROJECT         = "project"
-       KEY_RUNTIME         = "runtime"
-       KEY_SOURCE          = "source"
-       KEY_URL             = "url"
-       KEY_URL_TYPE        = "urltype"
-       KEY_VALUE           = "value"
-       KEY_VALUE_MIN       = "min" // TODO() attempt to use this for Limit 
value range errors
-       KEY_VALUE_MAX       = "max" // TODO() attempt to use this for Limit 
value range errors
+       KEY_ACTION             = "action"
+       KEY_CMD                = "cmd"
+       KEY_CODE               = "code"
+       KEY_DEPLOYMENT_NAME    = "dname"
+       KEY_DEPLOYMENT_PATH    = "dpath"
+       KEY_ERR                = "err"
+       KEY_EXTENTION          = "ext"
+       KEY_FILE_TYPE          = "filetype"
+       KEY_HOST               = "host"
+       KEY_KEY                = "key"
+       KEY_LIMIT              = "limit"
+       KEY_MANIFEST_NAME      = "mname"
+       KEY_MANIFEST_PATH      = "mpath"
+       KEY_NAME               = "name"
+       KEY_NAMESPACE          = "namespace"
+       KEY_NEW                = "newkey"
+       KEY_OLD                = "oldkey"
+       KEY_PATH               = "path"
+       KEY_PROJECT            = "project"
+       KEY_RUNTIME            = "runtime"
+       KEY_SOURCE             = "source"
+       KEY_URL                = "url"
+       KEY_URL_TYPE           = "urltype"
+       KEY_VALUE              = "value"
+       KEY_VALUE_MIN          = "min" // TODO() attempt to use this for Limit 
value range errors
+       KEY_VALUE_MAX          = "max" // TODO() attempt to use this for Limit 
value range errors
+       KEY_API                = "api"
+       KEY_APIGW_ACCESS_TOKEN = "apigw_access_token"
 )
 
 // Used to unit test that translations exist with these IDs
diff --git a/wski18n/i18n_resources.go b/wski18n/i18n_resources.go
index f85928c..fd6099d 100644
--- a/wski18n/i18n_resources.go
+++ b/wski18n/i18n_resources.go
@@ -1,3 +1,20 @@
+/*
+ * 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.
+ */
+
 // Code generated by go-bindata.
 // sources:
 // wski18n/resources/de_DE.all.json
@@ -92,12 +109,12 @@ func wski18nResourcesDe_deAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1501631495, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
 
-var _wski18nResourcesEn_usAllJson = 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x5a\x7b\x8f\x1b\xb7\x11\xff\xdf\x9f\x62\x60\x14\x70\x02\x9c\xd7\x4e\x8a\x02\x85\x81\x43\xe1\xd6\xd7\xe4\x9a\xd8\x67\xdc\x23\x41\xe0\x1c\xd6\xd4\x72\x24\x31\xe2\x92\x0b\x92\x2b\x59\x3e\xa8\x9f\xbd\x18\x72\x5f\xba\x3b\xee\x52\x72\x8c\xe6\x9f\xac\x8f\xc3\xf9\xcd\x83\x9c\x17\xf5\xe1\x09\xc0\xdd\x13\x00\x80\xa7\x82\x3f\x7d\x05\x4f\x4b\xbb\xc8\x2b\x83\x73\xf1\x29\x47\x63\xb4\x79\x7a\x12\x56\x9d\x61\xca\x4a
 [...]
+var _wski18nResourcesEn_usAllJson = 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x5a\x7b\x8f\x1b\xb7\x11\xff\xdf\x9f\x62\x60\x14\x70\x02\x9c\x65\x27\x45\x81\xc2\xc0\xa1\x70\x6b\x37\xb9\x26\xf6\x19\xf7\x48\x10\x38\x87\x35\xb5\x1c\xad\x18\x71\xc9\x05\xc9\x95\xac\x1c\xd4\xcf\x5e\x0c\xb9\x2f\xe9\x8e\xbb\x94\x9c\xa0\xf9\x27\xf2\x71\x38\xbf\x79\x90\xf3\xe2\x7e\x7c\x02\x70\xff\x04\x00\xe0\xa9\xe0\x4f\x5f\xc1\xd3\xd2\x16\x59\x65\x70\x21\x3e\x67\x68\x8c\x36\x4f\xcf\xc2\xaa\x33\x4c\x59\xc9
 [...]
 
 func wski18nResourcesEn_usAllJsonBytes() ([]byte, error) {
        return bindataRead(
@@ -112,7 +129,7 @@ func wski18nResourcesEn_usAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 
12172, mode: os.FileMode(420), modTime: time.Unix(1516809631, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 
12809, mode: os.FileMode(420), modTime: time.Unix(1518160471, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
@@ -132,7 +149,7 @@ func wski18nResourcesEs_esAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1501631495, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
@@ -152,7 +169,7 @@ func wski18nResourcesFr_frAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 
101, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 
101, mode: os.FileMode(420), modTime: time.Unix(1501631495, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
@@ -172,7 +189,7 @@ func wski18nResourcesIt_itAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1501631495, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
@@ -192,7 +209,7 @@ func wski18nResourcesJa_jaAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1501631495, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
@@ -212,7 +229,7 @@ func wski18nResourcesKo_krAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1501631495, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
@@ -232,7 +249,7 @@ func wski18nResourcesPt_brAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1501631495, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
@@ -252,7 +269,7 @@ func wski18nResourcesZh_hansAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", 
size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", 
size: 0, mode: os.FileMode(420), modTime: time.Unix(1501631495, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
@@ -272,7 +289,7 @@ func wski18nResourcesZh_hantAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", 
size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", 
size: 0, mode: os.FileMode(420), modTime: time.Unix(1501631495, 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 99aede8..d6b81b4 100644
--- a/wski18n/resources/en_US.all.json
+++ b/wski18n/resources/en_US.all.json
@@ -140,6 +140,10 @@
     "translation": "The namespace is [{{.namespace}}], from {{.source}}.\n"
   },
   {
+    "id": "msg_config_apigw_access_token_info",
+    "translation": "The apigw access token is set, from {{.source}}.\n"
+  },
+  {
     "id": "msg_unmarshall_local",
     "translation": "Unmarshal OpenWhisk info from local values.\n"
   },
@@ -312,6 +316,14 @@
     "translation": "JSON input data Missing 'cmd' key"
   },
   {
+    "id": "msg_err_api_missing_web_action",
+    "translation": "Action [{{.action}}] is not a web action, API [{{.api}}] 
can only be created using web action. Please update manifest file to convert 
[{{.action}}] to web action.\n"
+  },
+  {
+    "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": "WARNINGS",
     "translation": "================= WARNINGS ==================="
   },

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

Reply via email to