Skip to content

Commit 07bd596

Browse files
author
tietang
committed
add apollo 配置管理的支持
1 parent 8e67734 commit 07bd596

File tree

7 files changed

+329
-57
lines changed

7 files changed

+329
-57
lines changed

apollo/apollo_source.go

+169
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
package apollo
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"github.com/shima-park/agollo"
7+
log "github.com/sirupsen/logrus"
8+
"github.com/tietang/go-utils"
9+
"github.com/tietang/props/ini"
10+
"github.com/tietang/props/kvs"
11+
"github.com/tietang/props/yam"
12+
"io/ioutil"
13+
"net/http"
14+
"net/url"
15+
"strings"
16+
)
17+
18+
//通过key/value来组织,过滤root prefix后,替换/为.作为properties key
19+
type ApolloConfigSource struct {
20+
kvs.MapProperties
21+
Apollo agollo.Agollo
22+
name string
23+
address string
24+
appId string
25+
namespaces []string
26+
cluster string
27+
clientIP string
28+
contentType kvs.ContentType
29+
}
30+
31+
func NewApolloConfigSource(address, appId string, namespaces []string) *ApolloConfigSource {
32+
s := &ApolloConfigSource{}
33+
s.name = "apollo:" + address
34+
s.appId = appId
35+
s.address = address
36+
s.namespaces = namespaces
37+
s.contentType = kvs.KeyValueContentType
38+
s.clientIP, _ = utils.GetExternalIP()
39+
s.cluster = "default"
40+
s.Values = make(map[string]string)
41+
s.init()
42+
43+
return s
44+
}
45+
46+
func NewApolloCompositeConfigSource(url, appId string, namespaces []string) *kvs.CompositeConfigSource {
47+
s := kvs.NewEmptyNoSystemEnvCompositeConfigSource()
48+
s.ConfName = "ApolloKevValue"
49+
c := NewApolloConfigSource(url, appId, namespaces)
50+
s.Add(c)
51+
return s
52+
}
53+
func (s *ApolloConfigSource) init() {
54+
for _, ns := range s.namespaces {
55+
kvs, err := s.GetConfigsFromCache(s.address, s.appId, s.cluster, ns)
56+
if err != nil {
57+
log.Error(err)
58+
continue
59+
}
60+
for key, value := range kvs {
61+
s.initValue(ns, key, value)
62+
}
63+
}
64+
}
65+
66+
func (s *ApolloConfigSource) initValue(namespace, key, value string) {
67+
contentType := s.getContentType(namespace)
68+
if contentType == kvs.KeyValueContentType {
69+
contentType = s.getContentType(key)
70+
}
71+
if contentType == kvs.KeyValueContentType {
72+
s.Set(key, value)
73+
} else if contentType == kvs.ContentProps || contentType == kvs.ContentProperties {
74+
s.findProperties(value)
75+
} else if contentType == kvs.ContentIni {
76+
s.findIni(value)
77+
} else if contentType == kvs.ContentYaml || contentType == kvs.ContentYam || contentType == kvs.ContentYml {
78+
s.findYaml(value)
79+
} else {
80+
s.Set(key, value)
81+
}
82+
83+
}
84+
85+
func (s *ApolloConfigSource) getContentType(key string) (ctype kvs.ContentType) {
86+
idx := strings.LastIndex(key, ".")
87+
if idx == -1 || idx == len(key)-1 {
88+
ctype = kvs.KeyValueContentType
89+
} else {
90+
ctype = kvs.ContentType(key[idx+1:])
91+
}
92+
return
93+
}
94+
95+
func (s *ApolloConfigSource) watchContext() {
96+
97+
}
98+
99+
func (s *ApolloConfigSource) Close() {
100+
}
101+
102+
func (s *ApolloConfigSource) findYaml(content string) {
103+
props := yam.ByYaml(content)
104+
s.SetAll(props.Values)
105+
}
106+
107+
func (s *ApolloConfigSource) findIni(content string) {
108+
props := ini.ByIni(content)
109+
s.SetAll(props.Values)
110+
}
111+
112+
func (s *ApolloConfigSource) findProperties(content string) {
113+
props := kvs.ByProperties(content)
114+
s.SetAll(props.Values)
115+
}
116+
117+
func (s *ApolloConfigSource) registerProps(key, value string) {
118+
s.Set(strings.TrimSpace(key), strings.TrimSpace(value))
119+
120+
}
121+
122+
func (s *ApolloConfigSource) Name() string {
123+
return s.name
124+
}
125+
126+
func (c *ApolloConfigSource) GetConfigsFromCache(address, appID, cluster, namespace string) (kvs KeyValue, err error) {
127+
url := fmt.Sprintf("http://%s/configfiles/json/%s/%s/%s?ip=%s",
128+
address,
129+
url.QueryEscape(appID),
130+
url.QueryEscape(cluster),
131+
url.QueryEscape(namespace),
132+
c.clientIP,
133+
)
134+
135+
//调用请求
136+
res, err := http.Get(url)
137+
138+
if err != nil {
139+
log.Error(err)
140+
return nil, err
141+
}
142+
// 如果出错就不需要close,因此defer语句放在err处理逻辑后面
143+
defer res.Body.Close()
144+
//处理response,读取Response body
145+
respBody, err := ioutil.ReadAll(res.Body)
146+
147+
//
148+
if err := res.Body.Close(); err != nil {
149+
log.Error(err)
150+
}
151+
kvs = KeyValue{}
152+
err = json.Unmarshal(respBody, &kvs)
153+
if err != nil {
154+
log.Error(err)
155+
return nil, err
156+
}
157+
return kvs, err
158+
159+
}
160+
161+
type KeyValue map[string]string
162+
163+
type ConfigRes struct {
164+
AppID string `json:"appId"` // appId: "AppTest",
165+
Cluster string `json:"cluster"` // cluster: "default",
166+
Namespace string `json:"namespaceName"` // namespaceName: "TEST.Namespace1",
167+
KeyValue KeyValue `json:"configurations"` // configurations: {Name: "Foo"},
168+
ReleaseKey string `json:"releaseKey"` // releaseKey: "20181017110222-5ce3b2da895720e8"
169+
}

