|
| 1 | +package nacos |
| 2 | + |
| 3 | +import ( |
| 4 | + "bytes" |
| 5 | + "github.com/nacos-group/nacos-sdk-go/clients" |
| 6 | + "github.com/nacos-group/nacos-sdk-go/clients/config_client" |
| 7 | + "github.com/nacos-group/nacos-sdk-go/common/constant" |
| 8 | + "github.com/nacos-group/nacos-sdk-go/vo" |
| 9 | + log "github.com/sirupsen/logrus" |
| 10 | + "github.com/tietang/props/kvs" |
| 11 | + "strconv" |
| 12 | + "strings" |
| 13 | +) |
| 14 | + |
| 15 | +var _ kvs.ConfigSource = new(NacosClientPropsConfigSource) |
| 16 | + |
| 17 | +//通过key/value来组织,过滤root prefix后,替换/为.作为properties key |
| 18 | +type NacosClientPropsConfigSource struct { |
| 19 | + kvs.MapProperties |
| 20 | + // Required Configuration ID. Use a naming rule similar to package.class (for example, com.taobao.tc.refund.log.level) to ensure global uniqueness. It is recommended to indicate business meaning of the configuration in the "class" section. Use lower case for all characters. Use alphabetical letters and these four special characters (".", ":", "-", "_") only. Up to 256 characters are allowed. |
| 21 | + DataId string |
| 22 | + // Required Configuration group. To ensure uniqueness, format such as product name: module name (for example, Nacos:Test) is preferred. Use alphabetical letters and these four special characters (".", ":", "-", "_") only. Up to 128 characters are allowed. |
| 23 | + Group string |
| 24 | + |
| 25 | + //Tenant information. It corresponds to the Namespace field in Nacos. |
| 26 | + Tenant string |
| 27 | + NamespaceId string |
| 28 | + ContentType string |
| 29 | + AppName string |
| 30 | + |
| 31 | + LineSeparator string |
| 32 | + KVSeparator string |
| 33 | + // |
| 34 | + name string |
| 35 | + lastCt uint32 |
| 36 | + ClientConfig constant.ClientConfig |
| 37 | + ServerConfigs []constant.ServerConfig |
| 38 | + Client config_client.IConfigClient |
| 39 | +} |
| 40 | + |
| 41 | +func NewNacosClientPropsConfigSource(address, group, dataId, tenant string) *NacosClientPropsConfigSource { |
| 42 | + s := &NacosClientPropsConfigSource{} |
| 43 | + name := strings.Join([]string{"Nacos", address}, ":") |
| 44 | + s.name = name |
| 45 | + s.DataId = dataId |
| 46 | + s.Group = group |
| 47 | + s.Tenant = tenant |
| 48 | + s.ClientConfig = constant.ClientConfig{ |
| 49 | + TimeoutMs: 10 * 1000, //http请求超时时间,单位毫秒 |
| 50 | + ListenInterval: 30 * 1000, //监听间隔时间,单位毫秒(仅在ConfigClient中有效) |
| 51 | + BeatInterval: 5 * 1000, //心跳间隔时间,单位毫秒(仅在ServiceClient中有效) |
| 52 | + CacheDir: "./data/nacos/cache", //缓存目录 |
| 53 | + LogDir: "./data/nacos/log", //日志目录 |
| 54 | + UpdateThreadNum: 20, //更新服务的线程数 |
| 55 | + NotLoadCacheAtStart: true, //在启动时不读取本地缓存数据,true--不读取,false--读取 |
| 56 | + UpdateCacheWhenEmpty: true, //当服务列表为空时是否更新本地缓存,true--更新,false--不更新 |
| 57 | + } |
| 58 | + if len(tenant) > 0 { |
| 59 | + s.ClientConfig.NamespaceId = tenant |
| 60 | + s.NamespaceId = tenant |
| 61 | + } |
| 62 | + s.ServerConfigs = make([]constant.ServerConfig, 0) |
| 63 | + addrs := strings.Split(address, ",") |
| 64 | + for _, addr := range addrs { |
| 65 | + a := strings.Split(addr, ":") |
| 66 | + port := 80 |
| 67 | + if len(a) == 2 { |
| 68 | + var err error |
| 69 | + port, err = strconv.Atoi(a[1]) |
| 70 | + if err != nil { |
| 71 | + log.Error("error config nacos address:", addr) |
| 72 | + continue |
| 73 | + } |
| 74 | + } |
| 75 | + |
| 76 | + s.ServerConfigs = append(s.ServerConfigs, constant.ServerConfig{ |
| 77 | + IpAddr: a[0], |
| 78 | + ContextPath: "/nacos", |
| 79 | + Port: uint64(port), |
| 80 | + }) |
| 81 | + } |
| 82 | + |
| 83 | + s.Values = make(map[string]string) |
| 84 | + |
| 85 | + var err error |
| 86 | + s.Client, err = clients.CreateConfigClient(map[string]interface{}{ |
| 87 | + constant.KEY_SERVER_CONFIGS: s.ServerConfigs, |
| 88 | + constant.KEY_CLIENT_CONFIG: s.ClientConfig, |
| 89 | + }) |
| 90 | + if err != nil { |
| 91 | + log.Panic("error create ConfigClient: ", err) |
| 92 | + } |
| 93 | + s.init() |
| 94 | + |
| 95 | + return s |
| 96 | +} |
| 97 | + |
| 98 | +func NewNacosClientPropsCompositeConfigSource(address, group, tenant string, dataIds []string) *kvs.CompositeConfigSource { |
| 99 | + s := kvs.NewEmptyNoSystemEnvCompositeConfigSource() |
| 100 | + s.ConfName = "NacosKevValue" |
| 101 | + for _, dataId := range dataIds { |
| 102 | + c := NewNacosClientPropsConfigSource(address, group, dataId, tenant) |
| 103 | + s.Add(c) |
| 104 | + } |
| 105 | + |
| 106 | + return s |
| 107 | +} |
| 108 | + |
| 109 | +func (s *NacosClientPropsConfigSource) init() { |
| 110 | + s.findProperties() |
| 111 | + s.watchContext() |
| 112 | +} |
| 113 | + |
| 114 | +func (s *NacosClientPropsConfigSource) watchContext() { |
| 115 | + cp := vo.ConfigParam{ |
| 116 | + DataId: "dataId", |
| 117 | + Group: "group", |
| 118 | + } |
| 119 | + if len(s.AppName) > 0 { |
| 120 | + cp.AppName = s.AppName |
| 121 | + } |
| 122 | + cp.OnChange = func(namespace, group, dataId, data string) { |
| 123 | + s.parseAndregisterProps([]byte(data)) |
| 124 | + log.Info("changed config:", namespace, group, dataId) |
| 125 | + } |
| 126 | + s.Client.ListenConfig(cp) |
| 127 | + |
| 128 | +} |
| 129 | + |
| 130 | +func (s *NacosClientPropsConfigSource) Close() { |
| 131 | +} |
| 132 | + |
| 133 | +func (s *NacosClientPropsConfigSource) findProperties() { |
| 134 | + |
| 135 | + data, err := s.get() |
| 136 | + if err != nil { |
| 137 | + log.Error(err) |
| 138 | + return |
| 139 | + } |
| 140 | + s.parseAndregisterProps(data) |
| 141 | + |
| 142 | +} |
| 143 | + |
| 144 | +func (s *NacosClientPropsConfigSource) parseAndregisterProps(data []byte) { |
| 145 | + sep := s.LineSeparator |
| 146 | + if sep == "" { |
| 147 | + sep = NACOS_LINE_SEPARATOR |
| 148 | + } |
| 149 | + kvsep := s.KVSeparator |
| 150 | + if kvsep == "" { |
| 151 | + kvsep = NACOS_KV_SEPARATOR |
| 152 | + } |
| 153 | + lines := bytes.Split(data, []byte(sep)) |
| 154 | + |
| 155 | + for _, l := range lines { |
| 156 | + |
| 157 | + i := bytes.Index(l, []byte(kvsep)) |
| 158 | + if i <= 0 { |
| 159 | + continue |
| 160 | + } |
| 161 | + key := string(l[:i]) |
| 162 | + value := string(l[i+1:]) |
| 163 | + s.registerProps(key, value) |
| 164 | + //log.Info(key,"=",value) |
| 165 | + } |
| 166 | +} |
| 167 | + |
| 168 | +func (s *NacosClientPropsConfigSource) registerProps(key, value string) { |
| 169 | + s.Set(strings.TrimSpace(key), strings.TrimSpace(value)) |
| 170 | + |
| 171 | +} |
| 172 | + |
| 173 | +func (s *NacosClientPropsConfigSource) Name() string { |
| 174 | + return s.name |
| 175 | +} |
| 176 | + |
| 177 | +func (h *NacosClientPropsConfigSource) get() (body []byte, err error) { |
| 178 | + cp := vo.ConfigParam{ |
| 179 | + DataId: "dataId", |
| 180 | + Group: "group", |
| 181 | + } |
| 182 | + if len(h.AppName) > 0 { |
| 183 | + cp.AppName = h.AppName |
| 184 | + } |
| 185 | + content, err := h.Client.GetConfig(cp) |
| 186 | + if err != nil { |
| 187 | + log.Error(err) |
| 188 | + return nil, err |
| 189 | + } |
| 190 | + return []byte(content), err |
| 191 | +} |
0 commit comments