diff --git a/default_grpc.go b/default_grpc.go new file mode 100644 index 0000000..49df658 --- /dev/null +++ b/default_grpc.go @@ -0,0 +1,14 @@ +package atom + +import ( + "github.com/rogeecn/atom/container" + "github.com/rogeecn/atom/providers/grpcs" + "github.com/rogeecn/atom/providers/log" +) + +func DefaultGRPC(providers ...container.ProviderContainer) container.Providers { + return append(container.Providers{ + log.DefaultProvider(), + grpcs.DefaultProvider(), + }, providers...) +} diff --git a/go.mod b/go.mod index 544f7a9..6d2bace 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( go.uber.org/zap v1.21.0 golang.org/x/crypto v0.5.0 golang.org/x/sync v0.1.0 + google.golang.org/grpc v1.52.0 gorm.io/driver/mysql v1.4.1 gorm.io/driver/postgres v1.4.4 gorm.io/gen v0.3.19 @@ -34,6 +35,7 @@ require ( github.com/go-sql-driver/mysql v1.6.0 // indirect github.com/goccy/go-json v0.10.0 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect + github.com/golang/protobuf v1.5.2 // indirect github.com/google/uuid v1.3.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect @@ -71,6 +73,7 @@ require ( golang.org/x/sys v0.4.0 // indirect golang.org/x/text v0.6.0 // indirect golang.org/x/tools v0.1.12 // indirect + google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index e434737..94662a1 100644 --- a/go.sum +++ b/go.sum @@ -153,6 +153,8 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -725,6 +727,8 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef h1:uQ2vjV/sHTsWSqdKeLqmwitzgvjMl7o4IdtHwUDXSJY= +google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -741,6 +745,8 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.52.0 h1:kd48UiU7EHsV4rnLyOJRuP/Il/UHE7gdDAQ+SZI7nZk= +google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -752,6 +758,7 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/providers/grpcs/config.go b/providers/grpcs/config.go new file mode 100644 index 0000000..74b7148 --- /dev/null +++ b/providers/grpcs/config.go @@ -0,0 +1,30 @@ +package grpcs + +import ( + "fmt" +) + +const DefaultPrefix = "Grpc" + +type Config struct { + Host *string + Port uint + Tls *Tls +} + +type Tls struct { + CA string + Cert string + Key string +} + +func (h *Config) Address() string { + if h.Host == nil { + return h.PortString() + } + return fmt.Sprintf("%s:%d", *h.Host, h.Port) +} + +func (h *Config) PortString() string { + return fmt.Sprintf(":%d", h.Port) +} diff --git a/providers/grpcs/grpcs.go b/providers/grpcs/grpcs.go new file mode 100644 index 0000000..e467d15 --- /dev/null +++ b/providers/grpcs/grpcs.go @@ -0,0 +1,76 @@ +package grpcs + +import ( + "net" + + "github.com/pkg/errors" + "github.com/rogeecn/atom/container" + "github.com/rogeecn/atom/providers/log" + "github.com/rogeecn/atom/utils/opt" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/reflection" +) + +func DefaultProvider() container.ProviderContainer { + return container.ProviderContainer{ + Provider: Provide, + Options: []opt.Option{ + opt.Prefix(DefaultPrefix), + }, + } +} + +// 给注入启动调用使用 +type ServerService interface { + Name() string + Register(*grpc.Server) +} + +type Grpc struct { + server *grpc.Server + config *Config +} + +func Provide(opts ...opt.Option) error { + o := opt.New(opts...) + var config Config + if err := o.UnmarshalConfig(&config); err != nil { + log.Fatal(err) + } + + return container.Container.Provide(func() (*Grpc, error) { + serverOptions := []grpc.ServerOption{} + + // tls + if config.Tls != nil { + tlsConfig, err := credentials.NewServerTLSFromFile(config.Tls.Cert, config.Tls.Key) + if err != nil { + return nil, errors.Wrap(err, "Failed to create tls credential") + } + serverOptions = append(serverOptions, grpc.Creds(tlsConfig)) + } + + return &Grpc{ + server: grpc.NewServer(serverOptions...), + config: &config, + }, nil + }, o.DiOptions()...) +} + +func (g *Grpc) Serve() error { + ld, err := net.Listen("tcp", g.config.Address()) + if err != nil { + return errors.Wrapf(err, "bind address failed: %s", g.config.Address()) + } + + log.Infof("grpc server listen on %s", g.config.Address()) + reflection.Register(g.server) + + return g.server.Serve(ld) +} + +func (g *Grpc) RegisterService(name string, f func(*grpc.Server)) { + log.Debug("register service:", name) + f(g.server) +} diff --git a/providers/http/config.go b/providers/http/config.go index f70210f..22164c1 100644 --- a/providers/http/config.go +++ b/providers/http/config.go @@ -4,7 +4,7 @@ import ( "fmt" ) -const ConfigPrefix = "Http" +const DefaultPrefix = "Http" type Config struct { Static *string diff --git a/providers/http/env.go b/providers/http/env.go deleted file mode 100644 index f9c48e8..0000000 --- a/providers/http/env.go +++ /dev/null @@ -1,33 +0,0 @@ -package http - -import ( - "log" - - "github.com/spf13/viper" -) - -const DefaultPrefix = "Http" - -func AutoLoadConfig() *Config { - return LoadConfig("") -} - -func LoadConfig(file string) *Config { - if file == "" { - file = "config.toml" - } - - v := viper.NewWithOptions(viper.KeyDelimiter("_")) - v.AutomaticEnv() - v.SetConfigFile(file) - if err := v.ReadInConfig(); err != nil { - log.Fatal(err) - } - - var config Config - if err := v.UnmarshalKey(DefaultPrefix, &config); err != nil { - log.Fatal(err) - } - - return &config -} diff --git a/root.go b/root.go index 98c381e..0cadefe 100644 --- a/root.go +++ b/root.go @@ -14,7 +14,8 @@ import ( var cfgFile string var ( - GroupRoutes = dig.Group("routes") + GroupRoutes = dig.Group("routes") + GroupGrpcServer = dig.Group("grpc_server_services") ) func Serve(providers container.Providers, opts ...Option) error { diff --git a/services/grpc.go b/services/grpc.go new file mode 100644 index 0000000..2b18051 --- /dev/null +++ b/services/grpc.go @@ -0,0 +1,23 @@ +package services + +import ( + "github.com/rogeecn/atom/container" + "github.com/rogeecn/atom/providers/grpcs" + "go.uber.org/dig" +) + +type GrpcService struct { + dig.In + + Server *grpcs.Grpc + Services []grpcs.ServerService `group:"grpc_server_services"` +} + +func ServeGrpc() error { + return container.Container.Invoke(func(grpc GrpcService) error { + for _, svc := range grpc.Services { + grpc.Server.RegisterService(svc.Name(), svc.Register) + } + return grpc.Server.Serve() + }) +}