| /* |
| * 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. |
| */ |
| |
| package config |
| |
| import ( |
| "encoding/json" |
| "io/ioutil" |
| "log" |
| "path/filepath" |
| ) |
| |
| import ( |
| "github.com/ghodss/yaml" |
| "github.com/goinggo/mapstructure" |
| ) |
| |
| import ( |
| "github.com/apache/dubbo-go-pixiu/pkg/logger" |
| "github.com/apache/dubbo-go-pixiu/pkg/model" |
| ) |
| |
| var ( |
| configPath string |
| config *model.Bootstrap |
| configLoadFunc ConfigLoadFunc = DefaultConfigLoad |
| ) |
| |
| // GetBootstrap get config global, need a better name |
| func GetBootstrap() *model.Bootstrap { |
| return config |
| } |
| |
| // Load config file and parse |
| func Load(path string) *model.Bootstrap { |
| logger.Infof("[dubbopixiu go] load path:%s", path) |
| |
| configPath, _ = filepath.Abs(path) |
| if yamlFormat(path) { |
| RegisterConfigLoadFunc(YAMLConfigLoad) |
| } |
| if cfg := configLoadFunc(path); cfg != nil { |
| config = cfg |
| } |
| |
| return config |
| } |
| |
| // ConfigLoadFunc parse a input(usually file path) into a pixiu config |
| type ConfigLoadFunc func(path string) *model.Bootstrap |
| |
| // RegisterConfigLoadFunc can replace a new config load function instead of default |
| func RegisterConfigLoadFunc(f ConfigLoadFunc) { |
| configLoadFunc = f |
| } |
| |
| func yamlFormat(path string) bool { |
| ext := filepath.Ext(path) |
| if ext == ".yaml" || ext == ".yml" { |
| return true |
| } |
| return false |
| } |
| |
| // YAMLConfigLoad config load yaml |
| func YAMLConfigLoad(path string) *model.Bootstrap { |
| log.Println("load config in YAML format from : ", path) |
| content, err := ioutil.ReadFile(path) |
| if err != nil { |
| log.Fatalln("[config] [yaml load] load config failed, ", err) |
| } |
| cfg := &model.Bootstrap{} |
| |
| bytes, err := yaml.YAMLToJSON(content) |
| if err != nil { |
| log.Fatalln("[config] [yaml load] convert YAML to JSON failed, ", err) |
| } |
| |
| err = json.Unmarshal(bytes, cfg) |
| if err != nil { |
| log.Fatalln("[config] [yaml load] yaml unmarshal config failed, ", err) |
| } |
| |
| // other adapter |
| |
| for i, l := range cfg.StaticResources.Listeners { |
| if l.Address.SocketAddress.ProtocolStr == "" { |
| l.Address.SocketAddress.ProtocolStr = "HTTP" |
| } |
| l.Address.SocketAddress.Protocol = model.ProtocolType(model.ProtocolTypeValue[l.Address.SocketAddress.ProtocolStr]) |
| |
| hc := &model.HttpConfig{} |
| if l.Config != nil { |
| if v, ok := l.Config.(map[string]interface{}); ok { |
| switch l.Name { |
| case "net/http": |
| if err := mapstructure.Decode(v, hc); err != nil { |
| logger.Error(err) |
| } |
| |
| cfg.StaticResources.Listeners[i].Config = hc |
| } |
| } |
| } |
| |
| for _, fc := range l.FilterChains { |
| if fc.Filters != nil { |
| for i, fcf := range fc.Filters { |
| hcm := &model.HttpConnectionManager{} |
| if fcf.Config != nil { |
| switch fcf.Name { |
| case "dgp.filters.http_connect_manager": |
| if v, ok := fcf.Config.(map[string]interface{}); ok { |
| if err := mapstructure.Decode(v, hcm); err != nil { |
| logger.Error(err) |
| } |
| |
| fc.Filters[i].Config = hcm |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| } |
| |
| for _, c := range cfg.StaticResources.Clusters { |
| var discoverType int32 |
| if c.TypeStr != "" { |
| if t, ok := model.DiscoveryTypeValue[c.TypeStr]; ok { |
| discoverType = t |
| } else { |
| c.TypeStr = "EDS" |
| discoverType = model.DiscoveryTypeValue[c.TypeStr] |
| } |
| } else { |
| c.TypeStr = "EDS" |
| discoverType = model.DiscoveryTypeValue[c.TypeStr] |
| } |
| c.Type = model.DiscoveryType(discoverType) |
| |
| var lbPolicy int32 |
| if c.LbStr != "" { |
| if lb, ok := model.LbPolicyValue[c.LbStr]; ok { |
| lbPolicy = lb |
| } else { |
| c.LbStr = "RoundRobin" |
| lbPolicy = model.LbPolicyValue[c.LbStr] |
| } |
| } else { |
| c.LbStr = "RoundRobin" |
| lbPolicy = model.LbPolicyValue[c.LbStr] |
| } |
| c.Lb = model.LbPolicy(lbPolicy) |
| } |
| |
| return cfg |
| } |
| |
| // DefaultConfigLoad if not config, will load this |
| func DefaultConfigLoad(path string) *model.Bootstrap { |
| log.Println("load config from : ", path) |
| content, err := ioutil.ReadFile(path) |
| if err != nil { |
| log.Fatalln("[config] [default load] load config failed, ", err) |
| } |
| cfg := &model.Bootstrap{} |
| // translate to lower case |
| err = json.Unmarshal(content, cfg) |
| if err != nil { |
| log.Fatalln("[config] [default load] json unmarshal config failed, ", err) |
| } |
| return cfg |
| } |