|
|
@ -4,11 +4,13 @@ import ( |
|
|
|
"strings" |
|
|
|
"strings" |
|
|
|
|
|
|
|
|
|
|
|
"github.com/go-kratos/kratos/v2/config" |
|
|
|
"github.com/go-kratos/kratos/v2/config" |
|
|
|
"github.com/go-kratos/kratos/v2/encoding" |
|
|
|
|
|
|
|
"github.com/go-kratos/kratos/v2/log" |
|
|
|
"github.com/go-kratos/kratos/v2/log" |
|
|
|
|
|
|
|
|
|
|
|
"github.com/apolloconfig/agollo/v4" |
|
|
|
"github.com/apolloconfig/agollo/v4" |
|
|
|
|
|
|
|
"github.com/apolloconfig/agollo/v4/constant" |
|
|
|
apolloConfig "github.com/apolloconfig/agollo/v4/env/config" |
|
|
|
apolloConfig "github.com/apolloconfig/agollo/v4/env/config" |
|
|
|
|
|
|
|
"github.com/apolloconfig/agollo/v4/extension" |
|
|
|
|
|
|
|
"github.com/go-kratos/kratos/v2/encoding" |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
type apollo struct { |
|
|
|
type apollo struct { |
|
|
@ -34,6 +36,7 @@ type options struct { |
|
|
|
namespace string |
|
|
|
namespace string |
|
|
|
isBackupConfig bool |
|
|
|
isBackupConfig bool |
|
|
|
backupPath string |
|
|
|
backupPath string |
|
|
|
|
|
|
|
originConfig bool |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// WithAppID with apollo config app id
|
|
|
|
// WithAppID with apollo config app id
|
|
|
@ -92,6 +95,16 @@ func WithBackupPath(backupPath string) Option { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// WithOriginalConfig use the original configuration file without parse processing
|
|
|
|
|
|
|
|
func WithOriginalConfig() Option { |
|
|
|
|
|
|
|
return func(o *options) { |
|
|
|
|
|
|
|
extension.AddFormatParser(constant.JSON, &jsonExtParser{}) |
|
|
|
|
|
|
|
extension.AddFormatParser(constant.YAML, &yamlExtParser{}) |
|
|
|
|
|
|
|
extension.AddFormatParser(constant.YML, &yamlExtParser{}) |
|
|
|
|
|
|
|
o.originConfig = true |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func NewSource(opts ...Option) config.Source { |
|
|
|
func NewSource(opts ...Option) config.Source { |
|
|
|
op := options{} |
|
|
|
op := options{} |
|
|
|
for _, o := range opts { |
|
|
|
for _, o := range opts { |
|
|
@ -123,25 +136,41 @@ func format(ns string) string { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (e *apollo) load() []*config.KeyValue { |
|
|
|
func (e *apollo) load() []*config.KeyValue { |
|
|
|
kv := make([]*config.KeyValue, 0) |
|
|
|
kvs := make([]*config.KeyValue, 0) |
|
|
|
namespaces := strings.Split(e.opt.namespace, ",") |
|
|
|
namespaces := strings.Split(e.opt.namespace, ",") |
|
|
|
|
|
|
|
|
|
|
|
for _, ns := range namespaces { |
|
|
|
for _, ns := range namespaces { |
|
|
|
|
|
|
|
if !e.opt.originConfig { |
|
|
|
|
|
|
|
kv, err := e.getConfig(ns) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
log.Errorf("apollo get config failed,err:%v", err) |
|
|
|
|
|
|
|
continue |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
kvs = append(kvs, kv) |
|
|
|
|
|
|
|
continue |
|
|
|
|
|
|
|
} |
|
|
|
if strings.Contains(ns, ".") && !strings.Contains(ns, properties) && |
|
|
|
if strings.Contains(ns, ".") && !strings.Contains(ns, properties) && |
|
|
|
(format(ns) == yaml || format(ns) == yml || format(ns) == json) { |
|
|
|
(format(ns) == yaml || format(ns) == yml || format(ns) == json) { |
|
|
|
value, err := e.client.GetConfigCache(ns).Get("content") |
|
|
|
kv, err := e.getOriginConfig(ns) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
log.Errorf("apollo get config failed,err:%v", err) |
|
|
|
log.Errorf("apollo get config failed,err:%v", err) |
|
|
|
continue |
|
|
|
continue |
|
|
|
} |
|
|
|
} |
|
|
|
// serialize the namespace content KeyValue into bytes.
|
|
|
|
kvs = append(kvs, kv) |
|
|
|
kv = append(kv, &config.KeyValue{ |
|
|
|
|
|
|
|
Key: ns, |
|
|
|
|
|
|
|
Value: []byte(value.(string)), |
|
|
|
|
|
|
|
Format: format(ns), |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
continue |
|
|
|
continue |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
kv, err := e.getConfig(ns) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
log.Errorf("apollo get config failed,err:%v", err) |
|
|
|
|
|
|
|
continue |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
kvs = append(kvs, kv) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return kvs |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (e *apollo) getConfig(ns string) (*config.KeyValue, error) { |
|
|
|
next := map[string]interface{}{} |
|
|
|
next := map[string]interface{}{} |
|
|
|
e.client.GetConfigCache(ns).Range(func(key, value interface{}) bool { |
|
|
|
e.client.GetConfigCache(ns).Range(func(key, value interface{}) bool { |
|
|
|
// all values are out properties format
|
|
|
|
// all values are out properties format
|
|
|
@ -152,16 +181,26 @@ func (e *apollo) load() []*config.KeyValue { |
|
|
|
codec := encoding.GetCodec(f) |
|
|
|
codec := encoding.GetCodec(f) |
|
|
|
val, err := codec.Marshal(next) |
|
|
|
val, err := codec.Marshal(next) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
log.Warnf("apollo could not handle namespace %s: %v", ns, err) |
|
|
|
return nil, err |
|
|
|
continue |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
kv = append(kv, &config.KeyValue{ |
|
|
|
return &config.KeyValue{ |
|
|
|
Key: ns, |
|
|
|
Key: ns, |
|
|
|
Value: val, |
|
|
|
Value: val, |
|
|
|
Format: f, |
|
|
|
Format: f, |
|
|
|
}) |
|
|
|
}, nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (e apollo) getOriginConfig(ns string) (*config.KeyValue, error) { |
|
|
|
|
|
|
|
value, err := e.client.GetConfigCache(ns).Get("content") |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return nil, err |
|
|
|
} |
|
|
|
} |
|
|
|
return kv |
|
|
|
// serialize the namespace content KeyValue into bytes.
|
|
|
|
|
|
|
|
return &config.KeyValue{ |
|
|
|
|
|
|
|
Key: ns, |
|
|
|
|
|
|
|
Value: []byte(value.(string)), |
|
|
|
|
|
|
|
Format: format(ns), |
|
|
|
|
|
|
|
}, nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (e *apollo) Load() (kv []*config.KeyValue, err error) { |
|
|
|
func (e *apollo) Load() (kv []*config.KeyValue, err error) { |
|
|
|