diff --git a/client/rpc_codec.go b/client/rpc_codec.go index 67959b6a..1a341a7c 100644 --- a/client/rpc_codec.go +++ b/client/rpc_codec.go @@ -3,6 +3,8 @@ package client import ( "bytes" errs "errors" + "fmt" + "strconv" "github.com/micro/go-micro/codec" "github.com/micro/go-micro/codec/json" @@ -112,6 +114,7 @@ func (c *rpcCodec) WriteRequest(req *request, body interface{}) error { Method: req.ServiceMethod, Type: codec.Request, Header: map[string]string{ + "X-Micro-Id": fmt.Sprintf("%d", req.Seq), "X-Micro-Service": req.Service, "X-Micro-Method": req.ServiceMethod, }, @@ -147,6 +150,21 @@ func (c *rpcCodec) ReadResponse(r *response, b interface{}) error { r.Seq = me.Id r.Error = me.Error + // check error in header + if len(me.Error) == 0 { + r.Error = me.Header["X-Micro-Error"] + } + + // check method in header + if len(me.Method) == 0 { + r.ServiceMethod = me.Header["X-Micro-Method"] + } + + if me.Id == 0 && len(me.Header["X-Micro-Id"]) > 0 { + id, _ := strconv.ParseInt(me.Header["X-Micro-Id"], 10, 64) + r.Seq = uint64(id) + } + if err != nil { return errors.InternalServerError("go.micro.client.codec", err.Error()) } diff --git a/cmd/cmd.go b/cmd/cmd.go index 5793b48f..12cbb874 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -27,6 +27,7 @@ import ( // selectors "github.com/micro/go-micro/selector" "github.com/micro/go-micro/selector/dns" + "github.com/micro/go-micro/selector/static" // transports "github.com/micro/go-micro/transport" @@ -180,6 +181,7 @@ var ( "default": selector.NewSelector, "dns": dns.NewSelector, "cache": selector.NewSelector, + "static": static.NewSelector, } DefaultServers = map[string]func(...server.Option) server.Server{ diff --git a/selector/static/static.go b/selector/static/static.go new file mode 100644 index 00000000..11c2c9cf --- /dev/null +++ b/selector/static/static.go @@ -0,0 +1,71 @@ +// Package static provides a static resolver which returns the name/ip passed in without any change +package static + +import ( + "net" + "strconv" + + "github.com/micro/go-micro/registry" + "github.com/micro/go-micro/selector" +) + +// staticSelector is a static selector +type staticSelector struct { + opts selector.Options +} + +func (s *staticSelector) Init(opts ...selector.Option) error { + for _, o := range opts { + o(&s.opts) + } + return nil +} + +func (s *staticSelector) Options() selector.Options { + return s.opts +} + +func (s *staticSelector) Select(service string, opts ...selector.SelectOption) (selector.Next, error) { + var port int + addr, pt, err := net.SplitHostPort(service) + if err != nil { + addr = service + port = 0 + } else { + port, _ = strconv.Atoi(pt) + } + + return func() (*registry.Node, error) { + return ®istry.Node{ + Id: service, + Address: addr, + Port: port, + }, nil + }, nil +} + +func (s *staticSelector) Mark(service string, node *registry.Node, err error) { + return +} + +func (s *staticSelector) Reset(service string) { + return +} + +func (s *staticSelector) Close() error { + return nil +} + +func (s *staticSelector) String() string { + return "static" +} + +func NewSelector(opts ...selector.Option) selector.Selector { + var options selector.Options + for _, o := range opts { + o(&options) + } + return &staticSelector{ + opts: options, + } +} diff --git a/server/rpc_codec.go b/server/rpc_codec.go index f19b2782..6afc4e4b 100644 --- a/server/rpc_codec.go +++ b/server/rpc_codec.go @@ -2,6 +2,8 @@ package server import ( "bytes" + "fmt" + "strconv" "github.com/micro/go-micro/codec" "github.com/micro/go-micro/codec/grpc" @@ -87,9 +89,17 @@ func (c *rpcCodec) ReadRequestHeader(r *request, first bool) error { m.Target = m.Header["X-Micro-Service"] m.Method = m.Header["X-Micro-Method"] + // set id + if len(m.Header["X-Micro-Id"]) > 0 { + id, _ := strconv.ParseInt(m.Header["X-Micro-Id"], 10, 64) + m.Id = uint64(id) + } + + // read header via codec err := c.codec.ReadHeader(&m, codec.Request) r.ServiceMethod = m.Method r.Seq = m.Id + return err } @@ -104,11 +114,16 @@ func (c *rpcCodec) WriteResponse(r *response, body interface{}, last bool) error Id: r.Seq, Error: r.Error, Type: codec.Response, - Header: map[string]string{}, + Header: map[string]string{ + "X-Micro-Id": fmt.Sprintf("%d", r.Seq), + "X-Micro-Method": r.ServiceMethod, + "X-Micro-Error": r.Error, + }, } if err := c.codec.Write(m, body); err != nil { c.buf.wbuf.Reset() m.Error = errors.Wrapf(err, "Unable to encode body").Error() + m.Header["X-Micro-Error"] = m.Error if err := c.codec.Write(m, nil); err != nil { return err }