diff options
-rw-r--r-- | msb2pilot/src/msb2pilot/conf/consul.yml | 2 | ||||
-rw-r--r-- | msb2pilot/src/msb2pilot/consul/controller.go | 98 | ||||
-rw-r--r-- | msb2pilot/src/msb2pilot/consul/controller_test.go | 89 | ||||
-rw-r--r-- | msb2pilot/src/msb2pilot/log/log_test.go | 10 | ||||
-rw-r--r-- | msb2pilot/src/msb2pilot/main.go | 2 | ||||
-rw-r--r-- | msb2pilot/src/msb2pilot/models/config.go | 16 | ||||
-rw-r--r-- | msb2pilot/src/msb2pilot/models/conversion.go | 117 | ||||
-rw-r--r-- | msb2pilot/src/msb2pilot/models/msb.go | 65 | ||||
-rw-r--r-- | msb2pilot/src/msb2pilot/util/common.go | 1 |
9 files changed, 394 insertions, 6 deletions
diff --git a/msb2pilot/src/msb2pilot/conf/consul.yml b/msb2pilot/src/msb2pilot/conf/consul.yml new file mode 100644 index 0000000..3c30cba --- /dev/null +++ b/msb2pilot/src/msb2pilot/conf/consul.yml @@ -0,0 +1,2 @@ +# consul api address, default to be http://localhost:8500
+address: http://127.0.0.1:8500
diff --git a/msb2pilot/src/msb2pilot/consul/controller.go b/msb2pilot/src/msb2pilot/consul/controller.go new file mode 100644 index 0000000..b6e798f --- /dev/null +++ b/msb2pilot/src/msb2pilot/consul/controller.go @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2018 ZTE Corporation. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * ZTE - initial Project + */ +package consul + +import ( + "msb2pilot/log" + "msb2pilot/models" + "msb2pilot/util" + "os" + "path/filepath" + + "github.com/hashicorp/consul/api" +) + +var client *api.Client +var consulAddress string + +var ( + cfgFilePath = filepath.Join(util.GetCfgPath(), "consul.yml") +) + +const ( + defaultAddress = "http://localhost:8500" +) + +func init() { + consulAddress = getConsulAddress(cfgFilePath) + + conf := api.DefaultConfig() + conf.Address = consulAddress + var err error + client, err = api.NewClient(conf) + + if err != nil { + log.Log.Error("failed to init consul client", err) + } +} + +func getConsulAddress(path string) string { + res := os.Getenv(models.EnvConsulAddress) + if res != "" { + return res + } + + cfg, err := loadCfgInfo(path) + if err != nil { + log.Log.Error("load consul config info error", err) + return defaultAddress + } else { + if addr, exist := cfg["address"]; exist { + return addr.(string) + } else { + return defaultAddress + } + } +} + +func loadCfgInfo(path string) (map[interface{}]interface{}, error) { + log.Log.Informational("consul config path is:" + path) + cfg, err := util.Read(path) + if err != nil { + return nil, err + } + + result := make(map[interface{}]interface{}) + err = util.UnmarshalYaml(cfg, result) + if err != nil { + return nil, err + } + return result, nil +} + +func GetServices() (map[string][]string, error) { + data, _, err := client.Catalog().Services(nil) + + if err != nil { + return nil, err + } + return data, nil +} + +func GetInstances(serviceName string) ([]*api.CatalogService, error) { + endpoints, _, err := client.Catalog().Service(serviceName, "", nil) + if err != nil { + log.Log.Error("can not get endpoints of ", serviceName) + return nil, err + } + return endpoints, nil +} diff --git a/msb2pilot/src/msb2pilot/consul/controller_test.go b/msb2pilot/src/msb2pilot/consul/controller_test.go new file mode 100644 index 0000000..a6569bd --- /dev/null +++ b/msb2pilot/src/msb2pilot/consul/controller_test.go @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2018 ZTE Corporation. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * ZTE - initial Project + */ +package consul + +import ( + "msb2pilot/models" + "os" + "testing" +) + +func TestSetConsulAddress(t *testing.T) { + cases := []struct { + env, path, want string + }{ + { + env: "testEnv", + path: "", + want: `testEnv`, + }, + { + env: "", + path: cfgFilePath, + want: `http://127.0.0.1:8500`, + }, + { + env: "testEnvWithPath", + path: cfgFilePath, + want: `testEnvWithPath`, + }, + { + env: "", + path: ``, + want: `http://localhost:8500`, + }, + { + env: "", + path: `controller.go`, + want: `http://localhost:8500`, + }, + } + + oldEnv := os.Getenv(models.EnvConsulAddress) + + for _, cas := range cases { + os.Setenv(models.EnvConsulAddress, cas.env) + + res := getConsulAddress(cas.path) + if res != cas.want { + t.Errorf("getConsulAddress() => want %s, got %s", cas.want, res) + } + } + + os.Setenv(models.EnvConsulAddress, oldEnv) +} + +func TestLoadCfgInfo(t *testing.T) { + cases := []struct { + path, status string + }{ + { + path: cfgFilePath, + status: `success`, + }, + { + path: ``, + status: `path is empty`, + }, + { + path: `controller.go`, + status: `yaml format error`, + }, + } + + for _, cas := range cases { + _, err := loadCfgInfo(cas.path) + if (cas.status == "success" && err != nil) || (cas.status != "success" && err == nil) { + t.Errorf("loadCfgInfo() => want %s, got %v", cas.status, err) + } + } +} diff --git a/msb2pilot/src/msb2pilot/log/log_test.go b/msb2pilot/src/msb2pilot/log/log_test.go index 816e10f..9ed192a 100644 --- a/msb2pilot/src/msb2pilot/log/log_test.go +++ b/msb2pilot/src/msb2pilot/log/log_test.go @@ -12,14 +12,13 @@ package log import ( - "apiroute/util" + "msb2pilot/util" "os" "strings" "testing" ) func TestCheckLogDir(t *testing.T) { - pathSep := string(os.PathSeparator) cases := []struct { path string exist bool @@ -33,7 +32,7 @@ func TestCheckLogDir(t *testing.T) { exist: false, }, { - path: `.` + pathSep + `test` + pathSep + `test.log`, + path: `.` + util.PathSep + `test` + util.PathSep + `test.log`, exist: true, }, } @@ -41,7 +40,7 @@ func TestCheckLogDir(t *testing.T) { for _, cas := range cases { checkLogDir(cas.path) - index := strings.LastIndex(cas.path, pathSep) + index := strings.LastIndex(cas.path, util.PathSep) if cas.exist && !util.FileExists(cas.path[0:index]) { t.Errorf("checkLogDir() => dir not exist, want %s", cas.path) } @@ -52,13 +51,12 @@ func TestCheckLogDir(t *testing.T) { } func TestLoadCustom(t *testing.T) { - pathSep := string(os.PathSeparator) cases := []struct { path string want string }{ { - path: `..` + pathSep + "conf" + pathSep + cfgFileName, + path: `..` + util.PathSep + "conf" + util.PathSep + cfgFileName, want: "success", }, { diff --git a/msb2pilot/src/msb2pilot/main.go b/msb2pilot/src/msb2pilot/main.go index c19000a..236e369 100644 --- a/msb2pilot/src/msb2pilot/main.go +++ b/msb2pilot/src/msb2pilot/main.go @@ -12,6 +12,7 @@ package main import ( + _ "msb2pilot/consul" "msb2pilot/log" _ "msb2pilot/routers" @@ -20,5 +21,6 @@ import ( func main() { log.Log.Informational("**************** init msb2pilot ************************") + beego.Run() } diff --git a/msb2pilot/src/msb2pilot/models/config.go b/msb2pilot/src/msb2pilot/models/config.go new file mode 100644 index 0000000..7f34514 --- /dev/null +++ b/msb2pilot/src/msb2pilot/models/config.go @@ -0,0 +1,16 @@ +/** + * Copyright (c) 2018 ZTE Corporation. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * ZTE - initial Project + */ +package models + +const ( + EnvConsulAddress = "ConsulAddress" //http://localhost:8500 +) diff --git a/msb2pilot/src/msb2pilot/models/conversion.go b/msb2pilot/src/msb2pilot/models/conversion.go new file mode 100644 index 0000000..144d05b --- /dev/null +++ b/msb2pilot/src/msb2pilot/models/conversion.go @@ -0,0 +1,117 @@ +/** + * Copyright (c) 2018 ZTE Corporation. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * ZTE - initial Project + */ +package models + +import ( + "encoding/json" + "msb2pilot/log" + "strings" + + "github.com/hashicorp/consul/api" +) + +func ConvertService(endpoints []*api.CatalogService) *MsbService { + if len(endpoints) == 0 { + return nil + } + + endpoint := endpoints[0] + service := &MsbService{ + ServiceName: endpoint.ServiceName, + ModifyIndex: endpoint.ModifyIndex, + ConsulLabels: &ConsulLabels{}, + } + + convertMsbLabels(service.ConsulLabels, endpoint.ServiceTags) + return service +} + +func convertBaseInfo(baseString string) (baseInfo *BaseInfo, err error) { + baseInfo = new(BaseInfo) + err = json.Unmarshal([]byte(baseString), baseInfo) + + return +} + +func convertNameSpace(ns string) (nameSpace *NameSpace, err error) { + nameSpace = new(NameSpace) + err = json.Unmarshal([]byte(ns), nameSpace) + return +} + +func LoadMsbServiceFromMap(services map[string][]string) []*MsbService { + result := make([]*MsbService, 0, len(services)) + + for k, v := range services { + service := &MsbService{ + ServiceName: k, + ConsulLabels: new(ConsulLabels), + } + convertMsbLabels(service.ConsulLabels, v) + result = append(result, service) + } + return result +} + +func ConsulService2MsbService(consulService *api.CatalogService) *MsbService { + msbService := &MsbService{ + ServiceName: consulService.ServiceName, + ServiceAddress: consulService.ServiceAddress, + ServicePort: consulService.ServicePort, + ConsulLabels: new(ConsulLabels), + } + + convertMsbLabels(msbService.ConsulLabels, consulService.ServiceTags) + + return msbService +} + +func convertMsbLabel(label, labelstr string) interface{} { + var result interface{} + var err error + + labelPrefix := "\"" + label + "\":" + + if strings.HasPrefix(labelstr, labelPrefix) { + kvp := strings.Split(labelstr, labelPrefix) + value := kvp[1] + + switch label { + case "base": + result, err = convertBaseInfo(value) + case "ns": + result, err = convertNameSpace(value) + } + + if err != nil { + log.Log.Error("parse msb label error", err) + return nil + } + + return result + } + + return nil +} +func convertMsbLabels(consulLabels *ConsulLabels, labels []string) { + for _, label := range labels { + baseInfo := convertMsbLabel("base", label) + if baseInfo != nil { + consulLabels.BaseInfo = baseInfo.(*BaseInfo) + } + + ns := convertMsbLabel("ns", label) + if ns != nil { + consulLabels.NameSpace = ns.(*NameSpace) + } + } +} diff --git a/msb2pilot/src/msb2pilot/models/msb.go b/msb2pilot/src/msb2pilot/models/msb.go new file mode 100644 index 0000000..09418e7 --- /dev/null +++ b/msb2pilot/src/msb2pilot/models/msb.go @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2018 ZTE Corporation. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * ZTE - initial Project + */ +package models + +type Protocol string + +const ( + Protocol_UI Protocol = "UI" + Protocol_REST Protocol = "REST" + Protocol_HTTP Protocol = "HTTP" + Protocol_MQ Protocol = "MQ" + Protocol_FTP Protocol = "FTP" + Protocol_SNMP Protocol = "SNMP" + Protocol_TCP Protocol = "TCP" + Protocol_UDP Protocol = "UDP" +) + +type BaseInfo struct { + Path string `json:"path",omitempty` + VisualRange string `json:"visualRange"` + AppVersion string `json:"appversion"` + PublishPort string `json:"publish_port"` + EnableSSL string `json:"enable_ssl",omitempty` + IsManual string `json:"is_manual"` + Protocol Protocol `json:"protocol"` + ServiceStatus string `json:"status,omitempty"` + Version string `json:"version"` + Url string `json:"url"` +} + +type NameSpace struct { + NameSpace string `json:"namespace"` +} + +type ConsulLabels struct { + NameSpace *NameSpace + BaseInfo *BaseInfo +} + +type MsbService struct { + ConsulLabels *ConsulLabels + ServiceName string + ServiceAddress string + ServicePort int + ModifyIndex uint64 +} + +type PublishService struct { + ServiceName string `json:"serviceName"` + Version string `json:"version",omitempty` + PublishPort string `json:"publish_port",omitempty` + Protocol string `json:"protocol",omitempty` + NameSpace string `json:"namespace",omitempty` + PublishUrl string `json:"publish_url",omitempty` + PublishProtocol string `json:"publish_protocol",omitempty` +} diff --git a/msb2pilot/src/msb2pilot/util/common.go b/msb2pilot/src/msb2pilot/util/common.go index 1bb10df..d46bb6f 100644 --- a/msb2pilot/src/msb2pilot/util/common.go +++ b/msb2pilot/src/msb2pilot/util/common.go @@ -19,6 +19,7 @@ import ( const ( ConfigPath = "conf" + PathSep = string(os.PathSeparator) ) func GetCfgPath() string { |