The mega cruft proxy PR (#974)

* the mega cruft proxy PR

* Rename broker id

* add protocol=grpc

* fix compilation breaks

* Add the tunnel broker to the network

* fix broker id

* continue to be backwards compatible in the protocol
This commit is contained in:
Asim Aslam
2019-11-25 16:31:43 +00:00
committed by GitHub
parent 252667398e
commit 080363e8c4
23 changed files with 595 additions and 196 deletions

View File

@@ -10,7 +10,6 @@ import (
"github.com/micro/go-micro/client/grpc"
"github.com/micro/go-micro/codec"
"github.com/micro/go-micro/config/options"
"github.com/micro/go-micro/errors"
"github.com/micro/go-micro/proxy"
"github.com/micro/go-micro/server"
)
@@ -62,8 +61,14 @@ func readLoop(r server.Request, s client.Stream) error {
}
}
func (p *Proxy) SendRequest(ctx context.Context, req client.Request, rsp client.Response) error {
return errors.InternalServerError("go.micro.proxy.grpc", "SendRequest is unsupported")
// ProcessMessage acts as a message exchange and forwards messages to ongoing topics
// TODO: should we look at p.Endpoint and only send to the local endpoint? probably
func (p *Proxy) ProcessMessage(ctx context.Context, msg server.Message) error {
// TODO: check that we're not broadcast storming by sending to the same topic
// that we're actually subscribed to
// directly publish to the local client
return p.Client.Publish(ctx, msg)
}
// ServeRequest honours the server.Proxy interface

View File

@@ -10,7 +10,6 @@ import (
"net/url"
"path"
"github.com/micro/go-micro/client"
"github.com/micro/go-micro/config/options"
"github.com/micro/go-micro/errors"
"github.com/micro/go-micro/proxy"
@@ -45,8 +44,69 @@ func getEndpoint(hdr map[string]string) string {
return ""
}
func (p *Proxy) SendRequest(ctx context.Context, req client.Request, rsp client.Response) error {
return errors.InternalServerError("go.micro.proxy.http", "SendRequest is unsupported")
func getTopic(hdr map[string]string) string {
ep := hdr["Micro-Topic"]
if len(ep) > 0 && ep[0] == '/' {
return ep
}
return "/" + hdr["Micro-Topic"]
}
// ProcessMessage handles incoming asynchronous messages
func (p *Proxy) ProcessMessage(ctx context.Context, msg server.Message) error {
if p.Endpoint == "" {
p.Endpoint = proxy.DefaultEndpoint
}
// get the header
hdr := msg.Header()
// get topic
// use /topic as endpoint
endpoint := getTopic(hdr)
// set the endpoint
if len(endpoint) == 0 {
endpoint = p.Endpoint
} else {
// add endpoint to backend
u, err := url.Parse(p.Endpoint)
if err != nil {
return errors.InternalServerError(msg.Topic(), err.Error())
}
u.Path = path.Join(u.Path, endpoint)
endpoint = u.String()
}
// send to backend
hreq, err := http.NewRequest("POST", endpoint, bytes.NewReader(msg.Body()))
if err != nil {
return errors.InternalServerError(msg.Topic(), err.Error())
}
// set the headers
for k, v := range hdr {
hreq.Header.Set(k, v)
}
// make the call
hrsp, err := http.DefaultClient.Do(hreq)
if err != nil {
return errors.InternalServerError(msg.Topic(), err.Error())
}
// read body
b, err := ioutil.ReadAll(hrsp.Body)
hrsp.Body.Close()
if err != nil {
return errors.InternalServerError(msg.Topic(), err.Error())
}
if hrsp.StatusCode != 200 {
return errors.New(msg.Topic(), string(b), int32(hrsp.StatusCode))
}
return nil
}
// ServeRequest honours the server.Router interface

View File

@@ -281,8 +281,34 @@ func (p *Proxy) watchRoutes() {
}
}
func (p *Proxy) SendRequest(ctx context.Context, req client.Request, rsp client.Response) error {
return errors.InternalServerError("go.micro.proxy", "SendRequest is unsupported")
// ProcessMessage acts as a message exchange and forwards messages to ongoing topics
// TODO: should we look at p.Endpoint and only send to the local endpoint? probably
func (p *Proxy) ProcessMessage(ctx context.Context, msg server.Message) error {
// TODO: check that we're not broadcast storming by sending to the same topic
// that we're actually subscribed to
log.Tracef("Received message for %s", msg.Topic())
var errors []string
// directly publish to the local client
if err := p.Client.Publish(ctx, msg); err != nil {
errors = append(errors, err.Error())
}
// publish to all links
for _, client := range p.Links {
if err := client.Publish(ctx, msg); err != nil {
errors = append(errors, err.Error())
}
}
if len(errors) == 0 {
return nil
}
// there is no error...muahaha
return fmt.Errorf("Message processing error: %s", strings.Join(errors, "\n"))
}
// ServeRequest honours the server.Router interface
@@ -302,6 +328,8 @@ func (p *Proxy) ServeRequest(ctx context.Context, req server.Request, rsp server
return errors.BadRequest("go.micro.proxy", "service name is blank")
}
log.Tracef("Received request for %s", service)
// are we network routing or local routing
if len(p.Links) == 0 {
local = true

View File

@@ -13,9 +13,9 @@ import (
// Proxy can be used as a proxy server for go-micro services
type Proxy interface {
options.Options
// SendRequest honours the client.Router interface
SendRequest(context.Context, client.Request, client.Response) error
// ServeRequest honours the server.Router interface
// ProcessMessage handles inbound messages
ProcessMessage(context.Context, server.Message) error
// ServeRequest handles inbound requests
ServeRequest(context.Context, server.Request, server.Response) error
}