diff --git a/README.md b/README.md index a403ba7b..066a9162 100644 --- a/README.md +++ b/README.md @@ -9,4 +9,3 @@ 1. 实现`gobay.Extension` 2. 每一个ext目录都是你的例子 -3. ext读取配置的规则请参考这个[issue](https://github.com/shanbay/gobay/issues/8#issuecomment-558023666) diff --git a/app.go b/app.go index 21d91e90..7f023d57 100644 --- a/app.go +++ b/app.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" "sync" "github.com/spf13/viper" @@ -151,3 +152,18 @@ func CreateApp(rootPath string, env string, exts map[Key]Extension) (*Applicatio } return app, nil } + +func GetConfigByPrefix(config *viper.Viper, prefix string, trimPrefix bool) *viper.Viper { + subConfig := viper.New() + for k, v := range config.AllSettings() { + if !strings.HasPrefix(k, prefix) { + continue + } + key := k + if trimPrefix { + key = k[len(prefix):] + } + subConfig.SetDefault(key, v) + } + return subConfig +} diff --git a/asynctaskext/asynctaskext.go b/asynctaskext/asynctaskext.go index 49da1017..89d30ac6 100644 --- a/asynctaskext/asynctaskext.go +++ b/asynctaskext/asynctaskext.go @@ -1,6 +1,7 @@ package asynctaskext import ( + "errors" "os" "github.com/RichardKnop/machinery/v1" @@ -30,11 +31,12 @@ func (t *AsyncTaskExt) Application() *gobay.Application { } func (t *AsyncTaskExt) Init(app *gobay.Application) error { + if t.NS == "" { + return errors.New("lack of NS") + } t.app = app config := app.Config() - if t.NS != "" { - config = config.Sub(t.NS) - } + config = gobay.GetConfigByPrefix(config, t.NS, true) t.config = &machineryConfig.Config{} if err := config.Unmarshal(t.config, func(config *mapstructure. DecoderConfig) { diff --git a/asynctaskext/asynctaskext_test.go b/asynctaskext/asynctaskext_test.go index 1882aeac..0b6f8735 100644 --- a/asynctaskext/asynctaskext_test.go +++ b/asynctaskext/asynctaskext_test.go @@ -16,9 +16,9 @@ var ( ) func init() { - task = AsyncTaskExt{NS: "asynctask"} + task = AsyncTaskExt{NS: "asynctask_"} - app, _ = gobay.CreateApp( + app, _ := gobay.CreateApp( "../testdata", "testing", map[gobay.Key]gobay.Extension{ @@ -44,15 +44,15 @@ func TestPushConsume(t *testing.T) { Name: "add", Args: []tasks.Arg{ { - Type: "int64", + Type: "int64", Value: 1, }, { - Type: "int64", + Type: "int64", Value: 2, }, { - Type: "int64", + Type: "int64", Value: 3, }, }, diff --git a/busext/amqp.go b/busext/amqp.go index f4c7e224..794cb822 100644 --- a/busext/amqp.go +++ b/busext/amqp.go @@ -59,11 +59,12 @@ func (b *BusExt) Application() *gobay.Application { } func (b *BusExt) Init(app *gobay.Application) error { - b.app = app - b.config = app.Config() - if b.NS != "" { - b.config = b.config.Sub(b.NS) + if b.NS == "" { + return errors.New("lack of NS") } + b.app = app + config := app.Config() + b.config = gobay.GetConfigByPrefix(config, b.NS, true) setDefaultConfig(b.config) b.consumers = make(map[string]Handler) b.consumeChannels = make(map[string]<-chan amqp.Delivery) diff --git a/busext/amqp_test.go b/busext/amqp_test.go index 24f37f16..d85cd99a 100644 --- a/busext/amqp_test.go +++ b/busext/amqp_test.go @@ -16,7 +16,7 @@ var ( ) func init() { - bus = BusExt{NS: "bus"} + bus = BusExt{NS: "bus_"} app, _ = gobay.CreateApp( "../testdata", diff --git a/cachext/backend/redis/redis.go b/cachext/backend/redis/redis.go index 7f79063a..855cf9c2 100644 --- a/cachext/backend/redis/redis.go +++ b/cachext/backend/redis/redis.go @@ -20,9 +20,9 @@ type redisBackend struct { } func (b *redisBackend) Init(config *viper.Viper) error { - host := config.GetString("cache_host") - password := config.GetString("cache_password") - dbNum := config.GetInt("cache_db") + host := config.GetString("host") + password := config.GetString("password") + dbNum := config.GetInt("db") redisClient := redis.NewClient(&redis.Options{ Addr: host, Password: password, diff --git a/cachext/ext.go b/cachext/ext.go index 1b09820d..3970466d 100644 --- a/cachext/ext.go +++ b/cachext/ext.go @@ -47,6 +47,9 @@ type CacheBackend interface { // Init init a cache extension func (c *CacheExt) Init(app *gobay.Application) error { + if c.NS == "" { + return errors.New("lack of NS") + } mu.Lock() defer mu.Unlock() @@ -57,11 +60,9 @@ func (c *CacheExt) Init(app *gobay.Application) error { c.cachedFuncName = make(map[string]void) config := app.Config() c.enableApm = config.GetBool("elastic_apm_enable") - if c.NS != "" { - config = config.Sub(c.NS) - } - c.prefix = config.GetString("cache_prefix") - backendConfig := config.GetString("cache_backend") + config = gobay.GetConfigByPrefix(config, c.NS, true) + c.prefix = config.GetString("prefix") + backendConfig := config.GetString("backend") if backend, exist := backendMap[backendConfig]; exist { c.backend = backend if err := c.backend.Init(config); err != nil { diff --git a/cachext/ext_test.go b/cachext/ext_test.go index 233809a2..32287161 100644 --- a/cachext/ext_test.go +++ b/cachext/ext_test.go @@ -12,7 +12,7 @@ import ( ) func ExampleCacheExt_Set() { - cache := &cachext.CacheExt{} + cache := &cachext.CacheExt{NS: "cache_"} exts := map[gobay.Key]gobay.Extension{ "cache": cache, } @@ -33,7 +33,7 @@ func ExampleCacheExt_Set() { } func ExampleCacheExt_Cached() { - cache := &cachext.CacheExt{} + cache := &cachext.CacheExt{NS: "cache_"} exts := map[gobay.Key]gobay.Extension{ "cache": cache, } @@ -70,7 +70,7 @@ func ExampleCacheExt_Cached() { } func ExampleCacheExt_SetMany() { - cache := &cachext.CacheExt{} + cache := &cachext.CacheExt{NS: "cache_"} exts := map[gobay.Key]gobay.Extension{ "cache": cache, } @@ -98,7 +98,7 @@ func ExampleCacheExt_SetMany() { } func TestCacheExt_Operation(t *testing.T) { - cache := &cachext.CacheExt{} + cache := &cachext.CacheExt{NS: "cache_"} exts := map[gobay.Key]gobay.Extension{ "cache": cache, } @@ -223,7 +223,7 @@ func TestCacheExt_Operation(t *testing.T) { func TestCacheExt_Cached_Common(t *testing.T) { // 准备数据 - cache := &cachext.CacheExt{} + cache := &cachext.CacheExt{NS: "cache_"} exts := map[gobay.Key]gobay.Extension{ "cache": cache, } @@ -412,7 +412,7 @@ func TestCacheExt_Cached_Common(t *testing.T) { func TestCacheExt_Cached_Struct(t *testing.T) { // 准备数据 - cache := &cachext.CacheExt{} + cache := &cachext.CacheExt{NS: "cache_"} exts := map[gobay.Key]gobay.Extension{ "cache": cache, } @@ -461,7 +461,7 @@ func TestCacheExt_Cached_Struct(t *testing.T) { } func Benchmark_SetMany(b *testing.B) { - cache := &cachext.CacheExt{} + cache := &cachext.CacheExt{NS: "cache_"} exts := map[gobay.Key]gobay.Extension{ "cache": cache, } @@ -487,7 +487,7 @@ func Benchmark_SetMany(b *testing.B) { } func Benchmark_GetMany(b *testing.B) { - cache := &cachext.CacheExt{} + cache := &cachext.CacheExt{NS: "cache_"} exts := map[gobay.Key]gobay.Extension{ "cache": cache, } @@ -530,7 +530,7 @@ func Benchmark_GetMany(b *testing.B) { } func Benchmark_Cached(b *testing.B) { - cache := &cachext.CacheExt{} + cache := &cachext.CacheExt{NS: "cache_"} exts := map[gobay.Key]gobay.Extension{ "cache": cache, } diff --git a/entext/ext.go b/entext/ext.go index 0fa9ba7e..48ba4dea 100644 --- a/entext/ext.go +++ b/entext/ext.go @@ -2,6 +2,7 @@ package entext import ( "database/sql" + "errors" "github.com/facebookincubator/ent/dialect" entsql "github.com/facebookincubator/ent/dialect/sql" "github.com/shanbay/gobay" @@ -32,15 +33,15 @@ func (d *EntExt) Object() interface{} { return d.client } func (d *EntExt) Application() *gobay.Application { return d.app } func (d *EntExt) Init(app *gobay.Application) error { - d.app = app - config := app.Config() - if d.NS != "" { - config = config.Sub(d.NS) + if d.NS == "" { + return errors.New("lack of NS") } + d.app = app + config := gobay.GetConfigByPrefix(app.Config(), d.NS, true) config.SetDefault("max_open_conns", defaultMaxOpenConns) config.SetDefault("max_idle_conns", defaultMaxIdleConns) - dbURL := config.GetString("db_url") - dbDriver := config.GetString("db_driver") + dbURL := config.GetString("url") + dbDriver := config.GetString("driver") var db *sql.DB var err error diff --git a/entext/ext_test.go b/entext/ext_test.go index d5bdb415..0da050d1 100644 --- a/entext/ext_test.go +++ b/entext/ext_test.go @@ -15,7 +15,7 @@ var entclient *ent.Client func setup() func() error { exts := map[gobay.Key]gobay.Extension{ "entext": &EntExt{ - NS: "ent", + NS: "db_", NewClient: func(drvopt interface{}) Client { return ent.NewClient(drvopt.(ent.Option)) }, diff --git a/esapmext/ext.go b/esapmext/ext.go index 09b8119a..c82cb525 100644 --- a/esapmext/ext.go +++ b/esapmext/ext.go @@ -25,8 +25,7 @@ func (e *EsApmExt) Application() *gobay.Application { // https://www.elastic.co/guide/en/apm/agent/go/current/configuration.html func (e *EsApmExt) Init(app *gobay.Application) error { - - config := app.Config() + config := gobay.GetConfigByPrefix(app.Config(), "elastic_", false) if !config.GetBool("elastic_apm_enable") { return nil } diff --git a/go.sum b/go.sum index 48668a0c..7001574c 100644 --- a/go.sum +++ b/go.sum @@ -469,7 +469,9 @@ go.elastic.co/apm/module/apmgoredis v1.6.0 h1:E/4nyzB8yo1zX1BduAzFpvs/45fq8csMXZ go.elastic.co/apm/module/apmgoredis v1.6.0/go.mod h1:2A858ngLiX0/IqNEPPLoUVXT5v527UK0MD7JMEVrWJM= go.elastic.co/apm/module/apmgorm v1.6.0 h1:E1CANwa6+xdRUwMBSqgYILIK1mvrFzqIsW/6QYJXjsk= go.elastic.co/apm/module/apmgorm v1.6.0/go.mod h1:pnpRtjjQ7CJbq9c3OIIcpDq1vbumitJQFhKvOUkSbdw= +go.elastic.co/apm/module/apmgrpc v1.6.0 h1:LRJO/C2yxCTKSr3FW/0TxLzBW68dBQNm8XX/cq53OdU= go.elastic.co/apm/module/apmgrpc v1.6.0/go.mod h1:OnV9gT0x24g6R7w/eHIS8CFgRgJGvNUWRIrS3Qtd4Jk= +go.elastic.co/apm/module/apmhttp v1.6.0 h1:Y67VwDNnUyq4akeiem8Wtpb222RbZCRfY3FBI0swoJk= go.elastic.co/apm/module/apmhttp v1.6.0/go.mod h1:pf6GS5vDxdrSF0Qy6wESRBZCRZqATSZpr658ehD5QA4= go.elastic.co/apm/module/apmsql v1.6.0 h1:0vMQDYFtA7G6QgGai38CmYY5ki9Q6g/ub/jCQp8/7qU= go.elastic.co/apm/module/apmsql v1.6.0/go.mod h1:cmMxjn6l+tjYM9+/sYnlhyGOFcj5Ye+P2NW2yslp/N8= diff --git a/gormext/ext.go b/gormext/ext.go deleted file mode 100644 index e73a81e3..00000000 --- a/gormext/ext.go +++ /dev/null @@ -1,66 +0,0 @@ -package gormext - -import ( - "github.com/jinzhu/gorm" - _ "github.com/jinzhu/gorm/dialects/mysql" - "github.com/shanbay/gobay" - "go.elastic.co/apm/module/apmgorm" - _ "go.elastic.co/apm/module/apmsql/mysql" -) - -// GormExt gorm extention -type GormExt struct { - NS string - app *gobay.Application - db *gorm.DB - enableApm bool -} - -// Init implements Extension interface -func (d *GormExt) Init(app *gobay.Application) error { - d.app = app - config := app.Config() - d.enableApm = config.GetBool("elastic_apm_enable") - if d.NS != "" { - config = config.Sub(d.NS) - } - dbURL := config.GetString("db_url") - dbDriver := config.GetString("db_driver") - var db *gorm.DB - var err error - if d.enableApm { - db, err = apmgorm.Open(dbDriver, dbURL) - } else { - db, err = gorm.Open(dbDriver, dbURL) - } - if err != nil { - return err - } - sqldb := db.DB() - if config.IsSet("conn_max_lifetime") { - sqldb.SetConnMaxLifetime(config.GetDuration("conn_max_lifetime")) - } - if config.IsSet("max_open_conns") { - sqldb.SetMaxOpenConns(config.GetInt("max_open_conns")) - } - if config.IsSet("max_idle_conns") { - sqldb.SetMaxIdleConns(config.GetInt("max_idle_conns")) - } - d.db = db - return nil -} - -// Close implements Extension interface -func (d *GormExt) Close() error { - return d.db.Close() -} - -// Object implements Extension interface -func (d *GormExt) Object() interface{} { - return d.db -} - -// Application implements Extension interface -func (d *GormExt) Application() *gobay.Application { - return d.app -} diff --git a/redisext/ext.go b/redisext/ext.go index 852ab39c..bd9a8506 100644 --- a/redisext/ext.go +++ b/redisext/ext.go @@ -1,6 +1,7 @@ package redisext import ( + "errors" "github.com/go-redis/redis" "github.com/shanbay/gobay" ) @@ -16,14 +17,14 @@ var _ gobay.Extension = (*RedisExt)(nil) // Init func (c *RedisExt) Init(app *gobay.Application) error { - c.app = app - config := app.Config() - if c.NS != "" { - config = config.Sub(c.NS) + if c.NS == "" { + return errors.New("lack of NS") } - host := config.GetString("redis_host") - password := config.GetString("redis_password") - dbNum := config.GetInt("redis_db") + c.app = app + config := gobay.GetConfigByPrefix(app.Config(), c.NS, true) + host := config.GetString("host") + password := config.GetString("password") + dbNum := config.GetInt("db") c.client = redis.NewClient(&redis.Options{ Addr: host, Password: password, diff --git a/sentryext/ext.go b/sentryext/ext.go index 548d3070..97a8e55e 100644 --- a/sentryext/ext.go +++ b/sentryext/ext.go @@ -4,21 +4,24 @@ import ( "errors" "github.com/getsentry/sentry-go" "github.com/shanbay/gobay" + "github.com/spf13/viper" ) // SentryExt sentry OpenAPI extension type SentryExt struct { - NS string - app *gobay.Application + NS string + app *gobay.Application + config *viper.Viper } // Init implements Extension interface func (d *SentryExt) Init(app *gobay.Application) error { - d.app = app - config := app.Config() - if d.NS != "" { - config = config.Sub(d.NS) + if d.NS == "" { + return errors.New("lack of NS") } + d.app = app + config := gobay.GetConfigByPrefix(app.Config(), d.NS, true) + d.config = config co := sentry.ClientOptions{} if err := config.Unmarshal(&co); err != nil { return err @@ -46,3 +49,6 @@ func (d *SentryExt) Object() interface{} { func (d *SentryExt) Application() *gobay.Application { return d.app } + +// Config get subConfig +func (d *SentryExt) Config() *viper.Viper { return d.config } diff --git a/sentryext/grpc/mw_test.go b/sentryext/grpc/mw_test.go index 8f9b96d2..bd6743f7 100644 --- a/sentryext/grpc/mw_test.go +++ b/sentryext/grpc/mw_test.go @@ -29,7 +29,7 @@ type recoveryAssertService struct { } func init() { - sentry_extension = sentryext.SentryExt{NS: "sentry"} + sentry_extension = sentryext.SentryExt{NS: "sentry_"} app, err := gobay.CreateApp( "../../testdata", "testing", diff --git a/sentryext/openapi/mw.go b/sentryext/openapi/mw.go index 394776dd..87450678 100644 --- a/sentryext/openapi/mw.go +++ b/sentryext/openapi/mw.go @@ -7,7 +7,7 @@ import ( ) func GetMiddleWare(d *sentryext.SentryExt) (middleware.Builder, error) { - config := d.Application().Config().Sub(d.NS) + config := d.Config() o := sentryhttp.Options{} if err := config.Unmarshal(&o); err != nil { return nil, err diff --git a/sentryext/openapi/mw_test.go b/sentryext/openapi/mw_test.go index b9701151..d2c9ce3b 100644 --- a/sentryext/openapi/mw_test.go +++ b/sentryext/openapi/mw_test.go @@ -16,7 +16,7 @@ var handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { }) func init() { - sentry_extension = sentryext.SentryExt{NS: "sentry"} + sentry_extension = sentryext.SentryExt{NS: "sentry_"} app, err := gobay.CreateApp( "../../testdata", diff --git a/seqgenext/ext.go b/seqgenext/ext.go index dcff860c..fc321e92 100644 --- a/seqgenext/ext.go +++ b/seqgenext/ext.go @@ -9,6 +9,7 @@ package seqgenext '0000000010110101100111101101011000010111010001100000000000000000' */ import ( + "errors" "fmt" "sync" @@ -47,10 +48,10 @@ type SequenceGeneratorExt struct { // Init implements Extension interface func (d *SequenceGeneratorExt) Init(app *gobay.Application) error { - config := app.Config() - if d.NS != "" { - config = config.Sub(d.NS) + if d.NS == "" { + return errors.New("lack of NS") } + config := gobay.GetConfigByPrefix(app.Config(), d.NS, true) d.app = app d.SequenceBase = config.GetUint64("sequence_base") d.SequenceKey = config.GetString("sequence_key") diff --git a/stubext/ext.go b/stubext/ext.go index c5ecad2f..cca7e46e 100644 --- a/stubext/ext.go +++ b/stubext/ext.go @@ -58,6 +58,9 @@ func (d *StubExt) Object() interface{} { return d } func (d *StubExt) Close() error { return d.conn.Close() } func (d *StubExt) Init(app *gobay.Application) error { + if d.NS == "" { + return errors.New("lack of NS") + } // init from default d.ConnTimeout = defaultConnTimeout d.CallTimeout = defaultCallTimeout @@ -72,9 +75,7 @@ func (d *StubExt) Init(app *gobay.Application) error { d.app = app config := app.Config() d.enableApm = config.GetBool("elastic_apm_enable") - if d.NS != "" { - config = config.Sub(d.NS) - } + config = gobay.GetConfigByPrefix(config, d.NS, true) if err := config.Unmarshal(d); err != nil { return err } diff --git a/stubext/ext_test.go b/stubext/ext_test.go index f69d7eef..e116b4d7 100644 --- a/stubext/ext_test.go +++ b/stubext/ext_test.go @@ -20,7 +20,7 @@ var ( func setupStub(env string) { stubext = StubExt{ - NS: "stub_health", + NS: "stub_health_", DailOptions: []grpc.DialOption{grpc.WithInsecure(), grpc.WithBlock()}, NewClientFuncs: map[string]NewClientFunc{ "health": func(conn *grpc.ClientConn) interface{} { diff --git a/testdata/config.yaml b/testdata/config.yaml index bc0846c3..3c42f386 100644 --- a/testdata/config.yaml +++ b/testdata/config.yaml @@ -1,52 +1,46 @@ -bus: &bus - broker_url: "amqp://guest:guest@127.0.0.1:5672/" - reconnect_delay: "2s" - reinit_delay: "1s" - exhanges: +defaults: &defaults + bus_broker_url: "amqp://guest:guest@127.0.0.1:5672/" + bus_reconnect_delay: "2s" + bus_reinit_delay: "1s" + bus_exhanges: - sbay-exchange - queues: + bus_queues: - test - resend_delay: "1s" - publish_retry: 3 - prefetch: 10 - quit_consumer_on_empty_queue: false - bindings: + bus_resend_delay: "1s" + bus_publish_retry: 3 + bus_prefetch: 10 + bus_quit_consumer_on_empty_queue: false + bus_bindings: - exchange: sbay-exchange queue: test binding_key: buses.oc.post_order_paid -stub_health: &stub_health - host: '127.0.0.1' - port: 5555 - authority: 'health-rpc.xyz' - metadata: + + stub_health_host: '127.0.0.1' + stub_health_port: 5555 + stub_health_authority: 'health-rpc.xyz' + stub_health_metadata: svc_auth_token: 'abcdefg' - conntimeout: 1s - calltimeout: 300ms - retrybackoff: 50ms - retrytimes: 3 + stub_health_conntimeout: 1s + stub_health_calltimeout: 300ms + stub_health_retrybackoff: 50ms + stub_health_retrytimes: 3 -asynctask: &asynctask - concurrency: 10 - broker: "redis://127.0.0.1:6379/8" - default_queue: "gobay.task" - result_backend: "redis://127.0.0.1:6379/8" - results_expire_in: 1 - redis: {} + asynctask_concurrency: 10 + asynctask_broker: "redis://127.0.0.1:6379/8" + asynctask_default_queue: "gobay.task" + asynctask_result_backend: "redis://127.0.0.1:6379/8" + asynctask_results_expire_in: 1 + asynctask_redis: {} -defaults: &defaults db_driver: sqlite3 db_url: ":memory:" + short_url_alphabet: "mn6j2c4rv8bpygw95z7hsdaetxuk3fq" - asynctask: - <<: *asynctask - bus: - <<: *bus - sentry: - dsn: "http://user:pass@127.0.0.1/5" - environment: "default" - repanic: true - stub_health: - <<: *stub_health + + sentry_dsn: "http://user:pass@127.0.0.1/5" + sentry_environment: "default" + sentry_repanic: true + cache_backend: "memory" cache_prefix: "github" cache_host: "127.0.0.1:6379" @@ -54,39 +48,18 @@ defaults: &defaults cache_db: 3 testing: <<: *defaults - bus: - <<: *bus - stub_health: - <<: *stub_health - ent: - db_driver: mysql - db_url: "root:@(127.0.0.1:3306)/gobay?charset=utf8mb4&parseTime=true" + db_driver: mysql + db_url: "root:@(127.0.0.1:3306)/gobay?charset=utf8mb4&parseTime=true" grpclong: <<: *defaults - bus: - <<: *bus - stub_health: - <<: *stub_health - retrybackoff: 300ms + stub_health_retrybackoff: 300ms grpcnoretry: <<: *defaults - bus: - <<: *bus - stub_health: - <<: *stub_health - retrytimes: 0 + stub_health_retrytimes: 0 grpcmocked: <<: *defaults - bus: - <<: *bus - stub_health: - <<: *stub_health - mocked: true + stub_health_mocked: true development: <<: *defaults - stub_health: - <<: *stub_health production: <<: *defaults - stub_health: - <<: *stub_health