mirror of
https://github.com/go-kratos/kratos.git
synced 2025-03-17 21:07:54 +02:00
feat(config): config support custom merge config (#3106)
This commit is contained in:
parent
d13071e45f
commit
cd9ef38d13
@ -7,6 +7,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/imdario/mergo"
|
||||
|
||||
// init encoding
|
||||
_ "github.com/go-kratos/kratos/v2/encoding/json"
|
||||
_ "github.com/go-kratos/kratos/v2/encoding/proto"
|
||||
@ -17,12 +19,7 @@ import (
|
||||
|
||||
var _ Config = (*config)(nil)
|
||||
|
||||
var (
|
||||
// ErrNotFound is key not found.
|
||||
ErrNotFound = errors.New("key not found")
|
||||
// ErrTypeAssert is type assert error.
|
||||
ErrTypeAssert = errors.New("type assert error")
|
||||
)
|
||||
var ErrNotFound = errors.New("key not found") // ErrNotFound is key not found.
|
||||
|
||||
// Observer is config observer.
|
||||
type Observer func(string, Value)
|
||||
@ -49,6 +46,9 @@ func New(opts ...Option) Config {
|
||||
o := options{
|
||||
decoder: defaultDecoder,
|
||||
resolver: defaultResolver,
|
||||
merge: func(dst, src interface{}) error {
|
||||
return mergo.Map(dst, src, mergo.WithOverride)
|
||||
},
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(&o)
|
||||
|
@ -3,6 +3,8 @@ package config
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/imdario/mergo"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -131,6 +133,9 @@ func TestConfig(t *testing.T) {
|
||||
sources: []Source{jSource},
|
||||
decoder: defaultDecoder,
|
||||
resolver: defaultResolver,
|
||||
merge: func(dst, src interface{}) error {
|
||||
return mergo.Map(dst, src, mergo.WithOverride)
|
||||
},
|
||||
}
|
||||
cf := &config{}
|
||||
cf.opts = opts
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/go-kratos/kratos/v2/encoding"
|
||||
"github.com/go-kratos/kratos/v2/log"
|
||||
)
|
||||
|
||||
// Decoder is config decoder.
|
||||
@ -15,6 +14,9 @@ type Decoder func(*KeyValue, map[string]interface{}) error
|
||||
// Resolver resolve placeholder in config.
|
||||
type Resolver func(map[string]interface{}) error
|
||||
|
||||
// Merge is config merge func.
|
||||
type Merge func(dst, src interface{}) error
|
||||
|
||||
// Option is config option.
|
||||
type Option func(*options)
|
||||
|
||||
@ -22,6 +24,7 @@ type options struct {
|
||||
sources []Source
|
||||
decoder Decoder
|
||||
resolver Resolver
|
||||
merge Merge
|
||||
}
|
||||
|
||||
// WithSource with config source.
|
||||
@ -49,10 +52,11 @@ func WithResolver(r Resolver) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithLogger with config logger.
|
||||
// Deprecated: use global logger instead.
|
||||
func WithLogger(_ log.Logger) Option {
|
||||
return func(o *options) {}
|
||||
// WithMergeFunc with config merge func.
|
||||
func WithMergeFunc(m Merge) Option {
|
||||
return func(o *options) {
|
||||
o.merge = m
|
||||
}
|
||||
}
|
||||
|
||||
// defaultDecoder decode config from source KeyValue
|
||||
|
@ -226,3 +226,14 @@ func TestExpand(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithMergeFunc(t *testing.T) {
|
||||
c := &options{}
|
||||
a := func(dst, src interface{}) error {
|
||||
return nil
|
||||
}
|
||||
WithMergeFunc(a)(c)
|
||||
if c.merge == nil {
|
||||
t.Fatal("c.merge is nil")
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/imdario/mergo"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
@ -48,7 +47,7 @@ func (r *reader) Merge(kvs ...*KeyValue) error {
|
||||
log.Errorf("Failed to config decode error: %v key: %s value: %s", err, kv.Key, string(kv.Value))
|
||||
return err
|
||||
}
|
||||
if err := mergo.Map(&merged, convertMap(next), mergo.WithOverride); err != nil {
|
||||
if err := r.opts.merge(&merged, convertMap(next)); err != nil {
|
||||
log.Errorf("Failed to config merge error: %v key: %s value: %s", err, kv.Key, string(kv.Value))
|
||||
return err
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/go-kratos/kratos/v2/encoding"
|
||||
|
||||
"github.com/imdario/mergo"
|
||||
)
|
||||
|
||||
func TestReader_Merge(t *testing.T) {
|
||||
@ -21,6 +23,9 @@ func TestReader_Merge(t *testing.T) {
|
||||
return fmt.Errorf("unsupported key: %s format: %s", kv.Key, kv.Format)
|
||||
},
|
||||
resolver: defaultResolver,
|
||||
merge: func(dst, src interface{}) error {
|
||||
return mergo.Map(dst, src, mergo.WithOverride)
|
||||
},
|
||||
}
|
||||
r := newReader(opts)
|
||||
err = r.Merge(&KeyValue{
|
||||
@ -82,6 +87,9 @@ func TestReader_Value(t *testing.T) {
|
||||
return fmt.Errorf("unsupported key: %s format: %s", kv.Key, kv.Format)
|
||||
},
|
||||
resolver: defaultResolver,
|
||||
merge: func(dst, src interface{}) error {
|
||||
return mergo.Map(dst, src, mergo.WithOverride)
|
||||
},
|
||||
}
|
||||
|
||||
ymlval := `
|
||||
@ -184,6 +192,9 @@ func TestReader_Source(t *testing.T) {
|
||||
return fmt.Errorf("unsupported key: %s format: %s", kv.Key, kv.Format)
|
||||
},
|
||||
resolver: defaultResolver,
|
||||
merge: func(dst, src interface{}) error {
|
||||
return mergo.Map(dst, src, mergo.WithOverride)
|
||||
},
|
||||
}
|
||||
r := newReader(opts)
|
||||
err = r.Merge(&KeyValue{
|
||||
|
Loading…
x
Reference in New Issue
Block a user