You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@openwhisk.apache.org by GitBox <gi...@apache.org> on 2018/02/09 20:11:22 UTC

[GitHub] mrutkows closed pull request #717: API Gateway deployment/undeployment

mrutkows closed pull request #717: API Gateway deployment/undeployment
URL: https://github.com/apache/incubator-openwhisk-wskdeploy/pull/717
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json
index 4576bf6b..1758c5d9 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 06fbdcea..0442abc4 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 8861619b..14fc1c8b 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 83d2380e..4935b810 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 c5eb0c80..87d76b3b 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 a55566c2..cd07c5cb 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 b0b35fe2..7e517144 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 6bc33558..a75a033e 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 62f4dd0f..407347af 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 00000000..d2047a53
--- /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 00000000..e72f70d7
--- /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 00000000..7396fd26
--- /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 00000000..0b305753
--- /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 00000000..611c04af
--- /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 1f61cbbf..4ec1a624 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 ed05ad36..0d6c9c60 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 1667ce24..e3c87c76 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 d2f4be34..3ce8f210 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 f85928c2..fd6099d3 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\xe6\x84\x56\x44\x76\xe6\xd7\x9e\x00\xec\x4e\x46\x38\x08\x35\xd7\x11\x06\xe7\xb4\x34\xb5\xdf\xd6\x45\x81\xd6\x46\x58\x5c\x35\xab\x53\x5c\x36\xcc\x28\xa1\x16\x11\x2e\xbf\x36\xab\x51\x2e\x45\xc9\x73\x8e\xb6\xc8\xa5\x56\x8b\xbc\xaa\x67\x52\xd8\x65\x84\xd9\xfb\xb0\x0a\x0c\x2a\x56\xac\xd8\x02\xc1\x69\x70\x4b\x04\x83\x0b\x61\x9d\xd9\x82\x45\x07\x42\xc1\x7f\x5f\x64\x1b\xbb\xaa\x8c\xae\x6c\x96\x0a\x6d\xb0\xd2\xc6\x45\x90\x2f\xfd\xa2\x05\xad\x80\x63\x25\xf5\x16\x39\xa0\x72\xc2\x09\xb4\xf0\x8d\xc8\x30\x3b\x81\
 xf7\x41\x26\x7b\x02\xaf\x0b\xda\x67\x4f\xe0\xda\x88\xc5\x02\x8d\x3d\x81\xcb\x5a\xd2\x0a\xba\x22\xfb\x16\x98\x85\x0d\x4a\x49\xff\x37\x58\xa0\x72\x7e\xc7\xda\xa3\x59\x92\x9f\x74\xb2\x15\x16\x62\x2e\x90\x83\x62\x25\xda\x8a\x15\x98\xae\x8b\xd6\x31\x4d\x5e\x83\xd3\x5a\x92\xe1\x82\x22\x27\x50\xab\xf0\x05\x4c\x71\xb0\x5b\x55\x80\xae\x50\x6d\x96\xc2\xae\x5a\x3b\x5b\xa8\xad\x50\x0b\x60\x50\x32\x25\xe6\x68\x9d\x27\xd6\x15\x71\x65\xb2\x61\x55\x92\x26\x73\x21\x3b\xf2\xdf\x5e\xbf\xfd\x39\x45\x66\xbb\xd4\xc6\x1d\xe3\x7b\xd6\x79\x3e\x1d\x66\xd4\xcf\xef\x8d\x5e\x0b\x8e\x16\x18\xd8\xba\x2c\x99\xd9\x42\xa0\x07\x3d\x87\xcd\x92\xb9\x67\x16\x66\x88\x83\x53\xf0\x65\xde\x6a\x44\x9a\x74\x17\x9d\x6b\xa7\x61\x89\xb2\x6a\xa0\x61\xab\x6b\x93\xe4\x29\xf2\x48\xba\x2c\x8c\xf3\x98\x28\x9c\x03\x53\xc0\xfc\xe1\x3e\x81\x39\x22\x3f\x01\x17\x4e\x38\x68\x03\xa6\x96\xdd\x85\x6c\xc1\x0f\x81\xcd\xfd\x85\xda\x8e\xa1\xbf\x60\x0a\xee\xee\xb2\x15\x6e\x77\xbb\xfb\x50\x5e\xcf\x64\xbc\x35\x1a\x4b\x9c\x63\xc7\x40\x28\xe7\xb9\x37\x
 74\xa0\xea\x72\x46\x6a\xce\x61\x63\x57\xc1\x03\xe3\x58\x73\xc9\x16\x39\xab\x44\xbe\xd4\x36\xe6\xdc\xe0\xb9\xd7\xef\xcf\xe1\xe3\x8f\x17\x57\xd7\x1f\x13\x39\x8e\xcb\x3e\x60\xfa\xcb\xd9\xe5\xd5\xf9\xc5\xbb\x24\xbe\xb5\x5b\xe6\x2b\x8c\x59\x9f\x96\xb5\x11\x9f\xfd\x1f\xe0\xe3\x4f\x67\xbf\xa5\x30\x2d\xd0\xb8\xdc\xbb\xe5\x71\xae\x15\x73\x4b\x32\x29\x19\x3a\x23\xe2\x04\x1f\x06\xc6\x5a\xcd\x45\x2c\xe5\x84\x45\xcf\x0a\xbe\xe1\x38\x67\xb5\x74\x20\x2c\xfc\xe5\xc7\x8b\xb7\x67\x7d\x62\xf8\x36\xc5\x2a\x52\xea\x4d\xde\xf0\x88\x25\x4a\x4f\x04\x1d\xd1\x34\xd7\x3e\x5a\x8e\xd9\xa5\x8b\xd0\x5d\x58\x4d\x60\x2d\x94\x43\x43\x37\x74\x1d\xb3\x79\x90\x76\x40\x07\x95\xd1\x65\x95\x24\xf8\x0a\xb7\xc9\xee\x5c\xe1\x36\x55\xe8\x60\xe5\x92\x29\xb6\xc0\x58\xf0\x09\x62\x57\x46\xff\x81\x85\xeb\x53\xaf\xd3\x30\xa3\x10\x60\x56\xc8\xa1\xe5\x30\x8d\xd8\x85\xa7\x71\xfb\x1f\x10\x5a\x3c\xdb\x2e\xf4\x47\xf8\xf6\xeb\xd3\xbc\x1a\x55\x27\x24\xb4\x68\xd6\x68\x24\x5a\xdb\xda\x26\x81\xb5\x75\x46\x44\x39\x07\x43\xd7\x16\x0d\x1d\x69\xa
 1\x90\x83\xa9\x95\x13\x65\x17\x0b\x13\x10\x9c\x5e\x2c\x24\xe6\x94\xae\x22\x30\xd7\x9e\x02\x7e\xa4\x84\x56\xa2\xb5\x6c\x91\x7e\x52\xd6\x68\x66\xda\xc6\x8c\xdc\xac\x82\xae\x5d\x55\x8f\x99\xc3\x87\x89\xbc\x14\x96\x12\xa6\x0f\x80\xf1\xf8\x77\xbd\x44\x20\x0a\x3a\x78\x45\x08\x82\x74\xc0\x85\x05\xa5\x1d\x04\x56\xb5\x41\x9e\xfd\x3e\x66\x9e\x7b\x88\x95\x18\xc9\x0d\x84\x48\x41\x9c\x48\xbe\x0c\x67\xea\x54\x12\x52\x47\x73\x1c\x54\xa3\xca\x58\x47\x72\x5f\x9f\x0f\x77\x77\x19\x7d\xef\x76\xb7\x27\x30\x37\xba\xa4\xc4\x6e\x75\x6d\x0a\xdc\xed\x92\x30\x83\xc3\xa6\x30\x89\xac\xf5\x95\x45\x77\x1c\x56\x67\x9e\x29\xb4\x3d\x3b\x92\x8a\xdd\x1f\x0e\xd7\xb3\x56\x25\x33\x76\xc9\xa4\xcc\xa5\x2e\x98\x8c\xc0\xde\xb4\x64\x70\x51\xa1\xfa\xd5\x67\x7f\x92\x32\x80\xf9\x9d\xb0\x66\xb2\x46\x9b\x8a\xa6\xd0\x6d\xb4\x59\x1d\x85\xe7\x13\x8b\x42\x37\x8a\xd5\xe7\xb5\xbc\x60\xaa\x40\x29\xa3\x71\xff\xe2\xa7\x0c\xfe\x15\x68\xa8\xac\xed\x77\xa6\x02\xcc\x99\x88\x73\x7f\xd3\x27\x58\x2e\x78\x73\xf0\xcb\x4a\xa2\x43\xb0\x35\xb5\xbf\xf3
 \x5a\xca\x6d\x06\x97\xb5\x82\x8f\x5d\xe5\xd7\xb5\x4c\x1f\x29\x06\x1b\x2c\x35\xa5\x51\x66\x9c\x60\x52\x6e\xfb\xde\x80\x59\x8b\x6e\xdc\xec\x03\x49\x43\xa3\x91\x5b\xc7\x5c\x1d\xab\x35\x9e\x3f\x7f\xfe\xfc\xf4\xf4\xf4\x74\x60\xfb\x81\x0e\x57\x7e\x2b\x10\x01\x11\x26\xa1\xfa\x21\x00\xf2\x14\x13\xb5\xa6\xe1\xd0\x4c\x0e\x82\x71\xc6\x4f\xd5\xf1\xbe\x1e\xee\x4d\x07\x19\xf5\xf7\xcd\x80\x72\xdc\xe3\xc9\x78\x53\xf6\xdb\x83\x3c\xc2\x82\x6d\x0d\x92\xfb\xbe\x6e\xba\x76\xbc\xf1\xed\x1f\x85\x1e\xaa\x11\x76\xbb\x5b\x98\x6b\x93\x7a\x6f\xee\x81\x0d\x15\x3d\x08\x2e\xd9\x75\xa1\xe5\xcb\xdb\x1b\x33\x31\x92\xea\x5a\xbf\x36\xb2\x12\xde\x92\x35\x2d\xf9\xd0\xa4\xdd\x1d\x4c\x47\x8f\xcf\xb0\xde\xb4\xeb\xf0\xa8\x00\x59\x36\xd2\x5d\x37\x10\xad\x41\xfe\x4c\x15\x7b\x9e\x29\x4a\xb6\xd4\x71\x35\x6f\x7a\x8a\x23\x14\xe5\x58\xa1\xe2\xa8\x8a\x43\xec\xd9\x6f\x1a\x02\x1d\x86\xd3\xdf\xc2\xa8\x51\xdf\x3c\x0a\xf3\x25\x27\xe7\x71\x29\x28\xf6\xd4\x26\x56\x67\x0d\x22\xa9\x9e\x47\x54\xff\x3f\xa6\xa1\x56\x9f\xc3\x0e\xca\x97\x79\xf0\
 x61\x24\xfd\x73\x7c\x98\x78\x35\x62\x92\x8c\xfb\x71\x2f\xa2\x1f\xe9\xc9\x89\x20\x4c\x6d\xec\xb1\x69\xcd\x4b\x14\x92\x4c\xd7\x26\x8f\xc9\x02\xbc\x36\xe4\xc9\x06\x76\x98\x2a\xbe\xde\x79\x6b\x75\x9c\xeb\x5a\xf1\xbc\x91\x77\x7c\x00\xf8\x86\x88\xa2\xb1\x69\xb3\x14\xc5\x12\x36\x7e\xa2\x4e\x72\xf1\x50\x8e\xba\x25\x42\x51\x1b\x43\x86\x69\x15\x6c\x87\x08\x3e\x69\x85\x6f\xe2\xc0\xac\xd7\x85\xec\x97\x9c\xbe\xc2\xe8\x64\xa2\x93\xfb\x5d\xbd\x97\xc8\xac\x1f\xb4\xac\x05\x47\x2f\x14\xd1\x93\xec\x3e\x5d\x76\xc5\xdc\x2b\x98\xc6\x1a\xed\x53\x1f\x60\x31\x75\xbf\x6f\x75\x7a\x85\x2a\x01\xa8\x19\x72\x46\x9c\xa1\x61\xab\x6b\x30\xe8\x3d\xbf\x61\xca\xf5\xf3\x2a\x70\x4b\x61\xff\x01\xdf\x6c\x5f\xbc\xfb\x36\x01\x67\xaa\x3d\x7d\xa8\xd2\xa0\xcb\xfa\xd0\xce\xf7\x7c\x87\x43\x4d\xd7\xa2\x46\xeb\x6e\x13\x70\x5b\x27\x1f\xa4\x61\xf7\x56\x92\xa0\xe3\xd9\xe5\xe5\xc5\xe5\x55\x84\xfd\xe9\xfd\xff\x20\x90\xc3\x83\x85\xd3\xd3\x91\xdc\x6e\xcc\x7e\x10\x5b\x29\xbd\x51\xb9\xdb\x56\x23\x49\xa8\x0d\x56\x44\x45\x16\x6b\x76\x65\xd0\x
 8f\xb6\x41\x2b\xb9\x05\x5b\x57\xe1\xd5\xeb\x85\x9f\x29\x67\x76\x6b\x1d\x96\x30\x13\x8a\x0b\xb5\xb0\xa0\x0d\x2c\x84\x5b\xd6\xb3\xac\xd0\x65\xf7\x00\x31\x5e\x8c\x04\x81\xdb\xa8\x46\x8e\xcc\x95\x76\x21\x0e\x8c\xf4\xd5\x8f\xde\x79\xa1\xee\x4f\x48\x7d\x90\xf3\xbc\x68\x71\xff\x05\x64\x4a\xac\xa6\x4e\x2a\x0c\x32\x17\xb3\x9e\x7f\x97\x05\x4f\xb2\x17\x89\x36\xc2\x2d\xc1\x3f\xe8\xb6\xc3\xac\x57\xb4\x88\xc6\xec\x76\xfe\xa5\x2c\xac\x15\x9a\x87\x05\xfa\x98\xe8\xfe\x07\x22\x85\xf0\x38\x2a\x12\x7f\x10\x1c\xbf\x92\x48\x73\x44\x9e\x0b\xb5\xd6\xab\x98\x40\xff\xf6\x99\x8a\x2e\x4b\x20\xf3\xe1\x8e\xb6\xc1\x66\xe9\x1f\xce\x1a\x49\xdb\x97\xa3\xb0\xf4\x75\xa4\x5d\xe1\xb6\x1b\x83\x95\x4c\x71\xe6\xb4\x19\x1b\xf1\x75\x34\x7e\x62\xf4\xa1\x35\xe6\x2d\x5d\x93\x86\xcf\x24\x66\xd7\x43\x4d\x9d\xeb\xb7\xc3\xe3\x39\x38\xb9\xcc\x81\x1f\xef\x0e\x9a\xaa\x49\x50\x7f\x91\x4a\x61\x4b\xe6\x8a\xd8\x0b\xea\xde\x3d\xa2\x0d\xdc\x43\xf0\x91\xeb\xe4\xd7\xdb\xc6\x8e\x6b\x0c\xb3\x41\x0f\xe2\xdd\xea\x33\x18\x11\x95\x03\x26\x7b\xd7\x2
 e\xac\xb6\x6a\x8c\x2b\xd1\xcc\x99\xe9\x78\x31\x29\x62\x66\x3b\x0f\xab\x14\x7d\x1a\x97\x74\x03\x6a\xc2\x6a\xbe\x49\x96\xfe\x4d\x76\x4f\x2a\x6d\xbc\xec\xe1\x1d\xd3\xef\x09\x9f\x29\x76\x6e\x45\x9c\x30\xf5\xe5\x21\x02\xdd\xb3\xab\xbf\x0a\x41\xa2\x67\x16\xc2\xa4\x30\x98\x12\x3f\x39\x54\xb6\x15\x1a\x3f\xb9\xb6\xdd\xfe\x12\x55\x6c\xbe\xc0\x58\xe5\xd2\x5f\xe5\x05\x86\xe7\xd0\x26\x25\xf4\x8f\x02\x36\xd4\x59\xfd\x38\xca\xa2\x59\x8b\x62\x70\x7d\x27\x05\xa9\x8d\x3c\xdc\xe5\x77\x77\x59\x6d\x24\xa5\xb0\xdd\x0e\x6e\x2e\x7f\xf6\xca\xd7\x46\x36\x67\x90\xfe\x45\x36\x0b\x04\xb7\x69\x19\x80\x04\x29\x99\x9c\x6b\x53\x46\x4b\xed\xb7\xed\xfa\x98\x04\x19\x5c\x9b\x2d\xb0\x05\x13\x2a\xcb\x26\x61\xff\xb0\x5a\x75\x51\xaa\x28\xf9\xc8\x33\xec\x7f\xae\x2e\xde\x81\x50\x55\xed\x80\x33\xc7\xe0\x6d\x63\x8d\x67\x45\xc9\x9f\x51\xcc\x7a\x1c\xe9\xd7\xd7\x97\xef\xce\xdf\xfd\x90\x5e\x8b\xb4\x1b\x0e\xab\x46\x36\xcc\xa8\xbc\xd0\x25\x45\xd1\xdc\xa0\x8b\x86\xda\x4b\x5a\x6b\xe7\x46\x45\xc9\x7d\xf9\x3d\x77\x68\x42\x98\x7f\x15\xce
 \x37\x1d\x9e\xdb\x31\xe3\x35\x78\x7e\x42\x7f\xf0\x01\x1a\xbe\x12\x0f\xc7\x57\x1c\x1d\x16\x6e\xa2\x71\xf4\xc8\x94\x5c\x38\x56\x06\x0b\x46\xcd\x8b\xc1\x4a\xb2\x22\x7a\x70\x28\xfa\x12\x8e\x96\xbc\xc9\x29\xfe\x51\x22\xfc\x7a\x64\xef\xb4\x06\x99\x36\x42\x4a\xb0\x5a\x2b\x98\x21\xf4\x30\x27\x50\x85\x6a\xb8\xb6\x21\xb3\xfa\x82\x08\x37\x7b\x3c\xad\x43\x96\xa8\x40\x63\x8e\x63\x72\xa2\x5d\xea\x5a\x72\x12\xcf\xa2\xcb\x20\x4c\x02\xf7\xeb\x71\xa2\xf6\x5f\x61\x26\x90\x24\x91\xa7\x9f\xf0\x27\xc9\x15\x10\x28\xfc\x3d\xcc\xd5\x14\x4d\xfd\xfe\x43\x20\x29\x5f\x5b\xb6\x1e\xf5\xe0\x14\xa8\xdf\xdf\x7a\xb5\x6d\x3c\xdb\xdf\x90\x0c\x7f\x3c\x32\x2d\x98\x14\xa5\x70\xb9\x58\x28\x6d\xa2\x22\xb5\xe7\xba\x49\x00\x7e\x8b\x97\xca\x7f\xdd\xcf\xc7\xc2\x42\xc3\x2e\x15\xbd\x58\x32\xb5\x40\x36\x8b\x3e\xf9\xff\xdc\x21\x76\x05\x80\x6d\xf5\x96\xdb\x30\x73\xe8\x78\x64\x70\x4e\xf0\x54\x44\x25\x9c\x05\x2f\x81\xcd\xa5\x5e\xe4\x56\x7c\x8e\x09\x20\xf5\xe2\x4a\x7c\x46\xb2\x6d\xd8\xb0\xa7\x71\x7f\x44\x99\xf2\x4f\x53\x54\x70\xce\xd0\
 x6d\x10\x15\xbc\xf4\x85\xe5\x77\x2f\x93\x45\x29\xb1\xd4\x66\x3b\x26\x4d\xa0\x38\x56\xa0\xef\xbe\xff\xbb\x17\xe9\x6f\xdf\x7d\x9f\x2c\x13\xe5\x60\x5d\xc7\x12\x78\xb3\x7a\x94\x30\x2f\x83\x7d\xfe\xfa\x92\xfe\x9b\x96\xc7\xb7\x88\xd4\x5b\x57\x68\x9c\xc0\xd8\x18\xaf\x0d\x83\x83\x78\x15\x86\x36\xce\x08\xec\xc6\x36\xa1\xdf\xec\x99\xb5\xe3\x9d\xc7\x63\x62\x1b\x12\xb9\xf6\x07\x8e\x22\xa3\x70\xa0\x6b\x67\x05\xf7\x8e\xb8\x36\x6c\x2d\x2c\xcc\x6a\x21\xf9\x78\x7f\xea\x55\x09\xe1\xc0\xd0\xb1\x4d\x0a\x05\xdd\xe9\xdf\x0b\x08\xea\x5e\x54\x6f\xac\xed\xbb\xee\xbb\xbb\xac\xf9\x6b\x6b\x6e\xaa\x92\x85\x6a\x9a\x1d\xfa\x07\x2b\x26\x4a\x27\x2f\x6a\x5b\x8f\x86\x4b\x16\x0b\x13\x6d\x39\xda\x50\x51\x41\x77\xaf\x32\x9d\x31\x8b\x1c\xb4\x1a\x54\xc6\xd1\xe2\xf3\xa8\x8a\xd3\x4b\xdb\xf4\xb3\xbe\x59\xc1\x4f\xc2\x46\x7f\x52\xf5\xa0\x55\xd9\x0b\x31\x4c\x1a\x64\x7c\x0b\x81\x45\x06\xcd\x7c\xc8\xa2\xc4\xc2\x01\x53\xda\x2d\xd1\xf8\x6d\x51\x91\xde\x9c\xfd\xf3\xe6\x87\xe4\x72\xc8\x53\x1f\x56\x0b\xf1\x59\xf8\xb9\xd4\x1a\x8d\x98\x
 c7\xea\xa0\x5f\xfc\x62\x53\xce\x3e\x3c\x42\x8d\x7e\xe3\xb1\x92\x80\xba\x71\x7c\x78\xb7\x9b\x7c\x76\xf1\x54\xaf\xa6\xb8\x0e\x1e\x02\x46\xf9\x0e\x9f\x03\xd2\x38\x5b\x64\xa6\x58\x12\xdf\x66\xfe\x9a\x73\x61\xb0\x18\x69\xce\xaf\xda\x1d\xdd\xf4\xb6\xdb\xf1\xe0\xf1\xb1\xb7\x60\x6f\xba\x27\xb7\x4f\xfe\x17\x00\x00\xff\xff\x5a\x51\x51\x15\x8c\x2f\x00\x00")
