Add wrapper implementation
This commit is contained in:
parent
4fa909a3c7
commit
fb172df0ce
@ -12,6 +12,7 @@ type options struct {
|
|||||||
broker broker.Broker
|
broker broker.Broker
|
||||||
registry registry.Registry
|
registry registry.Registry
|
||||||
transport transport.Transport
|
transport transport.Transport
|
||||||
|
wrappers []Wrapper
|
||||||
}
|
}
|
||||||
|
|
||||||
// Broker to be used for pub/sub
|
// Broker to be used for pub/sub
|
||||||
@ -48,3 +49,10 @@ func Transport(t transport.Transport) Option {
|
|||||||
o.transport = t
|
o.transport = t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Adds a Wrapper to a list of options passed into the client
|
||||||
|
func Wrap(w Wrapper) Option {
|
||||||
|
return func(o *options) {
|
||||||
|
o.wrappers = append(o.wrappers, w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -23,6 +23,8 @@ type rpcClient struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newRpcClient(opt ...Option) Client {
|
func newRpcClient(opt ...Option) Client {
|
||||||
|
var once sync.Once
|
||||||
|
|
||||||
opts := options{
|
opts := options{
|
||||||
codecs: make(map[string]CodecFunc),
|
codecs: make(map[string]CodecFunc),
|
||||||
}
|
}
|
||||||
@ -43,12 +45,19 @@ func newRpcClient(opt ...Option) Client {
|
|||||||
opts.broker = broker.DefaultBroker
|
opts.broker = broker.DefaultBroker
|
||||||
}
|
}
|
||||||
|
|
||||||
var once sync.Once
|
rc := &rpcClient{
|
||||||
|
|
||||||
return &rpcClient{
|
|
||||||
once: once,
|
once: once,
|
||||||
opts: opts,
|
opts: opts,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c := Client(rc)
|
||||||
|
|
||||||
|
// wrap in reverse
|
||||||
|
for i := len(opts.wrappers); i > 0; i-- {
|
||||||
|
c = opts.wrappers[i-1](c)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rpcClient) codecFunc(contentType string) (codecFunc, error) {
|
func (r *rpcClient) codecFunc(contentType string) (codecFunc, error) {
|
||||||
|
37
client/wrapper.go
Normal file
37
client/wrapper.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
Wrapper is a type of middleware for the go-micro client. It allows
|
||||||
|
the client to be "wrapped" so that requests and responses can be intercepted
|
||||||
|
to perform extra requirements such as auth, tracing, monitoring, logging, etc.
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"github.com/micro/go-micro/client"
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
type LogWrapper struct {
|
||||||
|
client.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *LogWrapper) Call(ctx context.Context, req Request, rsp interface{}) error {
|
||||||
|
log.Println("Making request to service " + req.Service() + " method " + req.Method())
|
||||||
|
return w.Client.Call(ctx, req, rsp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Wrapper(c client.Client) client.Client {
|
||||||
|
return &LogWrapper{c}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
c := client.NewClient(client.Wrap(Wrapper))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
package client
|
||||||
|
|
||||||
|
// Wrapper wraps a client and returns a client
|
||||||
|
type Wrapper func(Client) Client
|
87
examples/client/wrapper.go
Normal file
87
examples/client/wrapper.go
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
An example of how to use client.Wrapper as middleware
|
||||||
|
*/
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/micro/go-micro/client"
|
||||||
|
"github.com/micro/go-micro/cmd"
|
||||||
|
c "github.com/micro/go-micro/context"
|
||||||
|
example "github.com/micro/go-micro/examples/server/proto/example"
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
// log wrapper logs every time a request is made
|
||||||
|
type logWrapper struct {
|
||||||
|
client.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *logWrapper) Call(ctx context.Context, req client.Request, rsp interface{}) error {
|
||||||
|
md, _ := c.GetMetadata(ctx)
|
||||||
|
fmt.Printf("[Log Wrapper] ctx: %v service: %s method: %s\n", md, req.Service(), req.Method())
|
||||||
|
return l.Client.Call(ctx, req, rsp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// trace wrapper attaches a unique trace ID - timestamp
|
||||||
|
type traceWrapper struct {
|
||||||
|
client.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *traceWrapper) Call(ctx context.Context, req client.Request, rsp interface{}) error {
|
||||||
|
ctx = c.WithMetadata(ctx, map[string]string{
|
||||||
|
"X-Trace-Id": fmt.Sprintf("%d", time.Now().Unix()),
|
||||||
|
})
|
||||||
|
return t.Client.Call(ctx, req, rsp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements client.Wrapper as logWrapper
|
||||||
|
func logWrap(c client.Client) client.Client {
|
||||||
|
return &logWrapper{c}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements client.Wrapper as traceWrapper
|
||||||
|
func traceWrap(c client.Client) client.Client {
|
||||||
|
return &traceWrapper{c}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calls the example service
|
||||||
|
func call(i int) {
|
||||||
|
// Create new request to service go.micro.srv.example, method Example.Call
|
||||||
|
req := client.NewRequest("go.micro.srv.example", "Example.Call", &example.Request{
|
||||||
|
Name: "John",
|
||||||
|
})
|
||||||
|
|
||||||
|
// create context with metadata
|
||||||
|
ctx := c.WithMetadata(context.Background(), map[string]string{
|
||||||
|
"X-User-Id": "john",
|
||||||
|
"X-From-Id": "script",
|
||||||
|
})
|
||||||
|
|
||||||
|
rsp := &example.Response{}
|
||||||
|
|
||||||
|
// Call service
|
||||||
|
if err := client.Call(ctx, req, rsp); err != nil {
|
||||||
|
fmt.Println("call err: ", err, rsp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
cmd.Init()
|
||||||
|
|
||||||
|
// Wrap the default client
|
||||||
|
client.DefaultClient = logWrap(client.DefaultClient)
|
||||||
|
|
||||||
|
call(0)
|
||||||
|
|
||||||
|
// Wrap using client.Wrap option
|
||||||
|
client.DefaultClient = client.NewClient(
|
||||||
|
client.Wrap(traceWrap),
|
||||||
|
client.Wrap(logWrap),
|
||||||
|
)
|
||||||
|
|
||||||
|
call(1)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user