mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
vendor: add go-grpc-middleware
Rebased to master PR #9994. Fixed a Go format issue in v3rpc/interceptor.go. Updated vendor to include go-grpc-middleware.
This commit is contained in:
8
Gopkg.lock
generated
8
Gopkg.lock
generated
@@ -129,9 +129,12 @@
|
|||||||
revision = "4201258b820c74ac8e6922fc9e6b52f71fe46f8d"
|
revision = "4201258b820c74ac8e6922fc9e6b52f71fe46f8d"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:f11ab206621794e7021bbb6d1bb26e82fd12a8893740805db14bdce4b4abe566"
|
digest = "1:d4fb49314d7f792a14c72f094f8fcb9ecfdf7a4c3e2186efb1f3d3a88806a844"
|
||||||
name = "github.com/grpc-ecosystem/go-grpc-middleware"
|
name = "github.com/grpc-ecosystem/go-grpc-middleware"
|
||||||
packages = ["util/backoffutils"]
|
packages = [
|
||||||
|
".",
|
||||||
|
"util/backoffutils",
|
||||||
|
]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "c250d6563d4d4c20252cd865923440e829844f4e"
|
revision = "c250d6563d4d4c20252cd865923440e829844f4e"
|
||||||
version = "v1.0.0"
|
version = "v1.0.0"
|
||||||
@@ -498,6 +501,7 @@
|
|||||||
"github.com/golang/groupcache/lru",
|
"github.com/golang/groupcache/lru",
|
||||||
"github.com/golang/protobuf/proto",
|
"github.com/golang/protobuf/proto",
|
||||||
"github.com/google/btree",
|
"github.com/google/btree",
|
||||||
|
"github.com/grpc-ecosystem/go-grpc-middleware",
|
||||||
"github.com/grpc-ecosystem/go-grpc-middleware/util/backoffutils",
|
"github.com/grpc-ecosystem/go-grpc-middleware/util/backoffutils",
|
||||||
"github.com/grpc-ecosystem/go-grpc-prometheus",
|
"github.com/grpc-ecosystem/go-grpc-prometheus",
|
||||||
"github.com/grpc-ecosystem/grpc-gateway/runtime",
|
"github.com/grpc-ecosystem/grpc-gateway/runtime",
|
||||||
|
|||||||
@@ -135,7 +135,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"project": "github.com/grpc-ecosystem/go-grpc-middleware/util/backoffutils",
|
"project": "github.com/grpc-ecosystem/go-grpc-middleware",
|
||||||
"licenses": [
|
"licenses": [
|
||||||
{
|
{
|
||||||
"type": "Apache License 2.0",
|
"type": "Apache License 2.0",
|
||||||
|
|||||||
@@ -78,8 +78,8 @@ func logUnaryRequestStats(ctx context.Context, lg *zap.Logger, info *grpc.UnaryS
|
|||||||
remote = peerInfo.Addr.String()
|
remote = peerInfo.Addr.String()
|
||||||
}
|
}
|
||||||
var responseType string = info.FullMethod
|
var responseType string = info.FullMethod
|
||||||
var reqCount, respCount int64 = 0, 0
|
var reqCount, respCount int64
|
||||||
var reqSize, respSize int = 0, 0
|
var reqSize, respSize int
|
||||||
var reqContent string
|
var reqContent string
|
||||||
switch _resp := resp.(type) {
|
switch _resp := resp.(type) {
|
||||||
case *pb.RangeResponse:
|
case *pb.RangeResponse:
|
||||||
@@ -152,15 +152,14 @@ func logUnaryRequestStats(ctx context.Context, lg *zap.Logger, info *grpc.UnaryS
|
|||||||
func logGenericRequestStats(lg *zap.Logger, startTime time.Time, duration time.Duration, remote string, responseType string,
|
func logGenericRequestStats(lg *zap.Logger, startTime time.Time, duration time.Duration, remote string, responseType string,
|
||||||
reqCount int64, reqSize int, respCount int64, respSize int, reqContent string) {
|
reqCount int64, reqSize int, respCount int64, respSize int, reqContent string) {
|
||||||
if lg == nil {
|
if lg == nil {
|
||||||
plog.Debugf(
|
plog.Debugf("start time = %v, "+
|
||||||
"start time = %v, " +
|
"time spent = %v, "+
|
||||||
"time spent = %v, " +
|
"remote = %s, "+
|
||||||
"remote = %s, " +
|
"response type = %s, "+
|
||||||
"response type = %s, " +
|
"request count = %d, "+
|
||||||
"request count = %d, " +
|
"request size = %d, "+
|
||||||
"request size = %d, " +
|
"response count = %d, "+
|
||||||
"response count = %d, " +
|
"response size = %d, "+
|
||||||
"response size = %d, " +
|
|
||||||
"request content = %s",
|
"request content = %s",
|
||||||
startTime, duration, remote, responseType, reqCount, reqSize, respCount, respSize, reqContent,
|
startTime, duration, remote, responseType, reqCount, reqSize, respCount, respSize, reqContent,
|
||||||
)
|
)
|
||||||
|
|||||||
183
vendor/github.com/grpc-ecosystem/go-grpc-middleware/chain.go
generated
vendored
Normal file
183
vendor/github.com/grpc-ecosystem/go-grpc-middleware/chain.go
generated
vendored
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
// Copyright 2016 Michal Witkowski. All Rights Reserved.
|
||||||
|
// See LICENSE for licensing terms.
|
||||||
|
|
||||||
|
// gRPC Server Interceptor chaining middleware.
|
||||||
|
|
||||||
|
package grpc_middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ChainUnaryServer creates a single interceptor out of a chain of many interceptors.
|
||||||
|
//
|
||||||
|
// Execution is done in left-to-right order, including passing of context.
|
||||||
|
// For example ChainUnaryServer(one, two, three) will execute one before two before three, and three
|
||||||
|
// will see context changes of one and two.
|
||||||
|
func ChainUnaryServer(interceptors ...grpc.UnaryServerInterceptor) grpc.UnaryServerInterceptor {
|
||||||
|
n := len(interceptors)
|
||||||
|
|
||||||
|
if n > 1 {
|
||||||
|
lastI := n - 1
|
||||||
|
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||||
|
var (
|
||||||
|
chainHandler grpc.UnaryHandler
|
||||||
|
curI int
|
||||||
|
)
|
||||||
|
|
||||||
|
chainHandler = func(currentCtx context.Context, currentReq interface{}) (interface{}, error) {
|
||||||
|
if curI == lastI {
|
||||||
|
return handler(currentCtx, currentReq)
|
||||||
|
}
|
||||||
|
curI++
|
||||||
|
resp, err := interceptors[curI](currentCtx, currentReq, info, chainHandler)
|
||||||
|
curI--
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return interceptors[0](ctx, req, info, chainHandler)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if n == 1 {
|
||||||
|
return interceptors[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// n == 0; Dummy interceptor maintained for backward compatibility to avoid returning nil.
|
||||||
|
return func(ctx context.Context, req interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||||
|
return handler(ctx, req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChainStreamServer creates a single interceptor out of a chain of many interceptors.
|
||||||
|
//
|
||||||
|
// Execution is done in left-to-right order, including passing of context.
|
||||||
|
// For example ChainUnaryServer(one, two, three) will execute one before two before three.
|
||||||
|
// If you want to pass context between interceptors, use WrapServerStream.
|
||||||
|
func ChainStreamServer(interceptors ...grpc.StreamServerInterceptor) grpc.StreamServerInterceptor {
|
||||||
|
n := len(interceptors)
|
||||||
|
|
||||||
|
if n > 1 {
|
||||||
|
lastI := n - 1
|
||||||
|
return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
|
||||||
|
var (
|
||||||
|
chainHandler grpc.StreamHandler
|
||||||
|
curI int
|
||||||
|
)
|
||||||
|
|
||||||
|
chainHandler = func(currentSrv interface{}, currentStream grpc.ServerStream) error {
|
||||||
|
if curI == lastI {
|
||||||
|
return handler(currentSrv, currentStream)
|
||||||
|
}
|
||||||
|
curI++
|
||||||
|
err := interceptors[curI](currentSrv, currentStream, info, chainHandler)
|
||||||
|
curI--
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return interceptors[0](srv, stream, info, chainHandler)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if n == 1 {
|
||||||
|
return interceptors[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// n == 0; Dummy interceptor maintained for backward compatibility to avoid returning nil.
|
||||||
|
return func(srv interface{}, stream grpc.ServerStream, _ *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
|
||||||
|
return handler(srv, stream)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChainUnaryClient creates a single interceptor out of a chain of many interceptors.
|
||||||
|
//
|
||||||
|
// Execution is done in left-to-right order, including passing of context.
|
||||||
|
// For example ChainUnaryClient(one, two, three) will execute one before two before three.
|
||||||
|
func ChainUnaryClient(interceptors ...grpc.UnaryClientInterceptor) grpc.UnaryClientInterceptor {
|
||||||
|
n := len(interceptors)
|
||||||
|
|
||||||
|
if n > 1 {
|
||||||
|
lastI := n - 1
|
||||||
|
return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
|
||||||
|
var (
|
||||||
|
chainHandler grpc.UnaryInvoker
|
||||||
|
curI int
|
||||||
|
)
|
||||||
|
|
||||||
|
chainHandler = func(currentCtx context.Context, currentMethod string, currentReq, currentRepl interface{}, currentConn *grpc.ClientConn, currentOpts ...grpc.CallOption) error {
|
||||||
|
if curI == lastI {
|
||||||
|
return invoker(currentCtx, currentMethod, currentReq, currentRepl, currentConn, currentOpts...)
|
||||||
|
}
|
||||||
|
curI++
|
||||||
|
err := interceptors[curI](currentCtx, currentMethod, currentReq, currentRepl, currentConn, chainHandler, currentOpts...)
|
||||||
|
curI--
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return interceptors[0](ctx, method, req, reply, cc, chainHandler, opts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if n == 1 {
|
||||||
|
return interceptors[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// n == 0; Dummy interceptor maintained for backward compatibility to avoid returning nil.
|
||||||
|
return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
|
||||||
|
return invoker(ctx, method, req, reply, cc, opts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChainStreamClient creates a single interceptor out of a chain of many interceptors.
|
||||||
|
//
|
||||||
|
// Execution is done in left-to-right order, including passing of context.
|
||||||
|
// For example ChainStreamClient(one, two, three) will execute one before two before three.
|
||||||
|
func ChainStreamClient(interceptors ...grpc.StreamClientInterceptor) grpc.StreamClientInterceptor {
|
||||||
|
n := len(interceptors)
|
||||||
|
|
||||||
|
if n > 1 {
|
||||||
|
lastI := n - 1
|
||||||
|
return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
|
||||||
|
var (
|
||||||
|
chainHandler grpc.Streamer
|
||||||
|
curI int
|
||||||
|
)
|
||||||
|
|
||||||
|
chainHandler = func(currentCtx context.Context, currentDesc *grpc.StreamDesc, currentConn *grpc.ClientConn, currentMethod string, currentOpts ...grpc.CallOption) (grpc.ClientStream, error) {
|
||||||
|
if curI == lastI {
|
||||||
|
return streamer(currentCtx, currentDesc, currentConn, currentMethod, currentOpts...)
|
||||||
|
}
|
||||||
|
curI++
|
||||||
|
stream, err := interceptors[curI](currentCtx, currentDesc, currentConn, currentMethod, chainHandler, currentOpts...)
|
||||||
|
curI--
|
||||||
|
return stream, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return interceptors[0](ctx, desc, cc, method, chainHandler, opts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if n == 1 {
|
||||||
|
return interceptors[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// n == 0; Dummy interceptor maintained for backward compatibility to avoid returning nil.
|
||||||
|
return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
|
||||||
|
return streamer(ctx, desc, cc, method, opts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chain creates a single interceptor out of a chain of many interceptors.
|
||||||
|
//
|
||||||
|
// WithUnaryServerChain is a grpc.Server config option that accepts multiple unary interceptors.
|
||||||
|
// Basically syntactic sugar.
|
||||||
|
func WithUnaryServerChain(interceptors ...grpc.UnaryServerInterceptor) grpc.ServerOption {
|
||||||
|
return grpc.UnaryInterceptor(ChainUnaryServer(interceptors...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithStreamServerChain is a grpc.Server config option that accepts multiple stream interceptors.
|
||||||
|
// Basically syntactic sugar.
|
||||||
|
func WithStreamServerChain(interceptors ...grpc.StreamServerInterceptor) grpc.ServerOption {
|
||||||
|
return grpc.StreamInterceptor(ChainStreamServer(interceptors...))
|
||||||
|
}
|
||||||
69
vendor/github.com/grpc-ecosystem/go-grpc-middleware/doc.go
generated
vendored
Normal file
69
vendor/github.com/grpc-ecosystem/go-grpc-middleware/doc.go
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
// Copyright 2016 Michal Witkowski. All Rights Reserved.
|
||||||
|
// See LICENSE for licensing terms.
|
||||||
|
|
||||||
|
/*
|
||||||
|
`grpc_middleware` is a collection of gRPC middleware packages: interceptors, helpers and tools.
|
||||||
|
|
||||||
|
Middleware
|
||||||
|
|
||||||
|
gRPC is a fantastic RPC middleware, which sees a lot of adoption in the Golang world. However, the
|
||||||
|
upstream gRPC codebase is relatively bare bones.
|
||||||
|
|
||||||
|
This package, and most of its child packages provides commonly needed middleware for gRPC:
|
||||||
|
client-side interceptors for retires, server-side interceptors for input validation and auth,
|
||||||
|
functions for chaining said interceptors, metadata convenience methods and more.
|
||||||
|
|
||||||
|
Chaining
|
||||||
|
|
||||||
|
By default, gRPC doesn't allow one to have more than one interceptor either on the client nor on
|
||||||
|
the server side. `grpc_middleware` provides convenient chaining methods
|
||||||
|
|
||||||
|
Simple way of turning a multiple interceptors into a single interceptor. Here's an example for
|
||||||
|
server chaining:
|
||||||
|
|
||||||
|
myServer := grpc.NewServer(
|
||||||
|
grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(loggingStream, monitoringStream, authStream)),
|
||||||
|
grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(loggingUnary, monitoringUnary, authUnary),
|
||||||
|
)
|
||||||
|
|
||||||
|
These interceptors will be executed from left to right: logging, monitoring and auth.
|
||||||
|
|
||||||
|
Here's an example for client side chaining:
|
||||||
|
|
||||||
|
clientConn, err = grpc.Dial(
|
||||||
|
address,
|
||||||
|
grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(monitoringClientUnary, retryUnary)),
|
||||||
|
grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(monitoringClientStream, retryStream)),
|
||||||
|
)
|
||||||
|
client = pb_testproto.NewTestServiceClient(clientConn)
|
||||||
|
resp, err := client.PingEmpty(s.ctx, &myservice.Request{Msg: "hello"})
|
||||||
|
|
||||||
|
These interceptors will be executed from left to right: monitoring and then retry logic.
|
||||||
|
|
||||||
|
The retry interceptor will call every interceptor that follows it whenever when a retry happens.
|
||||||
|
|
||||||
|
Writing Your Own
|
||||||
|
|
||||||
|
Implementing your own interceptor is pretty trivial: there are interfaces for that. But the interesting
|
||||||
|
bit exposing common data to handlers (and other middleware), similarly to HTTP Middleware design.
|
||||||
|
For example, you may want to pass the identity of the caller from the auth interceptor all the way
|
||||||
|
to the handling function.
|
||||||
|
|
||||||
|
For example, a client side interceptor example for auth looks like:
|
||||||
|
|
||||||
|
func FakeAuthUnaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||||
|
newCtx := context.WithValue(ctx, "user_id", "john@example.com")
|
||||||
|
return handler(newCtx, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
Unfortunately, it's not as easy for streaming RPCs. These have the `context.Context` embedded within
|
||||||
|
the `grpc.ServerStream` object. To pass values through context, a wrapper (`WrappedServerStream`) is
|
||||||
|
needed. For example:
|
||||||
|
|
||||||
|
func FakeAuthStreamingInterceptor(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
|
||||||
|
newStream := grpc_middleware.WrapServerStream(stream)
|
||||||
|
newStream.WrappedContext = context.WithValue(ctx, "user_id", "john@example.com")
|
||||||
|
return handler(srv, stream)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
package grpc_middleware
|
||||||
29
vendor/github.com/grpc-ecosystem/go-grpc-middleware/wrappers.go
generated
vendored
Normal file
29
vendor/github.com/grpc-ecosystem/go-grpc-middleware/wrappers.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2016 Michal Witkowski. All Rights Reserved.
|
||||||
|
// See LICENSE for licensing terms.
|
||||||
|
|
||||||
|
package grpc_middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WrappedServerStream is a thin wrapper around grpc.ServerStream that allows modifying context.
|
||||||
|
type WrappedServerStream struct {
|
||||||
|
grpc.ServerStream
|
||||||
|
// WrappedContext is the wrapper's own Context. You can assign it.
|
||||||
|
WrappedContext context.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
// Context returns the wrapper's WrappedContext, overwriting the nested grpc.ServerStream.Context()
|
||||||
|
func (w *WrappedServerStream) Context() context.Context {
|
||||||
|
return w.WrappedContext
|
||||||
|
}
|
||||||
|
|
||||||
|
// WrapServerStream returns a ServerStream that has the ability to overwrite context.
|
||||||
|
func WrapServerStream(stream grpc.ServerStream) *WrappedServerStream {
|
||||||
|
if existing, ok := stream.(*WrappedServerStream); ok {
|
||||||
|
return existing
|
||||||
|
}
|
||||||
|
return &WrappedServerStream{ServerStream: stream, WrappedContext: stream.Context()}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user