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

[incubator-openwhisk-wskdeploy] branch master updated: Adjust the code to reflect latest API gateway version. (#262)

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 484c2b4  Adjust the code to reflect latest API gateway version. (#262)
484c2b4 is described below

commit 484c2b43df685a732861396d8b6337462fb79f8b
Author: David Liu <da...@cn.ibm.com>
AuthorDate: Tue Sep 5 10:52:29 2017 +0800

    Adjust the code to reflect latest API gateway version. (#262)
    
    * Add api test case.
    
    * update the manifest yaml according to wskdeploy package
    specification v0.8.7.pdf
    
    * Tweak the manifest add multi method support in one single line.
    
    * Add basic api denote structure and composer api function.
    
    * Add the apigateway CI test file.
---
 cmd/root.go                                        | 126 +++---
 cmd/root_test.go                                   |   2 +-
 cmd/undeploy.go                                    |   2 +-
 deployers/manifestreader.go                        |  50 +-
 deployers/servicedeployer.go                       |   7 +-
 deployers/whiskclient.go                           |  34 +-
 parsers/deploy_parser.go                           |   2 +-
 parsers/manifest_parser.go                         |  32 +-
 parsers/manifest_parser_test.go                    |  12 +-
 parsers/yamlparser.go                              |  41 +-
 .../src/integration/apigateway/apigateway_test.go  |  40 +-
 tests/src/integration/apigateway/manifest.yml      |  34 ++
 tests/src/integration/apigateway/src/greeting.js   |  12 +
 tests/src/integration/common/wskdeploy.go          |  59 +--
 utils/errorhandlers.go                             |  16 +-
 utils/flags.go                                     |   2 +-
 utils/misc.go                                      |  20 +-
 utils/wskdeployerror.go                            |  12 +-
 wski18n/detection.go                               |  24 +-
 wski18n/i18n.go                                    | 152 +++----
 wski18n/i18n_resources.go                          | 504 ++++++++++-----------
 21 files changed, 608 insertions(+), 575 deletions(-)

diff --git a/cmd/root.go b/cmd/root.go
index 5596096..fe5d045 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -22,16 +22,16 @@ import (
 	"errors"
 	"fmt"
 	"github.com/apache/incubator-openwhisk-client-go/whisk"
-	"github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
 	"github.com/apache/incubator-openwhisk-wskdeploy/deployers"
 	"github.com/apache/incubator-openwhisk-wskdeploy/utils"
+	"github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
 	"github.com/spf13/cobra"
 	"os"
-	"regexp"
-	"strings"
 	"path"
 	"path/filepath"
     "net/http"
+	"regexp"
+	"strings"
 )
 
 var stderr = ""
@@ -49,7 +49,7 @@ wskdeploy without any commands or flags deploys openwhisk package in the current
 	RunE: RootCmdImp,
 }
 
-func RootCmdImp(cmd *cobra.Command, args []string) error{
+func RootCmdImp(cmd *cobra.Command, args []string) error {
 	return Deploy()
 }
 
@@ -65,7 +65,7 @@ func Execute() {
 	}
 
 	if err := RootCmd.Execute(); err != nil {
-        utils.PrintOpenWhiskError(err)
+		utils.PrintOpenWhiskError(err)
 		os.Exit(-1)
 	} else {
 		if utils.Flags.WithinOpenWhisk {
@@ -81,7 +81,7 @@ func substCmdArgs() error {
 
 	arg := os.Args[1]
 
-    fmt.Println("arg is " + arg)
+	fmt.Println("arg is " + arg)
 	// unmarshal the string to a JSON object
 	var obj map[string]interface{}
 	json.Unmarshal([]byte(arg), &obj)
@@ -114,42 +114,44 @@ func init() {
 	RootCmd.PersistentFlags().BoolVarP(&utils.Flags.UseDefaults, "allow-defaults", "a", false, "allow defaults")
 	RootCmd.PersistentFlags().BoolVarP(&utils.Flags.Verbose, "verbose", "v", false, "verbose output")
 	RootCmd.PersistentFlags().StringVarP(&utils.Flags.ApiHost, "apihost", "", "", wski18n.T("whisk API HOST"))
-    RootCmd.PersistentFlags().StringVarP(&utils.Flags.Namespace, "namespace", "n", "", wski18n.T("namespace"))
+	RootCmd.PersistentFlags().StringVarP(&utils.Flags.Namespace, "namespace", "n", "", wski18n.T("namespace"))
 	RootCmd.PersistentFlags().StringVarP(&utils.Flags.Auth, "auth", "u", "", wski18n.T("authorization `KEY`"))
 	RootCmd.PersistentFlags().StringVar(&utils.Flags.ApiVersion, "apiversion", "", wski18n.T("whisk API `VERSION`"))
 }
 
 // initConfig reads in config file and ENV variables if set.
 func initConfig() {
-    userHome := utils.GetHomeDirectory()
-    defaultPath := path.Join(userHome, whisk.DEFAULT_LOCAL_CONFIG)
+	userHome := utils.GetHomeDirectory()
+	defaultPath := path.Join(userHome, whisk.DEFAULT_LOCAL_CONFIG)
 	if utils.Flags.CfgFile != "" {
-        // Read the file as a wskprops file, to check if it is valid.
-        _, err := whisk.ReadProps(utils.Flags.CfgFile)
-        if err != nil {
-            utils.Flags.CfgFile = defaultPath
-            fmt.Println("Invalid config file detected, so by bdefault it is set to " + utils.Flags.CfgFile)
-        }
+
+		// Read the file as a wskprops file, to check if it is valid.
+		_, err := whisk.ReadProps(utils.Flags.CfgFile)
+		if err != nil {
+			utils.Flags.CfgFile = defaultPath
+			fmt.Println("Invalid config file detected, so by bdefault it is set to " + utils.Flags.CfgFile)
+		}
+
 	} else {
-        utils.Flags.CfgFile = defaultPath
-    }
+		utils.Flags.CfgFile = defaultPath
+	}
 }
 
 func setSupportedRuntimes(apiHost string) {
-    op, error := utils.ParseOpenWhisk(apiHost)
-    if error == nil {
-        utils.Rts = utils.ConvertToMap(op)
-    } else {
-        utils.Rts = utils.DefaultRts
-    }
+	op, error := utils.ParseOpenWhisk(apiHost)
+	if error == nil {
+		utils.Rts = utils.ConvertToMap(op)
+	} else {
+		utils.Rts = utils.DefaultRts
+	}
 }
 
 func Deploy() error {
 
 	whisk.SetVerbose(utils.Flags.Verbose)
-    // Verbose mode is the only mode for wskdeploy to turn on all the debug messages, so the currenty Verbose mode
-    // also set debug mode to true.
-    whisk.SetDebug(utils.Flags.Verbose)
+	// Verbose mode is the only mode for wskdeploy to turn on all the debug messages, so the currenty Verbose mode
+	// also set debug mode to true.
+	whisk.SetDebug(utils.Flags.Verbose)
 
 	projectPath, err := filepath.Abs(utils.Flags.ProjectPath)
 	utils.Check(err)
@@ -157,21 +159,21 @@ func Deploy() error {
 	if utils.Flags.ManifestPath == "" {
 		if _, err := os.Stat(path.Join(projectPath, utils.ManifestFileNameYaml)); err == nil {
 			utils.Flags.ManifestPath = path.Join(projectPath, utils.ManifestFileNameYaml)
-            stdout = wski18n.T("Using {{.manifestPath}} for deployment.\n",
-                map[string]interface{}{"manifestPath": utils.Flags.ManifestPath})
+			stdout = wski18n.T("Using {{.manifestPath}} for deployment.\n",
+				map[string]interface{}{"manifestPath": utils.Flags.ManifestPath})
 		} else if _, err := os.Stat(path.Join(projectPath, utils.ManifestFileNameYml)); err == nil {
 			utils.Flags.ManifestPath = path.Join(projectPath, utils.ManifestFileNameYml)
-            stdout = wski18n.T("Using {{.manifestPath}} for deployment.\n",
-                map[string]interface{}{"manifestPath": utils.Flags.ManifestPath})
+			stdout = wski18n.T("Using {{.manifestPath}} for deployment.\n",
+				map[string]interface{}{"manifestPath": utils.Flags.ManifestPath})
 		} else {
-            stderr = wski18n.T("Manifest file not found at path {{.projectPath}}.\n",
-                map[string]interface{}{"projectPath": projectPath})
-            whisk.Debug(whisk.DbgError, stderr)
-            errString := wski18n.T("Missing {{.yaml}}/{{.yml}} file.\n",
-                map[string]interface{}{"yaml": utils.ManifestFileNameYaml , "yml":utils.ManifestFileNameYml})
+			stderr = wski18n.T("Manifest file not found at path {{.projectPath}}.\n",
+				map[string]interface{}{"projectPath": projectPath})
+			whisk.Debug(whisk.DbgError, stderr)
+			errString := wski18n.T("Missing {{.yaml}}/{{.yml}} file.\n",
+				map[string]interface{}{"yaml": utils.ManifestFileNameYaml, "yml": utils.ManifestFileNameYml})
 			return utils.NewInputYamlFileError(errString)
 		}
-        whisk.Debug(whisk.DbgInfo, stdout)
+		whisk.Debug(whisk.DbgInfo, stdout)
 	}
 
 	if utils.Flags.DeploymentPath == "" {
@@ -212,8 +214,8 @@ func Deploy() error {
         deployer.Client = whiskClient
 		deployer.ClientConfig = clientConfig
 
-        // The auth, apihost and namespace have been chosen, so that we can check the supported runtimes here.
-        setSupportedRuntimes(clientConfig.Host)
+		// The auth, apihost and namespace have been chosen, so that we can check the supported runtimes here.
+		setSupportedRuntimes(clientConfig.Host)
 
 		err := deployer.ConstructDeploymentPlan()
 
@@ -231,10 +233,10 @@ func Deploy() error {
 		}
 
 	} else {
-        errString := wski18n.T("Missing {{.yaml}}/{{.yml}} file.\n",
-            map[string]interface{}{"yaml": utils.ManifestFileNameYaml , "yml":utils.ManifestFileNameYml})
-        whisk.Debug(whisk.DbgError, errString)
-        return utils.NewInputYamlFileError(errString)
+		errString := wski18n.T("Missing {{.yaml}}/{{.yml}} file.\n",
+			map[string]interface{}{"yaml": utils.ManifestFileNameYaml, "yml": utils.ManifestFileNameYml})
+		whisk.Debug(whisk.DbgError, errString)
+		return utils.NewInputYamlFileError(errString)
 	}
 
 }
@@ -242,9 +244,9 @@ func Deploy() error {
 func Undeploy() error {
 
 	whisk.SetVerbose(utils.Flags.Verbose)
-    // Verbose mode is the only mode for wskdeploy to turn on all the debug messages, so the currenty Verbose mode
-    // also set debug mode to true.
-    whisk.SetDebug(utils.Flags.Verbose)
+	// Verbose mode is the only mode for wskdeploy to turn on all the debug messages, so the currenty Verbose mode
+	// also set debug mode to true.
+	whisk.SetDebug(utils.Flags.Verbose)
 
 	projectPath, err := filepath.Abs(utils.Flags.ProjectPath)
 	utils.Check(err)
@@ -252,21 +254,21 @@ func Undeploy() error {
 	if utils.Flags.ManifestPath == "" {
 		if _, err := os.Stat(path.Join(projectPath, utils.ManifestFileNameYaml)); err == nil {
 			utils.Flags.ManifestPath = path.Join(projectPath, utils.ManifestFileNameYaml)
-            stdout = wski18n.T("Using {{.manifestPath}} for undeployment.\n",
-                map[string]interface{}{"manifestPath": utils.Flags.ManifestPath})
+			stdout = wski18n.T("Using {{.manifestPath}} for undeployment.\n",
+				map[string]interface{}{"manifestPath": utils.Flags.ManifestPath})
 		} else if _, err := os.Stat(path.Join(projectPath, utils.ManifestFileNameYml)); err == nil {
 			utils.Flags.ManifestPath = path.Join(projectPath, utils.ManifestFileNameYml)
-            stdout = wski18n.T("Using {{.manifestPath}} for undeployment.\n",
-                map[string]interface{}{"manifestPath": utils.Flags.ManifestPath})
+			stdout = wski18n.T("Using {{.manifestPath}} for undeployment.\n",
+				map[string]interface{}{"manifestPath": utils.Flags.ManifestPath})
 		} else {
-            stderr = wski18n.T("Manifest file not found at path {{.projectPath}}.\n",
-                map[string]interface{}{"projectPath": projectPath})
-            whisk.Debug(whisk.DbgError, stderr)
-            errString := wski18n.T("Missing {{.yaml}}/{{.yml}} file.\n",
-                map[string]interface{}{"yaml": utils.ManifestFileNameYaml , "yml":utils.ManifestFileNameYml})
-            return utils.NewInputYamlFileError(errString)
+			stderr = wski18n.T("Manifest file not found at path {{.projectPath}}.\n",
+				map[string]interface{}{"projectPath": projectPath})
+			whisk.Debug(whisk.DbgError, stderr)
+			errString := wski18n.T("Missing {{.yaml}}/{{.yml}} file.\n",
+				map[string]interface{}{"yaml": utils.ManifestFileNameYaml, "yml": utils.ManifestFileNameYml})
+			return utils.NewInputYamlFileError(errString)
 		}
-        whisk.Debug(whisk.DbgInfo, stdout)
+		whisk.Debug(whisk.DbgInfo, stdout)
 	}
 
 	if utils.Flags.DeploymentPath == "" {
@@ -302,8 +304,8 @@ func Undeploy() error {
         deployer.Client = whiskClient
 		deployer.ClientConfig = clientConfig
 
-        // The auth, apihost and namespace have been chosen, so that we can check the supported runtimes here.
-        setSupportedRuntimes(clientConfig.Host)
+		// The auth, apihost and namespace have been chosen, so that we can check the supported runtimes here.
+		setSupportedRuntimes(clientConfig.Host)
 
 		verifiedPlan, err := deployer.ConstructUnDeploymentPlan()
 		err = deployer.UnDeploy(verifiedPlan)
@@ -315,9 +317,9 @@ func Undeploy() error {
 		}
 
 	} else {
-        errString := wski18n.T("Missing {{.yaml}}/{{.yml}} file.\n",
-            map[string]interface{}{"yaml": utils.ManifestFileNameYaml , "yml":utils.ManifestFileNameYml})
-        whisk.Debug(whisk.DbgError, errString)
-        return utils.NewInputYamlFileError(errString)
+		errString := wski18n.T("Missing {{.yaml}}/{{.yml}} file.\n",
+			map[string]interface{}{"yaml": utils.ManifestFileNameYaml, "yml": utils.ManifestFileNameYml})
+		whisk.Debug(whisk.DbgError, errString)
+		return utils.NewInputYamlFileError(errString)
 	}
 }
diff --git a/cmd/root_test.go b/cmd/root_test.go
index 2a360c5..75c1469 100644
--- a/cmd/root_test.go
+++ b/cmd/root_test.go
@@ -24,9 +24,9 @@ import (
 	"github.com/apache/incubator-openwhisk-wskdeploy/utils"
 	"github.com/spf13/cobra"
 	"github.com/stretchr/testify/assert"
+	"os"
 	"strings"
 	"testing"
-    "os"
 )
 
 var rootcalled bool
diff --git a/cmd/undeploy.go b/cmd/undeploy.go
index 379ac36..ec464c8 100644
--- a/cmd/undeploy.go
+++ b/cmd/undeploy.go
@@ -27,7 +27,7 @@ var undeployCmd = &cobra.Command{
 	Use:   "undeploy",
 	Short: "Undeploy assets from OpenWhisk",
 	Long:  `Undeploy removes deployed assets from the manifest and deployment files`,
-	RunE:   UndeployCmdImp,
+	RunE:  UndeployCmdImp,
 }
 
 func UndeployCmdImp(cmd *cobra.Command, args []string) error {
diff --git a/deployers/manifestreader.go b/deployers/manifestreader.go
index 942af39..469e7e4 100644
--- a/deployers/manifestreader.go
+++ b/deployers/manifestreader.go
@@ -63,7 +63,7 @@ func (deployer *ManifestReader) HandleYaml(sdeployer *ServiceDeployer, manifestP
     var err error
 	deps, err := manifestParser.ComposeDependencies(manifest, deployer.serviceDeployer.ProjectPath)
 
-	actions, aubindings, err := manifestParser.ComposeActions(manifest, deployer.serviceDeployer.ManifestPath)
+	actions, err := manifestParser.ComposeActions(manifest, deployer.serviceDeployer.ManifestPath)
 	utils.Check(err)
 
 	sequences, err := manifestParser.ComposeSequences(deployer.serviceDeployer.ClientConfig.Namespace, manifest)
@@ -75,6 +75,8 @@ func (deployer *ManifestReader) HandleYaml(sdeployer *ServiceDeployer, manifestP
 	rules, err := manifestParser.ComposeRules(manifest)
 	utils.Check(err)
 
+	apis, err := manifestParser.ComposeApiRecords(manifest)
+
 	err = deployer.SetDependencies(deps)
 	utils.Check(err)
 
@@ -90,12 +92,10 @@ func (deployer *ManifestReader) HandleYaml(sdeployer *ServiceDeployer, manifestP
 	err = deployer.SetRules(rules)
 	utils.Check(err)
 
-	//only set api if aubindings
-	if len(aubindings) != 0 {
-		err = deployer.SetApis(sdeployer, aubindings)
-	}
+	err = deployer.SetApis(apis)
+
+	return nil
 
-	return err
 }
 
 func (reader *ManifestReader) SetDependencies(deps map[string]utils.DependencyRecord) error {
@@ -231,9 +231,9 @@ func (reader *ManifestReader) SetSequences(actions []utils.ActionRecord) error {
 		// If the sequence action exists in actions, return error
 		_, exists := reader.serviceDeployer.Deployment.Packages[seqAction.Packagename].Actions[seqAction.Action.Name]
 		if exists == true {
-			return errors.New("manifestReader. Error: Conflict sequence action with an action. "+
-					"Found a sequence action with the same name of an action:"+
-					seqAction.Action.Name)
+			return errors.New("manifestReader. Error: Conflict sequence action with an action. " +
+				"Found a sequence action with the same name of an action:" +
+				seqAction.Action.Name)
 		}
 		existAction, exists := reader.serviceDeployer.Deployment.Packages[seqAction.Packagename].Sequences[seqAction.Action.Name]
 
@@ -307,18 +307,13 @@ func (reader *ManifestReader) SetRules(rules []*whisk.Rule) error {
 	return nil
 }
 
-func (reader *ManifestReader) SetApis(deployer *ServiceDeployer, aubs []*utils.ActionExposedURLBinding) 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 _, aub := range aubs {
-		api := createApiEntity(deployer, aub)
-		apis = append(apis, api)
-	}
-
 	for _, api := range apis {
 		existApi, exist := dep.Deployment.Apis[api.ApiDoc.ApiName]
 		if exist {
@@ -331,31 +326,6 @@ func (reader *ManifestReader) SetApis(deployer *ServiceDeployer, aubs []*utils.A
 	return nil
 }
 
-// create the api entity according to the action definition and deployer.
-func createApiEntity(dp *ServiceDeployer, au *utils.ActionExposedURLBinding) *whisk.ApiCreateRequest {
-	sendapi := new(whisk.ApiCreateRequest)
-	api := new(whisk.Api)
-	//Compose the api
-	bindingInfo := strings.Split(au.ExposedUrl, "/")
-	api.Namespace = dp.Client.Namespace
-	//api.ApiName = ""
-	api.GatewayBasePath = bindingInfo[1]
-	api.GatewayRelPath = bindingInfo[2]
-	api.GatewayMethod = strings.ToUpper(bindingInfo[0])
-	api.Id = "API" + ":" + dp.ClientConfig.Namespace + ":" + "/" + api.GatewayBasePath
-	//api.GatewayFullPath = ""
-	//api.Swagger = ""
-	//compose the api action
-	api.Action = new(whisk.ApiAction)
-	api.Action.Name = au.ActionName
-	api.Action.Namespace = dp.ClientConfig.Namespace
-	api.Action.BackendMethod = "POST"
-	api.Action.BackendUrl = "https://" + dp.ClientConfig.Host + "/api/v1/namespaces/" + dp.ClientConfig.Namespace + "/actions/" + au.ActionName
-	api.Action.Auth = dp.Client.Config.AuthToken
-	sendapi.ApiDoc = api
-	return sendapi
-}
-
 // from whisk go client
 func (deployer *ManifestReader) getQualifiedName(name string, namespace string) string {
 	if strings.HasPrefix(name, "/") {
diff --git a/deployers/servicedeployer.go b/deployers/servicedeployer.go
index 254311a..3bd27ee 100644
--- a/deployers/servicedeployer.go
+++ b/deployers/servicedeployer.go
@@ -253,12 +253,11 @@ func (deployer *ServiceDeployer) deployAssets() error {
 		return err
 	}
 
-	if len(deployer.Deployment.Apis) != 0 {
-		if err := deployer.DeployApis(); err != nil {
-			return err
-		}
+	if err := deployer.DeployApis(); err != nil {
+		return err
 	}
 
+
 	return nil
 }
 
diff --git a/deployers/whiskclient.go b/deployers/whiskclient.go
index 87bf629..b26711f 100644
--- a/deployers/whiskclient.go
+++ b/deployers/whiskclient.go
@@ -23,7 +23,6 @@ import (
 	"net/http"
 	"os"
 	"strings"
-
 	"github.com/apache/incubator-openwhisk-client-go/whisk"
 	"github.com/apache/incubator-openwhisk-wskdeploy/parsers"
     "github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
@@ -32,40 +31,40 @@ import (
 )
 
 const (
-    COMMANDLINE = "wskdeploy command line"
-    DEFAULTVALUE = "default value"
-    WSKPROPS = ".wskprops"
-    WHISKPROPERTY = "whisk.properties"
-    INTERINPUT = "interactve input"
+	COMMANDLINE = "wskdeploy command line"
+	DEFAULTVALUE = "default value"
+	WSKPROPS = ".wskprops"
+	WHISKPROPERTY = "whisk.properties"
+	INTERINPUT = "interactve input"
 )
 
 type PropertyValue struct {
-    Value string
-    Source string
+	Value string
+	Source string
 }
 
 var GetPropertyValue = func (prop PropertyValue, newValue string, source string) PropertyValue {
-    if len(prop.Value) == 0 && len(newValue) > 0 {
-        prop.Value = newValue
-        prop.Source = source
-    }
-    return prop
+	if len(prop.Value) == 0 && len(newValue) > 0 {
+		prop.Value = newValue
+		prop.Source = source
+	}
+	return prop
 }
 
 var GetWskPropFromWskprops = func (pi whisk.Properties, proppath string) (*whisk.Wskprops, error) {
-    return whisk.GetWskPropFromWskprops(pi, proppath)
+	return whisk.GetWskPropFromWskprops(pi, proppath)
 }
 
 var GetWskPropFromWhiskProperty = func (pi whisk.Properties) (*whisk.Wskprops, error) {
-    return whisk.GetWskPropFromWhiskProperty(pi)
+	return whisk.GetWskPropFromWhiskProperty(pi)
 }
 
 var GetCommandLineFlags = func () (string, string, string) {
-    return utils.Flags.ApiHost, utils.Flags.Auth, utils.Flags.Namespace
+	return utils.Flags.ApiHost, utils.Flags.Auth, utils.Flags.Namespace
 }
 
 var CreateNewClient = func (httpClient *http.Client, config_input *whisk.Config) (*whisk.Client, error) {
-    return whisk.NewClient(http.DefaultClient, clientConfig)
+	return whisk.NewClient(http.DefaultClient, clientConfig)
 }
 
 func NewWhiskConfig(proppath string, deploymentPath string, manifestPath string, isInteractive bool) (*whisk.Config, error) {
@@ -198,7 +197,6 @@ func NewWhiskConfig(proppath string, deploymentPath string, manifestPath string,
     stdout = wski18n.T("The namespace is {{.namespace}}, from {{.namespacesource}}.\n",
         map[string]interface{}{"namespace": namespace.Value, "namespacesource": namespace.Source})
     whisk.Debug(whisk.DbgInfo, stdout)
-
     return clientConfig, nil
 }
 
diff --git a/parsers/deploy_parser.go b/parsers/deploy_parser.go
index 62a3292..b6ad73c 100644
--- a/parsers/deploy_parser.go
+++ b/parsers/deploy_parser.go
@@ -18,9 +18,9 @@
 package parsers
 
 import (
+	"fmt"
 	"github.com/apache/incubator-openwhisk-wskdeploy/utils"
 	"gopkg.in/yaml.v2"
-    "fmt"
 )
 
 func (dm *YAMLParser) UnmarshalDeployment(input []byte, deploy *DeploymentYAML) error {
diff --git a/parsers/manifest_parser.go b/parsers/manifest_parser.go
index 0e4f477..3034e12 100644
--- a/parsers/manifest_parser.go
+++ b/parsers/manifest_parser.go
@@ -230,11 +230,10 @@ func (dm *YAMLParser) ComposeSequences(namespace string, mani *ManifestYAML) ([]
 	return s1, nil
 }
 
-func (dm *YAMLParser) ComposeActions(mani *ManifestYAML, manipath string) (ar []utils.ActionRecord, aub []*utils.ActionExposedURLBinding, err error) {
+func (dm *YAMLParser) ComposeActions(mani *ManifestYAML, manipath string) (ar []utils.ActionRecord, err error) {
 
 	var errorParser error
 	var s1 []utils.ActionRecord = make([]utils.ActionRecord, 0)
-	var au []*utils.ActionExposedURLBinding = make([]*utils.ActionExposedURLBinding, 0)
 
 	for key, action := range mani.Package.Actions {
 		splitmanipath := strings.Split(manipath, string(os.PathSeparator))
@@ -246,9 +245,6 @@ func (dm *YAMLParser) ComposeActions(mani *ManifestYAML, manipath string) (ar []
 
 		wskaction := new(whisk.Action)
 		//bind action, and exposed URL
-		aubinding := new(utils.ActionExposedURLBinding)
-		aubinding.ActionName = key
-		aubinding.ExposedUrl = action.ExposedUrl
 
 		wskaction.Exec = new(whisk.Exec)
 		if action.Function != "" {
@@ -322,7 +318,7 @@ func (dm *YAMLParser) ComposeActions(mani *ManifestYAML, manipath string) (ar []
 			keyVal.Value, errorParser = ResolveParameter(name, &param)
 
 			if errorParser != nil {
-				return nil, nil, errorParser
+				return nil, errorParser
 			}
 
 			if keyVal.Value != nil {
@@ -357,14 +353,9 @@ func (dm *YAMLParser) ComposeActions(mani *ManifestYAML, manipath string) (ar []
 		record := utils.ActionRecord{wskaction, mani.Package.Packagename, action.Function}
 		s1 = append(s1, record)
 
-		//only append when the fields are exists
-		if aubinding.ActionName != "" && aubinding.ExposedUrl != "" {
-			au = append(au, aubinding)
-		}
-
 	}
 
-	return s1, au, nil
+	return s1, nil
 
 }
 
@@ -437,13 +428,16 @@ func (dm *YAMLParser) ComposeRules(manifest *ManifestYAML) ([]*whisk.Rule, error
 	return r1, nil
 }
 
-func (action *Action) ComposeWskAction(manipath string) (*whisk.Action, error) {
-	wskaction, err := utils.CreateActionFromFile(manipath, action.Location)
-	utils.Check(err)
-	wskaction.Name = action.Name
-	wskaction.Version = action.Version
-	wskaction.Namespace = action.Namespace
-	return wskaction, err
+func (dm *YAMLParser) ComposeApiRecords(manifest *ManifestYAML) ([]*whisk.ApiCreateRequest, error) {
+	pkg := manifest.Package
+	var acq []*whisk.ApiCreateRequest = make([]*whisk.ApiCreateRequest, 0)
+	apis := pkg.GetApis()
+	for _, api := range apis {
+		acr := new(whisk.ApiCreateRequest)
+		acr.ApiDoc = api
+		acq = append(acq, acr)
+	}
+	return acq, nil
 }
 
 // TODO(): Support other valid Package Manifest types
diff --git a/parsers/manifest_parser_test.go b/parsers/manifest_parser_test.go
index c4027dd..586a8e0 100644
--- a/parsers/manifest_parser_test.go
+++ b/parsers/manifest_parser_test.go
@@ -494,7 +494,7 @@ func TestComposeActionsForImplicitRuntimes(t *testing.T) {
 			// read and parse manifest.yaml file
 			p := NewYAMLParser()
 			m := p.ParseManifest(tmpfile.Name())
-			actions, _, err := p.ComposeActions(m, tmpfile.Name())
+			actions, err := p.ComposeActions(m, tmpfile.Name())
 			var expectedResult string
 			if err == nil {
 				for i := 0; i < len(actions); i++ {
@@ -536,7 +536,7 @@ func TestComposeActionsForInvalidRuntime(t *testing.T) {
 			// read and parse manifest.yaml file
 			p := NewYAMLParser()
 			m := p.ParseManifest(tmpfile.Name())
-			_, _, err := p.ComposeActions(m, tmpfile.Name())
+			_, err := p.ComposeActions(m, tmpfile.Name())
 			// (TODO) uncomment the following test case after issue #307 is fixed
 			// (TODO) its failing right now as we are lacking check on invalid runtime
 			// assert.NotNil(t, err, "Invalid runtime, ComposeActions should report an error")
@@ -555,7 +555,7 @@ func TestComposeActionsForSingleLineParams(t *testing.T) {
 	// read and parse manifest.yaml file
 	p := NewYAMLParser()
 	m := p.ParseManifest(manifestFile)
-	actions, _, err := p.ComposeActions(m, manifestFile)
+	actions, err := p.ComposeActions(m, manifestFile)
 
 	if err == nil {
 		// assert that the actions variable has only one action
@@ -640,7 +640,7 @@ func TestComposeActionsForMultiLineParams(t *testing.T) {
 	// read and parse manifest.yaml file
 	p := NewYAMLParser()
 	m := p.ParseManifest(manifestFile)
-	actions, _, err := p.ComposeActions(m, manifestFile)
+	actions, err := p.ComposeActions(m, manifestFile)
 
 	if err == nil {
 		// assert that the actions variable has only one action
@@ -720,7 +720,7 @@ func TestComposeActionsForFunction(t *testing.T) {
 			// read and parse manifest.yaml file
 			p := NewYAMLParser()
 			m := p.ParseManifest(tmpfile.Name())
-			actions, _, err := p.ComposeActions(m, tmpfile.Name())
+			actions, err := p.ComposeActions(m, tmpfile.Name())
 			var expectedResult, actualResult string
 			if err == nil {
 				for i := 0; i < len(actions); i++ {
@@ -808,7 +808,7 @@ func TestComposeActionsForWebActions(t *testing.T) {
 			// read and parse manifest.yaml file
 			p := NewYAMLParser()
 			m := p.ParseManifest(tmpfile.Name())
-			actions, _, err := p.ComposeActions(m, tmpfile.Name())
+			actions, err := p.ComposeActions(m, tmpfile.Name())
 			if err == nil {
 				for i := 0; i < len(actions); i++ {
 					if actions[i].Action.Name == "hello" {
diff --git a/parsers/yamlparser.go b/parsers/yamlparser.go
index 3a6a686..9190bbe 100644
--- a/parsers/yamlparser.go
+++ b/parsers/yamlparser.go
@@ -136,15 +136,15 @@ type Package struct {
 	//mapping to wsk.SentPackageNoPublish.Name
 	Packagename string `yaml:"name"` //used in manifest.yaml
 	//mapping to wsk.SentPackageNoPublish.Version
-	Version           string                `yaml:"version"` //used in manifest.yaml
-	License           string                `yaml:"license"` //used in manifest.yaml
-	Repositories      []Repository          `yaml:"repositories,omitempty"`
-	Dependencies      map[string]Dependency `yaml: dependencies`        // used in manifest.yaml
-	Function          string                `yaml:"function"`           //used in deployment.yaml
+	Version      string                `yaml:"version"` //used in manifest.yaml
+	License      string                `yaml:"license"` //used in manifest.yaml
+	Repositories []Repository          `yaml:"repositories,omitempty"`
+	Dependencies map[string]Dependency `yaml: dependencies` // used in manifest.yaml
+	Function     string                `yaml:"function"`    //used in deployment.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
+	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
@@ -153,6 +153,7 @@ type Package struct {
 	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 Application struct {
@@ -162,7 +163,7 @@ type Application struct {
 	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
+	Package    Package            `yaml:"package"`  // being deprecated, used in deployment.yaml
 }
 
 type DeploymentYAML struct {
@@ -247,3 +248,29 @@ func (pkg *Package) GetFeedList() []Feed {
 	}
 	return s1
 }
+
+// This is for parse the manifest yaml file.
+func (pkg *Package) GetApis() []*whisk.Api {
+	var apis = make([]*whisk.Api, 0)
+	for k, v := range pkg.Apis {
+		var apiName string = k
+		for k, v := range v {
+			var gatewayBasePath string = k
+			for k, v := range v {
+				var gatewayRelPath string = k
+				for k, v := range v {
+					api := &whisk.Api{}
+					api.ApiName = apiName
+					api.GatewayBasePath = gatewayBasePath
+					api.GatewayRelPath = gatewayRelPath
+					action := &whisk.ApiAction{}
+					action.Name = k
+					action.BackendMethod = v
+					api.Action = action
+					apis = append(apis, api)
+				}
+			}
+		}
+	}
+	return apis
+}
diff --git a/wski18n/detection.go b/tests/src/integration/apigateway/apigateway_test.go
similarity index 51%
copy from wski18n/detection.go
copy to tests/src/integration/apigateway/apigateway_test.go
index b442cc4..426365f 100644
--- a/wski18n/detection.go
+++ b/tests/src/integration/apigateway/apigateway_test.go
@@ -1,3 +1,5 @@
+// +build integration
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -15,29 +17,25 @@
  * limitations under the License.
  */
 
-package wski18n
-
-import "github.com/cloudfoundry/jibber_jabber"
+package tests
 
-type Detector interface {
-    DetectLocale() string
-    DetectLanguage() string
-}
+import (
+	"testing"
+	"github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/common"
+	"github.com/stretchr/testify/assert"
+	"os"
+)
 
-type JibberJabberDetector struct{}
+var wskprops = common.GetWskprops()
 
-func (d *JibberJabberDetector) DetectLocale() string {
-    userLocale, err := jibber_jabber.DetectIETF()
-    if err != nil {
-        userLocale = ""
-    }
-    return userLocale
+// TODO: write the integration against openwhisk
+func TestTriggerRule(t *testing.T) {
+	wskdeploy := common.NewWskdeploy()
+	manifestPath := os.Getenv("GOPATH") + "/src/github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/apigateway/manifest.yml"
+	_, err := wskdeploy.DeployManifestPathOnly(manifestPath)
+	assert.Equal(t, nil, err, "Failed to deploy based on the manifest file.")
+	_, err = wskdeploy.UndeployManifestPathOnly(manifestPath)
+	assert.Equal(t, nil, err, "Failed to undeploy based on the manifest file.")
 }
 
-func (d *JibberJabberDetector) DetectLanguage() string {
-    lang, err := jibber_jabber.DetectLanguage()
-    if err != nil {
-        lang = ""
-    }
-    return lang
-}
+
diff --git a/tests/src/integration/apigateway/manifest.yml b/tests/src/integration/apigateway/manifest.yml
new file mode 100644
index 0000000..c7e37b0
--- /dev/null
+++ b/tests/src/integration/apigateway/manifest.yml
@@ -0,0 +1,34 @@
+package:
+  name: 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
+
diff --git a/tests/src/integration/apigateway/src/greeting.js b/tests/src/integration/apigateway/src/greeting.js
new file mode 100644
index 0000000..7c069f1
--- /dev/null
+++ b/tests/src/integration/apigateway/src/greeting.js
@@ -0,0 +1,12 @@
+/**
+ * Return a simple greeting message for someone.
+ *
+ * @param name A person's name.
+ * @param place Where the person is from.
+ */
+function main(params) {
+    var name = params.name || params.payload || 'stranger';
+    var place = params.place || 'somewhere';
+    return {payload:  'Hello, ' + name + ' from ' + place + '!'};
+}
+
diff --git a/tests/src/integration/common/wskdeploy.go b/tests/src/integration/common/wskdeploy.go
index 37f731d..d91cb23 100644
--- a/tests/src/integration/common/wskdeploy.go
+++ b/tests/src/integration/common/wskdeploy.go
@@ -18,14 +18,14 @@
 package common
 
 import (
+	"bytes"
 	"fmt"
+	"github.com/apache/incubator-openwhisk-wskdeploy/utils"
+	"github.com/fatih/color"
+	"github.com/mattn/go-colorable"
 	"os"
 	"os/exec"
 	"strings"
-    "bytes"
-    "github.com/apache/incubator-openwhisk-wskdeploy/utils"
-    "github.com/mattn/go-colorable"
-    "github.com/fatih/color"
 )
 
 const cmd = "wskdeploy"
@@ -51,12 +51,12 @@ func printCommand(cmd *exec.Cmd) {
 }
 
 func printError(err string) {
-    outputStream := colorable.NewColorableStderr()
+	outputStream := colorable.NewColorableStderr()
 	if len(err) > 0 {
-        fmt.Fprintf(outputStream, "==> Error: %s.\n", color.RedString(err))
+		fmt.Fprintf(outputStream, "==> Error: %s.\n", color.RedString(err))
 	} else {
-        fmt.Fprintf(outputStream, "==> Error: %s.\n", color.RedString("No error message"))
-    }
+		fmt.Fprintf(outputStream, "==> Error: %s.\n", color.RedString("No error message"))
+	}
 }
 
 func printOutput(outs string) {
@@ -68,26 +68,29 @@ func printOutput(outs string) {
 func (wskdeploy *Wskdeploy) RunCommand(s ...string) (string, error) {
 	command := exec.Command(wskdeploy.Path, s...)
 	command.Dir = wskdeploy.Dir
+
+	fmt.Println("wskdeploy.Path is " + wskdeploy.Path)
+	//fmt.Println("s is " + string(s))
 	printCommand(command)
 
-    var outb, errb bytes.Buffer
-    command.Stdout = &outb
-    command.Stderr = &errb
+	var outb, errb bytes.Buffer
+	command.Stdout = &outb
+	command.Stderr = &errb
 	err := command.Run()
 
-    var returnError error = nil
-    if err != nil {
-        returnError = err
-    } else {
-        if (len(errb.String()) > 0) {
-            returnError = utils.NewTestCaseError(errb.String())
-        }
-    }
-    printOutput(outb.String())
-    if returnError != nil {
-        printError(returnError.Error())
-    }
-    return outb.String(), returnError
+	var returnError error = nil
+	if err != nil {
+		returnError = err
+	} else {
+		if len(errb.String()) > 0 {
+			returnError = utils.NewTestCaseError(errb.String())
+		}
+	}
+	printOutput(outb.String())
+	if returnError != nil {
+		printError(returnError.Error())
+	}
+	return outb.String(), returnError
 }
 
 func (wskdeploy *Wskdeploy) Deploy(manifestPath string, deploymentPath string) (string, error) {
@@ -99,11 +102,12 @@ func (wskdeploy *Wskdeploy) Undeploy(manifestPath string, deploymentPath string)
 }
 
 func (wskdeploy *Wskdeploy) DeployProjectPathOnly(projectPath string) (string, error) {
-	return wskdeploy.RunCommand( "-p", projectPath)
+	return wskdeploy.RunCommand("-p", projectPath)
 }
 
 func (wskdeploy *Wskdeploy) UndeployProjectPathOnly(projectPath string) (string, error) {
-    return wskdeploy.RunCommand("undeploy", "-p", projectPath)
+	return wskdeploy.RunCommand("undeploy", "-p", projectPath)
+
 }
 
 func (wskdeploy *Wskdeploy) DeployManifestPathOnly(manifestpath string) (string, error) {
@@ -111,5 +115,6 @@ func (wskdeploy *Wskdeploy) DeployManifestPathOnly(manifestpath string) (string,
 }
 
 func (wskdeploy *Wskdeploy) UndeployManifestPathOnly(manifestpath string) (string, error) {
-    return wskdeploy.RunCommand("undeploy", "-m", manifestpath)
+	return wskdeploy.RunCommand("undeploy", "-m", manifestpath)
+
 }
diff --git a/utils/errorhandlers.go b/utils/errorhandlers.go
index 04ecd57..cf81836 100644
--- a/utils/errorhandlers.go
+++ b/utils/errorhandlers.go
@@ -20,10 +20,10 @@ package utils
 import (
 	"errors"
 	"fmt"
+	"github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
+	"github.com/fatih/color"
+	"github.com/mattn/go-colorable"
 	"os"
-    "github.com/mattn/go-colorable"
-    "github.com/fatih/color"
-    "github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
 )
 
 // Check is a util function to panic when there is an error.
@@ -48,11 +48,11 @@ func Check(e error) {
 }
 
 func PrintOpenWhiskError(err error) {
-    outputStream := colorable.NewColorableStderr()
-    fmt.Fprintf(outputStream, "%s%s\n", color.RedString(wski18n.T("Error: ")), err.Error())
+	outputStream := colorable.NewColorableStderr()
+	fmt.Fprintf(outputStream, "%s%s\n", color.RedString(wski18n.T("Error: ")), err.Error())
 }
 
-func PrintOpenWhiskOutput(output string) {
-    fmt.Fprintf(os.Stdout, "%s\n", output)
+func PrintOpenWhiskOutput(err error) {
+	outputStream := colorable.NewColorableStderr()
+	fmt.Fprintf(outputStream, "%s%s\n", color.RedString(wski18n.T("Error: ")), err.Error())
 }
-
diff --git a/utils/flags.go b/utils/flags.go
index 673f9d2..451ddab 100644
--- a/utils/flags.go
+++ b/utils/flags.go
@@ -21,7 +21,7 @@ var Flags struct {
 	WithinOpenWhisk bool   // is this running within an OpenWhisk action?
 	ApiHost         string // OpenWhisk API host
 	Auth            string // OpenWhisk API key
-    Namespace       string
+	Namespace       string
 	ApiVersion      string // OpenWhisk version
 	CfgFile         string
 	CliVersion      string
diff --git a/utils/misc.go b/utils/misc.go
index deafa4f..64a45cc 100644
--- a/utils/misc.go
+++ b/utils/misc.go
@@ -59,12 +59,6 @@ type RuleRecord struct {
 	Packagename string
 }
 
-// Bind the action name and the ExposedUrl
-type ActionExposedURLBinding struct {
-	ActionName string //action name
-	ExposedUrl string //exposedUrl in format method/baseurl/relativeurl
-}
-
 // Utility to convert hostname to URL object
 func GetURLBase(host string) (*url.URL, error) {
 
@@ -160,7 +154,7 @@ func GetEnvVar(key interface{}) interface{} {
 			if value == "" {
 				// Issue a warning to the user (verbose) that env. var. was not found
 				// (i.e., and empty string was returned).
-				fmt.Println("WARNING: Missing Environment Variable "+envkey+".")
+				fmt.Println("WARNING: Missing Environment Variable " + envkey + ".")
 			}
 			return value
 		}
@@ -444,7 +438,7 @@ type OpenWhiskInfo struct {
 // hard coding it here in case of network unavailable or failure.
 func ParseOpenWhisk(apiHost string) (op OpenWhiskInfo, err error) {
 	ct := "application/json; charset=UTF-8"
-	req, _ := http.NewRequest("GET", "https://" + apiHost, nil)
+	req, _ := http.NewRequest("GET", "https://"+apiHost, nil)
 	req.Header.Set("Content-Type", ct)
 	tlsConfig := &tls.Config{
 		InsecureSkipVerify: true,
@@ -456,9 +450,9 @@ func ParseOpenWhisk(apiHost string) (op OpenWhiskInfo, err error) {
 	res, err := http.DefaultClient.Do(req)
 	defer res.Body.Close()
 
-    // Local openwhisk deployment sometimes only returns "application/json" as the content type
+	// Local openwhisk deployment sometimes only returns "application/json" as the content type
 	if err != nil || !strings.Contains(ct, res.Header.Get("Content-Type")) {
-        fmt.Println("failed get openwhisk info from internet")
+		fmt.Println("failed get openwhisk info from internet")
 		fmt.Println("Start unmarshal Openwhisk info from local values")
 		err = json.Unmarshal(runtimeInfo, &op)
 	} else {
@@ -587,9 +581,9 @@ var DefaultRts = map[string][]string{
 }
 
 func CheckExistRuntime(rtname string, rts map[string][]string) bool {
-	for _, v :=range rts{
-		for i := range v{
-			if rtname == v[i]{
+	for _, v := range rts {
+		for i := range v {
+			if rtname == v[i] {
 				return true
 			}
 		}
diff --git a/utils/wskdeployerror.go b/utils/wskdeployerror.go
index 8394d02..a942f22 100644
--- a/utils/wskdeployerror.go
+++ b/utils/wskdeployerror.go
@@ -24,21 +24,21 @@ import (
 )
 
 const (
-    INVALID_YAML_INPUT = "Invalid input of Yaml file"
+	INVALID_YAML_INPUT = "Invalid input of Yaml file"
 )
 
 type TestCaseError struct {
-    errorMessage string
+	errorMessage string
 }
 
 func NewTestCaseError(errorMessage string) *TestCaseError {
-    return &TestCaseError{
-        errorMessage: errorMessage,
-    }
+	return &TestCaseError{
+		errorMessage: errorMessage,
+	}
 }
 
 func (e *TestCaseError) Error() string {
-    return e.errorMessage
+	return e.errorMessage
 }
 
 type BaseErr struct {
diff --git a/wski18n/detection.go b/wski18n/detection.go
index b442cc4..c3866dd 100644
--- a/wski18n/detection.go
+++ b/wski18n/detection.go
@@ -20,24 +20,24 @@ package wski18n
 import "github.com/cloudfoundry/jibber_jabber"
 
 type Detector interface {
-    DetectLocale() string
-    DetectLanguage() string
+	DetectLocale() string
+	DetectLanguage() string
 }
 
 type JibberJabberDetector struct{}
 
 func (d *JibberJabberDetector) DetectLocale() string {
-    userLocale, err := jibber_jabber.DetectIETF()
-    if err != nil {
-        userLocale = ""
-    }
-    return userLocale
+	userLocale, err := jibber_jabber.DetectIETF()
+	if err != nil {
+		userLocale = ""
+	}
+	return userLocale
 }
 
 func (d *JibberJabberDetector) DetectLanguage() string {
-    lang, err := jibber_jabber.DetectLanguage()
-    if err != nil {
-        lang = ""
-    }
-    return lang
+	lang, err := jibber_jabber.DetectLanguage()
+	if err != nil {
+		lang = ""
+	}
+	return lang
 }
diff --git a/wski18n/i18n.go b/wski18n/i18n.go
index 245dc3b..02a25d3 100644
--- a/wski18n/i18n.go
+++ b/wski18n/i18n.go
@@ -18,131 +18,131 @@
 package wski18n
 
 import (
-    "path/filepath"
-    "strings"
+	"path/filepath"
+	"strings"
 
-    goi18n "github.com/nicksnyder/go-i18n/i18n"
+	goi18n "github.com/nicksnyder/go-i18n/i18n"
 )
 
 const (
-    DEFAULT_LOCALE = "en_US"
+	DEFAULT_LOCALE = "en_US"
 )
 
 var SUPPORTED_LOCALES = []string{
-    "de_DE",
-    "en_US",
-    "es_ES",
-    "fr_FR",
-    "it_IT",
-    "ja_JA",
-    "ko_KR",
-    "pt_BR",
-    "zh_Hans",
-    "zh_Hant",
+	"de_DE",
+	"en_US",
+	"es_ES",
+	"fr_FR",
+	"it_IT",
+	"ja_JA",
+	"ko_KR",
+	"pt_BR",
+	"zh_Hans",
+	"zh_Hant",
 }
 
 var resourcePath = filepath.Join("wski18n", "resources")
 
 func GetResourcePath() string {
-    return resourcePath
+	return resourcePath
 }
 
 func SetResourcePath(path string) {
-    resourcePath = path
+	resourcePath = path
 }
 
 var T goi18n.TranslateFunc
 var curLocale string
 
 func init() {
-    curLocale = Init(new(JibberJabberDetector))
+	curLocale = Init(new(JibberJabberDetector))
 }
 
 func CurLocale() string {
-    return curLocale
+	return curLocale
 }
 
 func Locale(detector Detector) string {
 
-    // Use default locale until strings are translated
-    /*sysLocale := normalize(detector.DetectLocale())
-      if isSupported(sysLocale) {
-          return sysLocale
-      }
+	// Use default locale until strings are translated
+	/*sysLocale := normalize(detector.DetectLocale())
+	  if isSupported(sysLocale) {
+	      return sysLocale
+	  }
 
-      locale := defaultLocaleForLang(detector.DetectLanguage())
-      if locale != "" {
-          return locale
-      }*/
+	  locale := defaultLocaleForLang(detector.DetectLanguage())
+	  if locale != "" {
+	      return locale
+	  }*/
 
-    return DEFAULT_LOCALE
+	return DEFAULT_LOCALE
 }
 
 func Init(detector Detector) string {
-    l := Locale(detector)
-    InitWithLocale(l)
-    return l
+	l := Locale(detector)
+	InitWithLocale(l)
+	return l
 }
 
 func InitWithLocale(locale string) {
-    err := loadFromAsset(locale)
-    if err != nil {
-        panic(err)
-    }
-    T = goi18n.MustTfunc(locale)
+	err := loadFromAsset(locale)
+	if err != nil {
+		panic(err)
+	}
+	T = goi18n.MustTfunc(locale)
 }
 
 func loadFromAsset(locale string) (err error) {
-    assetName := locale + ".all.json"
-    assetKey := filepath.Join(resourcePath, assetName)
-    bytes, err := Asset(assetKey)
-    if err != nil {
-        return
-    }
-    err = goi18n.ParseTranslationFileBytes(assetName, bytes)
-    return
+	assetName := locale + ".all.json"
+	assetKey := filepath.Join(resourcePath, assetName)
+	bytes, err := Asset(assetKey)
+	if err != nil {
+		return
+	}
+	err = goi18n.ParseTranslationFileBytes(assetName, bytes)
+	return
 }
 
 func normalize(locale string) string {
-    locale = strings.ToLower(strings.Replace(locale, "-", "_", 1))
-    for _, l := range SUPPORTED_LOCALES {
-        if strings.EqualFold(locale, l) {
-            return l
-        }
-    }
-    switch locale {
-    case "zh_cn", "zh_sg":
-        return "zh_Hans"
-    case "zh_hk", "zh_tw":
-        return "zh_Hant"
-    }
-    return locale
+	locale = strings.ToLower(strings.Replace(locale, "-", "_", 1))
+	for _, l := range SUPPORTED_LOCALES {
+		if strings.EqualFold(locale, l) {
+			return l
+		}
+	}
+	switch locale {
+	case "zh_cn", "zh_sg":
+		return "zh_Hans"
+	case "zh_hk", "zh_tw":
+		return "zh_Hant"
+	}
+	return locale
 }
 
 func isSupported(locale string) bool {
-    for _, l := range SUPPORTED_LOCALES {
-        if strings.EqualFold(locale, l) {
-            return true
-        }
-    }
-    return false
+	for _, l := range SUPPORTED_LOCALES {
+		if strings.EqualFold(locale, l) {
+			return true
+		}
+	}
+	return false
 }
 
 func defaultLocaleForLang(lang string) string {
-    if lang != "" {
-        lang = strings.ToLower(lang)
-        for _, l := range SUPPORTED_LOCALES {
-            if lang == LangOfLocale(l) {
-                return l
-            }
-        }
-    }
-    return ""
+	if lang != "" {
+		lang = strings.ToLower(lang)
+		for _, l := range SUPPORTED_LOCALES {
+			if lang == LangOfLocale(l) {
+				return l
+			}
+		}
+	}
+	return ""
 }
 
 func LangOfLocale(locale string) string {
-    if len(locale) < 2 {
-        return ""
-    }
-    return locale[0:2]
+	if len(locale) < 2 {
+		return ""
+	}
+	return locale[0:2]
 }
diff --git a/wski18n/i18n_resources.go b/wski18n/i18n_resources.go
index e9caf8d..81bd161 100644
--- a/wski18n/i18n_resources.go
+++ b/wski18n/i18n_resources.go
@@ -32,102 +32,102 @@
 package wski18n
 
 import (
-    "bytes"
-    "compress/gzip"
-    "fmt"
-    "io"
-    "io/ioutil"
-    "os"
-    "path/filepath"
-    "strings"
-    "time"
+	"bytes"
+	"compress/gzip"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strings"
+	"time"
 )
 
 func bindataRead(data []byte, name string) ([]byte, error) {
-    gz, err := gzip.NewReader(bytes.NewBuffer(data))
-    if err != nil {
-        return nil, fmt.Errorf("Read %q: %v", name, err)
-    }
+	gz, err := gzip.NewReader(bytes.NewBuffer(data))
+	if err != nil {
+		return nil, fmt.Errorf("Read %q: %v", name, err)
+	}
 
-    var buf bytes.Buffer
-    _, err = io.Copy(&buf, gz)
-    clErr := gz.Close()
+	var buf bytes.Buffer
+	_, err = io.Copy(&buf, gz)
+	clErr := gz.Close()
 
-    if err != nil {
-        return nil, fmt.Errorf("Read %q: %v", name, err)
-    }
-    if clErr != nil {
-        return nil, err
-    }
+	if err != nil {
+		return nil, fmt.Errorf("Read %q: %v", name, err)
+	}
+	if clErr != nil {
+		return nil, err
+	}
 
-    return buf.Bytes(), nil
+	return buf.Bytes(), nil
 }
 
 type asset struct {
-    bytes []byte
-    info  os.FileInfo
+	bytes []byte
+	info  os.FileInfo
 }
 
 type bindataFileInfo struct {
-    name    string
-    size    int64
-    mode    os.FileMode
-    modTime time.Time
+	name    string
+	size    int64
+	mode    os.FileMode
+	modTime time.Time
 }
 
 func (fi bindataFileInfo) Name() string {
-    return fi.name
+	return fi.name
 }
 func (fi bindataFileInfo) Size() int64 {
-    return fi.size
+	return fi.size
 }
 func (fi bindataFileInfo) Mode() os.FileMode {
-    return fi.mode
+	return fi.mode
 }
 func (fi bindataFileInfo) ModTime() time.Time {
-    return fi.modTime
+	return fi.modTime
 }
 func (fi bindataFileInfo) IsDir() bool {
-    return false
+	return false
 }
 func (fi bindataFileInfo) Sys() interface{} {
-    return nil
+	return nil
 }
 
 var _wski18nResourcesDe_deAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesDe_deAllJsonBytes() ([]byte, error) {
-    return bindataRead(
-        _wski18nResourcesDe_deAllJson,
-        "wski18n/resources/de_DE.all.json",
-    )
+	return bindataRead(
+		_wski18nResourcesDe_deAllJson,
+		"wski18n/resources/de_DE.all.json",
+	)
 }
 
 func wski18nResourcesDe_deAllJson() (*asset, error) {
-    bytes, err := wski18nResourcesDe_deAllJsonBytes()
-    if err != nil {
-        return nil, err
-    }
+	bytes, err := wski18nResourcesDe_deAllJsonBytes()
+	if err != nil {
+		return nil, err
+	}
 
-    info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
-    a := &asset{bytes: bytes, info: info}
-    return a, nil
+	info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+	a := &asset{bytes: bytes, info: info}
+	return a, nil
 }
 
 var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x94\xc1\x8e\xd3\x30\x10\x86\xef\x7e\x8a\x51\x2e\x7b\xa9\xc2\x9d\xdb\x1e\x56\xda\x15\x82\x5d\xb1\x0b\x12\x02\xa4\x9a\x78\xd2\x98\xc6\x76\x64\x8f\x41\xc5\xca\xbb\x23\xbb\x6d\xa8\x8a\xdd\xa6\xdd\x5b\x6c\xcf\x7c\xf3\x7b\x7e\x4f\xbe\x32\x80\xc0\x00\x00\x2a\x29\xaa\xb7\x50\xdd\x63\xdf\x9b\x6a\xb1\xdd\x22\xcb\xb5\xeb\x39\x49\xa3\xe3\xd9\xad\x86\xdb\xa7\x07\xe8\x8c\x23\x50\xde\x11\xfc\x40\x18\xac\xf9\x25\x05 [...]
 
 func wski18nResourcesEn_usAllJsonBytes() ([]byte, error) {
-    return bindataRead(
-        _wski18nResourcesEn_usAllJson,
-        "wski18n/resources/en_US.all.json",
-    )
+	return bindataRead(
+		_wski18nResourcesEn_usAllJson,
+		"wski18n/resources/en_US.all.json",
+	)
 }
 
 func wski18nResourcesEn_usAllJson() (*asset, error) {
-    bytes, err := wski18nResourcesEn_usAllJsonBytes()
-    if err != nil {
-        return nil, err
-    }
+	bytes, err := wski18nResourcesEn_usAllJsonBytes()
+	if err != nil {
+		return nil, err
+	}
 
     info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 1890, mode: os.FileMode(420), modTime: time.Unix(1504289235, 0)}
     a := &asset{bytes: bytes, info: info}
@@ -137,225 +137,225 @@ func wski18nResourcesEn_usAllJson() (*asset, error) {
 var _wski18nResourcesEs_esAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesEs_esAllJsonBytes() ([]byte, error) {
-    return bindataRead(
-        _wski18nResourcesEs_esAllJson,
-        "wski18n/resources/es_ES.all.json",
-    )
+	return bindataRead(
+		_wski18nResourcesEs_esAllJson,
+		"wski18n/resources/es_ES.all.json",
+	)
 }
 
 func wski18nResourcesEs_esAllJson() (*asset, error) {
-    bytes, err := wski18nResourcesEs_esAllJsonBytes()
-    if err != nil {
-        return nil, err
-    }
+	bytes, err := wski18nResourcesEs_esAllJsonBytes()
+	if err != nil {
+		return nil, err
+	}
 
-    info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
-    a := &asset{bytes: bytes, info: info}
-    return a, nil
+	info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+	a := &asset{bytes: bytes, info: info}
+	return a, nil
 }
 
 var _wski18nResourcesFr_frAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8a\xe6\x52\x50\xa8\xe6\x52\x50\x50\x50\x50\xca\x4c\x51\xb2\x52\x50\x4a\xaa\x2c\x48\x2c\x2e\x56\x48\x4e\x2d\x2a\xc9\x4c\xcb\x4c\x4e\x2c\x49\x55\x48\xce\x48\x4d\xce\xce\xcc\x4b\x57\xd2\x81\x28\x2c\x29\x4a\xcc\x2b\xce\x49\x2c\xc9\xcc\xcf\x03\xe9\x08\xce\xcf\x4d\x55\x40\x12\x53\xc8\xcc\x53\x70\x2b\x4a\xcd\x4b\xce\x50\xe2\x52\x50\xa8\xe5\x8a\xe5\x02\x04\x00\x00\xff\xff\x45\xa4\xe9\x62\x65\x00\x00\x00")
 
 func wski18nResourcesFr_frAllJsonBytes() ([]byte, error) {
-    return bindataRead(
-        _wski18nResourcesFr_frAllJson,
-        "wski18n/resources/fr_FR.all.json",
-    )
+	return bindataRead(
+		_wski18nResourcesFr_frAllJson,
+		"wski18n/resources/fr_FR.all.json",
+	)
 }
 
 func wski18nResourcesFr_frAllJson() (*asset, error) {
-    bytes, err := wski18nResourcesFr_frAllJsonBytes()
-    if err != nil {
-        return nil, err
-    }
+	bytes, err := wski18nResourcesFr_frAllJsonBytes()
+	if err != nil {
+		return nil, err
+	}
 
-    info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 101, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
-    a := &asset{bytes: bytes, info: info}
-    return a, nil
+	info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 101, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+	a := &asset{bytes: bytes, info: info}
+	return a, nil
 }
 
 var _wski18nResourcesIt_itAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesIt_itAllJsonBytes() ([]byte, error) {
-    return bindataRead(
-        _wski18nResourcesIt_itAllJson,
-        "wski18n/resources/it_IT.all.json",
-    )
+	return bindataRead(
+		_wski18nResourcesIt_itAllJson,
+		"wski18n/resources/it_IT.all.json",
+	)
 }
 
 func wski18nResourcesIt_itAllJson() (*asset, error) {
-    bytes, err := wski18nResourcesIt_itAllJsonBytes()
-    if err != nil {
-        return nil, err
-    }
+	bytes, err := wski18nResourcesIt_itAllJsonBytes()
+	if err != nil {
+		return nil, err
+	}
 
-    info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
-    a := &asset{bytes: bytes, info: info}
-    return a, nil
+	info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+	a := &asset{bytes: bytes, info: info}
+	return a, nil
 }
 
 var _wski18nResourcesJa_jaAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesJa_jaAllJsonBytes() ([]byte, error) {
-    return bindataRead(
-        _wski18nResourcesJa_jaAllJson,
-        "wski18n/resources/ja_JA.all.json",
-    )
+	return bindataRead(
+		_wski18nResourcesJa_jaAllJson,
+		"wski18n/resources/ja_JA.all.json",
+	)
 }
 
 func wski18nResourcesJa_jaAllJson() (*asset, error) {
-    bytes, err := wski18nResourcesJa_jaAllJsonBytes()
-    if err != nil {
-        return nil, err
-    }
+	bytes, err := wski18nResourcesJa_jaAllJsonBytes()
+	if err != nil {
+		return nil, err
+	}
 
-    info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
-    a := &asset{bytes: bytes, info: info}
-    return a, nil
+	info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+	a := &asset{bytes: bytes, info: info}
+	return a, nil
 }
 
 var _wski18nResourcesKo_krAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesKo_krAllJsonBytes() ([]byte, error) {
-    return bindataRead(
-        _wski18nResourcesKo_krAllJson,
-        "wski18n/resources/ko_KR.all.json",
-    )
+	return bindataRead(
+		_wski18nResourcesKo_krAllJson,
+		"wski18n/resources/ko_KR.all.json",
+	)
 }
 
 func wski18nResourcesKo_krAllJson() (*asset, error) {
-    bytes, err := wski18nResourcesKo_krAllJsonBytes()
-    if err != nil {
-        return nil, err
-    }
+	bytes, err := wski18nResourcesKo_krAllJsonBytes()
+	if err != nil {
+		return nil, err
+	}
 
-    info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
-    a := &asset{bytes: bytes, info: info}
-    return a, nil
+	info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+	a := &asset{bytes: bytes, info: info}
+	return a, nil
 }
 
 var _wski18nResourcesPt_brAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesPt_brAllJsonBytes() ([]byte, error) {
-    return bindataRead(
-        _wski18nResourcesPt_brAllJson,
-        "wski18n/resources/pt_BR.all.json",
-    )
+	return bindataRead(
+		_wski18nResourcesPt_brAllJson,
+		"wski18n/resources/pt_BR.all.json",
+	)
 }
 
 func wski18nResourcesPt_brAllJson() (*asset, error) {
-    bytes, err := wski18nResourcesPt_brAllJsonBytes()
-    if err != nil {
-        return nil, err
-    }
+	bytes, err := wski18nResourcesPt_brAllJsonBytes()
+	if err != nil {
+		return nil, err
+	}
 
-    info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
-    a := &asset{bytes: bytes, info: info}
-    return a, nil
+	info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+	a := &asset{bytes: bytes, info: info}
+	return a, nil
 }
 
 var _wski18nResourcesZh_hansAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesZh_hansAllJsonBytes() ([]byte, error) {
-    return bindataRead(
-        _wski18nResourcesZh_hansAllJson,
-        "wski18n/resources/zh_Hans.all.json",
-    )
+	return bindataRead(
+		_wski18nResourcesZh_hansAllJson,
+		"wski18n/resources/zh_Hans.all.json",
+	)
 }
 
 func wski18nResourcesZh_hansAllJson() (*asset, error) {
-    bytes, err := wski18nResourcesZh_hansAllJsonBytes()
-    if err != nil {
-        return nil, err
-    }
+	bytes, err := wski18nResourcesZh_hansAllJsonBytes()
+	if err != nil {
+		return nil, err
+	}
 
-    info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
-    a := &asset{bytes: bytes, info: info}
-    return a, nil
+	info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+	a := &asset{bytes: bytes, info: info}
+	return a, nil
 }
 
 var _wski18nResourcesZh_hantAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesZh_hantAllJsonBytes() ([]byte, error) {
-    return bindataRead(
-        _wski18nResourcesZh_hantAllJson,
-        "wski18n/resources/zh_Hant.all.json",
-    )
+	return bindataRead(
+		_wski18nResourcesZh_hantAllJson,
+		"wski18n/resources/zh_Hant.all.json",
+	)
 }
 
 func wski18nResourcesZh_hantAllJson() (*asset, error) {
-    bytes, err := wski18nResourcesZh_hantAllJsonBytes()
-    if err != nil {
-        return nil, err
-    }
+	bytes, err := wski18nResourcesZh_hantAllJsonBytes()
+	if err != nil {
+		return nil, err
+	}
 
-    info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
-    a := &asset{bytes: bytes, info: info}
-    return a, nil
+	info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+	a := &asset{bytes: bytes, info: info}
+	return a, nil
 }
 
 // Asset loads and returns the asset for the given name.
 // It returns an error if the asset could not be found or
 // could not be loaded.
 func Asset(name string) ([]byte, error) {
-    cannonicalName := strings.Replace(name, "\\", "/", -1)
-    if f, ok := _bindata[cannonicalName]; ok {
-        a, err := f()
-        if err != nil {
-            return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
-        }
-        return a.bytes, nil
-    }
-    return nil, fmt.Errorf("Asset %s not found", name)
+	cannonicalName := strings.Replace(name, "\\", "/", -1)
+	if f, ok := _bindata[cannonicalName]; ok {
+		a, err := f()
+		if err != nil {
+			return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
+		}
+		return a.bytes, nil
+	}
+	return nil, fmt.Errorf("Asset %s not found", name)
 }
 
 // MustAsset is like Asset but panics when Asset would return an error.
 // It simplifies safe initialization of global variables.
 func MustAsset(name string) []byte {
-    a, err := Asset(name)
-    if err != nil {
-        panic("asset: Asset(" + name + "): " + err.Error())
-    }
+	a, err := Asset(name)
+	if err != nil {
+		panic("asset: Asset(" + name + "): " + err.Error())
+	}
 
-    return a
+	return a
 }
 
 // AssetInfo loads and returns the asset info for the given name.
 // It returns an error if the asset could not be found or
 // could not be loaded.
 func AssetInfo(name string) (os.FileInfo, error) {
-    cannonicalName := strings.Replace(name, "\\", "/", -1)
-    if f, ok := _bindata[cannonicalName]; ok {
-        a, err := f()
-        if err != nil {
-            return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
-        }
-        return a.info, nil
-    }
-    return nil, fmt.Errorf("AssetInfo %s not found", name)
+	cannonicalName := strings.Replace(name, "\\", "/", -1)
+	if f, ok := _bindata[cannonicalName]; ok {
+		a, err := f()
+		if err != nil {
+			return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
+		}
+		return a.info, nil
+	}
+	return nil, fmt.Errorf("AssetInfo %s not found", name)
 }
 
 // AssetNames returns the names of the assets.
 func AssetNames() []string {
-    names := make([]string, 0, len(_bindata))
-    for name := range _bindata {
-        names = append(names, name)
-    }
-    return names
+	names := make([]string, 0, len(_bindata))
+	for name := range _bindata {
+		names = append(names, name)
+	}
+	return names
 }
 
 // _bindata is a table, holding each asset generator, mapped to its name.
 var _bindata = map[string]func() (*asset, error){
-    "wski18n/resources/de_DE.all.json": wski18nResourcesDe_deAllJson,
-    "wski18n/resources/en_US.all.json": wski18nResourcesEn_usAllJson,
-    "wski18n/resources/es_ES.all.json": wski18nResourcesEs_esAllJson,
-    "wski18n/resources/fr_FR.all.json": wski18nResourcesFr_frAllJson,
-    "wski18n/resources/it_IT.all.json": wski18nResourcesIt_itAllJson,
-    "wski18n/resources/ja_JA.all.json": wski18nResourcesJa_jaAllJson,
-    "wski18n/resources/ko_KR.all.json": wski18nResourcesKo_krAllJson,
-    "wski18n/resources/pt_BR.all.json": wski18nResourcesPt_brAllJson,
-    "wski18n/resources/zh_Hans.all.json": wski18nResourcesZh_hansAllJson,
-    "wski18n/resources/zh_Hant.all.json": wski18nResourcesZh_hantAllJson,
+	"wski18n/resources/de_DE.all.json":   wski18nResourcesDe_deAllJson,
+	"wski18n/resources/en_US.all.json":   wski18nResourcesEn_usAllJson,
+	"wski18n/resources/es_ES.all.json":   wski18nResourcesEs_esAllJson,
+	"wski18n/resources/fr_FR.all.json":   wski18nResourcesFr_frAllJson,
+	"wski18n/resources/it_IT.all.json":   wski18nResourcesIt_itAllJson,
+	"wski18n/resources/ja_JA.all.json":   wski18nResourcesJa_jaAllJson,
+	"wski18n/resources/ko_KR.all.json":   wski18nResourcesKo_krAllJson,
+	"wski18n/resources/pt_BR.all.json":   wski18nResourcesPt_brAllJson,
+	"wski18n/resources/zh_Hans.all.json": wski18nResourcesZh_hansAllJson,
+	"wski18n/resources/zh_Hant.all.json": wski18nResourcesZh_hantAllJson,
 }
 
 // AssetDir returns the file names below a certain
@@ -372,92 +372,92 @@ var _bindata = map[string]func() (*asset, error){
 // AssetDir("foo.txt") and AssetDir("notexist") would return an error
 // AssetDir("") will return []string{"data"}.
 func AssetDir(name string) ([]string, error) {
-    node := _bintree
-    if len(name) != 0 {
-        cannonicalName := strings.Replace(name, "\\", "/", -1)
-        pathList := strings.Split(cannonicalName, "/")
-        for _, p := range pathList {
-            node = node.Children[p]
-            if node == nil {
-                return nil, fmt.Errorf("Asset %s not found", name)
-            }
-        }
-    }
-    if node.Func != nil {
-        return nil, fmt.Errorf("Asset %s not found", name)
-    }
-    rv := make([]string, 0, len(node.Children))
-    for childName := range node.Children {
-        rv = append(rv, childName)
-    }
-    return rv, nil
+	node := _bintree
+	if len(name) != 0 {
+		cannonicalName := strings.Replace(name, "\\", "/", -1)
+		pathList := strings.Split(cannonicalName, "/")
+		for _, p := range pathList {
+			node = node.Children[p]
+			if node == nil {
+				return nil, fmt.Errorf("Asset %s not found", name)
+			}
+		}
+	}
+	if node.Func != nil {
+		return nil, fmt.Errorf("Asset %s not found", name)
+	}
+	rv := make([]string, 0, len(node.Children))
+	for childName := range node.Children {
+		rv = append(rv, childName)
+	}
+	return rv, nil
 }
 
 type bintree struct {
-    Func     func() (*asset, error)
-    Children map[string]*bintree
+	Func     func() (*asset, error)
+	Children map[string]*bintree
 }
+
 var _bintree = &bintree{nil, map[string]*bintree{
-    "wski18n": &bintree{nil, map[string]*bintree{
-        "resources": &bintree{nil, map[string]*bintree{
-            "de_DE.all.json": &bintree{wski18nResourcesDe_deAllJson, map[string]*bintree{}},
-            "en_US.all.json": &bintree{wski18nResourcesEn_usAllJson, map[string]*bintree{}},
-            "es_ES.all.json": &bintree{wski18nResourcesEs_esAllJson, map[string]*bintree{}},
-            "fr_FR.all.json": &bintree{wski18nResourcesFr_frAllJson, map[string]*bintree{}},
-            "it_IT.all.json": &bintree{wski18nResourcesIt_itAllJson, map[string]*bintree{}},
-            "ja_JA.all.json": &bintree{wski18nResourcesJa_jaAllJson, map[string]*bintree{}},
-            "ko_KR.all.json": &bintree{wski18nResourcesKo_krAllJson, map[string]*bintree{}},
-            "pt_BR.all.json": &bintree{wski18nResourcesPt_brAllJson, map[string]*bintree{}},
-            "zh_Hans.all.json": &bintree{wski18nResourcesZh_hansAllJson, map[string]*bintree{}},
-            "zh_Hant.all.json": &bintree{wski18nResourcesZh_hantAllJson, map[string]*bintree{}},
-        }},
-    }},
+	"wski18n": &bintree{nil, map[string]*bintree{
+		"resources": &bintree{nil, map[string]*bintree{
+			"de_DE.all.json":   &bintree{wski18nResourcesDe_deAllJson, map[string]*bintree{}},
+			"en_US.all.json":   &bintree{wski18nResourcesEn_usAllJson, map[string]*bintree{}},
+			"es_ES.all.json":   &bintree{wski18nResourcesEs_esAllJson, map[string]*bintree{}},
+			"fr_FR.all.json":   &bintree{wski18nResourcesFr_frAllJson, map[string]*bintree{}},
+			"it_IT.all.json":   &bintree{wski18nResourcesIt_itAllJson, map[string]*bintree{}},
+			"ja_JA.all.json":   &bintree{wski18nResourcesJa_jaAllJson, map[string]*bintree{}},
+			"ko_KR.all.json":   &bintree{wski18nResourcesKo_krAllJson, map[string]*bintree{}},
+			"pt_BR.all.json":   &bintree{wski18nResourcesPt_brAllJson, map[string]*bintree{}},
+			"zh_Hans.all.json": &bintree{wski18nResourcesZh_hansAllJson, map[string]*bintree{}},
+			"zh_Hant.all.json": &bintree{wski18nResourcesZh_hantAllJson, map[string]*bintree{}},
+		}},
+	}},
 }}
 
 // RestoreAsset restores an asset under the given directory
 func RestoreAsset(dir, name string) error {
-    data, err := Asset(name)
-    if err != nil {
-        return err
-    }
-    info, err := AssetInfo(name)
-    if err != nil {
-        return err
-    }
-    err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
-    if err != nil {
-        return err
-    }
-    err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
-    if err != nil {
-        return err
-    }
-    err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
-    if err != nil {
-        return err
-    }
-    return nil
+	data, err := Asset(name)
+	if err != nil {
+		return err
+	}
+	info, err := AssetInfo(name)
+	if err != nil {
+		return err
+	}
+	err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
+	if err != nil {
+		return err
+	}
+	err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
+	if err != nil {
+		return err
+	}
+	err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
+	if err != nil {
+		return err
+	}
+	return nil
 }
 
 // RestoreAssets restores an asset under the given directory recursively
 func RestoreAssets(dir, name string) error {
-    children, err := AssetDir(name)
-    // File
-    if err != nil {
-        return RestoreAsset(dir, name)
-    }
-    // Dir
-    for _, child := range children {
-        err = RestoreAssets(dir, filepath.Join(name, child))
-        if err != nil {
-            return err
-        }
-    }
-    return nil
+	children, err := AssetDir(name)
+	// File
+	if err != nil {
+		return RestoreAsset(dir, name)
+	}
+	// Dir
+	for _, child := range children {
+		err = RestoreAssets(dir, filepath.Join(name, child))
+		if err != nil {
+			return err
+		}
+	}
+	return nil
 }
 
 func _filePath(dir, name string) string {
-    cannonicalName := strings.Replace(name, "\\", "/", -1)
-    return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
+	cannonicalName := strings.Replace(name, "\\", "/", -1)
+	return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
 }
-

-- 
To stop receiving notification emails like this one, please contact
['"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>'].