apollo/example/e.go

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"github.com/tietang/props/apollo"
6+
)
7+
8+
func main() {
9+
//http://106.12.25.204:8080/configfiles/json/we/default/application?ip=1.1.1.1
10+
a := apollo.NewApolloConfigSource("106.12.25.204:8080", "we", []string{
11+
"application", "development.redis",
12+
})
13+
keys := a.Keys()
14+
for _, key := range keys {
15+
value := a.GetDefault(key, "null")
16+
fmt.Println(key, "=", value)
17+
}
18+
19+
}

example/p.go

+29-26
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,33 @@
11
package main
22

3-
import (
4-
"fmt"
5-
"github.com/tietang/props/kvs"
6-
)
3+
import "fmt"
74

8-
func main10() {
9-
p, err := kvs.ReadPropertyFile("config.properties")
10-
if err != nil {
11-
panic(err)
12-
}
13-
stringValue, err := p.Get("prefix.key1")
14-
fmt.Println(stringValue, err)
15-
//如果不存在,则返回默认值
16-
stringDefaultValue := p.GetDefault("prefix.key1", "default value")
17-
fmt.Println(stringDefaultValue)
18-
boolValue, err := p.GetBool("prefix.key2")
19-
fmt.Println(boolValue)
20-
boolDefaultValue := p.GetBoolDefault("prefix.key2", false)
21-
fmt.Println(boolDefaultValue)
22-
intValue, err := p.GetInt("prefix.key3")
23-
fmt.Println(intValue)
24-
intDefaultValue := p.GetIntDefault("prefix.key3", 1)
25-
fmt.Println(intDefaultValue)
26-
floatValue, err := p.GetFloat64("prefix.key4")
27-
fmt.Println(floatValue)
28-
floatDefaultValue := p.GetFloat64Default("prefix.key4", 1.2)
29-
fmt.Println(floatDefaultValue)
5+
func main12() {
6+
var s interface{}
7+
s = struct {
8+
Key string
9+
Value int
10+
}{Key: "kw1", Value: 12}
11+
fmt.Println(fmt.Sprintf("%v", s))
12+
//p, err := kvs.ReadPropertyFile("config.properties")
13+
//if err != nil {
14+
// panic(err)
15+
//}
16+
//stringValue, err := p.Get("prefix.key1")
17+
//fmt.Println(stringValue, err)
18+
////如果不存在,则返回默认值
19+
//stringDefaultValue := p.GetDefault("prefix.key1", "default value")
20+
//fmt.Println(stringDefaultValue)
21+
//boolValue, err := p.GetBool("prefix.key2")
22+
//fmt.Println(boolValue)
23+
//boolDefaultValue := p.GetBoolDefault("prefix.key2", false)
24+
//fmt.Println(boolDefaultValue)
25+
//intValue, err := p.GetInt("prefix.key3")
26+
//fmt.Println(intValue)
27+
//intDefaultValue := p.GetIntDefault("prefix.key3", 1)
28+
//fmt.Println(intDefaultValue)
29+
//floatValue, err := p.GetFloat64("prefix.key4")
30+
//fmt.Println(floatValue)
31+
//floatDefaultValue := p.GetFloat64Default("prefix.key4", 1.2)
32+
//fmt.Println(floatDefaultValue)
3033
}

go.mod

+27-8
Original file line numberDiff line numberDiff line change
@@ -27,49 +27,68 @@ replace (
2727

2828
require (
2929
github.com/coreos/bbolt v1.3.2 // indirect
30-
github.com/coreos/etcd v3.3.8+incompatible
31-
github.com/coreos/go-semver v0.2.0 // indirect
30+
github.com/coreos/etcd v3.3.13+incompatible
31+
github.com/coreos/go-semver v0.3.0 // indirect
32+
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e // indirect
3233
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
3334
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
3435
github.com/go-ini/ini v1.37.0
36+
github.com/gogo/protobuf v1.2.1 // indirect
3537
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef // indirect
3638
github.com/google/btree v1.0.0 // indirect
3739
github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f // indirect
3840
github.com/gorilla/websocket v1.4.0 // indirect
41+
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 // indirect
3942
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
40-
github.com/grpc-ecosystem/grpc-gateway v1.8.5 // indirect
43+
github.com/grpc-ecosystem/grpc-gateway v1.9.0 // indirect
4144
github.com/hashicorp/consul v1.2.0
4245
github.com/hashicorp/go-cleanhttp v0.0.0-20171218145408-d5fe4b57a186 // indirect
4346
github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 // indirect
4447
github.com/hashicorp/go-uuid v1.0.1 // indirect
48+
github.com/hashicorp/golang-lru v0.5.1 // indirect
4549
github.com/hashicorp/memberlist v0.1.3 // indirect
4650
github.com/hashicorp/serf v0.8.1 // indirect
4751
github.com/jonboulle/clockwork v0.1.0 // indirect
52+
github.com/json-iterator/go v1.1.6 // indirect
4853
github.com/jtolds/gls v4.20.0+incompatible // indirect
54+
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
4955
github.com/mattn/go-colorable v0.0.9 // indirect
5056
github.com/mattn/go-isatty v0.0.3 // indirect
5157
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
5258
github.com/mitchellh/go-homedir v0.0.0-20180523094522-3864e76763d9 // indirect
5359
github.com/mitchellh/go-testing-interface v1.0.0 // indirect
54-
github.com/mitchellh/mapstructure v0.0.0-20180511142126-bb74f1db0675 // indirect
60+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
61+
github.com/modern-go/reflect2 v1.0.1 // indirect
5562
github.com/pascaldekloe/goe v0.1.0 // indirect
5663
github.com/pkg/errors v0.8.1 // indirect
57-
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 // indirect
58-
github.com/prometheus/common v0.2.0
64+
github.com/prometheus/client_golang v0.9.3 // indirect
65+
github.com/prometheus/common v0.4.1
66+
github.com/prometheus/procfs v0.0.2 // indirect
5967
github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec
60-
github.com/sirupsen/logrus v1.2.0
68+
github.com/shima-park/agollo v0.0.0-20190529100944-a00256588ae8
69+
github.com/sirupsen/logrus v1.4.2
6170
github.com/smartystreets/assertions v0.0.0-20180301161246-7678a5452ebe // indirect
6271
github.com/smartystreets/goconvey v0.0.0-20170602164621-9e8dc3f972df
6372
github.com/smartystreets/gunit v0.0.0-20180314194857-6f0d6275bdcd // indirect
6473
github.com/soheilhy/cmux v0.1.4 // indirect
6574
github.com/stretchr/testify v1.3.0 // indirect
6675
github.com/tietang/go-utils v0.0.0-20180420232328-76758c2288ca
6776
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect
68-
github.com/ugorji/go v1.1.1 // indirect
6977
github.com/valyala/bytebufferpool v1.0.0 // indirect
7078
github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4
7179
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
7280
go.etcd.io/bbolt v1.3.2 // indirect
81+
go.uber.org/atomic v1.4.0 // indirect
82+
go.uber.org/multierr v1.1.0 // indirect
83+
go.uber.org/zap v1.10.0 // indirect
84+
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 // indirect
85+
golang.org/x/net v0.0.0-20190603091049-60506f45cf65 // indirect
86+
golang.org/x/sync v0.0.0-20190423024810-112230192c58 // indirect
87+
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed // indirect
88+
golang.org/x/text v0.3.2 // indirect
89+
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
90+
google.golang.org/genproto v0.0.0-20190605220351-eb0b1bdb6ae6 // indirect
91+
google.golang.org/grpc v1.21.1 // indirect
7392
gopkg.in/ini.v1 v1.42.0 // indirect
7493
gopkg.in/yaml.v2 v2.2.2
7594
)

0 commit comments

Comments
 (0)