diff options
author | Valery Piashchynski <[email protected]> | 2021-09-08 20:55:25 +0300 |
---|---|---|
committer | Valery Piashchynski <[email protected]> | 2021-09-08 20:55:25 +0300 |
commit | f855d878c281285bd8f468af0dba2521e4f211db (patch) | |
tree | 5d10640eb0f09718672819a30d39169589519e0d | |
parent | b72643e64e116e51a245bc9331e25c3f73175030 (diff) |
Update protoc plugin,
Update serverOptions,
Update codec.
Signed-off-by: Valery Piashchynski <[email protected]>
-rw-r--r-- | go.mod | 1 | ||||
-rw-r--r-- | go.sum | 1 | ||||
-rw-r--r-- | plugins/grpc/codec.go | 5 | ||||
-rw-r--r-- | plugins/grpc/config.go | 8 | ||||
-rw-r--r-- | plugins/grpc/plugin.go | 8 | ||||
-rw-r--r-- | plugins/grpc/protoc_plugins/protoc-gen-php-grpc/main.go (renamed from plugins/grpc/protoc-gen-php-grpc/main.go) | 2 | ||||
-rw-r--r-- | plugins/grpc/protoc_plugins/protoc-gen-php-grpc/php/generate.go (renamed from plugins/grpc/protoc-gen-php-grpc/php/generate.go) | 0 | ||||
-rw-r--r-- | plugins/grpc/protoc_plugins/protoc-gen-php-grpc/php/keywords.go (renamed from plugins/grpc/protoc-gen-php-grpc/php/keywords.go) | 0 | ||||
-rw-r--r-- | plugins/grpc/protoc_plugins/protoc-gen-php-grpc/php/ns.go (renamed from plugins/grpc/protoc-gen-php-grpc/php/ns.go) | 0 | ||||
-rw-r--r-- | plugins/grpc/protoc_plugins/protoc-gen-php-grpc/php/template.go (renamed from plugins/grpc/protoc-gen-php-grpc/php/template.go) | 0 | ||||
-rw-r--r-- | plugins/grpc/server.go | 119 | ||||
-rw-r--r-- | tests/plugins/grpc/configs/.rr-grpc-init.yaml | 50 | ||||
-rw-r--r-- | tests/plugins/grpc/plugin_test.go | 2 | ||||
-rw-r--r-- | tests/plugins/logger/logger_test.go | 24 |
14 files changed, 206 insertions, 14 deletions
@@ -88,6 +88,7 @@ require ( go.uber.org/atomic v1.9.0 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/tools v0.1.5 // indirect + google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c // indirect gopkg.in/ini.v1 v1.63.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect @@ -769,6 +769,7 @@ google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= diff --git a/plugins/grpc/codec.go b/plugins/grpc/codec.go index dd299601..aeb373b9 100644 --- a/plugins/grpc/codec.go +++ b/plugins/grpc/codec.go @@ -4,6 +4,7 @@ import "google.golang.org/grpc/encoding" type rawMessage []byte +const cName string = "proto" const rm string = "rawMessage" func (r rawMessage) Reset() {} @@ -31,6 +32,10 @@ func (c *codec) Unmarshal(data []byte, v interface{}) error { return c.base.Unmarshal(data, v) } +func (c *codec) Name() string { + return cName +} + // String return codec name. func (c *codec) String() string { return "raw:" + c.base.Name() diff --git a/plugins/grpc/config.go b/plugins/grpc/config.go index 9a9f8c2c..53c50e22 100644 --- a/plugins/grpc/config.go +++ b/plugins/grpc/config.go @@ -32,3 +32,11 @@ type TLS struct { func (c *Config) InitDefaults() { } + +func (c *Config) EnableTLS() bool { + if c.TLS != nil { + return (c.TLS.RootCA != "" && c.TLS.Key != "" && c.TLS.Cert != "") || (c.TLS.Key != "" && c.TLS.Cert != "") + } + + return false +} diff --git a/plugins/grpc/plugin.go b/plugins/grpc/plugin.go index 4871a8a7..b424c5d0 100644 --- a/plugins/grpc/plugin.go +++ b/plugins/grpc/plugin.go @@ -4,6 +4,8 @@ import ( "github.com/spiral/errors" "github.com/spiral/roadrunner/v2/plugins/config" "github.com/spiral/roadrunner/v2/plugins/logger" + "google.golang.org/grpc" + "google.golang.org/grpc/encoding" ) const ( @@ -11,6 +13,9 @@ const ( ) type Plugin struct { + config *Config + opts []grpc.ServerOption + cfg config.Configurer log logger.Logger } @@ -18,6 +23,9 @@ type Plugin struct { func (p *Plugin) Init(cfg config.Configurer, log logger.Logger) error { const op = errors.Op("grpc_plugin_init") + // register the codec + encoding.RegisterCodec(&codec{}) + return nil } diff --git a/plugins/grpc/protoc-gen-php-grpc/main.go b/plugins/grpc/protoc_plugins/protoc-gen-php-grpc/main.go index c9c4a573..0894a7a8 100644 --- a/plugins/grpc/protoc-gen-php-grpc/main.go +++ b/plugins/grpc/protoc_plugins/protoc-gen-php-grpc/main.go @@ -27,7 +27,7 @@ import ( "io/ioutil" "os" - "github.com/spiral/roadrunner/v2/plugins/grpc/protoc-gen-php-grpc/php" + "github.com/spiral/roadrunner/v2/plugins/grpc/protoc_plugins/protoc-gen-php-grpc/php" "google.golang.org/protobuf/proto" plugin "google.golang.org/protobuf/types/pluginpb" ) diff --git a/plugins/grpc/protoc-gen-php-grpc/php/generate.go b/plugins/grpc/protoc_plugins/protoc-gen-php-grpc/php/generate.go index 03c48ac8..03c48ac8 100644 --- a/plugins/grpc/protoc-gen-php-grpc/php/generate.go +++ b/plugins/grpc/protoc_plugins/protoc-gen-php-grpc/php/generate.go diff --git a/plugins/grpc/protoc-gen-php-grpc/php/keywords.go b/plugins/grpc/protoc_plugins/protoc-gen-php-grpc/php/keywords.go index 32579e33..32579e33 100644 --- a/plugins/grpc/protoc-gen-php-grpc/php/keywords.go +++ b/plugins/grpc/protoc_plugins/protoc-gen-php-grpc/php/keywords.go diff --git a/plugins/grpc/protoc-gen-php-grpc/php/ns.go b/plugins/grpc/protoc_plugins/protoc-gen-php-grpc/php/ns.go index c1dc3898..c1dc3898 100644 --- a/plugins/grpc/protoc-gen-php-grpc/php/ns.go +++ b/plugins/grpc/protoc_plugins/protoc-gen-php-grpc/php/ns.go diff --git a/plugins/grpc/protoc-gen-php-grpc/php/template.go b/plugins/grpc/protoc_plugins/protoc-gen-php-grpc/php/template.go index e00c6fdd..e00c6fdd 100644 --- a/plugins/grpc/protoc-gen-php-grpc/php/template.go +++ b/plugins/grpc/protoc_plugins/protoc-gen-php-grpc/php/template.go diff --git a/plugins/grpc/server.go b/plugins/grpc/server.go new file mode 100644 index 00000000..53b0b2ae --- /dev/null +++ b/plugins/grpc/server.go @@ -0,0 +1,119 @@ +package grpc + +import ( + "context" + "crypto/tls" + "crypto/x509" + "os" + + "github.com/spiral/errors" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/keepalive" +) + +func (p *Plugin) createGRPCserver() (*grpc.Server, error) { + const op = errors.Op("grpc_plugin_create_server") + opts, err := p.serverOptions() + if err != nil { + return nil, errors.E(op, err) + } + + server := grpc.NewServer(opts...) + + /* + proto descriptors parser + */ + + return server, nil +} + +func (p *Plugin) interceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { + // start := time.Now() + resp, err = handler(ctx, req) + + // svc.throw(EventUnaryCall, &UnaryCallEvent{ + // Info: info, + // Context: ctx, + // Error: err, + // start: start, + // elapsed: time.Since(start), + // }) + + return resp, err +} + +func (p *Plugin) serverOptions() ([]grpc.ServerOption, error) { + const op = errors.Op("grpc_plugin_server_options") + + var tcreds credentials.TransportCredentials + var opts []grpc.ServerOption + var cert tls.Certificate + var certPool *x509.CertPool + var rca []byte + var err error + + if p.config.EnableTLS() { + // if client CA is not empty we combine it with Cert and Key + if p.config.TLS.RootCA != "" { + cert, err = tls.LoadX509KeyPair(p.config.TLS.Cert, p.config.TLS.Key) + if err != nil { + return nil, err + } + + certPool, err = x509.SystemCertPool() + if err != nil { + return nil, err + } + if certPool == nil { + certPool = x509.NewCertPool() + } + + rca, err = os.ReadFile(p.config.TLS.RootCA) + if err != nil { + return nil, err + } + + if ok := certPool.AppendCertsFromPEM(rca); !ok { + return nil, errors.E(op, errors.Str("could not append Certs from PEM")) + } + + tcreds = credentials.NewTLS(&tls.Config{ + MinVersion: tls.VersionTLS12, + ClientAuth: tls.RequireAndVerifyClientCert, + Certificates: []tls.Certificate{cert}, + ClientCAs: certPool, + }) + } else { + tcreds, err = credentials.NewServerTLSFromFile(p.config.TLS.Cert, p.config.TLS.Key) + if err != nil { + return nil, err + } + } + + serverOptions := []grpc.ServerOption{ + grpc.MaxSendMsgSize(int(p.config.MaxSendMsgSize)), + grpc.MaxRecvMsgSize(int(p.config.MaxRecvMsgSize)), + grpc.KeepaliveParams(keepalive.ServerParameters{ + MaxConnectionIdle: p.config.MaxConnectionIdle, + MaxConnectionAge: p.config.MaxConnectionAge, + MaxConnectionAgeGrace: p.config.MaxConnectionAge, + Time: p.config.PingTime, + Timeout: p.config.Timeout, + }), + grpc.MaxConcurrentStreams(uint32(p.config.MaxConcurrentStreams)), + } + + opts = append(opts, grpc.Creds(tcreds)) + opts = append(opts, serverOptions...) + } + + opts = append(opts, p.opts...) + + // custom codec is required to bypass protobuf, common interceptor used for debug and stats + return append( + opts, + grpc.UnaryInterceptor(p.interceptor), + // grpc.CustomCodec(&codec{encoding.GetCodec(encCodec)}), + ), nil +} diff --git a/tests/plugins/grpc/configs/.rr-grpc-init.yaml b/tests/plugins/grpc/configs/.rr-grpc-init.yaml index e69de29b..010e904e 100644 --- a/tests/plugins/grpc/configs/.rr-grpc-init.yaml +++ b/tests/plugins/grpc/configs/.rr-grpc-init.yaml @@ -0,0 +1,50 @@ +# GRPC service configuration +grpc: + # socket to listen + listen: "tcp://localhost:9001" + + # proto root file + proto: "test.proto" + + # max send limit (MB) + max_send_msg_size: 50 + + # max receive limit (MB) + max_recv_msg_size: 50 + + # MaxConnectionIdle is a duration for the amount of time after which an + # idle connection would be closed by sending a GoAway. Idleness duration is + # defined since the most recent time the number of outstanding RPCs became + # zero or the connection establishment. + max_connection_idle: 0s + + # MaxConnectionAge is a duration for the maximum amount of time a + # connection may exist before it will be closed by sending a GoAway. A + # random jitter of +/-10% will be added to MaxConnectionAge to spread out + # connection storms. + max_connection_age: 0s + + # MaxConnectionAgeGrace is an additive period after MaxConnectionAge after + # which the connection will be forcibly closed. + max_connection_age_grace: 0s + + # MaxConnectionAgeGrace is an additive period after MaxConnectionAge after + # which the connection will be forcibly closed. + max_concurrent_streams: 10 + + # After a duration of this time if the server doesn't see any activity it + # pings the client to see if the transport is still alive. + # If set below 1s, a minimum value of 1s will be used instead. + ping_time: 1s + + # After having pinged for keepalive check, the server waits for a duration + # of Timeout and if no activity is seen even after that the connection is + # closed. + timeout: 200s + + # Usual workers pool configuration + pool: + num_workers: 2 + max_jobs: 0 + allocate_timeout: 60s + destroy_timeout: 60 diff --git a/tests/plugins/grpc/plugin_test.go b/tests/plugins/grpc/plugin_test.go index 74a71c62..cfbe0121 100644 --- a/tests/plugins/grpc/plugin_test.go +++ b/tests/plugins/grpc/plugin_test.go @@ -19,7 +19,7 @@ func init() { } func build() error { - cmd := exec.Command("go", "build", "-o", "plugin", "../../../plugins/grpc/protoc-gen-php-grpc") + cmd := exec.Command("go", "build", "-o", "plugin", "../../../plugins/grpc/protoc_plugins/protoc-gen-php-grpc") return cmd.Run() } diff --git a/tests/plugins/logger/logger_test.go b/tests/plugins/logger/logger_test.go index 05ca2d53..e077f0bc 100644 --- a/tests/plugins/logger/logger_test.go +++ b/tests/plugins/logger/logger_test.go @@ -346,18 +346,6 @@ func TestFileLogger(t *testing.T) { wg.Wait() } -func httpEcho(t *testing.T) { - req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:54224?hello=world", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - assert.Equal(t, http.StatusCreated, r.StatusCode) - - err = r.Body.Close() - assert.NoError(t, err) -} - func TestMarshalObjectLogging(t *testing.T) { container, err := endure.NewContainer(nil, endure.RetryOnFail(true), endure.SetLogLevel(endure.ErrorLevel)) if err != nil { @@ -428,3 +416,15 @@ func TestMarshalObjectLogging(t *testing.T) { stopCh <- struct{}{} wg.Wait() } + +func httpEcho(t *testing.T) { + req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:54224?hello=world", nil) + assert.NoError(t, err) + + r, err := http.DefaultClient.Do(req) + assert.NoError(t, err) + assert.Equal(t, http.StatusCreated, r.StatusCode) + + err = r.Body.Close() + assert.NoError(t, err) +} |