+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\x9c\xd0\x8a\xc8\xde\xfa\xb5\x27\x00\xbb\xb3\x11\x0e\x42\x2d\x74\x84\xc1\x05\x2d\x4d\xed\xb7\x75\x9e\xa3\xb5\x11\x16\xd7\xcd\xea\x14\x97\x0d\x33\x4a\xa8\x22\xc2\xe5\xe7\x66\x35\xca\x25\x2f\x79\xc6\xd1\xe6\x99\xd4\xaa\xc8\xaa\x7a\x2e\x85\x5d\x46\x98\x7d\x08\xab\xc0\xa0\x62\xf9\x8a\x15\x08\x4e\x83\x5b\x22\x18\x2c\x84\x75\x66\x0b\x16\x1d\x08\x05\xff\x7d\x31\xdb\xd8\x55\x65\x74\x65\x67\xa9\xd0\x06\x2b\x6d\x5c\x04\xf9\xca\x2f\x5a\xd0\x0a\x38\x56\x52\x6f\x91\x03\x2a\x27\x9c\x40\x0b\x5f\x89\x19\xce\xce\xe0\
 x43\x90\xc9\x9e\xc1\xeb\x9c\xf6\xd9\x33\xb8\x31\xa2\x28\xd0\xd8\x33\xb8\xaa\x25\xad\xa0\xcb\x67\x5f\x03\xb3\xb0\x41\x29\xe9\xff\x06\x73\x54\xce\xef\x58\x7b\x34\x4b\xf2\x93\x4e\xb6\xc2\x5c\x2c\x04\x72\x50\xac\x44\x5b\xb1\x1c\xd3\x75\xd1\x3a\xa6\xc9\x6b\x70\x5a\x4b\x32\x5c\x50\xe4\x0c\x6a\x15\x7e\x01\x53\x1c\xec\x56\xe5\xa0\x2b\x54\x9b\xa5\xb0\xab\xd6\xce\x16\x6a\x2b\x54\x01\x0c\x4a\xa6\xc4\x02\xad\xf3\xc4\xba\x22\xae\x4c\x36\xac\x4a\xd2\x64\x21\x64\x47\xfe\xcb\xeb\x77\x3f\xa6\xc8\x6c\x97\xda\xb8\x53\x7c\xcf\x3a\xcf\xa7\xc3\x8c\xfa\xf9\x83\xd1\x6b\xc1\xd1\x02\x03\x5b\x97\x25\x33\x5b\x08\xf4\xa0\x17\xb0\x59\x32\xf7\xcc\xc2\x1c\x71\x70\x0a\xbe\xcc\x5b\x8d\x48\x93\xee\xa2\x73\xed\x34\x2c\x51\x56\x0d\x34\x6c\x75\x6d\x92\x3c\x45\x1e\x49\x97\x85\x71\x1e\x13\x85\x73\x60\x0a\x98\x3f\xdc\x67\xb0\x40\xe4\x67\xe0\xc2\x09\x07\x6d\xc0\xd4\xb2\xbb\x90\x2d\xf8\x31\xb0\x99\xbf\x50\xdb\x31\xf4\x17\x4c\xc1\xfd\xfd\x6c\x85\xdb\xdd\xee\x10\xca\xeb\x99\x8c\xb7\x46\x63\x89\x73\xec\x18\x08\xe5\x3c\xf7\x86\x
 0e\x54\x5d\xce\x49\xcd\x05\x6c\xec\x2a\x78\x60\x1c\x6b\x21\x59\x91\xb1\x4a\x64\x4b\x6d\x63\xce\x0d\x9e\x7b\xfd\xe1\x02\x3e\x7d\x7f\x79\x7d\xf3\x29\x91\xe3\xb8\xec\x03\xa6\x3f\xbd\xbd\xba\xbe\xb8\x7c\x9f\xc4\xb7\x76\xcb\x6c\x85\x31\xeb\xd3\xb2\x36\xe2\x77\xff\x07\xf8\xf4\xc3\xdb\x5f\x52\x98\xe6\x68\x5c\xe6\xdd\xf2\x38\xd7\x8a\xb9\x25\x99\x94\x0c\x3d\x23\xe2\x04\x1f\x06\xc6\x5a\x2d\x44\x2c\xe5\x84\x45\xcf\x0a\xbe\xe2\xb8\x60\xb5\x74\x20\x2c\xfc\xe5\xfb\xcb\x77\x6f\xfb\xc4\xf0\x75\x8a\x55\xa4\xd4\x9b\xac\xe1\x11\x4b\x94\x9e\x08\x3a\xa2\x69\xae\x7d\xb4\x1c\xb3\x4b\x17\xa1\xbb\xb0\x9a\xc0\x5a\x28\x87\x86\x6e\xe8\x3a\x66\xf3\x20\xed\x80\x0e\x2a\xa3\xcb\x2a\x49\xf0\x15\x6e\x93\xdd\xb9\xc2\x6d\xaa\xd0\xc1\xca\x25\x53\xac\xc0\x58\xf0\x09\x62\x57\x46\xff\x86\xb9\xeb\x53\xaf\xd3\x30\xa7\x10\x60\x56\xc8\xa1\xe5\x30\x8d\xd8\x85\xa7\x71\xfb\x1f\x11\x5a\x3c\xdb\x2e\xf4\x47\xf8\xf6\xeb\xd3\xbc\x1a\x55\x27\x24\xb4\x68\xd6\x68\x24\x5a\xdb\xda\x26\x81\xb5\x75\x46\x44\x39\x07\x43\xd7\x16\x0d\x1d\x69\xa
 1\x90\x83\xa9\x95\x13\x65\x17\x0b\x13\x10\x9c\x2e\x0a\x89\x19\xa5\xab\x08\xcc\x8d\xa7\x80\xef\x29\xa1\x95\x68\x2d\x2b\xd2\x4f\xca\x1a\xcd\x5c\xdb\x98\x91\x9b\x55\xd0\xb5\xab\xea\x31\x73\xf8\x30\x91\x95\xc2\x52\xc2\xf4\x01\x30\x1e\xff\x6e\x96\x08\x44\x41\x07\x2f\x0f\x41\x90\x0e\xb8\xb0\xa0\xb4\x83\xc0\xaa\x36\xc8\x67\xbf\x8e\x99\xe7\x00\xb1\x12\x23\xb9\x81\x10\x29\x88\x13\xc9\x97\xe1\x4c\x9d\x4a\x42\xea\x68\x4e\x83\x6a\x54\x19\xeb\x48\x0e\xf5\xf9\x78\x7f\x3f\xa3\xdf\xbb\xdd\xdd\x19\x2c\x8c\x2e\x29\xb1\x5b\x5d\x9b\x1c\x77\xbb\x24\xcc\xe0\xb0\x29\x4c\x22\x6b\x7d\x65\xd1\x9d\x86\xd5\x99\x67\x0a\x6d\xcf\x8e\xa4\x62\xf7\x87\xd3\xf5\xac\x44\xb1\xc9\x98\x6f\xc6\x32\xa7\x57\xa8\x26\x55\xa6\x1d\x10\x76\x80\xdf\x71\x9a\xf2\xb5\x2a\x99\xb1\x4b\x26\x65\x26\x75\xce\x64\x04\xf2\xb6\x25\x83\xcb\x0a\xd5\xcf\xbe\xfc\x20\x09\x03\x98\xdf\x09\x6b\x26\x6b\xb4\xa9\x68\x0a\xdd\x46\x9b\xd5\x49\x78\x3e\xb3\x29\x74\xa3\x58\x7d\x62\xcd\x72\xa6\x72\x94\x32\x9a\x78\x2e\x7f\x98\xc1\xbf\x02\x0d\xd5\xd5\xfd\xce\x54
 \x80\x05\x13\x71\xee\x6f\xfa\x0c\xcf\x05\x6f\x6e\x5e\x59\x49\x74\x08\xb6\x26\x07\x2e\x6a\x29\xb7\x33\xb8\xaa\x15\x7c\xea\x4a\xcf\xae\x67\xfb\x44\x49\xc0\x60\xa9\x29\x8f\x33\xe3\x04\x93\x72\xdb\x37\x27\xcc\x5a\x74\xe3\x66\x1f\x48\x1a\x3a\x9d\xcc\x3a\xe6\xea\x58\xb1\xf3\xfc\xf9\xf3\xe7\xe7\xe7\xe7\xe7\x03\xdb\x0f\x74\xb8\xf6\x5b\x81\x08\x88\x30\x09\xd5\x4f\x21\x90\xa7\x98\xa8\x35\x0d\x87\x66\x74\x11\x8c\x33\x7e\xaa\x4e\xf7\xf5\x70\x6f\x3a\xc8\xa8\xbf\x6f\x07\x94\xe3\x1e\x4f\xc6\x9b\xb2\xdf\x1e\xe4\x09\x16\x6c\x8b\xa0\xcc\x37\x96\xd3\xc5\xeb\xad\xef\x3f\x29\xf6\x51\x91\xb2\xdb\xdd\xc1\x42\x9b\xd4\x7b\x73\x00\x36\x54\xf4\x28\xb8\x64\xd7\x85\x9e\x33\x6b\x6f\xcc\xc4\x4c\xac\xeb\x3d\xdb\xd0\x4e\x78\x4b\xd6\xcc\x04\x86\x26\xed\xee\x60\x3a\x7a\x7c\x88\xf6\xa6\x5d\x87\x47\x05\x98\xcd\x46\xda\xfb\x06\xa2\x35\xc8\x1f\xa9\x62\xcf\x33\x45\xc9\x96\x3a\xae\xe6\x6d\x4f\x71\x82\xa2\x1c\x2b\x54\x1c\x55\x7e\x8c\x3d\xfb\x4d\x43\xa0\xe3\x70\xfa\x5b\x18\x35\xea\x9b\x47\x61\xbe\xe4\xe4\x3c\x2e\x05\xc5\x9e\
 xda\xc4\x0a\xbd\x41\x24\xd5\x8b\x88\xea\xff\xc7\x34\xd4\xea\x73\xdc\x41\xf9\x32\x0f\x3e\x8c\xa4\x7f\x8c\x0f\x13\xaf\x46\x4c\x92\x71\x3f\xee\x45\xf4\x13\x3d\x39\x11\x84\xa9\x8f\x3e\x35\xad\x79\x89\x42\x92\xe9\xfa\xf4\x31\x59\x80\xd7\x86\x3c\xd9\xc0\x0e\x53\xc5\x9f\x77\xde\x5a\x1d\x17\xba\x56\x3c\x6b\xe4\x1d\x9f\x40\xbe\x21\xa2\x68\x6c\xda\x2c\x45\xbe\x84\x8d\x1f\xe9\x93\x5c\x3c\x94\xa3\x6e\x89\x90\xd7\xc6\x90\x61\x5a\x05\xdb\x29\x86\x4f\x5a\xe1\x37\x71\x60\xd6\xeb\x42\xf6\x4b\x4e\x5f\x61\x76\x33\xd1\x4a\xfe\xaa\x3e\x48\x64\xd6\x4f\x7a\xd6\x82\xa3\x17\x8a\xe8\x49\x76\x9f\x2e\xbb\x62\xee\x15\x4c\x63\x8d\x36\xca\x0f\xb0\x98\x3a\x6c\x9c\x7d\x47\x92\x00\xd4\x4c\x59\x23\xce\xd0\xb0\xd5\x35\x18\xf4\x9e\xdf\x30\xe5\xfa\x81\x19\xb8\xa5\xb0\xff\x80\xaf\xb6\x2f\xde\x7f\x9d\x80\x33\xd5\x1f\x3f\x54\x69\xd0\xe6\x7d\x6c\x07\x8c\xbe\xc3\xa1\x3e\xab\xa8\xd1\xba\xbb\x04\xdc\xd6\xc9\x47\x69\xd8\x3d\xd6\x24\xe8\xf8\xf6\xea\xea\xf2\xea\x3a\xc2\xfe\xfc\xf0\x3f\x08\xe4\xf0\x60\xe1\xfc\x7c\x24\xb7\x1b\xb3\x
 1f\xc4\x56\x4a\x6f\x54\xe6\xb6\xd5\x48\x12\x6a\x83\x15\x51\x91\xc5\x9a\x5d\x33\xe8\x67\xeb\xa0\x95\xdc\x82\xad\xab\xf0\xec\xf6\xc2\x0f\xb5\x67\x76\x6b\x1d\x96\x30\x17\x8a\x0b\x55\x58\xd0\x06\x0a\xe1\x96\xf5\x7c\x96\xeb\xb2\x7b\x01\x19\x2f\x46\x82\xc0\x6d\x54\x23\x47\x66\x4a\xbb\x10\x07\x46\x7a\xea\x47\xef\xbc\x50\x87\x23\x5a\x1f\xe4\x3c\x2f\x5a\xdc\x7f\x82\x99\x12\xab\xa9\x93\x72\x83\xcc\xc5\xac\xe7\x1f\x86\xc1\x93\xec\x45\xa2\x8d\x70\x4b\xf0\x2f\xca\xed\x34\xed\x15\x2d\xa2\x31\xbb\x9d\x7f\xaa\x0b\x6b\xb9\xe6\x61\x81\x7e\x4c\x74\xff\x03\x91\x42\x78\x1c\x15\x89\x3f\x08\x8e\x7f\x92\x48\x0b\x44\x9e\x09\xb5\xd6\xab\x98\x40\xff\xf6\x99\x8a\x2e\x4b\x20\xf3\xe1\x8e\xb6\xc1\x66\xe9\x5f\xee\x1a\x49\xdb\xa7\xab\xb0\xf4\xe7\x48\xbb\xc2\x6d\x37\x87\x2b\x99\xe2\xcc\x69\x33\x36\x63\xec\x68\xfc\xc8\xea\x63\x6b\xcc\x3b\xba\x26\x0d\x9f\x49\xcc\xae\x87\x9a\x3a\xd7\xef\x86\xc7\x73\x70\x72\x99\x03\x3f\x5f\x1e\x34\x55\x93\xa0\xfe\x22\x95\xc2\x96\xcc\xe5\xb1\x27\xdc\xbd\x7b\x44\x1b\xb8\x87\xe0\x23\xd7\xc
 9\xaf\xb7\x8d\x1d\xd7\x18\x86\x93\x1e\xc4\xbb\xd5\x67\x30\x22\x2a\x07\x4c\xf6\xae\x5d\x58\x6d\xd5\x18\x57\xa2\x19\x74\xd3\xf1\x62\x52\xc4\xcc\x76\x11\x56\x29\xfa\x34\x2e\xe9\x26\xe4\x84\xd5\xfc\x26\x59\xfa\x47\xe1\x3d\xa9\xb4\xf1\xb2\x87\x87\x54\xbf\x27\xfc\x4c\xb1\x73\x2b\xe2\x84\xa9\xaf\x8e\x11\xe8\xc0\xae\xfe\x2a\x04\x89\x9e\x59\x08\x93\xc2\x60\x4a\xfc\xec\x50\xd9\x56\x68\xfc\xec\xda\x76\xfb\x4b\x54\xb1\x59\x81\xb1\xca\xa5\xbf\xca\x05\x86\xf7\xd8\x26\x25\xf4\xaf\x12\x36\xd4\x59\xfd\x38\xca\xa2\x59\x8b\x7c\x70\x7d\x27\x05\xa9\x8d\x3c\xde\xe5\xf7\xf7\xb3\xda\x48\x4a\x61\xbb\x1d\xdc\x5e\xfd\xe8\x95\xaf\x8d\x6c\xce\x20\xfd\x8b\x6c\x16\x08\xee\xd2\x32\x00\x09\x52\x32\xb9\xd0\xa6\x8c\x96\xda\xef\xda\xf5\x31\x09\x66\x70\x63\xb6\xc0\x0a\x26\xd4\x6c\x36\x09\xfb\x9b\xd5\xaa\x8b\x52\x79\xc9\x47\xde\x81\xff\x73\x7d\xf9\x1e\x84\xaa\x6a\x07\x9c\x39\x06\xef\x1a\x6b\x3c\xcb\x4b\xfe\x8c\x62\xd6\x38\x12\xab\x44\x07\xb4\xc1\x79\x16\x0e\x4b\xec\xc5\xff\x91\x43\xd5\x3e\x4f\x30\xd8\xe0\xbc\xfb\x14\xe1
 \xf5\x87\x8b\x40\x56\x09\xa2\xc9\x99\x0a\xf5\xc3\x1c\x43\xaa\x44\xde\x7c\x15\xd1\x6f\x9a\x41\x53\xd4\xd5\x15\x67\xee\xe0\x2b\x02\x3a\x70\xb9\x56\x6b\x34\xee\x00\xde\xe9\x21\x8f\x29\xc3\x0e\xd5\x3d\x49\xd5\xf6\xb0\xf9\x23\xbe\x27\x62\x92\xd2\x73\x66\x91\x83\x56\xc3\x70\xf3\x90\xd5\xa4\x29\x84\xca\x65\xcd\xf1\x40\x3c\x66\xf7\xbc\x10\x35\xc6\xcf\xaf\xaf\xde\x5f\xbc\xff\x2e\xbd\x0e\x6d\x37\x1c\x57\x89\x6e\x98\x51\x59\xae\x4b\xca\xa0\x99\x41\x17\x4d\xb3\x57\xb4\xd6\xce\x0c\xf3\x92\x7b\x5d\x16\x0e\x4d\x48\xf1\xaf\x42\x6c\xa3\xc0\x71\x37\xe6\xdf\x06\xcf\x3f\xd1\x1c\x1d\x3c\x86\x9f\x28\x0c\x47\x97\x1c\x1d\xe6\x6e\x62\x68\xe0\x91\xa9\xb0\xe0\x58\x19\xcc\xc9\xd3\x99\xc1\x4a\xb2\x3c\x1a\x34\x28\xf3\x12\x8e\x96\xbc\xa9\x27\xfc\x8b\x58\x38\x18\x7b\x91\x2a\xc8\xb4\x11\x52\x82\xd5\x5a\xd1\x69\xea\x61\xce\xa0\x6a\x4e\x8a\x0d\x55\x95\x2f\x86\x71\xb3\xc7\xd3\x3a\x64\x89\x0a\x34\xe6\x38\xa5\x1e\xb2\x4b\x5d\x4b\x4e\xe2\x59\x74\x33\x08\x53\xe0\xfd\x5e\x8c\xa8\xfd\xaf\x30\x0f\x4a\x92\xc8\xd3\x4f\xf8\x93\
 xe4\x0a\x08\x94\xfa\x1e\xd6\x69\x14\x9f\xfc\xfe\x63\x20\xa9\x56\xb3\x6c\x3d\xea\xc1\x29\x50\xbf\xbf\xf5\x6a\x3b\x74\x68\x3f\x60\x1a\x7e\xb9\x34\x2d\x98\x14\xa5\x70\x99\x28\x94\x36\x51\x91\xda\x73\xdd\x04\x16\xbf\xc5\x4b\xe5\x7f\x1d\xd6\x62\xc2\x42\xc3\x2e\x15\x3d\x5f\x32\x55\x20\x9b\x47\xbf\x37\xf9\xb1\x43\xec\x8a\x3f\xdb\xea\x2d\xb7\x61\xde\xd4\xf1\x98\xc1\x05\xc1\x53\x01\x9d\x70\x16\xbc\x04\x36\x93\xba\xc8\xac\xf8\x3d\x26\x80\xd4\xc5\xb5\xf8\x1d\xc9\xb6\x61\xc3\x9e\xc6\xfd\x11\x65\xca\x3f\x4b\x52\xb3\x31\x47\xb7\x41\x54\xf0\xd2\x37\x15\xdf\xbc\x4c\x16\xa5\xc4\x52\x9b\xed\x98\x34\x81\xe2\x54\x81\xbe\xf9\xf6\xef\x5e\xa4\xbf\x7d\xf3\x6d\xb2\x4c\x54\x7f\xe9\x3a\x56\xbc\x35\xab\x27\x09\xf3\x32\xd8\xe7\xaf\x2f\xe9\xbf\x69\x79\xfc\x78\x20\xab\x8c\xae\xd0\x38\x81\xb1\x11\x6e\x1b\x06\x07\xf1\x2a\x0c\xec\x9c\x11\xd8\x8d\xec\xc2\xac\xa1\x67\xd6\x8e\xf6\x1e\x8f\x89\x6d\x48\xe4\xda\x1f\x38\x8a\x8c\xc2\x81\xae\x9d\x15\xdc\x3b\xe2\xc6\xb0\xb5\xb0\x30\xaf\x85\xe4\xe3\xb3\x09\xaf\x4a\x08\x07\x86\x
 8e\x6d\x52\x28\xe8\x4e\xff\x5e\x40\x50\x07\x51\xbd\xb1\xb6\x9f\xb8\xdc\xdf\xcf\x9a\xbf\xb6\xe6\xa6\x0e\x49\xa8\xa6\xd1\xa5\x7f\xb0\x7c\xa2\x6c\xf6\xa2\xb6\xbd\x48\xb8\x64\xb1\x30\xd1\xb6\x22\x0d\x15\x15\x14\x07\x5d\xc9\x23\x65\x4a\xb4\xf1\x38\xa9\xdb\xf0\xd2\x36\xb3\x0c\xdf\xa8\xe2\x67\x61\xa3\xdf\xf3\x3d\x68\x53\xf7\x42\x0c\x93\x06\x19\xdf\x42\x60\xd1\xd5\x4e\x16\x25\xe6\x0e\x98\xd2\x6e\x89\xc6\x6f\x8b\x8a\xf4\xe6\xed\x3f\x6f\xbf\x4b\x2e\x87\x3c\xf5\x71\xb5\x10\x9f\x87\x6f\xf5\xd6\x68\xc4\x22\x56\x07\xfd\xe4\x17\x9b\x56\xe6\xe1\x11\x6a\xf4\x1b\x8f\x95\x04\xd4\x3d\xc5\x84\x37\xdb\xc9\x27\x37\x4f\xf5\x6a\x8a\xeb\xe0\x11\x68\x94\xef\xf0\x29\x28\x8d\xb3\x45\x66\xf2\x25\xf1\x6d\x66\xef\x19\x17\x06\xf3\x91\xc1\xcc\x75\xbb\xa3\x9b\xdc\x77\x3b\x1e\x3c\x3c\xf7\x16\xec\x4d\xf7\xe4\xee\xc9\xff\x02\x00\x00\xff\xff\x3d\xdc\x82\x73\x09\x32\x00\x00")
 
 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 99aede82..d6b81b49 100644
--- a/wski18n/resources/en_US.all.json
+++ b/wski18n/resources/en_US.all.json
@@ -139,6 +139,10 @@
     "id": "msg_config_namespace_info",
     "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"
@@ -311,6 +315,14 @@
     "id": "msg_err_json_missing_cmd_key",
     "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 ==================="


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services