Merge branch 'master' of github.com:micro/go-micro
This commit is contained in:
		
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,3 +1,7 @@ | ||||
| # Develop tools | ||||
| /.vscode/ | ||||
| /.idea/ | ||||
|  | ||||
| # Binaries for programs and plugins | ||||
| *.exe | ||||
| *.exe~ | ||||
|   | ||||
| @@ -32,5 +32,5 @@ Go Micro把分布式系统的各种细节抽象出来。下面是它的主要特 | ||||
|  | ||||
| ## 快速上手 | ||||
|  | ||||
| 更多关于架构、安装的资料可以查看[文档](https://micro.mu/docs/go-micro_cn.html)。 | ||||
| 更多关于架构、安装的资料可以查看[文档](https://micro.mu/docs/cn/)。 | ||||
|  | ||||
|   | ||||
| @@ -30,6 +30,7 @@ var ( | ||||
| 		"application/proto":        protoCodec{}, | ||||
| 		"application/protobuf":     protoCodec{}, | ||||
| 		"application/octet-stream": protoCodec{}, | ||||
| 		"application/grpc":         protoCodec{}, | ||||
| 		"application/grpc+json":    jsonCodec{}, | ||||
| 		"application/grpc+proto":   protoCodec{}, | ||||
| 		"application/grpc+bytes":   bytesCodec{}, | ||||
|   | ||||
| @@ -96,7 +96,15 @@ func (r *rpcClient) call(ctx context.Context, node *registry.Node, req Request, | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	c, err := r.pool.Get(address, transport.WithTimeout(opts.DialTimeout)) | ||||
| 	dOpts := []transport.DialOption{ | ||||
| 		transport.WithStream(), | ||||
| 	} | ||||
|  | ||||
| 	if opts.DialTimeout >= 0 { | ||||
| 		dOpts = append(dOpts, transport.WithTimeout(opts.DialTimeout)) | ||||
| 	} | ||||
|  | ||||
| 	c, err := r.pool.Get(address, dOpts...) | ||||
| 	if err != nil { | ||||
| 		return errors.InternalServerError("go.micro.client", "connection error: %v", err) | ||||
| 	} | ||||
|   | ||||
| @@ -44,6 +44,6 @@ Load the source into config | ||||
| // Create new config | ||||
| conf := config.NewConfig() | ||||
|  | ||||
| // Load file source | ||||
| // Load consul source | ||||
| conf.Load(consulSource) | ||||
| ``` | ||||
|   | ||||
							
								
								
									
										2
									
								
								config/source/env/README.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								config/source/env/README.md
									
									
									
									
										vendored
									
									
								
							| @@ -91,6 +91,6 @@ Load the source into config | ||||
| // Create new config | ||||
| conf := config.NewConfig() | ||||
|  | ||||
| // Load file source | ||||
| // Load env source | ||||
| conf.Load(src) | ||||
| ``` | ||||
|   | ||||
| @@ -42,6 +42,6 @@ Load the source into config | ||||
| // Create new config | ||||
| conf := config.NewConfig() | ||||
|  | ||||
| // Load file source | ||||
| // Load flag source | ||||
| conf.Load(flagSource) | ||||
| ``` | ||||
|   | ||||
| @@ -39,6 +39,6 @@ Load the source into config | ||||
| // Create new config | ||||
| conf := config.NewConfig() | ||||
|  | ||||
| // Load file source | ||||
| // Load memory source | ||||
| conf.Load(memorySource) | ||||
| ``` | ||||
|   | ||||
							
								
								
									
										1005
									
								
								network/default.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1005
									
								
								network/default.go
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										111
									
								
								network/handler/handler.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								network/handler/handler.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,111 @@ | ||||
| // Package handler implements network RPC handler | ||||
| package handler | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"sort" | ||||
|  | ||||
| 	"github.com/micro/go-micro/errors" | ||||
| 	"github.com/micro/go-micro/network" | ||||
| 	pbNet "github.com/micro/go-micro/network/proto" | ||||
| 	pbRtr "github.com/micro/go-micro/router/proto" | ||||
| ) | ||||
|  | ||||
| // Network implements network handler | ||||
| type Network struct { | ||||
| 	Network network.Network | ||||
| } | ||||
|  | ||||
| // ListRoutes returns a list of routing table routes | ||||
| func (n *Network) ListRoutes(ctx context.Context, req *pbRtr.Request, resp *pbRtr.ListResponse) error { | ||||
| 	routes, err := n.Network.Options().Router.Table().List() | ||||
| 	if err != nil { | ||||
| 		return errors.InternalServerError("go.micro.network", "failed to list routes: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	var respRoutes []*pbRtr.Route | ||||
| 	for _, route := range routes { | ||||
| 		respRoute := &pbRtr.Route{ | ||||
| 			Service: route.Service, | ||||
| 			Address: route.Address, | ||||
| 			Gateway: route.Gateway, | ||||
| 			Network: route.Network, | ||||
| 			Router:  route.Router, | ||||
| 			Link:    route.Link, | ||||
| 			Metric:  int64(route.Metric), | ||||
| 		} | ||||
| 		respRoutes = append(respRoutes, respRoute) | ||||
| 	} | ||||
|  | ||||
| 	resp.Routes = respRoutes | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // ListNodes returns a list of all accessible nodes in the network | ||||
| func (n *Network) ListNodes(ctx context.Context, req *pbNet.ListRequest, resp *pbNet.ListResponse) error { | ||||
| 	nodes := n.Network.Nodes() | ||||
|  | ||||
| 	var respNodes []*pbNet.Node | ||||
| 	for _, node := range nodes { | ||||
| 		respNode := &pbNet.Node{ | ||||
| 			Id:      node.Id(), | ||||
| 			Address: node.Address(), | ||||
| 		} | ||||
| 		respNodes = append(respNodes, respNode) | ||||
| 	} | ||||
|  | ||||
| 	resp.Nodes = respNodes | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Neighbourhood returns a list of immediate neighbours | ||||
| func (n *Network) Neighbourhood(ctx context.Context, req *pbNet.NeighbourhoodRequest, resp *pbNet.NeighbourhoodResponse) error { | ||||
| 	// extract the id of the node to query | ||||
| 	id := req.Id | ||||
| 	// if no id is passed, we assume local node | ||||
| 	if id == "" { | ||||
| 		id = n.Network.Id() | ||||
| 	} | ||||
|  | ||||
| 	// get all the nodes in the network | ||||
| 	nodes := n.Network.Nodes() | ||||
|  | ||||
| 	// sort the slice of nodes | ||||
| 	sort.Slice(nodes, func(i, j int) bool { return nodes[i].Id() <= nodes[j].Id() }) | ||||
| 	// find a node with a given id | ||||
| 	i := sort.Search(len(nodes), func(j int) bool { return nodes[j].Id() >= id }) | ||||
|  | ||||
| 	var neighbours []*pbNet.Node | ||||
| 	// collect all the nodes in the neighbourhood of the found node | ||||
| 	if i < len(nodes) && nodes[i].Id() == id { | ||||
| 		for _, neighbour := range nodes[i].Neighbourhood() { | ||||
| 			// don't return yourself in response | ||||
| 			if neighbour.Id() == n.Network.Id() { | ||||
| 				continue | ||||
| 			} | ||||
| 			pbNeighbour := &pbNet.Node{ | ||||
| 				Id:      neighbour.Id(), | ||||
| 				Address: neighbour.Address(), | ||||
| 			} | ||||
| 			neighbours = append(neighbours, pbNeighbour) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// requested neighbourhood node | ||||
| 	node := &pbNet.Node{ | ||||
| 		Id:      nodes[i].Id(), | ||||
| 		Address: nodes[i].Address(), | ||||
| 	} | ||||
|  | ||||
| 	// creaate neighbourhood answer | ||||
| 	neighbourhood := &pbNet.Neighbour{ | ||||
| 		Node:       node, | ||||
| 		Neighbours: neighbours, | ||||
| 	} | ||||
|  | ||||
| 	resp.Neighbourhood = neighbourhood | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
| @@ -1,2 +1,60 @@ | ||||
| // Package network is for creating internetworks | ||||
| package network | ||||
|  | ||||
| import ( | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/micro/go-micro/client" | ||||
| 	"github.com/micro/go-micro/server" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// DefaultName is default network name | ||||
| 	DefaultName = "go.micro" | ||||
| 	// DefaultAddress is default network address | ||||
| 	DefaultAddress = ":0" | ||||
| 	// ResolveTime defines time interval to periodically resolve network nodes | ||||
| 	ResolveTime = 1 * time.Minute | ||||
| 	// AnnounceTime defines time interval to periodically announce node neighbours | ||||
| 	AnnounceTime = 30 * time.Second | ||||
| 	// PruneTime defines time interval to periodically check nodes that need to be pruned | ||||
| 	// due to their not announcing their presence within this time interval | ||||
| 	PruneTime = 90 * time.Second | ||||
| ) | ||||
|  | ||||
| // Node is network node | ||||
| type Node interface { | ||||
| 	// Id is node id | ||||
| 	Id() string | ||||
| 	// Address is node bind address | ||||
| 	Address() string | ||||
| 	// Neighbourhood is node neighbourhood | ||||
| 	Neighbourhood() []Node | ||||
| 	// Network is the network node is in | ||||
| 	Network() Network | ||||
| } | ||||
|  | ||||
| // Network is micro network | ||||
| type Network interface { | ||||
| 	// Node is network node | ||||
| 	Node | ||||
| 	// Options returns the network options | ||||
| 	Options() Options | ||||
| 	// Name of the network | ||||
| 	Name() string | ||||
| 	// Connect starts the resolver and tunnel server | ||||
| 	Connect() error | ||||
| 	// Nodes returns list of network nodes | ||||
| 	Nodes() []Node | ||||
| 	// Close stops the tunnel and resolving | ||||
| 	Close() error | ||||
| 	// Client is micro client | ||||
| 	Client() client.Client | ||||
| 	// Server is micro server | ||||
| 	Server() server.Server | ||||
| } | ||||
|  | ||||
| // NewNetwork returns a new network interface | ||||
| func NewNetwork(opts ...Option) Network { | ||||
| 	return newNetwork(opts...) | ||||
| } | ||||
|   | ||||
							
								
								
									
										103
									
								
								network/options.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								network/options.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | ||||
| package network | ||||
|  | ||||
| import ( | ||||
| 	"github.com/google/uuid" | ||||
| 	"github.com/micro/go-micro/network/resolver" | ||||
| 	"github.com/micro/go-micro/network/resolver/registry" | ||||
| 	"github.com/micro/go-micro/proxy" | ||||
| 	"github.com/micro/go-micro/proxy/mucp" | ||||
| 	"github.com/micro/go-micro/router" | ||||
| 	"github.com/micro/go-micro/tunnel" | ||||
| ) | ||||
|  | ||||
| type Option func(*Options) | ||||
|  | ||||
| // Options configure network | ||||
| type Options struct { | ||||
| 	// Id of the node | ||||
| 	Id string | ||||
| 	// Name of the network | ||||
| 	Name string | ||||
| 	// Address to bind to | ||||
| 	Address string | ||||
| 	// Nodes is a list of seed nodes | ||||
| 	Nodes []string | ||||
| 	// Tunnel is network tunnel | ||||
| 	Tunnel tunnel.Tunnel | ||||
| 	// Router is network router | ||||
| 	Router router.Router | ||||
| 	// Proxy is network proxy | ||||
| 	Proxy proxy.Proxy | ||||
| 	// Resolver is network resolver | ||||
| 	Resolver resolver.Resolver | ||||
| } | ||||
|  | ||||
| // Id sets the id of the network node | ||||
| func Id(id string) Option { | ||||
| 	return func(o *Options) { | ||||
| 		o.Id = id | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Name sets the network name | ||||
| func Name(n string) Option { | ||||
| 	return func(o *Options) { | ||||
| 		o.Name = n | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Address sets the network address | ||||
| func Address(a string) Option { | ||||
| 	return func(o *Options) { | ||||
| 		o.Address = a | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Nodes is a list of seed nodes used along | ||||
| // with resolved node | ||||
| func Nodes(n ...string) Option { | ||||
| 	return func(o *Options) { | ||||
| 		o.Nodes = n | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Tunnel sets the network tunnel | ||||
| func Tunnel(t tunnel.Tunnel) Option { | ||||
| 	return func(o *Options) { | ||||
| 		o.Tunnel = t | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Router sets the network router | ||||
| func Router(r router.Router) Option { | ||||
| 	return func(o *Options) { | ||||
| 		o.Router = r | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Proxy sets the network proxy | ||||
| func Proxy(p proxy.Proxy) Option { | ||||
| 	return func(o *Options) { | ||||
| 		o.Proxy = p | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Resolver is the network resolver | ||||
| func Resolver(r resolver.Resolver) Option { | ||||
| 	return func(o *Options) { | ||||
| 		o.Resolver = r | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // DefaultOptions returns network default options | ||||
| func DefaultOptions() Options { | ||||
| 	return Options{ | ||||
| 		Id:       uuid.New().String(), | ||||
| 		Name:     DefaultName, | ||||
| 		Address:  DefaultAddress, | ||||
| 		Tunnel:   tunnel.NewTunnel(), | ||||
| 		Router:   router.DefaultRouter, | ||||
| 		Proxy:    mucp.NewProxy(), | ||||
| 		Resolver: ®istry.Resolver{}, | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										126
									
								
								network/proto/network.micro.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								network/proto/network.micro.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | ||||
| // Code generated by protoc-gen-micro. DO NOT EDIT. | ||||
| // source: network.proto | ||||
|  | ||||
| package go_micro_network | ||||
|  | ||||
| import ( | ||||
| 	fmt "fmt" | ||||
| 	proto "github.com/golang/protobuf/proto" | ||||
| 	proto1 "github.com/micro/go-micro/router/proto" | ||||
| 	math "math" | ||||
| ) | ||||
|  | ||||
| import ( | ||||
| 	context "context" | ||||
| 	client "github.com/micro/go-micro/client" | ||||
| 	server "github.com/micro/go-micro/server" | ||||
| ) | ||||
|  | ||||
| // Reference imports to suppress errors if they are not otherwise used. | ||||
| var _ = proto.Marshal | ||||
| var _ = fmt.Errorf | ||||
| var _ = math.Inf | ||||
|  | ||||
| // This is a compile-time assertion to ensure that this generated file | ||||
| // is compatible with the proto package it is being compiled against. | ||||
| // A compilation error at this line likely means your copy of the | ||||
| // proto package needs to be updated. | ||||
| const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package | ||||
|  | ||||
| // Reference imports to suppress errors if they are not otherwise used. | ||||
| var _ context.Context | ||||
| var _ client.Option | ||||
| var _ server.Option | ||||
|  | ||||
| // Client API for Network service | ||||
|  | ||||
| type NetworkService interface { | ||||
| 	ListRoutes(ctx context.Context, in *proto1.Request, opts ...client.CallOption) (*proto1.ListResponse, error) | ||||
| 	ListNodes(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) | ||||
| 	Neighbourhood(ctx context.Context, in *NeighbourhoodRequest, opts ...client.CallOption) (*NeighbourhoodResponse, error) | ||||
| } | ||||
|  | ||||
| type networkService struct { | ||||
| 	c    client.Client | ||||
| 	name string | ||||
| } | ||||
|  | ||||
| func NewNetworkService(name string, c client.Client) NetworkService { | ||||
| 	if c == nil { | ||||
| 		c = client.NewClient() | ||||
| 	} | ||||
| 	if len(name) == 0 { | ||||
| 		name = "go.micro.network" | ||||
| 	} | ||||
| 	return &networkService{ | ||||
| 		c:    c, | ||||
| 		name: name, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (c *networkService) ListRoutes(ctx context.Context, in *proto1.Request, opts ...client.CallOption) (*proto1.ListResponse, error) { | ||||
| 	req := c.c.NewRequest(c.name, "Network.ListRoutes", in) | ||||
| 	out := new(proto1.ListResponse) | ||||
| 	err := c.c.Call(ctx, req, out, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return out, nil | ||||
| } | ||||
|  | ||||
| func (c *networkService) ListNodes(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) { | ||||
| 	req := c.c.NewRequest(c.name, "Network.ListNodes", in) | ||||
| 	out := new(ListResponse) | ||||
| 	err := c.c.Call(ctx, req, out, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return out, nil | ||||
| } | ||||
|  | ||||
| func (c *networkService) Neighbourhood(ctx context.Context, in *NeighbourhoodRequest, opts ...client.CallOption) (*NeighbourhoodResponse, error) { | ||||
| 	req := c.c.NewRequest(c.name, "Network.Neighbourhood", in) | ||||
| 	out := new(NeighbourhoodResponse) | ||||
| 	err := c.c.Call(ctx, req, out, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return out, nil | ||||
| } | ||||
|  | ||||
| // Server API for Network service | ||||
|  | ||||
| type NetworkHandler interface { | ||||
| 	ListRoutes(context.Context, *proto1.Request, *proto1.ListResponse) error | ||||
| 	ListNodes(context.Context, *ListRequest, *ListResponse) error | ||||
| 	Neighbourhood(context.Context, *NeighbourhoodRequest, *NeighbourhoodResponse) error | ||||
| } | ||||
|  | ||||
| func RegisterNetworkHandler(s server.Server, hdlr NetworkHandler, opts ...server.HandlerOption) error { | ||||
| 	type network interface { | ||||
| 		ListRoutes(ctx context.Context, in *proto1.Request, out *proto1.ListResponse) error | ||||
| 		ListNodes(ctx context.Context, in *ListRequest, out *ListResponse) error | ||||
| 		Neighbourhood(ctx context.Context, in *NeighbourhoodRequest, out *NeighbourhoodResponse) error | ||||
| 	} | ||||
| 	type Network struct { | ||||
| 		network | ||||
| 	} | ||||
| 	h := &networkHandler{hdlr} | ||||
| 	return s.Handle(s.NewHandler(&Network{h}, opts...)) | ||||
| } | ||||
|  | ||||
| type networkHandler struct { | ||||
| 	NetworkHandler | ||||
| } | ||||
|  | ||||
| func (h *networkHandler) ListRoutes(ctx context.Context, in *proto1.Request, out *proto1.ListResponse) error { | ||||
| 	return h.NetworkHandler.ListRoutes(ctx, in, out) | ||||
| } | ||||
|  | ||||
| func (h *networkHandler) ListNodes(ctx context.Context, in *ListRequest, out *ListResponse) error { | ||||
| 	return h.NetworkHandler.ListNodes(ctx, in, out) | ||||
| } | ||||
|  | ||||
| func (h *networkHandler) Neighbourhood(ctx context.Context, in *NeighbourhoodRequest, out *NeighbourhoodResponse) error { | ||||
| 	return h.NetworkHandler.Neighbourhood(ctx, in, out) | ||||
| } | ||||
							
								
								
									
										438
									
								
								network/proto/network.pb.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										438
									
								
								network/proto/network.pb.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,438 @@ | ||||
| // Code generated by protoc-gen-go. DO NOT EDIT. | ||||
| // source: network.proto | ||||
|  | ||||
| package go_micro_network | ||||
|  | ||||
| import ( | ||||
| 	fmt "fmt" | ||||
| 	proto "github.com/golang/protobuf/proto" | ||||
| 	_ "github.com/micro/go-micro/router/proto" | ||||
| 	math "math" | ||||
| ) | ||||
|  | ||||
| // Reference imports to suppress errors if they are not otherwise used. | ||||
| var _ = proto.Marshal | ||||
| var _ = fmt.Errorf | ||||
| var _ = math.Inf | ||||
|  | ||||
| // This is a compile-time assertion to ensure that this generated file | ||||
| // is compatible with the proto package it is being compiled against. | ||||
| // A compilation error at this line likely means your copy of the | ||||
| // proto package needs to be updated. | ||||
| const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package | ||||
|  | ||||
| // Empty request | ||||
| type ListRequest struct { | ||||
| 	XXX_NoUnkeyedLiteral struct{} `json:"-"` | ||||
| 	XXX_unrecognized     []byte   `json:"-"` | ||||
| 	XXX_sizecache        int32    `json:"-"` | ||||
| } | ||||
|  | ||||
| func (m *ListRequest) Reset()         { *m = ListRequest{} } | ||||
| func (m *ListRequest) String() string { return proto.CompactTextString(m) } | ||||
| func (*ListRequest) ProtoMessage()    {} | ||||
| func (*ListRequest) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_8571034d60397816, []int{0} | ||||
| } | ||||
|  | ||||
| func (m *ListRequest) XXX_Unmarshal(b []byte) error { | ||||
| 	return xxx_messageInfo_ListRequest.Unmarshal(m, b) | ||||
| } | ||||
| func (m *ListRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	return xxx_messageInfo_ListRequest.Marshal(b, m, deterministic) | ||||
| } | ||||
| func (m *ListRequest) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_ListRequest.Merge(m, src) | ||||
| } | ||||
| func (m *ListRequest) XXX_Size() int { | ||||
| 	return xxx_messageInfo_ListRequest.Size(m) | ||||
| } | ||||
| func (m *ListRequest) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_ListRequest.DiscardUnknown(m) | ||||
| } | ||||
|  | ||||
| var xxx_messageInfo_ListRequest proto.InternalMessageInfo | ||||
|  | ||||
| // ListResponse is returned by ListNodes and ListNeighbours | ||||
| type ListResponse struct { | ||||
| 	Nodes                []*Node  `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"` | ||||
| 	XXX_NoUnkeyedLiteral struct{} `json:"-"` | ||||
| 	XXX_unrecognized     []byte   `json:"-"` | ||||
| 	XXX_sizecache        int32    `json:"-"` | ||||
| } | ||||
|  | ||||
| func (m *ListResponse) Reset()         { *m = ListResponse{} } | ||||
| func (m *ListResponse) String() string { return proto.CompactTextString(m) } | ||||
| func (*ListResponse) ProtoMessage()    {} | ||||
| func (*ListResponse) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_8571034d60397816, []int{1} | ||||
| } | ||||
|  | ||||
| func (m *ListResponse) XXX_Unmarshal(b []byte) error { | ||||
| 	return xxx_messageInfo_ListResponse.Unmarshal(m, b) | ||||
| } | ||||
| func (m *ListResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	return xxx_messageInfo_ListResponse.Marshal(b, m, deterministic) | ||||
| } | ||||
| func (m *ListResponse) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_ListResponse.Merge(m, src) | ||||
| } | ||||
| func (m *ListResponse) XXX_Size() int { | ||||
| 	return xxx_messageInfo_ListResponse.Size(m) | ||||
| } | ||||
| func (m *ListResponse) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_ListResponse.DiscardUnknown(m) | ||||
| } | ||||
|  | ||||
| var xxx_messageInfo_ListResponse proto.InternalMessageInfo | ||||
|  | ||||
| func (m *ListResponse) GetNodes() []*Node { | ||||
| 	if m != nil { | ||||
| 		return m.Nodes | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // NeighbourhoodRequest is sent to query node neighbourhood | ||||
| type NeighbourhoodRequest struct { | ||||
| 	Id                   string   `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` | ||||
| 	XXX_NoUnkeyedLiteral struct{} `json:"-"` | ||||
| 	XXX_unrecognized     []byte   `json:"-"` | ||||
| 	XXX_sizecache        int32    `json:"-"` | ||||
| } | ||||
|  | ||||
| func (m *NeighbourhoodRequest) Reset()         { *m = NeighbourhoodRequest{} } | ||||
| func (m *NeighbourhoodRequest) String() string { return proto.CompactTextString(m) } | ||||
| func (*NeighbourhoodRequest) ProtoMessage()    {} | ||||
| func (*NeighbourhoodRequest) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_8571034d60397816, []int{2} | ||||
| } | ||||
|  | ||||
| func (m *NeighbourhoodRequest) XXX_Unmarshal(b []byte) error { | ||||
| 	return xxx_messageInfo_NeighbourhoodRequest.Unmarshal(m, b) | ||||
| } | ||||
| func (m *NeighbourhoodRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	return xxx_messageInfo_NeighbourhoodRequest.Marshal(b, m, deterministic) | ||||
| } | ||||
| func (m *NeighbourhoodRequest) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_NeighbourhoodRequest.Merge(m, src) | ||||
| } | ||||
| func (m *NeighbourhoodRequest) XXX_Size() int { | ||||
| 	return xxx_messageInfo_NeighbourhoodRequest.Size(m) | ||||
| } | ||||
| func (m *NeighbourhoodRequest) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_NeighbourhoodRequest.DiscardUnknown(m) | ||||
| } | ||||
|  | ||||
| var xxx_messageInfo_NeighbourhoodRequest proto.InternalMessageInfo | ||||
|  | ||||
| func (m *NeighbourhoodRequest) GetId() string { | ||||
| 	if m != nil { | ||||
| 		return m.Id | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| // NeighbourhoodResponse contains node neighbourhood hierarchy | ||||
| type NeighbourhoodResponse struct { | ||||
| 	Neighbourhood        *Neighbour `protobuf:"bytes,1,opt,name=neighbourhood,proto3" json:"neighbourhood,omitempty"` | ||||
| 	XXX_NoUnkeyedLiteral struct{}   `json:"-"` | ||||
| 	XXX_unrecognized     []byte     `json:"-"` | ||||
| 	XXX_sizecache        int32      `json:"-"` | ||||
| } | ||||
|  | ||||
| func (m *NeighbourhoodResponse) Reset()         { *m = NeighbourhoodResponse{} } | ||||
| func (m *NeighbourhoodResponse) String() string { return proto.CompactTextString(m) } | ||||
| func (*NeighbourhoodResponse) ProtoMessage()    {} | ||||
| func (*NeighbourhoodResponse) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_8571034d60397816, []int{3} | ||||
| } | ||||
|  | ||||
| func (m *NeighbourhoodResponse) XXX_Unmarshal(b []byte) error { | ||||
| 	return xxx_messageInfo_NeighbourhoodResponse.Unmarshal(m, b) | ||||
| } | ||||
| func (m *NeighbourhoodResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	return xxx_messageInfo_NeighbourhoodResponse.Marshal(b, m, deterministic) | ||||
| } | ||||
| func (m *NeighbourhoodResponse) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_NeighbourhoodResponse.Merge(m, src) | ||||
| } | ||||
| func (m *NeighbourhoodResponse) XXX_Size() int { | ||||
| 	return xxx_messageInfo_NeighbourhoodResponse.Size(m) | ||||
| } | ||||
| func (m *NeighbourhoodResponse) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_NeighbourhoodResponse.DiscardUnknown(m) | ||||
| } | ||||
|  | ||||
| var xxx_messageInfo_NeighbourhoodResponse proto.InternalMessageInfo | ||||
|  | ||||
| func (m *NeighbourhoodResponse) GetNeighbourhood() *Neighbour { | ||||
| 	if m != nil { | ||||
| 		return m.Neighbourhood | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Node is network node | ||||
| type Node struct { | ||||
| 	// node ide | ||||
| 	Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` | ||||
| 	// node address | ||||
| 	Address              string   `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` | ||||
| 	XXX_NoUnkeyedLiteral struct{} `json:"-"` | ||||
| 	XXX_unrecognized     []byte   `json:"-"` | ||||
| 	XXX_sizecache        int32    `json:"-"` | ||||
| } | ||||
|  | ||||
| func (m *Node) Reset()         { *m = Node{} } | ||||
| func (m *Node) String() string { return proto.CompactTextString(m) } | ||||
| func (*Node) ProtoMessage()    {} | ||||
| func (*Node) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_8571034d60397816, []int{4} | ||||
| } | ||||
|  | ||||
| func (m *Node) XXX_Unmarshal(b []byte) error { | ||||
| 	return xxx_messageInfo_Node.Unmarshal(m, b) | ||||
| } | ||||
| func (m *Node) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	return xxx_messageInfo_Node.Marshal(b, m, deterministic) | ||||
| } | ||||
| func (m *Node) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_Node.Merge(m, src) | ||||
| } | ||||
| func (m *Node) XXX_Size() int { | ||||
| 	return xxx_messageInfo_Node.Size(m) | ||||
| } | ||||
| func (m *Node) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_Node.DiscardUnknown(m) | ||||
| } | ||||
|  | ||||
| var xxx_messageInfo_Node proto.InternalMessageInfo | ||||
|  | ||||
| func (m *Node) GetId() string { | ||||
| 	if m != nil { | ||||
| 		return m.Id | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| func (m *Node) GetAddress() string { | ||||
| 	if m != nil { | ||||
| 		return m.Address | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| // Connect is sent when the node connects to the network | ||||
| type Connect struct { | ||||
| 	// network mode | ||||
| 	Node                 *Node    `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` | ||||
| 	XXX_NoUnkeyedLiteral struct{} `json:"-"` | ||||
| 	XXX_unrecognized     []byte   `json:"-"` | ||||
| 	XXX_sizecache        int32    `json:"-"` | ||||
| } | ||||
|  | ||||
| func (m *Connect) Reset()         { *m = Connect{} } | ||||
| func (m *Connect) String() string { return proto.CompactTextString(m) } | ||||
| func (*Connect) ProtoMessage()    {} | ||||
| func (*Connect) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_8571034d60397816, []int{5} | ||||
| } | ||||
|  | ||||
| func (m *Connect) XXX_Unmarshal(b []byte) error { | ||||
| 	return xxx_messageInfo_Connect.Unmarshal(m, b) | ||||
| } | ||||
| func (m *Connect) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	return xxx_messageInfo_Connect.Marshal(b, m, deterministic) | ||||
| } | ||||
| func (m *Connect) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_Connect.Merge(m, src) | ||||
| } | ||||
| func (m *Connect) XXX_Size() int { | ||||
| 	return xxx_messageInfo_Connect.Size(m) | ||||
| } | ||||
| func (m *Connect) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_Connect.DiscardUnknown(m) | ||||
| } | ||||
|  | ||||
| var xxx_messageInfo_Connect proto.InternalMessageInfo | ||||
|  | ||||
| func (m *Connect) GetNode() *Node { | ||||
| 	if m != nil { | ||||
| 		return m.Node | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Close is sent when the node disconnects from the network | ||||
| type Close struct { | ||||
| 	// network node | ||||
| 	Node                 *Node    `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` | ||||
| 	XXX_NoUnkeyedLiteral struct{} `json:"-"` | ||||
| 	XXX_unrecognized     []byte   `json:"-"` | ||||
| 	XXX_sizecache        int32    `json:"-"` | ||||
| } | ||||
|  | ||||
| func (m *Close) Reset()         { *m = Close{} } | ||||
| func (m *Close) String() string { return proto.CompactTextString(m) } | ||||
| func (*Close) ProtoMessage()    {} | ||||
| func (*Close) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_8571034d60397816, []int{6} | ||||
| } | ||||
|  | ||||
| func (m *Close) XXX_Unmarshal(b []byte) error { | ||||
| 	return xxx_messageInfo_Close.Unmarshal(m, b) | ||||
| } | ||||
| func (m *Close) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	return xxx_messageInfo_Close.Marshal(b, m, deterministic) | ||||
| } | ||||
| func (m *Close) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_Close.Merge(m, src) | ||||
| } | ||||
| func (m *Close) XXX_Size() int { | ||||
| 	return xxx_messageInfo_Close.Size(m) | ||||
| } | ||||
| func (m *Close) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_Close.DiscardUnknown(m) | ||||
| } | ||||
|  | ||||
| var xxx_messageInfo_Close proto.InternalMessageInfo | ||||
|  | ||||
| func (m *Close) GetNode() *Node { | ||||
| 	if m != nil { | ||||
| 		return m.Node | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Solicit is sent when requesting route advertisement from the network nodes | ||||
| type Solicit struct { | ||||
| 	// network node | ||||
| 	Node                 *Node    `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` | ||||
| 	XXX_NoUnkeyedLiteral struct{} `json:"-"` | ||||
| 	XXX_unrecognized     []byte   `json:"-"` | ||||
| 	XXX_sizecache        int32    `json:"-"` | ||||
| } | ||||
|  | ||||
| func (m *Solicit) Reset()         { *m = Solicit{} } | ||||
| func (m *Solicit) String() string { return proto.CompactTextString(m) } | ||||
| func (*Solicit) ProtoMessage()    {} | ||||
| func (*Solicit) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_8571034d60397816, []int{7} | ||||
| } | ||||
|  | ||||
| func (m *Solicit) XXX_Unmarshal(b []byte) error { | ||||
| 	return xxx_messageInfo_Solicit.Unmarshal(m, b) | ||||
| } | ||||
| func (m *Solicit) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	return xxx_messageInfo_Solicit.Marshal(b, m, deterministic) | ||||
| } | ||||
| func (m *Solicit) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_Solicit.Merge(m, src) | ||||
| } | ||||
| func (m *Solicit) XXX_Size() int { | ||||
| 	return xxx_messageInfo_Solicit.Size(m) | ||||
| } | ||||
| func (m *Solicit) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_Solicit.DiscardUnknown(m) | ||||
| } | ||||
|  | ||||
| var xxx_messageInfo_Solicit proto.InternalMessageInfo | ||||
|  | ||||
| func (m *Solicit) GetNode() *Node { | ||||
| 	if m != nil { | ||||
| 		return m.Node | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Neighbour is used to nnounce node neighbourhood | ||||
| type Neighbour struct { | ||||
| 	// network node | ||||
| 	Node *Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` | ||||
| 	// neighbours | ||||
| 	Neighbours           []*Node  `protobuf:"bytes,3,rep,name=neighbours,proto3" json:"neighbours,omitempty"` | ||||
| 	XXX_NoUnkeyedLiteral struct{} `json:"-"` | ||||
| 	XXX_unrecognized     []byte   `json:"-"` | ||||
| 	XXX_sizecache        int32    `json:"-"` | ||||
| } | ||||
|  | ||||
| func (m *Neighbour) Reset()         { *m = Neighbour{} } | ||||
| func (m *Neighbour) String() string { return proto.CompactTextString(m) } | ||||
| func (*Neighbour) ProtoMessage()    {} | ||||
| func (*Neighbour) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_8571034d60397816, []int{8} | ||||
| } | ||||
|  | ||||
| func (m *Neighbour) XXX_Unmarshal(b []byte) error { | ||||
| 	return xxx_messageInfo_Neighbour.Unmarshal(m, b) | ||||
| } | ||||
| func (m *Neighbour) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	return xxx_messageInfo_Neighbour.Marshal(b, m, deterministic) | ||||
| } | ||||
| func (m *Neighbour) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_Neighbour.Merge(m, src) | ||||
| } | ||||
| func (m *Neighbour) XXX_Size() int { | ||||
| 	return xxx_messageInfo_Neighbour.Size(m) | ||||
| } | ||||
| func (m *Neighbour) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_Neighbour.DiscardUnknown(m) | ||||
| } | ||||
|  | ||||
| var xxx_messageInfo_Neighbour proto.InternalMessageInfo | ||||
|  | ||||
| func (m *Neighbour) GetNode() *Node { | ||||
| 	if m != nil { | ||||
| 		return m.Node | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (m *Neighbour) GetNeighbours() []*Node { | ||||
| 	if m != nil { | ||||
| 		return m.Neighbours | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func init() { | ||||
| 	proto.RegisterType((*ListRequest)(nil), "go.micro.network.ListRequest") | ||||
| 	proto.RegisterType((*ListResponse)(nil), "go.micro.network.ListResponse") | ||||
| 	proto.RegisterType((*NeighbourhoodRequest)(nil), "go.micro.network.NeighbourhoodRequest") | ||||
| 	proto.RegisterType((*NeighbourhoodResponse)(nil), "go.micro.network.NeighbourhoodResponse") | ||||
| 	proto.RegisterType((*Node)(nil), "go.micro.network.Node") | ||||
| 	proto.RegisterType((*Connect)(nil), "go.micro.network.Connect") | ||||
| 	proto.RegisterType((*Close)(nil), "go.micro.network.Close") | ||||
| 	proto.RegisterType((*Solicit)(nil), "go.micro.network.Solicit") | ||||
| 	proto.RegisterType((*Neighbour)(nil), "go.micro.network.Neighbour") | ||||
| } | ||||
|  | ||||
| func init() { proto.RegisterFile("network.proto", fileDescriptor_8571034d60397816) } | ||||
|  | ||||
| var fileDescriptor_8571034d60397816 = []byte{ | ||||
| 	// 360 bytes of a gzipped FileDescriptorProto | ||||
| 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0x41, 0x4f, 0xf2, 0x40, | ||||
| 	0x10, 0xfd, 0x28, 0xf0, 0x35, 0x0c, 0x1f, 0x5f, 0xcc, 0x46, 0x4d, 0x53, 0x83, 0x21, 0x7b, 0x40, | ||||
| 	0x62, 0xb4, 0x18, 0x08, 0x9e, 0xbc, 0x18, 0x0e, 0x5e, 0x08, 0x87, 0x7a, 0xf3, 0x66, 0xbb, 0x9b, | ||||
| 	0xb2, 0x11, 0x3a, 0xb8, 0xbb, 0x8d, 0x7f, 0xc0, 0x1f, 0x6e, 0xba, 0x5d, 0xb0, 0x80, 0x60, 0xb8, | ||||
| 	0x75, 0xe6, 0xbd, 0x37, 0x6f, 0xa7, 0xfb, 0x16, 0x5a, 0x29, 0xd7, 0x1f, 0x28, 0xdf, 0x82, 0xa5, | ||||
| 	0x44, 0x8d, 0xe4, 0x24, 0xc1, 0x60, 0x21, 0x62, 0x89, 0x81, 0xed, 0xfb, 0xc3, 0x44, 0xe8, 0x59, | ||||
| 	0x16, 0x05, 0x31, 0x2e, 0xfa, 0x06, 0xe9, 0x27, 0x78, 0x5b, 0x7c, 0x48, 0xcc, 0x34, 0x97, 0x7d, | ||||
| 	0xa3, 0xb4, 0x45, 0x31, 0x86, 0xb6, 0xa0, 0x39, 0x11, 0x4a, 0x87, 0xfc, 0x3d, 0xe3, 0x4a, 0xd3, | ||||
| 	0x07, 0xf8, 0x57, 0x94, 0x6a, 0x89, 0xa9, 0xe2, 0xe4, 0x06, 0xea, 0x29, 0x32, 0xae, 0xbc, 0x4a, | ||||
| 	0xa7, 0xda, 0x6b, 0x0e, 0xce, 0x83, 0x6d, 0xd7, 0x60, 0x8a, 0x8c, 0x87, 0x05, 0x89, 0x76, 0xe1, | ||||
| 	0x74, 0xca, 0x45, 0x32, 0x8b, 0x30, 0x93, 0x33, 0x44, 0x66, 0xa7, 0x92, 0xff, 0xe0, 0x08, 0xe6, | ||||
| 	0x55, 0x3a, 0x95, 0x5e, 0x23, 0x74, 0x04, 0xa3, 0x2f, 0x70, 0xb6, 0xc5, 0xb3, 0x76, 0x8f, 0xf9, | ||||
| 	0x96, 0x25, 0xc0, 0x68, 0x9a, 0x83, 0x8b, 0x1f, 0x6c, 0x57, 0xb4, 0x70, 0x53, 0x41, 0xef, 0xa0, | ||||
| 	0x96, 0x1f, 0x69, 0xdb, 0x93, 0x78, 0xe0, 0xbe, 0x32, 0x26, 0xb9, 0x52, 0x9e, 0x63, 0x9a, 0xab, | ||||
| 	0x92, 0x8e, 0xc0, 0x1d, 0x63, 0x9a, 0xf2, 0x58, 0x93, 0x6b, 0xa8, 0xe5, 0x9b, 0x58, 0xdb, 0x7d, | ||||
| 	0xdb, 0x1a, 0x0e, 0x1d, 0x42, 0x7d, 0x3c, 0x47, 0xc5, 0x8f, 0x12, 0x8d, 0xc0, 0x7d, 0xc6, 0xb9, | ||||
| 	0x88, 0xc5, 0x71, 0x5e, 0x08, 0x8d, 0xf5, 0xc2, 0xc7, 0x08, 0xc9, 0x3d, 0xc0, 0xfa, 0xf7, 0x28, | ||||
| 	0xaf, 0x7a, 0xf0, 0x12, 0x4b, 0xcc, 0xc1, 0xa7, 0x03, 0xee, 0xb4, 0x00, 0xc9, 0x13, 0x80, 0xc9, | ||||
| 	0x44, 0x1e, 0x1b, 0x45, 0xbc, 0x6f, 0xb5, 0x0d, 0x92, 0xbd, 0x65, 0xbf, 0xbd, 0x83, 0x94, 0xa3, | ||||
| 	0x44, 0xff, 0x90, 0x09, 0x34, 0xf2, 0x4e, 0x6e, 0xa6, 0x48, 0x7b, 0xf7, 0x14, 0xa5, 0x20, 0xfa, | ||||
| 	0x97, 0xfb, 0xe0, 0xf5, 0xb4, 0x08, 0x5a, 0x1b, 0x21, 0x22, 0xdd, 0x03, 0x29, 0x29, 0xa5, 0xd1, | ||||
| 	0xbf, 0xfa, 0x95, 0xb7, 0xf2, 0x88, 0xfe, 0x9a, 0x47, 0x32, 0xfc, 0x0a, 0x00, 0x00, 0xff, 0xff, | ||||
| 	0x59, 0xcf, 0xab, 0xb5, 0x7c, 0x03, 0x00, 0x00, | ||||
| } | ||||
							
								
								
									
										64
									
								
								network/proto/network.proto
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								network/proto/network.proto
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| syntax = "proto3"; | ||||
|  | ||||
| package go.micro.network; | ||||
|  | ||||
| import "github.com/micro/go-micro/router/proto/router.proto"; | ||||
|  | ||||
| // Network service is usesd to gain visibility into networks | ||||
| service Network { | ||||
|         rpc ListRoutes(go.micro.router.Request) returns (go.micro.router.ListResponse) {}; | ||||
|         rpc ListNodes(ListRequest) returns (ListResponse) {}; | ||||
|         rpc Neighbourhood(NeighbourhoodRequest) returns (NeighbourhoodResponse) {}; | ||||
| } | ||||
|  | ||||
| // Empty request | ||||
| message ListRequest {} | ||||
|  | ||||
| // ListResponse is returned by ListNodes and ListNeighbours | ||||
| message ListResponse { | ||||
| 	repeated Node nodes = 1; | ||||
| } | ||||
|  | ||||
| // NeighbourhoodRequest is sent to query node neighbourhood | ||||
| message NeighbourhoodRequest { | ||||
|         string id = 1; | ||||
| } | ||||
|  | ||||
| // NeighbourhoodResponse contains node neighbourhood hierarchy | ||||
| message NeighbourhoodResponse { | ||||
|         Neighbour neighbourhood = 1; | ||||
| } | ||||
|  | ||||
| // Node is network node | ||||
| message Node { | ||||
|         // node ide | ||||
|         string id = 1; | ||||
|         // node address | ||||
|         string address = 2; | ||||
| } | ||||
|  | ||||
| // Connect is sent when the node connects to the network | ||||
| message Connect { | ||||
|         // network mode | ||||
|         Node node = 1; | ||||
| } | ||||
|  | ||||
| // Close is sent when the node disconnects from the network | ||||
| message Close { | ||||
|         // network node | ||||
|         Node node = 1; | ||||
| } | ||||
|  | ||||
| // Solicit is sent when requesting route advertisement from the network nodes | ||||
| message Solicit { | ||||
|         // network node | ||||
|         Node node = 1; | ||||
| } | ||||
|  | ||||
| // Neighbour is used to nnounce node neighbourhood | ||||
| message Neighbour { | ||||
|         // network node | ||||
|         Node node = 1; | ||||
|         // neighbours | ||||
|         repeated Node neighbours = 3; | ||||
| } | ||||
| @@ -8,6 +8,7 @@ import ( | ||||
| 	"github.com/micro/go-micro/network/resolver" | ||||
| ) | ||||
|  | ||||
| // Resolver is a DNS network resolve | ||||
| type Resolver struct{} | ||||
|  | ||||
| // Resolve assumes ID is a domain name e.g micro.mu | ||||
|   | ||||
| @@ -10,6 +10,7 @@ import ( | ||||
| 	"github.com/micro/go-micro/network/resolver" | ||||
| ) | ||||
|  | ||||
| // Resolver is a HTTP network resolver | ||||
| type Resolver struct { | ||||
| 	// If not set, defaults to http | ||||
| 	Proto string | ||||
|   | ||||
| @@ -6,6 +6,7 @@ import ( | ||||
| 	"github.com/micro/go-micro/registry" | ||||
| ) | ||||
|  | ||||
| // Resolver is a registry network resolver | ||||
| type Resolver struct { | ||||
| 	// Registry is the registry to use otherwise we use the defaul | ||||
| 	Registry registry.Registry | ||||
|   | ||||
| @@ -5,7 +5,7 @@ package resolver | ||||
| // via the name to connect to. This is done based on Network.Name(). | ||||
| // Before we can be part of any network, we have to connect to it. | ||||
| type Resolver interface { | ||||
| 	// Resolve returns a list of addresses for an name | ||||
| 	// Resolve returns a list of addresses for a name | ||||
| 	Resolve(name string) ([]*Record, error) | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										125
									
								
								plugin/default.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								plugin/default.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,125 @@ | ||||
| // Package plugin provides the ability to load plugins | ||||
| package plugin | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
| 	"path/filepath" | ||||
| 	pg "plugin" | ||||
| 	"strings" | ||||
| 	"text/template" | ||||
|  | ||||
| 	"github.com/micro/go-micro/broker" | ||||
| 	"github.com/micro/go-micro/client" | ||||
| 	"github.com/micro/go-micro/client/selector" | ||||
| 	"github.com/micro/go-micro/config/cmd" | ||||
| 	"github.com/micro/go-micro/registry" | ||||
| 	"github.com/micro/go-micro/server" | ||||
| 	"github.com/micro/go-micro/transport" | ||||
| ) | ||||
|  | ||||
| type plugin struct{} | ||||
|  | ||||
| // Init sets up the plugin | ||||
| func (p *plugin) Init(c *Config) error { | ||||
| 	switch c.Type { | ||||
| 	case "broker": | ||||
| 		pg, ok := c.NewFunc.(func(...broker.Option) broker.Broker) | ||||
| 		if !ok { | ||||
| 			return fmt.Errorf("Invalid plugin %s", c.Name) | ||||
| 		} | ||||
| 		cmd.DefaultBrokers[c.Name] = pg | ||||
| 	case "client": | ||||
| 		pg, ok := c.NewFunc.(func(...client.Option) client.Client) | ||||
| 		if !ok { | ||||
| 			return fmt.Errorf("Invalid plugin %s", c.Name) | ||||
| 		} | ||||
| 		cmd.DefaultClients[c.Name] = pg | ||||
| 	case "registry": | ||||
| 		pg, ok := c.NewFunc.(func(...registry.Option) registry.Registry) | ||||
| 		if !ok { | ||||
| 			return fmt.Errorf("Invalid plugin %s", c.Name) | ||||
| 		} | ||||
| 		cmd.DefaultRegistries[c.Name] = pg | ||||
|  | ||||
| 	case "selector": | ||||
| 		pg, ok := c.NewFunc.(func(...selector.Option) selector.Selector) | ||||
| 		if !ok { | ||||
| 			return fmt.Errorf("Invalid plugin %s", c.Name) | ||||
| 		} | ||||
| 		cmd.DefaultSelectors[c.Name] = pg | ||||
| 	case "server": | ||||
| 		pg, ok := c.NewFunc.(func(...server.Option) server.Server) | ||||
| 		if !ok { | ||||
| 			return fmt.Errorf("Invalid plugin %s", c.Name) | ||||
| 		} | ||||
| 		cmd.DefaultServers[c.Name] = pg | ||||
| 	case "transport": | ||||
| 		pg, ok := c.NewFunc.(func(...transport.Option) transport.Transport) | ||||
| 		if !ok { | ||||
| 			return fmt.Errorf("Invalid plugin %s", c.Name) | ||||
| 		} | ||||
| 		cmd.DefaultTransports[c.Name] = pg | ||||
| 	default: | ||||
| 		return fmt.Errorf("Unknown plugin type: %s for %s", c.Type, c.Name) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Load loads a plugin created with `go build -buildmode=plugin` | ||||
| func (p *plugin) Load(path string) (*Config, error) { | ||||
| 	plugin, err := pg.Open(path) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	s, err := plugin.Lookup("Plugin") | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	pl, ok := s.(*Config) | ||||
| 	if !ok { | ||||
| 		return nil, errors.New("could not cast Plugin object") | ||||
| 	} | ||||
| 	return pl, nil | ||||
| } | ||||
|  | ||||
| // Generate creates a go file at the specified path. | ||||
| // You must use `go build -buildmode=plugin`to build it. | ||||
| func (p *plugin) Generate(path string, c *Config) error { | ||||
| 	f, err := os.Create(path) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer f.Close() | ||||
| 	t, err := template.New(c.Name).Parse(tmpl) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return t.Execute(f, c) | ||||
| } | ||||
|  | ||||
| // Build generates a dso plugin using the go command `go build -buildmode=plugin` | ||||
| func (p *plugin) Build(path string, c *Config) error { | ||||
| 	path = strings.TrimSuffix(path, ".so") | ||||
|  | ||||
| 	// create go file in tmp path | ||||
| 	temp := os.TempDir() | ||||
| 	base := filepath.Base(path) | ||||
| 	goFile := filepath.Join(temp, base+".go") | ||||
|  | ||||
| 	// generate .go file | ||||
| 	if err := p.Generate(goFile, c); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	// remove .go file | ||||
| 	defer os.Remove(goFile) | ||||
|  | ||||
| 	if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil && !os.IsExist(err) { | ||||
| 		return fmt.Errorf("Failed to create dir %s: %v", filepath.Dir(path), err) | ||||
| 	} | ||||
| 	cmd := exec.Command("go", "build", "-buildmode=plugin", "-o", path+".so", goFile) | ||||
| 	return cmd.Run() | ||||
| } | ||||
							
								
								
									
										46
									
								
								plugin/plugin.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								plugin/plugin.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| // Package plugin provides the ability to load plugins | ||||
| package plugin | ||||
|  | ||||
| // Plugin is a plugin loaded from a file | ||||
| type Plugin interface { | ||||
| 	// Initialise a plugin with the config | ||||
| 	Init(c *Config) error | ||||
| 	// Load loads a .so plugin at the given path | ||||
| 	Load(path string) (*Config, error) | ||||
| 	// Build a .so plugin with config at the path specified | ||||
| 	Build(path string, c *Config) error | ||||
| } | ||||
|  | ||||
| // Config is the plugin config | ||||
| type Config struct { | ||||
| 	// Name of the plugin e.g rabbitmq | ||||
| 	Name string | ||||
| 	// Type of the plugin e.g broker | ||||
| 	Type string | ||||
| 	// Path specifies the import path | ||||
| 	Path string | ||||
| 	// NewFunc creates an instance of the plugin | ||||
| 	NewFunc interface{} | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	// Default plugin loader | ||||
| 	DefaultPlugin = NewPlugin() | ||||
| ) | ||||
|  | ||||
| // NewPlugin creates a new plugin interface | ||||
| func NewPlugin() Plugin { | ||||
| 	return &plugin{} | ||||
| } | ||||
|  | ||||
| func Build(path string, c *Config) error { | ||||
| 	return DefaultPlugin.Build(path, c) | ||||
| } | ||||
|  | ||||
| func Load(path string) (*Config, error) { | ||||
| 	return DefaultPlugin.Load(path) | ||||
| } | ||||
|  | ||||
| func Init(c *Config) error { | ||||
| 	return DefaultPlugin.Init(c) | ||||
| } | ||||
							
								
								
									
										20
									
								
								plugin/template.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								plugin/template.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| package plugin | ||||
|  | ||||
| var ( | ||||
| 	tmpl = ` | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"github.com/micro/go-micro/plugin" | ||||
|  | ||||
| 	"{{.Path}}" | ||||
| ) | ||||
|  | ||||
| var Plugin = plugin.Config{ | ||||
| 	Name: "{{.Name}}", | ||||
| 	Type: "{{.Type}}", | ||||
| 	Path: "{{.Path}}", | ||||
| 	NewFunc: {{.Name}}.{{.NewFunc}}, | ||||
| } | ||||
| ` | ||||
| ) | ||||
| @@ -161,9 +161,6 @@ func (p *Proxy) manageRouteCache(route router.Route, action string) error { | ||||
| 		} | ||||
| 		p.Routes[route.Service][route.Hash()] = route | ||||
| 	case "delete": | ||||
| 		if _, ok := p.Routes[route.Service]; !ok { | ||||
| 			return fmt.Errorf("route not found") | ||||
| 		} | ||||
| 		delete(p.Routes[route.Service], route.Hash()) | ||||
| 	default: | ||||
| 		return fmt.Errorf("unknown action: %s", action) | ||||
| @@ -219,6 +216,10 @@ func (p *Proxy) ServeRequest(ctx context.Context, req server.Request, rsp server | ||||
| 	// endpoint to call | ||||
| 	endpoint := req.Endpoint() | ||||
|  | ||||
| 	if len(service) == 0 { | ||||
| 		return errors.BadRequest("go.micro.proxy", "service name is blank") | ||||
| 	} | ||||
|  | ||||
| 	// are we network routing or local routing | ||||
| 	if len(p.Links) == 0 { | ||||
| 		local = true | ||||
|   | ||||
							
								
								
									
										76
									
								
								registry/handler/handler.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								registry/handler/handler.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| package handler | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
|  | ||||
| 	"github.com/micro/go-micro/errors" | ||||
| 	"github.com/micro/go-micro/registry" | ||||
| 	pb "github.com/micro/go-micro/registry/proto" | ||||
| 	"github.com/micro/go-micro/registry/service" | ||||
| ) | ||||
|  | ||||
| type Registry struct { | ||||
| 	// internal registry | ||||
| 	Registry registry.Registry | ||||
| } | ||||
|  | ||||
| func (r *Registry) GetService(ctx context.Context, req *pb.GetRequest, rsp *pb.GetResponse) error { | ||||
| 	services, err := r.Registry.GetService(req.Service) | ||||
| 	if err != nil { | ||||
| 		return errors.InternalServerError("go.micro.registry", err.Error()) | ||||
| 	} | ||||
| 	for _, srv := range services { | ||||
| 		rsp.Services = append(rsp.Services, service.ToProto(srv)) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (r *Registry) Register(ctx context.Context, req *pb.Service, rsp *pb.EmptyResponse) error { | ||||
| 	err := r.Registry.Register(service.ToService(req)) | ||||
| 	if err != nil { | ||||
| 		return errors.InternalServerError("go.micro.registry", err.Error()) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (r *Registry) Deregister(ctx context.Context, req *pb.Service, rsp *pb.EmptyResponse) error { | ||||
| 	err := r.Registry.Deregister(service.ToService(req)) | ||||
| 	if err != nil { | ||||
| 		return errors.InternalServerError("go.micro.registry", err.Error()) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (r *Registry) ListServices(ctx context.Context, req *pb.ListRequest, rsp *pb.ListResponse) error { | ||||
| 	services, err := r.Registry.ListServices() | ||||
| 	if err != nil { | ||||
| 		return errors.InternalServerError("go.micro.registry", err.Error()) | ||||
| 	} | ||||
| 	for _, srv := range services { | ||||
| 		rsp.Services = append(rsp.Services, service.ToProto(srv)) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (r *Registry) Watch(ctx context.Context, req *pb.WatchRequest, rsp pb.Registry_WatchStream) error { | ||||
| 	watcher, err := r.Registry.Watch(registry.WatchService(req.Service)) | ||||
| 	if err != nil { | ||||
| 		return errors.InternalServerError("go.micro.registry", err.Error()) | ||||
| 	} | ||||
|  | ||||
| 	for { | ||||
| 		next, err := watcher.Next() | ||||
| 		if err != nil { | ||||
| 			return errors.InternalServerError("go.micro.registry", err.Error()) | ||||
| 		} | ||||
| 		err = rsp.Send(&pb.Result{ | ||||
| 			Action:  next.Action, | ||||
| 			Service: service.ToProto(next.Service), | ||||
| 		}) | ||||
| 		if err != nil { | ||||
| 			return errors.InternalServerError("go.micro.registry", err.Error()) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
| @@ -2,6 +2,8 @@ | ||||
| package mdns | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
|  | ||||
| 	"github.com/micro/go-micro/registry" | ||||
| ) | ||||
|  | ||||
| @@ -9,3 +11,13 @@ import ( | ||||
| func NewRegistry(opts ...registry.Option) registry.Registry { | ||||
| 	return registry.NewRegistry(opts...) | ||||
| } | ||||
|  | ||||
| // Domain sets the mdnsDomain | ||||
| func Domain(d string) registry.Option { | ||||
| 	return func(o *registry.Options) { | ||||
| 		if o.Context == nil { | ||||
| 			o.Context = context.Background() | ||||
| 		} | ||||
| 		o.Context = context.WithValue(o.Context, "mdns.domain", d) | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -14,6 +14,11 @@ import ( | ||||
| 	hash "github.com/mitchellh/hashstructure" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// use a .micro domain rather than .local | ||||
| 	mdnsDomain = "micro" | ||||
| ) | ||||
|  | ||||
| type mdnsTxt struct { | ||||
| 	Service   string | ||||
| 	Version   string | ||||
| @@ -29,6 +34,8 @@ type mdnsEntry struct { | ||||
|  | ||||
| type mdnsRegistry struct { | ||||
| 	opts Options | ||||
| 	// the mdns domain | ||||
| 	domain string | ||||
|  | ||||
| 	sync.Mutex | ||||
| 	services map[string][]*mdnsEntry | ||||
| @@ -36,11 +43,25 @@ type mdnsRegistry struct { | ||||
|  | ||||
| func newRegistry(opts ...Option) Registry { | ||||
| 	options := Options{ | ||||
| 		Context: context.Background(), | ||||
| 		Timeout: time.Millisecond * 100, | ||||
| 	} | ||||
|  | ||||
| 	for _, o := range opts { | ||||
| 		o(&options) | ||||
| 	} | ||||
|  | ||||
| 	// set the domain | ||||
| 	domain := mdnsDomain | ||||
|  | ||||
| 	d, ok := options.Context.Value("mdns.domain").(string) | ||||
| 	if ok { | ||||
| 		domain = d | ||||
| 	} | ||||
|  | ||||
| 	return &mdnsRegistry{ | ||||
| 		opts:     options, | ||||
| 		domain:   domain, | ||||
| 		services: make(map[string][]*mdnsEntry), | ||||
| 	} | ||||
| } | ||||
| @@ -66,7 +87,7 @@ func (m *mdnsRegistry) Register(service *Service, opts ...RegisterOption) error | ||||
| 		s, err := mdns.NewMDNSService( | ||||
| 			service.Name, | ||||
| 			"_services", | ||||
| 			"", | ||||
| 			m.domain+".", | ||||
| 			"", | ||||
| 			9999, | ||||
| 			[]net.IP{net.ParseIP("0.0.0.0")}, | ||||
| @@ -141,7 +162,7 @@ func (m *mdnsRegistry) Register(service *Service, opts ...RegisterOption) error | ||||
| 		s, err := mdns.NewMDNSService( | ||||
| 			node.Id, | ||||
| 			service.Name, | ||||
| 			"", | ||||
| 			m.domain+".", | ||||
| 			"", | ||||
| 			port, | ||||
| 			[]net.IP{net.ParseIP(host)}, | ||||
| @@ -214,6 +235,8 @@ func (m *mdnsRegistry) GetService(service string) ([]*Service, error) { | ||||
| 	p.Context, _ = context.WithTimeout(context.Background(), m.opts.Timeout) | ||||
| 	// set entries channel | ||||
| 	p.Entries = entries | ||||
| 	// set the domain | ||||
| 	p.Domain = m.domain | ||||
|  | ||||
| 	go func() { | ||||
| 		for { | ||||
| @@ -223,7 +246,9 @@ func (m *mdnsRegistry) GetService(service string) ([]*Service, error) { | ||||
| 				if p.Service == "_services" { | ||||
| 					continue | ||||
| 				} | ||||
|  | ||||
| 				if p.Domain != m.domain { | ||||
| 					continue | ||||
| 				} | ||||
| 				if e.TTL == 0 { | ||||
| 					continue | ||||
| 				} | ||||
| @@ -288,6 +313,8 @@ func (m *mdnsRegistry) ListServices() ([]*Service, error) { | ||||
| 	p.Context, _ = context.WithTimeout(context.Background(), m.opts.Timeout) | ||||
| 	// set entries channel | ||||
| 	p.Entries = entries | ||||
| 	// set domain | ||||
| 	p.Domain = m.domain | ||||
|  | ||||
| 	var services []*Service | ||||
|  | ||||
| @@ -298,7 +325,9 @@ func (m *mdnsRegistry) ListServices() ([]*Service, error) { | ||||
| 				if e.TTL == 0 { | ||||
| 					continue | ||||
| 				} | ||||
|  | ||||
| 				if !strings.HasSuffix(e.Name, p.Domain+".") { | ||||
| 					continue | ||||
| 				} | ||||
| 				name := strings.TrimSuffix(e.Name, "."+p.Service+"."+p.Domain+".") | ||||
| 				if !serviceMap[name] { | ||||
| 					serviceMap[name] = true | ||||
| @@ -329,9 +358,10 @@ func (m *mdnsRegistry) Watch(opts ...WatchOption) (Watcher, error) { | ||||
| 	} | ||||
|  | ||||
| 	md := &mdnsWatcher{ | ||||
| 		wo:   wo, | ||||
| 		ch:   make(chan *mdns.ServiceEntry, 32), | ||||
| 		exit: make(chan struct{}), | ||||
| 		wo:     wo, | ||||
| 		ch:     make(chan *mdns.ServiceEntry, 32), | ||||
| 		exit:   make(chan struct{}), | ||||
| 		domain: m.domain, | ||||
| 	} | ||||
|  | ||||
| 	go func() { | ||||
|   | ||||
| @@ -11,6 +11,8 @@ type mdnsWatcher struct { | ||||
| 	wo   WatchOptions | ||||
| 	ch   chan *mdns.ServiceEntry | ||||
| 	exit chan struct{} | ||||
| 	// the mdns domain | ||||
| 	domain string | ||||
| } | ||||
|  | ||||
| func (m *mdnsWatcher) Next() (*Result, error) { | ||||
| @@ -46,13 +48,14 @@ func (m *mdnsWatcher) Next() (*Result, error) { | ||||
| 				Endpoints: txt.Endpoints, | ||||
| 			} | ||||
|  | ||||
| 			// TODO: don't hardcode .local. | ||||
| 			if !strings.HasSuffix(e.Name, "."+service.Name+".local.") { | ||||
| 			// skip anything without the domain we care about | ||||
| 			suffix := fmt.Sprintf(".%s.%s.", service.Name, m.domain) | ||||
| 			if !strings.HasSuffix(e.Name, suffix) { | ||||
| 				continue | ||||
| 			} | ||||
|  | ||||
| 			service.Nodes = append(service.Nodes, &Node{ | ||||
| 				Id:       strings.TrimSuffix(e.Name, "."+service.Name+".local."), | ||||
| 				Id:       strings.TrimSuffix(e.Name, suffix), | ||||
| 				Address:  fmt.Sprintf("%s:%d", e.AddrV4.String(), e.Port), | ||||
| 				Metadata: txt.Metadata, | ||||
| 			}) | ||||
|   | ||||
							
								
								
									
										224
									
								
								registry/proto/registry.micro.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								registry/proto/registry.micro.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,224 @@ | ||||
| // Code generated by protoc-gen-micro. DO NOT EDIT. | ||||
| // source: micro/go-micro/registry/proto/registry.proto | ||||
|  | ||||
| package go_micro_registry | ||||
|  | ||||
| import ( | ||||
| 	fmt "fmt" | ||||
| 	proto "github.com/golang/protobuf/proto" | ||||
| 	math "math" | ||||
| ) | ||||
|  | ||||
| import ( | ||||
| 	context "context" | ||||
| 	client "github.com/micro/go-micro/client" | ||||
| 	server "github.com/micro/go-micro/server" | ||||
| ) | ||||
|  | ||||
| // Reference imports to suppress errors if they are not otherwise used. | ||||
| var _ = proto.Marshal | ||||
| var _ = fmt.Errorf | ||||
| var _ = math.Inf | ||||
|  | ||||
| // This is a compile-time assertion to ensure that this generated file | ||||
| // is compatible with the proto package it is being compiled against. | ||||
| // A compilation error at this line likely means your copy of the | ||||
| // proto package needs to be updated. | ||||
| const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package | ||||
|  | ||||
| // Reference imports to suppress errors if they are not otherwise used. | ||||
| var _ context.Context | ||||
| var _ client.Option | ||||
| var _ server.Option | ||||
|  | ||||
| // Client API for Registry service | ||||
|  | ||||
| type RegistryService interface { | ||||
| 	GetService(ctx context.Context, in *GetRequest, opts ...client.CallOption) (*GetResponse, error) | ||||
| 	Register(ctx context.Context, in *Service, opts ...client.CallOption) (*EmptyResponse, error) | ||||
| 	Deregister(ctx context.Context, in *Service, opts ...client.CallOption) (*EmptyResponse, error) | ||||
| 	ListServices(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) | ||||
| 	Watch(ctx context.Context, in *WatchRequest, opts ...client.CallOption) (Registry_WatchService, error) | ||||
| } | ||||
|  | ||||
| type registryService struct { | ||||
| 	c    client.Client | ||||
| 	name string | ||||
| } | ||||
|  | ||||
| func NewRegistryService(name string, c client.Client) RegistryService { | ||||
| 	if c == nil { | ||||
| 		c = client.NewClient() | ||||
| 	} | ||||
| 	if len(name) == 0 { | ||||
| 		name = "go.micro.registry" | ||||
| 	} | ||||
| 	return ®istryService{ | ||||
| 		c:    c, | ||||
| 		name: name, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (c *registryService) GetService(ctx context.Context, in *GetRequest, opts ...client.CallOption) (*GetResponse, error) { | ||||
| 	req := c.c.NewRequest(c.name, "Registry.GetService", in) | ||||
| 	out := new(GetResponse) | ||||
| 	err := c.c.Call(ctx, req, out, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return out, nil | ||||
| } | ||||
|  | ||||
| func (c *registryService) Register(ctx context.Context, in *Service, opts ...client.CallOption) (*EmptyResponse, error) { | ||||
| 	req := c.c.NewRequest(c.name, "Registry.Register", in) | ||||
| 	out := new(EmptyResponse) | ||||
| 	err := c.c.Call(ctx, req, out, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return out, nil | ||||
| } | ||||
|  | ||||
| func (c *registryService) Deregister(ctx context.Context, in *Service, opts ...client.CallOption) (*EmptyResponse, error) { | ||||
| 	req := c.c.NewRequest(c.name, "Registry.Deregister", in) | ||||
| 	out := new(EmptyResponse) | ||||
| 	err := c.c.Call(ctx, req, out, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return out, nil | ||||
| } | ||||
|  | ||||
| func (c *registryService) ListServices(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) { | ||||
| 	req := c.c.NewRequest(c.name, "Registry.ListServices", in) | ||||
| 	out := new(ListResponse) | ||||
| 	err := c.c.Call(ctx, req, out, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return out, nil | ||||
| } | ||||
|  | ||||
| func (c *registryService) Watch(ctx context.Context, in *WatchRequest, opts ...client.CallOption) (Registry_WatchService, error) { | ||||
| 	req := c.c.NewRequest(c.name, "Registry.Watch", &WatchRequest{}) | ||||
| 	stream, err := c.c.Stream(ctx, req, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if err := stream.Send(in); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return ®istryServiceWatch{stream}, nil | ||||
| } | ||||
|  | ||||
| type Registry_WatchService interface { | ||||
| 	SendMsg(interface{}) error | ||||
| 	RecvMsg(interface{}) error | ||||
| 	Close() error | ||||
| 	Recv() (*Result, error) | ||||
| } | ||||
|  | ||||
| type registryServiceWatch struct { | ||||
| 	stream client.Stream | ||||
| } | ||||
|  | ||||
| func (x *registryServiceWatch) Close() error { | ||||
| 	return x.stream.Close() | ||||
| } | ||||
|  | ||||
| func (x *registryServiceWatch) SendMsg(m interface{}) error { | ||||
| 	return x.stream.Send(m) | ||||
| } | ||||
|  | ||||
| func (x *registryServiceWatch) RecvMsg(m interface{}) error { | ||||
| 	return x.stream.Recv(m) | ||||
| } | ||||
|  | ||||
| func (x *registryServiceWatch) Recv() (*Result, error) { | ||||
| 	m := new(Result) | ||||
| 	err := x.stream.Recv(m) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return m, nil | ||||
| } | ||||
|  | ||||
| // Server API for Registry service | ||||
|  | ||||
| type RegistryHandler interface { | ||||
| 	GetService(context.Context, *GetRequest, *GetResponse) error | ||||
| 	Register(context.Context, *Service, *EmptyResponse) error | ||||
| 	Deregister(context.Context, *Service, *EmptyResponse) error | ||||
| 	ListServices(context.Context, *ListRequest, *ListResponse) error | ||||
| 	Watch(context.Context, *WatchRequest, Registry_WatchStream) error | ||||
| } | ||||
|  | ||||
| func RegisterRegistryHandler(s server.Server, hdlr RegistryHandler, opts ...server.HandlerOption) error { | ||||
| 	type registry interface { | ||||
| 		GetService(ctx context.Context, in *GetRequest, out *GetResponse) error | ||||
| 		Register(ctx context.Context, in *Service, out *EmptyResponse) error | ||||
| 		Deregister(ctx context.Context, in *Service, out *EmptyResponse) error | ||||
| 		ListServices(ctx context.Context, in *ListRequest, out *ListResponse) error | ||||
| 		Watch(ctx context.Context, stream server.Stream) error | ||||
| 	} | ||||
| 	type Registry struct { | ||||
| 		registry | ||||
| 	} | ||||
| 	h := ®istryHandler{hdlr} | ||||
| 	return s.Handle(s.NewHandler(&Registry{h}, opts...)) | ||||
| } | ||||
|  | ||||
| type registryHandler struct { | ||||
| 	RegistryHandler | ||||
| } | ||||
|  | ||||
| func (h *registryHandler) GetService(ctx context.Context, in *GetRequest, out *GetResponse) error { | ||||
| 	return h.RegistryHandler.GetService(ctx, in, out) | ||||
| } | ||||
|  | ||||
| func (h *registryHandler) Register(ctx context.Context, in *Service, out *EmptyResponse) error { | ||||
| 	return h.RegistryHandler.Register(ctx, in, out) | ||||
| } | ||||
|  | ||||
| func (h *registryHandler) Deregister(ctx context.Context, in *Service, out *EmptyResponse) error { | ||||
| 	return h.RegistryHandler.Deregister(ctx, in, out) | ||||
| } | ||||
|  | ||||
| func (h *registryHandler) ListServices(ctx context.Context, in *ListRequest, out *ListResponse) error { | ||||
| 	return h.RegistryHandler.ListServices(ctx, in, out) | ||||
| } | ||||
|  | ||||
| func (h *registryHandler) Watch(ctx context.Context, stream server.Stream) error { | ||||
| 	m := new(WatchRequest) | ||||
| 	if err := stream.Recv(m); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return h.RegistryHandler.Watch(ctx, m, ®istryWatchStream{stream}) | ||||
| } | ||||
|  | ||||
| type Registry_WatchStream interface { | ||||
| 	SendMsg(interface{}) error | ||||
| 	RecvMsg(interface{}) error | ||||
| 	Close() error | ||||
| 	Send(*Result) error | ||||
| } | ||||
|  | ||||
| type registryWatchStream struct { | ||||
| 	stream server.Stream | ||||
| } | ||||
|  | ||||
| func (x *registryWatchStream) Close() error { | ||||
| 	return x.stream.Close() | ||||
| } | ||||
|  | ||||
| func (x *registryWatchStream) SendMsg(m interface{}) error { | ||||
| 	return x.stream.Send(m) | ||||
| } | ||||
|  | ||||
| func (x *registryWatchStream) RecvMsg(m interface{}) error { | ||||
| 	return x.stream.Recv(m) | ||||
| } | ||||
|  | ||||
| func (x *registryWatchStream) Send(m *Result) error { | ||||
| 	return x.stream.Send(m) | ||||
| } | ||||
							
								
								
									
										848
									
								
								registry/proto/registry.pb.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										848
									
								
								registry/proto/registry.pb.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,848 @@ | ||||
| // Code generated by protoc-gen-go. DO NOT EDIT. | ||||
| // source: micro/go-micro/registry/proto/registry.proto | ||||
|  | ||||
| package go_micro_registry | ||||
|  | ||||
| import ( | ||||
| 	context "context" | ||||
| 	fmt "fmt" | ||||
| 	proto "github.com/golang/protobuf/proto" | ||||
| 	grpc "google.golang.org/grpc" | ||||
| 	math "math" | ||||
| ) | ||||
|  | ||||
| // Reference imports to suppress errors if they are not otherwise used. | ||||
| var _ = proto.Marshal | ||||
| var _ = fmt.Errorf | ||||
| var _ = math.Inf | ||||
|  | ||||
| // This is a compile-time assertion to ensure that this generated file | ||||
| // is compatible with the proto package it is being compiled against. | ||||
| // A compilation error at this line likely means your copy of the | ||||
| // proto package needs to be updated. | ||||
| const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package | ||||
|  | ||||
| // Service represents a go-micro service | ||||
| type Service struct { | ||||
| 	Name                 string            `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` | ||||
| 	Version              string            `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` | ||||
| 	Metadata             map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` | ||||
| 	Endpoints            []*Endpoint       `protobuf:"bytes,4,rep,name=endpoints,proto3" json:"endpoints,omitempty"` | ||||
| 	Nodes                []*Node           `protobuf:"bytes,5,rep,name=nodes,proto3" json:"nodes,omitempty"` | ||||
| 	XXX_NoUnkeyedLiteral struct{}          `json:"-"` | ||||
| 	XXX_unrecognized     []byte            `json:"-"` | ||||
| 	XXX_sizecache        int32             `json:"-"` | ||||
| } | ||||
|  | ||||
| func (m *Service) Reset()         { *m = Service{} } | ||||
| func (m *Service) String() string { return proto.CompactTextString(m) } | ||||
| func (*Service) ProtoMessage()    {} | ||||
| func (*Service) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_f287a6b809166ad2, []int{0} | ||||
| } | ||||
|  | ||||
| func (m *Service) XXX_Unmarshal(b []byte) error { | ||||
| 	return xxx_messageInfo_Service.Unmarshal(m, b) | ||||
| } | ||||
| func (m *Service) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	return xxx_messageInfo_Service.Marshal(b, m, deterministic) | ||||
| } | ||||
| func (m *Service) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_Service.Merge(m, src) | ||||
| } | ||||
| func (m *Service) XXX_Size() int { | ||||
| 	return xxx_messageInfo_Service.Size(m) | ||||
| } | ||||
| func (m *Service) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_Service.DiscardUnknown(m) | ||||
| } | ||||
|  | ||||
| var xxx_messageInfo_Service proto.InternalMessageInfo | ||||
|  | ||||
| func (m *Service) GetName() string { | ||||
| 	if m != nil { | ||||
| 		return m.Name | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| func (m *Service) GetVersion() string { | ||||
| 	if m != nil { | ||||
| 		return m.Version | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| func (m *Service) GetMetadata() map[string]string { | ||||
| 	if m != nil { | ||||
| 		return m.Metadata | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (m *Service) GetEndpoints() []*Endpoint { | ||||
| 	if m != nil { | ||||
| 		return m.Endpoints | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (m *Service) GetNodes() []*Node { | ||||
| 	if m != nil { | ||||
| 		return m.Nodes | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Node represents the node the service is on | ||||
| type Node struct { | ||||
| 	Id                   string            `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` | ||||
| 	Address              string            `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` | ||||
| 	Port                 int64             `protobuf:"varint,3,opt,name=port,proto3" json:"port,omitempty"` | ||||
| 	Metadata             map[string]string `protobuf:"bytes,4,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` | ||||
| 	XXX_NoUnkeyedLiteral struct{}          `json:"-"` | ||||
| 	XXX_unrecognized     []byte            `json:"-"` | ||||
| 	XXX_sizecache        int32             `json:"-"` | ||||
| } | ||||
|  | ||||
| func (m *Node) Reset()         { *m = Node{} } | ||||
| func (m *Node) String() string { return proto.CompactTextString(m) } | ||||
| func (*Node) ProtoMessage()    {} | ||||
| func (*Node) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_f287a6b809166ad2, []int{1} | ||||
| } | ||||
|  | ||||
| func (m *Node) XXX_Unmarshal(b []byte) error { | ||||
| 	return xxx_messageInfo_Node.Unmarshal(m, b) | ||||
| } | ||||
| func (m *Node) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	return xxx_messageInfo_Node.Marshal(b, m, deterministic) | ||||
| } | ||||
| func (m *Node) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_Node.Merge(m, src) | ||||
| } | ||||
| func (m *Node) XXX_Size() int { | ||||
| 	return xxx_messageInfo_Node.Size(m) | ||||
| } | ||||
| func (m *Node) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_Node.DiscardUnknown(m) | ||||
| } | ||||
|  | ||||
| var xxx_messageInfo_Node proto.InternalMessageInfo | ||||
|  | ||||
| func (m *Node) GetId() string { | ||||
| 	if m != nil { | ||||
| 		return m.Id | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| func (m *Node) GetAddress() string { | ||||
| 	if m != nil { | ||||
| 		return m.Address | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| func (m *Node) GetPort() int64 { | ||||
| 	if m != nil { | ||||
| 		return m.Port | ||||
| 	} | ||||
| 	return 0 | ||||
| } | ||||
|  | ||||
| func (m *Node) GetMetadata() map[string]string { | ||||
| 	if m != nil { | ||||
| 		return m.Metadata | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Endpoint is a endpoint provided by a service | ||||
| type Endpoint struct { | ||||
| 	Name                 string            `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` | ||||
| 	Request              *Value            `protobuf:"bytes,2,opt,name=request,proto3" json:"request,omitempty"` | ||||
| 	Response             *Value            `protobuf:"bytes,3,opt,name=response,proto3" json:"response,omitempty"` | ||||
| 	Metadata             map[string]string `protobuf:"bytes,4,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` | ||||
| 	XXX_NoUnkeyedLiteral struct{}          `json:"-"` | ||||
| 	XXX_unrecognized     []byte            `json:"-"` | ||||
| 	XXX_sizecache        int32             `json:"-"` | ||||
| } | ||||
|  | ||||
| func (m *Endpoint) Reset()         { *m = Endpoint{} } | ||||
| func (m *Endpoint) String() string { return proto.CompactTextString(m) } | ||||
| func (*Endpoint) ProtoMessage()    {} | ||||
| func (*Endpoint) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_f287a6b809166ad2, []int{2} | ||||
| } | ||||
|  | ||||
| func (m *Endpoint) XXX_Unmarshal(b []byte) error { | ||||
| 	return xxx_messageInfo_Endpoint.Unmarshal(m, b) | ||||
| } | ||||
| func (m *Endpoint) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	return xxx_messageInfo_Endpoint.Marshal(b, m, deterministic) | ||||
| } | ||||
| func (m *Endpoint) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_Endpoint.Merge(m, src) | ||||
| } | ||||
| func (m *Endpoint) XXX_Size() int { | ||||
| 	return xxx_messageInfo_Endpoint.Size(m) | ||||
| } | ||||
| func (m *Endpoint) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_Endpoint.DiscardUnknown(m) | ||||
| } | ||||
|  | ||||
| var xxx_messageInfo_Endpoint proto.InternalMessageInfo | ||||
|  | ||||
| func (m *Endpoint) GetName() string { | ||||
| 	if m != nil { | ||||
| 		return m.Name | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| func (m *Endpoint) GetRequest() *Value { | ||||
| 	if m != nil { | ||||
| 		return m.Request | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (m *Endpoint) GetResponse() *Value { | ||||
| 	if m != nil { | ||||
| 		return m.Response | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (m *Endpoint) GetMetadata() map[string]string { | ||||
| 	if m != nil { | ||||
| 		return m.Metadata | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Value is an opaque value for a request or response | ||||
| type Value struct { | ||||
| 	Name                 string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` | ||||
| 	Type                 string   `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` | ||||
| 	Values               []*Value `protobuf:"bytes,3,rep,name=values,proto3" json:"values,omitempty"` | ||||
| 	XXX_NoUnkeyedLiteral struct{} `json:"-"` | ||||
| 	XXX_unrecognized     []byte   `json:"-"` | ||||
| 	XXX_sizecache        int32    `json:"-"` | ||||
| } | ||||
|  | ||||
| func (m *Value) Reset()         { *m = Value{} } | ||||
| func (m *Value) String() string { return proto.CompactTextString(m) } | ||||
| func (*Value) ProtoMessage()    {} | ||||
| func (*Value) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_f287a6b809166ad2, []int{3} | ||||
| } | ||||
|  | ||||
| func (m *Value) XXX_Unmarshal(b []byte) error { | ||||
| 	return xxx_messageInfo_Value.Unmarshal(m, b) | ||||
| } | ||||
| func (m *Value) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	return xxx_messageInfo_Value.Marshal(b, m, deterministic) | ||||
| } | ||||
| func (m *Value) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_Value.Merge(m, src) | ||||
| } | ||||
| func (m *Value) XXX_Size() int { | ||||
| 	return xxx_messageInfo_Value.Size(m) | ||||
| } | ||||
| func (m *Value) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_Value.DiscardUnknown(m) | ||||
| } | ||||
|  | ||||
| var xxx_messageInfo_Value proto.InternalMessageInfo | ||||
|  | ||||
| func (m *Value) GetName() string { | ||||
| 	if m != nil { | ||||
| 		return m.Name | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| func (m *Value) GetType() string { | ||||
| 	if m != nil { | ||||
| 		return m.Type | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| func (m *Value) GetValues() []*Value { | ||||
| 	if m != nil { | ||||
| 		return m.Values | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Result is returns by the watcher | ||||
| type Result struct { | ||||
| 	Action               string   `protobuf:"bytes,1,opt,name=action,proto3" json:"action,omitempty"` | ||||
| 	Service              *Service `protobuf:"bytes,2,opt,name=service,proto3" json:"service,omitempty"` | ||||
| 	Timestamp            int64    `protobuf:"varint,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"` | ||||
| 	XXX_NoUnkeyedLiteral struct{} `json:"-"` | ||||
| 	XXX_unrecognized     []byte   `json:"-"` | ||||
| 	XXX_sizecache        int32    `json:"-"` | ||||
| } | ||||
|  | ||||
| func (m *Result) Reset()         { *m = Result{} } | ||||
| func (m *Result) String() string { return proto.CompactTextString(m) } | ||||
| func (*Result) ProtoMessage()    {} | ||||
| func (*Result) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_f287a6b809166ad2, []int{4} | ||||
| } | ||||
|  | ||||
| func (m *Result) XXX_Unmarshal(b []byte) error { | ||||
| 	return xxx_messageInfo_Result.Unmarshal(m, b) | ||||
| } | ||||
| func (m *Result) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	return xxx_messageInfo_Result.Marshal(b, m, deterministic) | ||||
| } | ||||
| func (m *Result) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_Result.Merge(m, src) | ||||
| } | ||||
| func (m *Result) XXX_Size() int { | ||||
| 	return xxx_messageInfo_Result.Size(m) | ||||
| } | ||||
| func (m *Result) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_Result.DiscardUnknown(m) | ||||
| } | ||||
|  | ||||
| var xxx_messageInfo_Result proto.InternalMessageInfo | ||||
|  | ||||
| func (m *Result) GetAction() string { | ||||
| 	if m != nil { | ||||
| 		return m.Action | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| func (m *Result) GetService() *Service { | ||||
| 	if m != nil { | ||||
| 		return m.Service | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (m *Result) GetTimestamp() int64 { | ||||
| 	if m != nil { | ||||
| 		return m.Timestamp | ||||
| 	} | ||||
| 	return 0 | ||||
| } | ||||
|  | ||||
| type EmptyResponse struct { | ||||
| 	XXX_NoUnkeyedLiteral struct{} `json:"-"` | ||||
| 	XXX_unrecognized     []byte   `json:"-"` | ||||
| 	XXX_sizecache        int32    `json:"-"` | ||||
| } | ||||
|  | ||||
| func (m *EmptyResponse) Reset()         { *m = EmptyResponse{} } | ||||
| func (m *EmptyResponse) String() string { return proto.CompactTextString(m) } | ||||
| func (*EmptyResponse) ProtoMessage()    {} | ||||
| func (*EmptyResponse) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_f287a6b809166ad2, []int{5} | ||||
| } | ||||
|  | ||||
| func (m *EmptyResponse) XXX_Unmarshal(b []byte) error { | ||||
| 	return xxx_messageInfo_EmptyResponse.Unmarshal(m, b) | ||||
| } | ||||
| func (m *EmptyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	return xxx_messageInfo_EmptyResponse.Marshal(b, m, deterministic) | ||||
| } | ||||
| func (m *EmptyResponse) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_EmptyResponse.Merge(m, src) | ||||
| } | ||||
| func (m *EmptyResponse) XXX_Size() int { | ||||
| 	return xxx_messageInfo_EmptyResponse.Size(m) | ||||
| } | ||||
| func (m *EmptyResponse) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_EmptyResponse.DiscardUnknown(m) | ||||
| } | ||||
|  | ||||
| var xxx_messageInfo_EmptyResponse proto.InternalMessageInfo | ||||
|  | ||||
| type GetRequest struct { | ||||
| 	Service              string   `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"` | ||||
| 	XXX_NoUnkeyedLiteral struct{} `json:"-"` | ||||
| 	XXX_unrecognized     []byte   `json:"-"` | ||||
| 	XXX_sizecache        int32    `json:"-"` | ||||
| } | ||||
|  | ||||
| func (m *GetRequest) Reset()         { *m = GetRequest{} } | ||||
| func (m *GetRequest) String() string { return proto.CompactTextString(m) } | ||||
| func (*GetRequest) ProtoMessage()    {} | ||||
| func (*GetRequest) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_f287a6b809166ad2, []int{6} | ||||
| } | ||||
|  | ||||
| func (m *GetRequest) XXX_Unmarshal(b []byte) error { | ||||
| 	return xxx_messageInfo_GetRequest.Unmarshal(m, b) | ||||
| } | ||||
| func (m *GetRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	return xxx_messageInfo_GetRequest.Marshal(b, m, deterministic) | ||||
| } | ||||
| func (m *GetRequest) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_GetRequest.Merge(m, src) | ||||
| } | ||||
| func (m *GetRequest) XXX_Size() int { | ||||
| 	return xxx_messageInfo_GetRequest.Size(m) | ||||
| } | ||||
| func (m *GetRequest) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_GetRequest.DiscardUnknown(m) | ||||
| } | ||||
|  | ||||
| var xxx_messageInfo_GetRequest proto.InternalMessageInfo | ||||
|  | ||||
| func (m *GetRequest) GetService() string { | ||||
| 	if m != nil { | ||||
| 		return m.Service | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| type GetResponse struct { | ||||
| 	Services             []*Service `protobuf:"bytes,1,rep,name=services,proto3" json:"services,omitempty"` | ||||
| 	XXX_NoUnkeyedLiteral struct{}   `json:"-"` | ||||
| 	XXX_unrecognized     []byte     `json:"-"` | ||||
| 	XXX_sizecache        int32      `json:"-"` | ||||
| } | ||||
|  | ||||
| func (m *GetResponse) Reset()         { *m = GetResponse{} } | ||||
| func (m *GetResponse) String() string { return proto.CompactTextString(m) } | ||||
| func (*GetResponse) ProtoMessage()    {} | ||||
| func (*GetResponse) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_f287a6b809166ad2, []int{7} | ||||
| } | ||||
|  | ||||
| func (m *GetResponse) XXX_Unmarshal(b []byte) error { | ||||
| 	return xxx_messageInfo_GetResponse.Unmarshal(m, b) | ||||
| } | ||||
| func (m *GetResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	return xxx_messageInfo_GetResponse.Marshal(b, m, deterministic) | ||||
| } | ||||
| func (m *GetResponse) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_GetResponse.Merge(m, src) | ||||
| } | ||||
| func (m *GetResponse) XXX_Size() int { | ||||
| 	return xxx_messageInfo_GetResponse.Size(m) | ||||
| } | ||||
| func (m *GetResponse) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_GetResponse.DiscardUnknown(m) | ||||
| } | ||||
|  | ||||
| var xxx_messageInfo_GetResponse proto.InternalMessageInfo | ||||
|  | ||||
| func (m *GetResponse) GetServices() []*Service { | ||||
| 	if m != nil { | ||||
| 		return m.Services | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type ListRequest struct { | ||||
| 	XXX_NoUnkeyedLiteral struct{} `json:"-"` | ||||
| 	XXX_unrecognized     []byte   `json:"-"` | ||||
| 	XXX_sizecache        int32    `json:"-"` | ||||
| } | ||||
|  | ||||
| func (m *ListRequest) Reset()         { *m = ListRequest{} } | ||||
| func (m *ListRequest) String() string { return proto.CompactTextString(m) } | ||||
| func (*ListRequest) ProtoMessage()    {} | ||||
| func (*ListRequest) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_f287a6b809166ad2, []int{8} | ||||
| } | ||||
|  | ||||
| func (m *ListRequest) XXX_Unmarshal(b []byte) error { | ||||
| 	return xxx_messageInfo_ListRequest.Unmarshal(m, b) | ||||
| } | ||||
| func (m *ListRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	return xxx_messageInfo_ListRequest.Marshal(b, m, deterministic) | ||||
| } | ||||
| func (m *ListRequest) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_ListRequest.Merge(m, src) | ||||
| } | ||||
| func (m *ListRequest) XXX_Size() int { | ||||
| 	return xxx_messageInfo_ListRequest.Size(m) | ||||
| } | ||||
| func (m *ListRequest) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_ListRequest.DiscardUnknown(m) | ||||
| } | ||||
|  | ||||
| var xxx_messageInfo_ListRequest proto.InternalMessageInfo | ||||
|  | ||||
| type ListResponse struct { | ||||
| 	Services             []*Service `protobuf:"bytes,1,rep,name=services,proto3" json:"services,omitempty"` | ||||
| 	XXX_NoUnkeyedLiteral struct{}   `json:"-"` | ||||
| 	XXX_unrecognized     []byte     `json:"-"` | ||||
| 	XXX_sizecache        int32      `json:"-"` | ||||
| } | ||||
|  | ||||
| func (m *ListResponse) Reset()         { *m = ListResponse{} } | ||||
| func (m *ListResponse) String() string { return proto.CompactTextString(m) } | ||||
| func (*ListResponse) ProtoMessage()    {} | ||||
| func (*ListResponse) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_f287a6b809166ad2, []int{9} | ||||
| } | ||||
|  | ||||
| func (m *ListResponse) XXX_Unmarshal(b []byte) error { | ||||
| 	return xxx_messageInfo_ListResponse.Unmarshal(m, b) | ||||
| } | ||||
| func (m *ListResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	return xxx_messageInfo_ListResponse.Marshal(b, m, deterministic) | ||||
| } | ||||
| func (m *ListResponse) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_ListResponse.Merge(m, src) | ||||
| } | ||||
| func (m *ListResponse) XXX_Size() int { | ||||
| 	return xxx_messageInfo_ListResponse.Size(m) | ||||
| } | ||||
| func (m *ListResponse) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_ListResponse.DiscardUnknown(m) | ||||
| } | ||||
|  | ||||
| var xxx_messageInfo_ListResponse proto.InternalMessageInfo | ||||
|  | ||||
| func (m *ListResponse) GetServices() []*Service { | ||||
| 	if m != nil { | ||||
| 		return m.Services | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type WatchRequest struct { | ||||
| 	// service is optional | ||||
| 	Service              string   `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"` | ||||
| 	XXX_NoUnkeyedLiteral struct{} `json:"-"` | ||||
| 	XXX_unrecognized     []byte   `json:"-"` | ||||
| 	XXX_sizecache        int32    `json:"-"` | ||||
| } | ||||
|  | ||||
| func (m *WatchRequest) Reset()         { *m = WatchRequest{} } | ||||
| func (m *WatchRequest) String() string { return proto.CompactTextString(m) } | ||||
| func (*WatchRequest) ProtoMessage()    {} | ||||
| func (*WatchRequest) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_f287a6b809166ad2, []int{10} | ||||
| } | ||||
|  | ||||
| func (m *WatchRequest) XXX_Unmarshal(b []byte) error { | ||||
| 	return xxx_messageInfo_WatchRequest.Unmarshal(m, b) | ||||
| } | ||||
| func (m *WatchRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	return xxx_messageInfo_WatchRequest.Marshal(b, m, deterministic) | ||||
| } | ||||
| func (m *WatchRequest) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_WatchRequest.Merge(m, src) | ||||
| } | ||||
| func (m *WatchRequest) XXX_Size() int { | ||||
| 	return xxx_messageInfo_WatchRequest.Size(m) | ||||
| } | ||||
| func (m *WatchRequest) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_WatchRequest.DiscardUnknown(m) | ||||
| } | ||||
|  | ||||
| var xxx_messageInfo_WatchRequest proto.InternalMessageInfo | ||||
|  | ||||
| func (m *WatchRequest) GetService() string { | ||||
| 	if m != nil { | ||||
| 		return m.Service | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| func init() { | ||||
| 	proto.RegisterType((*Service)(nil), "go.micro.registry.Service") | ||||
| 	proto.RegisterMapType((map[string]string)(nil), "go.micro.registry.Service.MetadataEntry") | ||||
| 	proto.RegisterType((*Node)(nil), "go.micro.registry.Node") | ||||
| 	proto.RegisterMapType((map[string]string)(nil), "go.micro.registry.Node.MetadataEntry") | ||||
| 	proto.RegisterType((*Endpoint)(nil), "go.micro.registry.Endpoint") | ||||
| 	proto.RegisterMapType((map[string]string)(nil), "go.micro.registry.Endpoint.MetadataEntry") | ||||
| 	proto.RegisterType((*Value)(nil), "go.micro.registry.Value") | ||||
| 	proto.RegisterType((*Result)(nil), "go.micro.registry.Result") | ||||
| 	proto.RegisterType((*EmptyResponse)(nil), "go.micro.registry.EmptyResponse") | ||||
| 	proto.RegisterType((*GetRequest)(nil), "go.micro.registry.GetRequest") | ||||
| 	proto.RegisterType((*GetResponse)(nil), "go.micro.registry.GetResponse") | ||||
| 	proto.RegisterType((*ListRequest)(nil), "go.micro.registry.ListRequest") | ||||
| 	proto.RegisterType((*ListResponse)(nil), "go.micro.registry.ListResponse") | ||||
| 	proto.RegisterType((*WatchRequest)(nil), "go.micro.registry.WatchRequest") | ||||
| } | ||||
|  | ||||
| func init() { | ||||
| 	proto.RegisterFile("micro/go-micro/registry/proto/registry.proto", fileDescriptor_f287a6b809166ad2) | ||||
| } | ||||
|  | ||||
| var fileDescriptor_f287a6b809166ad2 = []byte{ | ||||
| 	// 577 bytes of a gzipped FileDescriptorProto | ||||
| 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0x6d, 0x8b, 0xd3, 0x4c, | ||||
| 	0x14, 0x6d, 0x92, 0xbe, 0xde, 0x6e, 0x9f, 0x47, 0x2f, 0xa2, 0x31, 0xbe, 0x95, 0x80, 0x52, 0xc1, | ||||
| 	0xcd, 0x2e, 0x75, 0x11, 0x5f, 0x3e, 0x09, 0x5b, 0x17, 0x64, 0x57, 0x70, 0x04, 0xfd, 0x1c, 0x9b, | ||||
| 	0x4b, 0x0d, 0x6e, 0x5e, 0x9c, 0x99, 0x16, 0xfa, 0x1f, 0x04, 0xff, 0x84, 0x3f, 0xc5, 0x1f, 0x26, | ||||
| 	0x99, 0xcc, 0x34, 0x5d, 0x36, 0xa9, 0x1f, 0x56, 0xbf, 0xcd, 0xcd, 0x9c, 0x73, 0xe6, 0x9e, 0x73, | ||||
| 	0x67, 0x5a, 0x78, 0x92, 0xc4, 0x73, 0x9e, 0x1d, 0x2c, 0xb2, 0xfd, 0x72, 0xc1, 0x69, 0x11, 0x0b, | ||||
| 	0xc9, 0xd7, 0x07, 0x39, 0xcf, 0x64, 0x55, 0x06, 0xaa, 0xc4, 0xeb, 0x8b, 0x2c, 0x50, 0xb8, 0xc0, | ||||
| 	0x6c, 0xf8, 0x3f, 0x6d, 0xe8, 0x7d, 0x20, 0xbe, 0x8a, 0xe7, 0x84, 0x08, 0xed, 0x34, 0x4c, 0xc8, | ||||
| 	0xb5, 0xc6, 0xd6, 0x64, 0xc0, 0xd4, 0x1a, 0x5d, 0xe8, 0xad, 0x88, 0x8b, 0x38, 0x4b, 0x5d, 0x5b, | ||||
| 	0x7d, 0x36, 0x25, 0x1e, 0x43, 0x3f, 0x21, 0x19, 0x46, 0xa1, 0x0c, 0x5d, 0x67, 0xec, 0x4c, 0x86, | ||||
| 	0xd3, 0x49, 0x70, 0x49, 0x3f, 0xd0, 0xda, 0xc1, 0x99, 0x86, 0xce, 0x52, 0xc9, 0xd7, 0x6c, 0xc3, | ||||
| 	0xc4, 0x17, 0x30, 0xa0, 0x34, 0xca, 0xb3, 0x38, 0x95, 0xc2, 0x6d, 0x2b, 0x99, 0x3b, 0x35, 0x32, | ||||
| 	0x33, 0x8d, 0x61, 0x15, 0x1a, 0xf7, 0xa1, 0x93, 0x66, 0x11, 0x09, 0xb7, 0xa3, 0x68, 0xb7, 0x6a, | ||||
| 	0x68, 0xef, 0xb2, 0x88, 0x58, 0x89, 0xf2, 0x5e, 0xc1, 0xe8, 0x42, 0x13, 0x78, 0x0d, 0x9c, 0xaf, | ||||
| 	0xb4, 0xd6, 0x6e, 0x8b, 0x25, 0xde, 0x80, 0xce, 0x2a, 0x3c, 0x5f, 0x92, 0xb6, 0x5a, 0x16, 0x2f, | ||||
| 	0xed, 0xe7, 0x96, 0xff, 0xcb, 0x82, 0x76, 0x21, 0x86, 0xff, 0x81, 0x1d, 0x47, 0x9a, 0x63, 0xc7, | ||||
| 	0x51, 0x91, 0x4f, 0x18, 0x45, 0x9c, 0x84, 0x30, 0xf9, 0xe8, 0xb2, 0x48, 0x33, 0xcf, 0xb8, 0x74, | ||||
| 	0x9d, 0xb1, 0x35, 0x71, 0x98, 0x5a, 0xe3, 0xeb, 0xad, 0xcc, 0x4a, 0xb3, 0x0f, 0x1b, 0xba, 0x6e, | ||||
| 	0x0a, 0xec, 0x6a, 0x36, 0xbe, 0xdb, 0xd0, 0x37, 0x51, 0xd6, 0x8e, 0x7b, 0x0a, 0x3d, 0x4e, 0xdf, | ||||
| 	0x96, 0x24, 0xa4, 0x22, 0x0f, 0xa7, 0x6e, 0x4d, 0x7f, 0x1f, 0x0b, 0x3d, 0x66, 0x80, 0x78, 0x04, | ||||
| 	0x7d, 0x4e, 0x22, 0xcf, 0x52, 0x41, 0xca, 0xec, 0x2e, 0xd2, 0x06, 0x89, 0xb3, 0x4b, 0x51, 0x3c, | ||||
| 	0xde, 0x31, 0xf7, 0x7f, 0x13, 0x47, 0x08, 0x1d, 0xd5, 0x56, 0x6d, 0x14, 0x08, 0x6d, 0xb9, 0xce, | ||||
| 	0x0d, 0x4b, 0xad, 0xf1, 0x10, 0xba, 0x8a, 0x2d, 0xf4, 0x8d, 0x6f, 0x36, 0xaa, 0x71, 0xbe, 0x84, | ||||
| 	0x2e, 0x23, 0xb1, 0x3c, 0x97, 0x78, 0x13, 0xba, 0xe1, 0x5c, 0x16, 0x0f, 0xa9, 0x3c, 0x45, 0x57, | ||||
| 	0x78, 0x04, 0x3d, 0x51, 0x3e, 0x12, 0x1d, 0xb9, 0xd7, 0xfc, 0x8c, 0x98, 0x81, 0xe2, 0x5d, 0x18, | ||||
| 	0xc8, 0x38, 0x21, 0x21, 0xc3, 0x24, 0xd7, 0x57, 0xac, 0xfa, 0xe0, 0xff, 0x0f, 0xa3, 0x59, 0x92, | ||||
| 	0xcb, 0x35, 0xd3, 0x69, 0xfb, 0x8f, 0x00, 0x4e, 0x48, 0x32, 0x3d, 0x31, 0xb7, 0x3a, 0xb2, 0xec, | ||||
| 	0xc5, 0x94, 0xfe, 0x0c, 0x86, 0x0a, 0xa7, 0x87, 0xf4, 0x0c, 0xfa, 0x7a, 0x47, 0xb8, 0x96, 0x72, | ||||
| 	0xbc, 0xab, 0xb9, 0x0d, 0xd6, 0x1f, 0xc1, 0xf0, 0x34, 0x16, 0xe6, 0x3c, 0xff, 0x0d, 0xec, 0x95, | ||||
| 	0xe5, 0x15, 0x65, 0x27, 0xb0, 0xf7, 0x29, 0x94, 0xf3, 0x2f, 0x7f, 0xf4, 0x31, 0xfd, 0xe1, 0x40, | ||||
| 	0x9f, 0x69, 0x21, 0x3c, 0x53, 0xe6, 0xcd, 0xaf, 0xdc, 0xbd, 0x9a, 0xa3, 0xaa, 0x6c, 0xbc, 0xfb, | ||||
| 	0x4d, 0xdb, 0x3a, 0xc9, 0x16, 0xbe, 0x35, 0xd2, 0xc4, 0x71, 0x47, 0xdf, 0xde, 0xb8, 0xee, 0x3e, | ||||
| 	0x5f, 0x98, 0x4a, 0x0b, 0x4f, 0x01, 0x8e, 0x89, 0xff, 0x2d, 0xb5, 0xf7, 0x65, 0xce, 0x9a, 0x22, | ||||
| 	0xb0, 0xce, 0xcb, 0xd6, 0x5c, 0xbc, 0x07, 0x8d, 0xfb, 0x1b, 0xc9, 0x13, 0xe8, 0xa8, 0xc8, 0xb1, | ||||
| 	0x0e, 0xbb, 0x3d, 0x0c, 0xef, 0x76, 0x0d, 0xa0, 0xbc, 0xfa, 0x7e, 0xeb, 0xd0, 0xfa, 0xdc, 0x55, | ||||
| 	0x7f, 0x41, 0x4f, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0x6b, 0x0b, 0x12, 0xd6, 0xb2, 0x06, 0x00, | ||||
| 	0x00, | ||||
| } | ||||
|  | ||||
| // Reference imports to suppress errors if they are not otherwise used. | ||||
| var _ context.Context | ||||
| var _ grpc.ClientConn | ||||
|  | ||||
| // This is a compile-time assertion to ensure that this generated file | ||||
| // is compatible with the grpc package it is being compiled against. | ||||
| const _ = grpc.SupportPackageIsVersion4 | ||||
|  | ||||
| // RegistryClient is the client API for Registry service. | ||||
| // | ||||
| // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. | ||||
| type RegistryClient interface { | ||||
| 	GetService(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*GetResponse, error) | ||||
| 	Register(ctx context.Context, in *Service, opts ...grpc.CallOption) (*EmptyResponse, error) | ||||
| 	Deregister(ctx context.Context, in *Service, opts ...grpc.CallOption) (*EmptyResponse, error) | ||||
| 	ListServices(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) | ||||
| 	Watch(ctx context.Context, in *WatchRequest, opts ...grpc.CallOption) (Registry_WatchClient, error) | ||||
| } | ||||
|  | ||||
| type registryClient struct { | ||||
| 	cc *grpc.ClientConn | ||||
| } | ||||
|  | ||||
| func NewRegistryClient(cc *grpc.ClientConn) RegistryClient { | ||||
| 	return ®istryClient{cc} | ||||
| } | ||||
|  | ||||
| func (c *registryClient) GetService(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*GetResponse, error) { | ||||
| 	out := new(GetResponse) | ||||
| 	err := c.cc.Invoke(ctx, "/go.micro.registry.Registry/GetService", in, out, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return out, nil | ||||
| } | ||||
|  | ||||
| func (c *registryClient) Register(ctx context.Context, in *Service, opts ...grpc.CallOption) (*EmptyResponse, error) { | ||||
| 	out := new(EmptyResponse) | ||||
| 	err := c.cc.Invoke(ctx, "/go.micro.registry.Registry/Register", in, out, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return out, nil | ||||
| } | ||||
|  | ||||
| func (c *registryClient) Deregister(ctx context.Context, in *Service, opts ...grpc.CallOption) (*EmptyResponse, error) { | ||||
| 	out := new(EmptyResponse) | ||||
| 	err := c.cc.Invoke(ctx, "/go.micro.registry.Registry/Deregister", in, out, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return out, nil | ||||
| } | ||||
|  | ||||
| func (c *registryClient) ListServices(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) { | ||||
| 	out := new(ListResponse) | ||||
| 	err := c.cc.Invoke(ctx, "/go.micro.registry.Registry/ListServices", in, out, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return out, nil | ||||
| } | ||||
|  | ||||
| func (c *registryClient) Watch(ctx context.Context, in *WatchRequest, opts ...grpc.CallOption) (Registry_WatchClient, error) { | ||||
| 	stream, err := c.cc.NewStream(ctx, &_Registry_serviceDesc.Streams[0], "/go.micro.registry.Registry/Watch", opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	x := ®istryWatchClient{stream} | ||||
| 	if err := x.ClientStream.SendMsg(in); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if err := x.ClientStream.CloseSend(); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return x, nil | ||||
| } | ||||
|  | ||||
| type Registry_WatchClient interface { | ||||
| 	Recv() (*Result, error) | ||||
| 	grpc.ClientStream | ||||
| } | ||||
|  | ||||
| type registryWatchClient struct { | ||||
| 	grpc.ClientStream | ||||
| } | ||||
|  | ||||
| func (x *registryWatchClient) Recv() (*Result, error) { | ||||
| 	m := new(Result) | ||||
| 	if err := x.ClientStream.RecvMsg(m); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return m, nil | ||||
| } | ||||
|  | ||||
| // RegistryServer is the server API for Registry service. | ||||
| type RegistryServer interface { | ||||
| 	GetService(context.Context, *GetRequest) (*GetResponse, error) | ||||
| 	Register(context.Context, *Service) (*EmptyResponse, error) | ||||
| 	Deregister(context.Context, *Service) (*EmptyResponse, error) | ||||
| 	ListServices(context.Context, *ListRequest) (*ListResponse, error) | ||||
| 	Watch(*WatchRequest, Registry_WatchServer) error | ||||
| } | ||||
|  | ||||
| func RegisterRegistryServer(s *grpc.Server, srv RegistryServer) { | ||||
| 	s.RegisterService(&_Registry_serviceDesc, srv) | ||||
| } | ||||
|  | ||||
| func _Registry_GetService_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { | ||||
| 	in := new(GetRequest) | ||||
| 	if err := dec(in); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if interceptor == nil { | ||||
| 		return srv.(RegistryServer).GetService(ctx, in) | ||||
| 	} | ||||
| 	info := &grpc.UnaryServerInfo{ | ||||
| 		Server:     srv, | ||||
| 		FullMethod: "/go.micro.registry.Registry/GetService", | ||||
| 	} | ||||
| 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | ||||
| 		return srv.(RegistryServer).GetService(ctx, req.(*GetRequest)) | ||||
| 	} | ||||
| 	return interceptor(ctx, in, info, handler) | ||||
| } | ||||
|  | ||||
| func _Registry_Register_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { | ||||
| 	in := new(Service) | ||||
| 	if err := dec(in); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if interceptor == nil { | ||||
| 		return srv.(RegistryServer).Register(ctx, in) | ||||
| 	} | ||||
| 	info := &grpc.UnaryServerInfo{ | ||||
| 		Server:     srv, | ||||
| 		FullMethod: "/go.micro.registry.Registry/Register", | ||||
| 	} | ||||
| 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | ||||
| 		return srv.(RegistryServer).Register(ctx, req.(*Service)) | ||||
| 	} | ||||
| 	return interceptor(ctx, in, info, handler) | ||||
| } | ||||
|  | ||||
| func _Registry_Deregister_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { | ||||
| 	in := new(Service) | ||||
| 	if err := dec(in); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if interceptor == nil { | ||||
| 		return srv.(RegistryServer).Deregister(ctx, in) | ||||
| 	} | ||||
| 	info := &grpc.UnaryServerInfo{ | ||||
| 		Server:     srv, | ||||
| 		FullMethod: "/go.micro.registry.Registry/Deregister", | ||||
| 	} | ||||
| 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | ||||
| 		return srv.(RegistryServer).Deregister(ctx, req.(*Service)) | ||||
| 	} | ||||
| 	return interceptor(ctx, in, info, handler) | ||||
| } | ||||
|  | ||||
| func _Registry_ListServices_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { | ||||
| 	in := new(ListRequest) | ||||
| 	if err := dec(in); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if interceptor == nil { | ||||
| 		return srv.(RegistryServer).ListServices(ctx, in) | ||||
| 	} | ||||
| 	info := &grpc.UnaryServerInfo{ | ||||
| 		Server:     srv, | ||||
| 		FullMethod: "/go.micro.registry.Registry/ListServices", | ||||
| 	} | ||||
| 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | ||||
| 		return srv.(RegistryServer).ListServices(ctx, req.(*ListRequest)) | ||||
| 	} | ||||
| 	return interceptor(ctx, in, info, handler) | ||||
| } | ||||
|  | ||||
| func _Registry_Watch_Handler(srv interface{}, stream grpc.ServerStream) error { | ||||
| 	m := new(WatchRequest) | ||||
| 	if err := stream.RecvMsg(m); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return srv.(RegistryServer).Watch(m, ®istryWatchServer{stream}) | ||||
| } | ||||
|  | ||||
| type Registry_WatchServer interface { | ||||
| 	Send(*Result) error | ||||
| 	grpc.ServerStream | ||||
| } | ||||
|  | ||||
| type registryWatchServer struct { | ||||
| 	grpc.ServerStream | ||||
| } | ||||
|  | ||||
| func (x *registryWatchServer) Send(m *Result) error { | ||||
| 	return x.ServerStream.SendMsg(m) | ||||
| } | ||||
|  | ||||
| var _Registry_serviceDesc = grpc.ServiceDesc{ | ||||
| 	ServiceName: "go.micro.registry.Registry", | ||||
| 	HandlerType: (*RegistryServer)(nil), | ||||
| 	Methods: []grpc.MethodDesc{ | ||||
| 		{ | ||||
| 			MethodName: "GetService", | ||||
| 			Handler:    _Registry_GetService_Handler, | ||||
| 		}, | ||||
| 		{ | ||||
| 			MethodName: "Register", | ||||
| 			Handler:    _Registry_Register_Handler, | ||||
| 		}, | ||||
| 		{ | ||||
| 			MethodName: "Deregister", | ||||
| 			Handler:    _Registry_Deregister_Handler, | ||||
| 		}, | ||||
| 		{ | ||||
| 			MethodName: "ListServices", | ||||
| 			Handler:    _Registry_ListServices_Handler, | ||||
| 		}, | ||||
| 	}, | ||||
| 	Streams: []grpc.StreamDesc{ | ||||
| 		{ | ||||
| 			StreamName:    "Watch", | ||||
| 			Handler:       _Registry_Watch_Handler, | ||||
| 			ServerStreams: true, | ||||
| 		}, | ||||
| 	}, | ||||
| 	Metadata: "micro/go-micro/registry/proto/registry.proto", | ||||
| } | ||||
							
								
								
									
										73
									
								
								registry/proto/registry.proto
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								registry/proto/registry.proto
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| syntax = "proto3"; | ||||
|  | ||||
| package go.micro.registry; | ||||
|  | ||||
| service Registry { | ||||
| 	rpc GetService(GetRequest) returns (GetResponse) {}; | ||||
| 	rpc Register(Service) returns (EmptyResponse) {}; | ||||
| 	rpc Deregister(Service) returns (EmptyResponse) {}; | ||||
| 	rpc ListServices(ListRequest) returns (ListResponse) {}; | ||||
| 	rpc Watch(WatchRequest) returns (stream Result) {}; | ||||
| } | ||||
|  | ||||
| // Service represents a go-micro service | ||||
| message Service { | ||||
| 	string name = 1; | ||||
| 	string version = 2; | ||||
| 	map<string,string> metadata = 3; | ||||
| 	repeated Endpoint endpoints = 4; | ||||
| 	repeated Node nodes = 5; | ||||
| } | ||||
|  | ||||
| // Node represents the node the service is on | ||||
| message Node { | ||||
| 	string id = 1; | ||||
| 	string address = 2; | ||||
| 	int64 port = 3; | ||||
| 	map<string,string> metadata = 4; | ||||
| } | ||||
|  | ||||
| // Endpoint is a endpoint provided by a service | ||||
| message Endpoint { | ||||
| 	string name = 1; | ||||
| 	Value request = 2; | ||||
| 	Value response = 3; | ||||
| 	map<string, string> metadata = 4; | ||||
| } | ||||
|  | ||||
| // Value is an opaque value for a request or response | ||||
| message Value { | ||||
| 	string name = 1; | ||||
| 	string type = 2; | ||||
| 	repeated Value values = 3; | ||||
| } | ||||
|  | ||||
| // Result is returns by the watcher | ||||
| message Result { | ||||
| 	string action = 1; // create, update, delete | ||||
| 	Service service = 2; | ||||
| 	int64 timestamp = 3; // unix timestamp | ||||
| } | ||||
|  | ||||
| message EmptyResponse {} | ||||
|  | ||||
| message GetRequest { | ||||
| 	string service = 1; | ||||
| } | ||||
|  | ||||
| message GetResponse { | ||||
| 	repeated Service services = 1; | ||||
| } | ||||
|  | ||||
| message ListRequest { | ||||
| 	// TODO: filtering | ||||
| } | ||||
|  | ||||
| message ListResponse { | ||||
| 	repeated Service services = 1; | ||||
| } | ||||
|  | ||||
| message WatchRequest { | ||||
| 	// service is optional | ||||
| 	string service = 1; | ||||
| } | ||||
							
								
								
									
										155
									
								
								registry/service/service.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								registry/service/service.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,155 @@ | ||||
| // Package service uses the registry service | ||||
| package service | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/micro/go-micro/client" | ||||
| 	"github.com/micro/go-micro/registry" | ||||
| 	pb "github.com/micro/go-micro/registry/proto" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// The default service name | ||||
| 	DefaultService = "go.micro.service" | ||||
| ) | ||||
|  | ||||
| type serviceRegistry struct { | ||||
| 	opts registry.Options | ||||
| 	// name of the registry | ||||
| 	name string | ||||
| 	// address | ||||
| 	address []string | ||||
| 	// client to call registry | ||||
| 	client pb.RegistryService | ||||
| } | ||||
|  | ||||
| func (s *serviceRegistry) callOpts() []client.CallOption { | ||||
| 	var opts []client.CallOption | ||||
|  | ||||
| 	// set registry address | ||||
| 	if len(s.address) > 0 { | ||||
| 		opts = append(opts, client.WithAddress(s.address...)) | ||||
| 	} | ||||
|  | ||||
| 	// set timeout | ||||
| 	if s.opts.Timeout > time.Duration(0) { | ||||
| 		opts = append(opts, client.WithRequestTimeout(s.opts.Timeout)) | ||||
| 	} | ||||
|  | ||||
| 	return opts | ||||
| } | ||||
|  | ||||
| func (s *serviceRegistry) Init(opts ...registry.Option) error { | ||||
| 	for _, o := range opts { | ||||
| 		o(&s.opts) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (s *serviceRegistry) Options() registry.Options { | ||||
| 	return s.opts | ||||
| } | ||||
|  | ||||
| func (s *serviceRegistry) Register(srv *registry.Service, opts ...registry.RegisterOption) error { | ||||
| 	var options registry.RegisterOptions | ||||
| 	for _, o := range opts { | ||||
| 		o(&options) | ||||
| 	} | ||||
|  | ||||
| 	// register the service | ||||
| 	_, err := s.client.Register(context.TODO(), ToProto(srv), s.callOpts()...) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (s *serviceRegistry) Deregister(srv *registry.Service) error { | ||||
| 	// deregister the service | ||||
| 	_, err := s.client.Deregister(context.TODO(), ToProto(srv), s.callOpts()...) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (s *serviceRegistry) GetService(name string) ([]*registry.Service, error) { | ||||
| 	rsp, err := s.client.GetService(context.TODO(), &pb.GetRequest{ | ||||
| 		Service: name, | ||||
| 	}, s.callOpts()...) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	var services []*registry.Service | ||||
| 	for _, service := range rsp.Services { | ||||
| 		services = append(services, ToService(service)) | ||||
| 	} | ||||
| 	return services, nil | ||||
| } | ||||
|  | ||||
| func (s *serviceRegistry) ListServices() ([]*registry.Service, error) { | ||||
| 	rsp, err := s.client.ListServices(context.TODO(), &pb.ListRequest{}, s.callOpts()...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	var services []*registry.Service | ||||
| 	for _, service := range rsp.Services { | ||||
| 		services = append(services, ToService(service)) | ||||
| 	} | ||||
|  | ||||
| 	return services, nil | ||||
| } | ||||
|  | ||||
| func (s *serviceRegistry) Watch(opts ...registry.WatchOption) (registry.Watcher, error) { | ||||
| 	var options registry.WatchOptions | ||||
| 	for _, o := range opts { | ||||
| 		o(&options) | ||||
| 	} | ||||
|  | ||||
| 	stream, err := s.client.Watch(context.TODO(), &pb.WatchRequest{ | ||||
| 		Service: options.Service, | ||||
| 	}, s.callOpts()...) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return newWatcher(stream), nil | ||||
| } | ||||
|  | ||||
| func (s *serviceRegistry) String() string { | ||||
| 	return s.name | ||||
| } | ||||
|  | ||||
| // NewRegistry returns a new registry service client | ||||
| func NewRegistry(opts ...registry.Option) registry.Registry { | ||||
| 	var options registry.Options | ||||
| 	for _, o := range opts { | ||||
| 		o(&options) | ||||
| 	} | ||||
|  | ||||
| 	// use mdns to find the service registry | ||||
| 	mReg := registry.NewRegistry() | ||||
|  | ||||
| 	// create new client with mdns | ||||
| 	cli := client.NewClient( | ||||
| 		client.Registry(mReg), | ||||
| 	) | ||||
|  | ||||
| 	// service name | ||||
| 	// TODO: accept option | ||||
| 	name := DefaultService | ||||
|  | ||||
| 	return &serviceRegistry{ | ||||
| 		opts:    options, | ||||
| 		name:    name, | ||||
| 		address: options.Addrs, | ||||
| 		client:  pb.NewRegistryService(name, cli), | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										133
									
								
								registry/service/util.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								registry/service/util.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| package service | ||||
|  | ||||
| import ( | ||||
| 	"github.com/micro/go-micro/registry" | ||||
| 	pb "github.com/micro/go-micro/registry/proto" | ||||
| ) | ||||
|  | ||||
| func values(v []*registry.Value) []*pb.Value { | ||||
| 	if len(v) == 0 { | ||||
| 		return []*pb.Value{} | ||||
| 	} | ||||
|  | ||||
| 	var vs []*pb.Value | ||||
| 	for _, vi := range v { | ||||
| 		vs = append(vs, &pb.Value{ | ||||
| 			Name:   vi.Name, | ||||
| 			Type:   vi.Type, | ||||
| 			Values: values(vi.Values), | ||||
| 		}) | ||||
| 	} | ||||
| 	return vs | ||||
| } | ||||
|  | ||||
| func toValues(v []*pb.Value) []*registry.Value { | ||||
| 	if len(v) == 0 { | ||||
| 		return []*registry.Value{} | ||||
| 	} | ||||
|  | ||||
| 	var vs []*registry.Value | ||||
| 	for _, vi := range v { | ||||
| 		vs = append(vs, ®istry.Value{ | ||||
| 			Name:   vi.Name, | ||||
| 			Type:   vi.Type, | ||||
| 			Values: toValues(vi.Values), | ||||
| 		}) | ||||
| 	} | ||||
| 	return vs | ||||
| } | ||||
|  | ||||
| func ToProto(s *registry.Service) *pb.Service { | ||||
| 	var endpoints []*pb.Endpoint | ||||
| 	for _, ep := range s.Endpoints { | ||||
| 		var request, response *pb.Value | ||||
|  | ||||
| 		if ep.Request != nil { | ||||
| 			request = &pb.Value{ | ||||
| 				Name:   ep.Request.Name, | ||||
| 				Type:   ep.Request.Type, | ||||
| 				Values: values(ep.Request.Values), | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if ep.Response != nil { | ||||
| 			response = &pb.Value{ | ||||
| 				Name:   ep.Response.Name, | ||||
| 				Type:   ep.Response.Type, | ||||
| 				Values: values(ep.Response.Values), | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		endpoints = append(endpoints, &pb.Endpoint{ | ||||
| 			Name:     ep.Name, | ||||
| 			Request:  request, | ||||
| 			Response: response, | ||||
| 			Metadata: ep.Metadata, | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
| 	var nodes []*pb.Node | ||||
|  | ||||
| 	for _, node := range s.Nodes { | ||||
| 		nodes = append(nodes, &pb.Node{ | ||||
| 			Id:       node.Id, | ||||
| 			Address:  node.Address, | ||||
| 			Metadata: node.Metadata, | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
| 	return &pb.Service{ | ||||
| 		Name:      s.Name, | ||||
| 		Version:   s.Version, | ||||
| 		Metadata:  s.Metadata, | ||||
| 		Endpoints: endpoints, | ||||
| 		Nodes:     nodes, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func ToService(s *pb.Service) *registry.Service { | ||||
| 	var endpoints []*registry.Endpoint | ||||
| 	for _, ep := range s.Endpoints { | ||||
| 		var request, response *registry.Value | ||||
|  | ||||
| 		if ep.Request != nil { | ||||
| 			request = ®istry.Value{ | ||||
| 				Name:   ep.Request.Name, | ||||
| 				Type:   ep.Request.Type, | ||||
| 				Values: toValues(ep.Request.Values), | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if ep.Response != nil { | ||||
| 			response = ®istry.Value{ | ||||
| 				Name:   ep.Response.Name, | ||||
| 				Type:   ep.Response.Type, | ||||
| 				Values: toValues(ep.Response.Values), | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		endpoints = append(endpoints, ®istry.Endpoint{ | ||||
| 			Name:     ep.Name, | ||||
| 			Request:  request, | ||||
| 			Response: response, | ||||
| 			Metadata: ep.Metadata, | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
| 	var nodes []*registry.Node | ||||
| 	for _, node := range s.Nodes { | ||||
| 		nodes = append(nodes, ®istry.Node{ | ||||
| 			Id:       node.Id, | ||||
| 			Address:  node.Address, | ||||
| 			Metadata: node.Metadata, | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
| 	return ®istry.Service{ | ||||
| 		Name:      s.Name, | ||||
| 		Version:   s.Version, | ||||
| 		Metadata:  s.Metadata, | ||||
| 		Endpoints: endpoints, | ||||
| 		Nodes:     nodes, | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										49
									
								
								registry/service/watcher.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								registry/service/watcher.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| package service | ||||
|  | ||||
| import ( | ||||
| 	"github.com/micro/go-micro/registry" | ||||
| 	pb "github.com/micro/go-micro/registry/proto" | ||||
| ) | ||||
|  | ||||
| type serviceWatcher struct { | ||||
| 	stream pb.Registry_WatchService | ||||
| 	closed chan bool | ||||
| } | ||||
|  | ||||
| func (s *serviceWatcher) Next() (*registry.Result, error) { | ||||
| 	for { | ||||
| 		// check if closed | ||||
| 		select { | ||||
| 		case <-s.closed: | ||||
| 			return nil, registry.ErrWatcherStopped | ||||
| 		default: | ||||
| 		} | ||||
|  | ||||
| 		r, err := s.stream.Recv() | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		return ®istry.Result{ | ||||
| 			Action:  r.Action, | ||||
| 			Service: ToService(r.Service), | ||||
| 		}, nil | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (s *serviceWatcher) Stop() { | ||||
| 	select { | ||||
| 	case <-s.closed: | ||||
| 		return | ||||
| 	default: | ||||
| 		close(s.closed) | ||||
| 		s.stream.Close() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func newWatcher(stream pb.Registry_WatchService) registry.Watcher { | ||||
| 	return &serviceWatcher{ | ||||
| 		stream: stream, | ||||
| 		closed: make(chan bool), | ||||
| 	} | ||||
| } | ||||
| @@ -10,6 +10,7 @@ import ( | ||||
|  | ||||
| 	"github.com/google/uuid" | ||||
| 	"github.com/micro/go-micro/registry" | ||||
| 	"github.com/micro/go-micro/util/log" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| @@ -43,7 +44,7 @@ var ( | ||||
| // router implements default router | ||||
| type router struct { | ||||
| 	sync.RWMutex | ||||
| 	opts      Options | ||||
| 	options   Options | ||||
| 	status    Status | ||||
| 	table     *table | ||||
| 	exit      chan struct{} | ||||
| @@ -70,7 +71,7 @@ func newRouter(opts ...Option) Router { | ||||
| 	status := Status{Code: Stopped, Error: nil} | ||||
|  | ||||
| 	return &router{ | ||||
| 		opts:        options, | ||||
| 		options:     options, | ||||
| 		status:      status, | ||||
| 		table:       newTable(), | ||||
| 		advertWg:    &sync.WaitGroup{}, | ||||
| @@ -85,7 +86,7 @@ func (r *router) Init(opts ...Option) error { | ||||
| 	defer r.Unlock() | ||||
|  | ||||
| 	for _, o := range opts { | ||||
| 		o(&r.opts) | ||||
| 		o(&r.options) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| @@ -94,10 +95,10 @@ func (r *router) Init(opts ...Option) error { | ||||
| // Options returns router options | ||||
| func (r *router) Options() Options { | ||||
| 	r.Lock() | ||||
| 	opts := r.opts | ||||
| 	options := r.options | ||||
| 	r.Unlock() | ||||
|  | ||||
| 	return opts | ||||
| 	return options | ||||
| } | ||||
|  | ||||
| // Table returns routing table | ||||
| @@ -120,6 +121,9 @@ func (r *router) manageRoute(route Route, action string) error { | ||||
| 		if err := r.table.Delete(route); err != nil && err != ErrRouteNotFound { | ||||
| 			return fmt.Errorf("failed deleting route for service %s: %s", route.Service, err) | ||||
| 		} | ||||
| 	case "solicit": | ||||
| 		// nothing to do here | ||||
| 		return nil | ||||
| 	default: | ||||
| 		return fmt.Errorf("failed to manage route for service %s. Unknown action: %s", route.Service, action) | ||||
| 	} | ||||
| @@ -139,7 +143,8 @@ func (r *router) manageServiceRoutes(service *registry.Service, action string) e | ||||
| 			Service: service.Name, | ||||
| 			Address: node.Address, | ||||
| 			Gateway: "", | ||||
| 			Network: r.opts.Network, | ||||
| 			Network: r.options.Network, | ||||
| 			Router:  r.options.Id, | ||||
| 			Link:    DefaultLink, | ||||
| 			Metric:  DefaultLocalMetric, | ||||
| 		} | ||||
| @@ -278,13 +283,14 @@ func (r *router) publishAdvert(advType AdvertType, events []*Event) { | ||||
| 	defer r.advertWg.Done() | ||||
|  | ||||
| 	a := &Advert{ | ||||
| 		Id:        r.opts.Id, | ||||
| 		Id:        r.options.Id, | ||||
| 		Type:      advType, | ||||
| 		TTL:       DefaultAdvertTTL, | ||||
| 		Timestamp: time.Now(), | ||||
| 		Events:    events, | ||||
| 	} | ||||
|  | ||||
| 	log.Debugf("Router publishing advert; %+v", a) | ||||
| 	r.RLock() | ||||
| 	for _, sub := range r.subscribers { | ||||
| 		// check the exit chan first | ||||
| @@ -529,20 +535,22 @@ func (r *router) Start() error { | ||||
| 	} | ||||
|  | ||||
| 	// add all local service routes into the routing table | ||||
| 	if err := r.manageRegistryRoutes(r.opts.Registry, "create"); err != nil { | ||||
| 	if err := r.manageRegistryRoutes(r.options.Registry, "create"); err != nil { | ||||
| 		e := fmt.Errorf("failed adding registry routes: %s", err) | ||||
| 		r.status = Status{Code: Error, Error: e} | ||||
| 		return e | ||||
| 	} | ||||
|  | ||||
| 	// add default gateway into routing table | ||||
| 	if r.opts.Gateway != "" { | ||||
| 	if r.options.Gateway != "" { | ||||
| 		// note, the only non-default value is the gateway | ||||
| 		route := Route{ | ||||
| 			Service: "*", | ||||
| 			Address: "*", | ||||
| 			Gateway: r.opts.Gateway, | ||||
| 			Gateway: r.options.Gateway, | ||||
| 			Network: "*", | ||||
| 			Router:  r.options.Id, | ||||
| 			Link:    DefaultLink, | ||||
| 			Metric:  DefaultLocalMetric, | ||||
| 		} | ||||
| 		if err := r.table.Create(route); err != nil { | ||||
| @@ -557,7 +565,7 @@ func (r *router) Start() error { | ||||
| 	r.exit = make(chan struct{}) | ||||
|  | ||||
| 	// registry watcher | ||||
| 	regWatcher, err := r.opts.Registry.Watch() | ||||
| 	regWatcher, err := r.options.Registry.Watch() | ||||
| 	if err != nil { | ||||
| 		e := fmt.Errorf("failed creating registry watcher: %v", err) | ||||
| 		r.status = Status{Code: Error, Error: e} | ||||
| @@ -595,25 +603,14 @@ func (r *router) Advertise() (<-chan *Advert, error) { | ||||
|  | ||||
| 	switch r.status.Code { | ||||
| 	case Advertising: | ||||
| 		advertChan := make(chan *Advert) | ||||
| 		advertChan := make(chan *Advert, 128) | ||||
| 		r.subscribers[uuid.New().String()] = advertChan | ||||
| 		return advertChan, nil | ||||
| 	case Running: | ||||
| 		// list routing table routes to announce | ||||
| 		routes, err := r.table.List() | ||||
| 		// list all the routes and pack them into even slice to advertise | ||||
| 		events, err := r.flushRouteEvents(Create) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("failed listing routes: %s", err) | ||||
| 		} | ||||
|  | ||||
| 		// collect all the added routes before we attempt to add default gateway | ||||
| 		events := make([]*Event, len(routes)) | ||||
| 		for i, route := range routes { | ||||
| 			event := &Event{ | ||||
| 				Type:      Create, | ||||
| 				Timestamp: time.Now(), | ||||
| 				Route:     route, | ||||
| 			} | ||||
| 			events[i] = event | ||||
| 			return nil, fmt.Errorf("failed to flush routes: %s", err) | ||||
| 		} | ||||
|  | ||||
| 		// create event channels | ||||
| @@ -646,7 +643,7 @@ func (r *router) Advertise() (<-chan *Advert, error) { | ||||
| 		r.status = Status{Code: Advertising, Error: nil} | ||||
|  | ||||
| 		// create advert channel | ||||
| 		advertChan := make(chan *Advert) | ||||
| 		advertChan := make(chan *Advert, 128) | ||||
| 		r.subscribers[uuid.New().String()] = advertChan | ||||
|  | ||||
| 		return advertChan, nil | ||||
| @@ -669,6 +666,10 @@ func (r *router) Process(a *Advert) error { | ||||
| 	}) | ||||
|  | ||||
| 	for _, event := range events { | ||||
| 		// skip if the router is the origin of this route | ||||
| 		if event.Route.Router == r.options.Id { | ||||
| 			continue | ||||
| 		} | ||||
| 		// create a copy of the route | ||||
| 		route := event.Route | ||||
| 		action := event.Type | ||||
| @@ -680,6 +681,43 @@ func (r *router) Process(a *Advert) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // flushRouteEvents returns a slice of events, one per each route in the routing table | ||||
| func (r *router) flushRouteEvents(evType EventType) ([]*Event, error) { | ||||
| 	// list all routes | ||||
| 	routes, err := r.table.List() | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed listing routes: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	// build a list of events to advertise | ||||
| 	events := make([]*Event, len(routes)) | ||||
| 	for i, route := range routes { | ||||
| 		event := &Event{ | ||||
| 			Type:      evType, | ||||
| 			Timestamp: time.Now(), | ||||
| 			Route:     route, | ||||
| 		} | ||||
| 		events[i] = event | ||||
| 	} | ||||
|  | ||||
| 	return events, nil | ||||
| } | ||||
|  | ||||
| // Solicit advertises all of its routes to the network | ||||
| // It returns error if the router fails to list the routes | ||||
| func (r *router) Solicit() error { | ||||
| 	events, err := r.flushRouteEvents(Update) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("failed solicit routes: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	// advertise the routes | ||||
| 	r.advertWg.Add(1) | ||||
| 	go r.publishAdvert(RouteUpdate, events) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Lookup routes in the routing table | ||||
| func (r *router) Lookup(q Query) ([]Route, error) { | ||||
| 	return r.table.Query(q) | ||||
|   | ||||
| @@ -33,6 +33,7 @@ func (r *Router) Lookup(ctx context.Context, req *pb.LookupRequest, resp *pb.Loo | ||||
| 			Address: route.Address, | ||||
| 			Gateway: route.Gateway, | ||||
| 			Network: route.Network, | ||||
| 			Router:  route.Router, | ||||
| 			Link:    route.Link, | ||||
| 			Metric:  int64(route.Metric), | ||||
| 		} | ||||
| @@ -58,6 +59,7 @@ func (r *Router) Advertise(ctx context.Context, req *pb.Request, stream pb.Route | ||||
| 				Address: event.Route.Address, | ||||
| 				Gateway: event.Route.Gateway, | ||||
| 				Network: event.Route.Network, | ||||
| 				Router:  event.Route.Router, | ||||
| 				Link:    event.Route.Link, | ||||
| 				Metric:  int64(event.Route.Metric), | ||||
| 			} | ||||
| @@ -97,6 +99,7 @@ func (r *Router) Process(ctx context.Context, req *pb.Advert, rsp *pb.ProcessRes | ||||
| 			Address: event.Route.Address, | ||||
| 			Gateway: event.Route.Gateway, | ||||
| 			Network: event.Route.Network, | ||||
| 			Router:  event.Route.Router, | ||||
| 			Link:    event.Route.Link, | ||||
| 			Metric:  int(event.Route.Metric), | ||||
| 		} | ||||
| @@ -161,6 +164,7 @@ func (r *Router) Watch(ctx context.Context, req *pb.WatchRequest, stream pb.Rout | ||||
| 			Address: event.Route.Address, | ||||
| 			Gateway: event.Route.Gateway, | ||||
| 			Network: event.Route.Network, | ||||
| 			Router:  event.Route.Router, | ||||
| 			Link:    event.Route.Link, | ||||
| 			Metric:  int64(event.Route.Metric), | ||||
| 		} | ||||
|   | ||||
| @@ -18,6 +18,7 @@ func (t *Table) Create(ctx context.Context, route *pb.Route, resp *pb.CreateResp | ||||
| 		Address: route.Address, | ||||
| 		Gateway: route.Gateway, | ||||
| 		Network: route.Network, | ||||
| 		Router:  route.Router, | ||||
| 		Link:    route.Link, | ||||
| 		Metric:  int(route.Metric), | ||||
| 	}) | ||||
| @@ -34,6 +35,7 @@ func (t *Table) Update(ctx context.Context, route *pb.Route, resp *pb.UpdateResp | ||||
| 		Address: route.Address, | ||||
| 		Gateway: route.Gateway, | ||||
| 		Network: route.Network, | ||||
| 		Router:  route.Router, | ||||
| 		Link:    route.Link, | ||||
| 		Metric:  int(route.Metric), | ||||
| 	}) | ||||
| @@ -50,6 +52,7 @@ func (t *Table) Delete(ctx context.Context, route *pb.Route, resp *pb.DeleteResp | ||||
| 		Address: route.Address, | ||||
| 		Gateway: route.Gateway, | ||||
| 		Network: route.Network, | ||||
| 		Router:  route.Router, | ||||
| 		Link:    route.Link, | ||||
| 		Metric:  int(route.Metric), | ||||
| 	}) | ||||
| @@ -74,6 +77,7 @@ func (t *Table) List(ctx context.Context, req *pb.Request, resp *pb.ListResponse | ||||
| 			Address: route.Address, | ||||
| 			Gateway: route.Gateway, | ||||
| 			Network: route.Network, | ||||
| 			Router:  route.Router, | ||||
| 			Link:    route.Link, | ||||
| 			Metric:  int64(route.Metric), | ||||
| 		} | ||||
| @@ -102,6 +106,7 @@ func (t *Table) Query(ctx context.Context, req *pb.QueryRequest, resp *pb.QueryR | ||||
| 			Address: route.Address, | ||||
| 			Gateway: route.Gateway, | ||||
| 			Network: route.Network, | ||||
| 			Router:  route.Router, | ||||
| 			Link:    route.Link, | ||||
| 			Metric:  int64(route.Metric), | ||||
| 		} | ||||
|   | ||||
| @@ -672,10 +672,12 @@ type Route struct { | ||||
| 	Gateway string `protobuf:"bytes,3,opt,name=gateway,proto3" json:"gateway,omitempty"` | ||||
| 	// the network for this destination | ||||
| 	Network string `protobuf:"bytes,4,opt,name=network,proto3" json:"network,omitempty"` | ||||
| 	// router if the router id | ||||
| 	Router string `protobuf:"bytes,5,opt,name=router,proto3" json:"router,omitempty"` | ||||
| 	// the network link | ||||
| 	Link string `protobuf:"bytes,5,opt,name=link,proto3" json:"link,omitempty"` | ||||
| 	Link string `protobuf:"bytes,6,opt,name=link,proto3" json:"link,omitempty"` | ||||
| 	// the metric / score of this route | ||||
| 	Metric               int64    `protobuf:"varint,6,opt,name=metric,proto3" json:"metric,omitempty"` | ||||
| 	Metric               int64    `protobuf:"varint,7,opt,name=metric,proto3" json:"metric,omitempty"` | ||||
| 	XXX_NoUnkeyedLiteral struct{} `json:"-"` | ||||
| 	XXX_unrecognized     []byte   `json:"-"` | ||||
| 	XXX_sizecache        int32    `json:"-"` | ||||
| @@ -734,6 +736,13 @@ func (m *Route) GetNetwork() string { | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| func (m *Route) GetRouter() string { | ||||
| 	if m != nil { | ||||
| 		return m.Router | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| func (m *Route) GetLink() string { | ||||
| 	if m != nil { | ||||
| 		return m.Link | ||||
| @@ -861,51 +870,51 @@ func init() { | ||||
| } | ||||
|  | ||||
| var fileDescriptor_6a36eee0b1adf739 = []byte{ | ||||
| 	// 689 bytes of a gzipped FileDescriptorProto | ||||
| 	// 699 bytes of a gzipped FileDescriptorProto | ||||
| 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0xcd, 0x4e, 0xdb, 0x40, | ||||
| 	0x10, 0xb6, 0x93, 0xd8, 0x28, 0xd3, 0x10, 0xdc, 0x51, 0x05, 0x56, 0x5a, 0x20, 0xf2, 0x29, 0x42, | ||||
| 	0xd4, 0xa9, 0xd2, 0x6b, 0xff, 0x02, 0xa5, 0xaa, 0x54, 0x0e, 0xad, 0x0b, 0xea, 0xd9, 0xd8, 0x23, | ||||
| 	0x6a, 0x91, 0xd8, 0x66, 0x77, 0x03, 0xca, 0xb9, 0x8f, 0xd1, 0x27, 0xe8, 0x73, 0xf5, 0xda, 0x87, | ||||
| 	0xa8, 0xbc, 0xbb, 0x0e, 0x21, 0xc6, 0x48, 0x70, 0xf2, 0xce, 0xdf, 0x37, 0xff, 0x63, 0x18, 0x4c, | ||||
| 	0x93, 0x88, 0x65, 0xc3, 0xf3, 0xec, 0xa5, 0x7a, 0xb0, 0x6c, 0x26, 0x88, 0x0d, 0x73, 0x96, 0x89, | ||||
| 	0x92, 0xf0, 0x25, 0x81, 0x1b, 0xe7, 0x99, 0x2f, 0x75, 0x7c, 0xc5, 0xf6, 0xda, 0xb0, 0x16, 0xd0, | ||||
| 	0xe5, 0x8c, 0xb8, 0xf0, 0xde, 0x41, 0xe7, 0x38, 0xe1, 0x22, 0x20, 0x9e, 0x67, 0x29, 0x27, 0xf4, | ||||
| 	0xc1, 0x96, 0x4a, 0xdc, 0x35, 0xfb, 0xcd, 0xc1, 0x93, 0xd1, 0xa6, 0xbf, 0x62, 0xec, 0x07, 0xc5, | ||||
| 	0x27, 0xd0, 0x5a, 0xde, 0x5b, 0x58, 0x3f, 0xce, 0xb2, 0x8b, 0x59, 0xae, 0x01, 0x71, 0x1f, 0xac, | ||||
| 	0xcb, 0x19, 0xb1, 0xb9, 0x6b, 0xf6, 0xcd, 0x3b, 0xed, 0xbf, 0x15, 0xd2, 0x40, 0x29, 0x79, 0x1f, | ||||
| 	0xa0, 0x5b, 0x9a, 0x3f, 0x32, 0x80, 0x37, 0xd0, 0x51, 0x88, 0x8f, 0xf2, 0xff, 0x1e, 0xd6, 0xb5, | ||||
| 	0xf5, 0x23, 0xdd, 0x77, 0xa1, 0xf3, 0x23, 0x14, 0xd1, 0xcf, 0xb2, 0x9e, 0x7f, 0x4c, 0xb0, 0xc7, | ||||
| 	0xf1, 0x15, 0x31, 0x81, 0x5d, 0x68, 0x24, 0xb1, 0x0c, 0xa3, 0x1d, 0x34, 0x92, 0x18, 0x87, 0xd0, | ||||
| 	0x12, 0xf3, 0x9c, 0xdc, 0x46, 0xdf, 0x1c, 0x74, 0x47, 0xcf, 0x2b, 0xc0, 0xca, 0xec, 0x64, 0x9e, | ||||
| 	0x53, 0x20, 0x15, 0xf1, 0x05, 0xb4, 0x45, 0x32, 0x25, 0x2e, 0xc2, 0x69, 0xee, 0x36, 0xfb, 0xe6, | ||||
| 	0xa0, 0x19, 0xdc, 0x30, 0xd0, 0x81, 0xa6, 0x10, 0x13, 0xb7, 0x25, 0xf9, 0xc5, 0xb3, 0x88, 0x9d, | ||||
| 	0xae, 0x28, 0x15, 0xdc, 0xb5, 0x6a, 0x62, 0x3f, 0x2a, 0xc4, 0x81, 0xd6, 0xf2, 0x9e, 0xc2, 0xc6, | ||||
| 	0x57, 0x96, 0x45, 0xc4, 0x79, 0x99, 0xbe, 0xe7, 0x40, 0xf7, 0x90, 0x51, 0x28, 0x68, 0x99, 0xf3, | ||||
| 	0x91, 0x26, 0x74, 0x9b, 0x73, 0x9a, 0xc7, 0xcb, 0x3a, 0xbf, 0x4c, 0xb0, 0x24, 0x34, 0xfa, 0x3a, | ||||
| 	0x47, 0x53, 0xe6, 0xd8, 0xbb, 0x3b, 0x80, 0xba, 0x14, 0x1b, 0xab, 0x29, 0xee, 0x83, 0x25, 0xed, | ||||
| 	0x64, 0xf2, 0xf5, 0xbd, 0x50, 0x4a, 0xde, 0x29, 0x58, 0xb2, 0x97, 0xe8, 0xc2, 0x1a, 0x27, 0x76, | ||||
| 	0x95, 0x44, 0xa4, 0xab, 0x5f, 0x92, 0x85, 0xe4, 0x3c, 0x14, 0x74, 0x1d, 0xce, 0xa5, 0xb3, 0x76, | ||||
| 	0x50, 0x92, 0x85, 0x24, 0x25, 0x71, 0x9d, 0xb1, 0x0b, 0xe9, 0xac, 0x1d, 0x94, 0xa4, 0xf7, 0xdb, | ||||
| 	0x04, 0x4b, 0xfa, 0xb9, 0x1f, 0x37, 0x8c, 0x63, 0x46, 0x9c, 0x97, 0xb8, 0x9a, 0x5c, 0xf6, 0xd8, | ||||
| 	0xac, 0xf5, 0xd8, 0xba, 0xe5, 0x11, 0x11, 0x5a, 0x93, 0x24, 0xbd, 0x70, 0x2d, 0xc9, 0x96, 0x6f, | ||||
| 	0xdc, 0x04, 0x7b, 0x4a, 0x82, 0x25, 0x91, 0x6b, 0xcb, 0x2a, 0x69, 0xca, 0x1b, 0x81, 0xfd, 0x5d, | ||||
| 	0x84, 0x62, 0xc6, 0x0b, 0xab, 0x28, 0x8b, 0xcb, 0xd0, 0xe4, 0x1b, 0x9f, 0x81, 0x45, 0x8c, 0x65, | ||||
| 	0x4c, 0x47, 0xa5, 0x08, 0x6f, 0x0c, 0x5d, 0x65, 0xb3, 0x98, 0xfa, 0x21, 0xd8, 0x5c, 0x72, 0xf4, | ||||
| 	0xd6, 0x6c, 0x55, 0x2a, 0xad, 0x0d, 0xb4, 0xda, 0xde, 0x08, 0xe0, 0x66, 0x5c, 0x11, 0xa1, 0xab, | ||||
| 	0xa8, 0x71, 0x9a, 0x66, 0xb3, 0x34, 0x22, 0xc7, 0x40, 0x07, 0x3a, 0x8a, 0xa7, 0x66, 0xc5, 0x31, | ||||
| 	0xf7, 0x86, 0xd0, 0x5e, 0xb4, 0x1f, 0x01, 0x6c, 0x35, 0x68, 0x8e, 0x51, 0xbc, 0xd5, 0x88, 0x39, | ||||
| 	0x66, 0xf1, 0xd6, 0x06, 0x8d, 0xd1, 0xbf, 0x06, 0xd8, 0xb2, 0xf2, 0x0c, 0xbf, 0x80, 0xad, 0xee, | ||||
| 	0x04, 0xee, 0x54, 0x42, 0xbb, 0x75, 0x7f, 0x7a, 0xbb, 0xb5, 0x72, 0x3d, 0xac, 0x06, 0x1e, 0x80, | ||||
| 	0x25, 0x77, 0x16, 0xb7, 0x2b, 0xba, 0xcb, 0xbb, 0xdc, 0xab, 0xd9, 0x1f, 0xcf, 0x78, 0x65, 0xe2, | ||||
| 	0x01, 0xb4, 0x55, 0x7a, 0x09, 0x27, 0x74, 0xab, 0x83, 0xa9, 0x21, 0xb6, 0x6a, 0xb6, 0x5c, 0x62, | ||||
| 	0x7c, 0x82, 0x35, 0xbd, 0x7f, 0x58, 0xa7, 0xd7, 0xeb, 0x57, 0x04, 0xab, 0x2b, 0x6b, 0xe0, 0xd1, | ||||
| 	0x62, 0x06, 0xea, 0x03, 0xd9, 0xad, 0xeb, 0xe8, 0x02, 0x66, 0xf4, 0xb7, 0x01, 0xd6, 0x49, 0x78, | ||||
| 	0x36, 0x21, 0x3c, 0x2c, 0x9b, 0x83, 0x35, 0x2b, 0x77, 0x07, 0xdc, 0xca, 0xd9, 0x30, 0x0a, 0x10, | ||||
| 	0xd5, 0xd5, 0x07, 0x80, 0xac, 0x5c, 0x1a, 0x09, 0xa2, 0xc6, 0xe1, 0x01, 0x20, 0x2b, 0xc7, 0xc9, | ||||
| 	0xc0, 0x31, 0xb4, 0x8a, 0x7f, 0xdc, 0x3d, 0xd5, 0xa9, 0x0e, 0xc2, 0xf2, 0x4f, 0xd1, 0x33, 0xf0, | ||||
| 	0x73, 0x79, 0x5b, 0xb6, 0x6b, 0xfe, 0x27, 0x1a, 0x68, 0xa7, 0x4e, 0x5c, 0x22, 0x9d, 0xd9, 0xf2, | ||||
| 	0x9f, 0xfc, 0xfa, 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8c, 0xd0, 0xc0, 0x27, 0xbf, 0x07, 0x00, | ||||
| 	0x00, | ||||
| 	0x10, 0xb6, 0x9d, 0xd8, 0x91, 0xa7, 0xc1, 0xb8, 0xa3, 0x0a, 0xac, 0xb4, 0x40, 0xe4, 0x53, 0x84, | ||||
| 	0xa8, 0x53, 0xa5, 0xd7, 0xfe, 0x05, 0x4a, 0x55, 0xa9, 0x1c, 0x5a, 0x17, 0xd4, 0xb3, 0xb1, 0x57, | ||||
| 	0xd4, 0x22, 0xb1, 0xcd, 0xee, 0x06, 0x94, 0x73, 0x9f, 0xa6, 0xe7, 0x3e, 0x52, 0xaf, 0x7d, 0x88, | ||||
| 	0xca, 0xbb, 0xeb, 0x10, 0x62, 0x8c, 0x44, 0x4e, 0xde, 0x99, 0xf9, 0xe6, 0x9b, 0x99, 0xdd, 0x99, | ||||
| 	0x31, 0x0c, 0xa6, 0x69, 0x4c, 0xf3, 0xe1, 0x45, 0xfe, 0x52, 0x1e, 0x68, 0x3e, 0xe3, 0x84, 0x0e, | ||||
| 	0x0b, 0x9a, 0xf3, 0x4a, 0x08, 0x84, 0x80, 0x9b, 0x17, 0x79, 0x20, 0x30, 0x81, 0x54, 0xfb, 0x36, | ||||
| 	0x74, 0x42, 0x72, 0x35, 0x23, 0x8c, 0xfb, 0xef, 0xa0, 0x7b, 0x92, 0x32, 0x1e, 0x12, 0x56, 0xe4, | ||||
| 	0x19, 0x23, 0x18, 0x80, 0x25, 0x40, 0xcc, 0xd3, 0xfb, 0xad, 0xc1, 0x93, 0xd1, 0x56, 0xb0, 0xe2, | ||||
| 	0x1c, 0x84, 0xe5, 0x27, 0x54, 0x28, 0xff, 0x2d, 0x6c, 0x9c, 0xe4, 0xf9, 0xe5, 0xac, 0x50, 0x84, | ||||
| 	0x78, 0x00, 0xe6, 0xd5, 0x8c, 0xd0, 0xb9, 0xa7, 0xf7, 0xf5, 0x7b, 0xfd, 0xbf, 0x95, 0xd6, 0x50, | ||||
| 	0x82, 0xfc, 0x0f, 0xe0, 0x54, 0xee, 0x6b, 0x26, 0xf0, 0x06, 0xba, 0x92, 0x71, 0xad, 0xf8, 0xef, | ||||
| 	0x61, 0x43, 0x79, 0xaf, 0x19, 0xde, 0x81, 0xee, 0x8f, 0x88, 0xc7, 0x3f, 0xab, 0xfb, 0xfc, 0xad, | ||||
| 	0x83, 0x35, 0x4e, 0xae, 0x09, 0xe5, 0xe8, 0x80, 0x91, 0x26, 0x22, 0x0d, 0x3b, 0x34, 0xd2, 0x04, | ||||
| 	0x87, 0xd0, 0xe6, 0xf3, 0x82, 0x78, 0x46, 0x5f, 0x1f, 0x38, 0xa3, 0xe7, 0x35, 0x62, 0xe9, 0x76, | ||||
| 	0x3a, 0x2f, 0x48, 0x28, 0x80, 0xf8, 0x02, 0x6c, 0x9e, 0x4e, 0x09, 0xe3, 0xd1, 0xb4, 0xf0, 0x5a, | ||||
| 	0x7d, 0x7d, 0xd0, 0x0a, 0x6f, 0x15, 0xe8, 0x42, 0x8b, 0xf3, 0x89, 0xd7, 0x16, 0xfa, 0xf2, 0x58, | ||||
| 	0xe6, 0x4e, 0xae, 0x49, 0xc6, 0x99, 0x67, 0x36, 0xe4, 0x7e, 0x5c, 0x9a, 0x43, 0x85, 0xf2, 0x9f, | ||||
| 	0xc2, 0xe6, 0x57, 0x9a, 0xc7, 0x84, 0xb1, 0xaa, 0x7c, 0xdf, 0x05, 0xe7, 0x88, 0x92, 0x88, 0x93, | ||||
| 	0x65, 0xcd, 0x47, 0x32, 0x21, 0x77, 0x35, 0x67, 0x45, 0xb2, 0x8c, 0xf9, 0xa5, 0x83, 0x29, 0xa8, | ||||
| 	0x31, 0x50, 0x35, 0xea, 0xa2, 0xc6, 0xde, 0xfd, 0x09, 0x34, 0x95, 0x68, 0xac, 0x96, 0x78, 0x00, | ||||
| 	0xa6, 0xf0, 0x13, 0xc5, 0x37, 0xbf, 0x85, 0x04, 0xf9, 0x67, 0x60, 0x8a, 0xb7, 0x44, 0x0f, 0x3a, | ||||
| 	0x8c, 0xd0, 0xeb, 0x34, 0x26, 0xea, 0xf6, 0x2b, 0xb1, 0xb4, 0x5c, 0x44, 0x9c, 0xdc, 0x44, 0x73, | ||||
| 	0x11, 0xcc, 0x0e, 0x2b, 0xb1, 0xb4, 0x64, 0x84, 0xdf, 0xe4, 0xf4, 0x52, 0x04, 0xb3, 0xc3, 0x4a, | ||||
| 	0xf4, 0xff, 0xe8, 0x60, 0x8a, 0x38, 0x0f, 0xf3, 0x46, 0x49, 0x42, 0x09, 0x63, 0x15, 0xaf, 0x12, | ||||
| 	0x97, 0x23, 0xb6, 0x1a, 0x23, 0xb6, 0xef, 0x44, 0xc4, 0x2d, 0xd5, 0x83, 0xd4, 0x33, 0x85, 0x41, | ||||
| 	0x49, 0x88, 0xd0, 0x9e, 0xa4, 0xd9, 0xa5, 0x67, 0x09, 0xad, 0x38, 0x97, 0xd8, 0x29, 0xe1, 0x34, | ||||
| 	0x8d, 0xbd, 0x8e, 0xb8, 0x3d, 0x25, 0xf9, 0x23, 0xb0, 0xbe, 0xf3, 0x88, 0xcf, 0x58, 0xe9, 0x15, | ||||
| 	0xe7, 0x49, 0x95, 0xb2, 0x38, 0xe3, 0x33, 0x30, 0x09, 0xa5, 0x39, 0x55, 0xd9, 0x4a, 0xc1, 0x1f, | ||||
| 	0x83, 0x23, 0x7d, 0x16, 0xd3, 0x30, 0x04, 0x8b, 0x09, 0x8d, 0x9a, 0xa6, 0xed, 0xda, 0x0b, 0x28, | ||||
| 	0x07, 0x05, 0xdb, 0x1f, 0x01, 0xdc, 0xb6, 0x31, 0x22, 0x38, 0x52, 0x1a, 0x67, 0x59, 0x3e, 0xcb, | ||||
| 	0x62, 0xe2, 0x6a, 0xe8, 0x42, 0x57, 0xea, 0x64, 0x0f, 0xb9, 0xfa, 0xfe, 0x10, 0xec, 0x45, 0x5b, | ||||
| 	0x20, 0x80, 0x25, 0x1b, 0xd0, 0xd5, 0xca, 0xb3, 0x6c, 0x3d, 0x57, 0x2f, 0xcf, 0xca, 0xc1, 0x18, | ||||
| 	0xfd, 0x33, 0xc0, 0x0a, 0xe5, 0x95, 0x7c, 0x01, 0x4b, 0xee, 0x0f, 0xdc, 0xad, 0xa5, 0x76, 0x67, | ||||
| 	0x2f, 0xf5, 0xf6, 0x1a, 0xed, 0xaa, 0x89, 0x35, 0x3c, 0x04, 0x53, 0xcc, 0x32, 0xee, 0xd4, 0xb0, | ||||
| 	0xcb, 0x33, 0xde, 0x6b, 0x98, 0x2b, 0x5f, 0x7b, 0xa5, 0xe3, 0x21, 0xd8, 0xb2, 0xbc, 0x94, 0x11, | ||||
| 	0xf4, 0xea, 0x0d, 0xab, 0x28, 0xb6, 0x1b, 0xa6, 0x5f, 0x70, 0x7c, 0x82, 0x8e, 0x9a, 0x4b, 0x6c, | ||||
| 	0xc2, 0xf5, 0xfa, 0x35, 0xc3, 0xea, 0x28, 0x6b, 0x78, 0xbc, 0xe8, 0x81, 0xe6, 0x44, 0xf6, 0x9a, | ||||
| 	0x5e, 0x74, 0x41, 0x33, 0xfa, 0x6b, 0x80, 0x79, 0x1a, 0x9d, 0x4f, 0x08, 0x1e, 0x55, 0x8f, 0x83, | ||||
| 	0x0d, 0xa3, 0x78, 0x0f, 0xdd, 0xca, 0x3a, 0xd1, 0x4a, 0x12, 0xf9, 0xaa, 0x8f, 0x20, 0x59, 0xd9, | ||||
| 	0x40, 0x82, 0x44, 0xb6, 0xc3, 0x23, 0x48, 0x56, 0x96, 0x96, 0x86, 0x63, 0x68, 0x97, 0xff, 0xbe, | ||||
| 	0x07, 0x6e, 0xa7, 0xde, 0x08, 0xcb, 0x3f, 0x4b, 0x5f, 0xc3, 0xcf, 0xd5, 0xce, 0xd9, 0x69, 0xf8, | ||||
| 	0xcf, 0x28, 0xa2, 0xdd, 0x26, 0x73, 0xc5, 0x74, 0x6e, 0x89, 0x7f, 0xf5, 0xeb, 0xff, 0x01, 0x00, | ||||
| 	0x00, 0xff, 0xff, 0xe2, 0xe9, 0xe2, 0x3b, 0xd7, 0x07, 0x00, 0x00, | ||||
| } | ||||
|  | ||||
| // Reference imports to suppress errors if they are not otherwise used. | ||||
|   | ||||
| @@ -7,6 +7,7 @@ service Router { | ||||
| 	rpc Lookup(LookupRequest) returns (LookupResponse) {}; | ||||
|         rpc Watch(WatchRequest) returns (stream Event) {}; | ||||
|         rpc Advertise(Request) returns (stream Advert) {}; | ||||
|         rpc Solicit(Request) returns (Response) {}; | ||||
|         rpc Process(Advert) returns (ProcessResponse) {}; | ||||
| 	rpc Status(Request) returns (StatusResponse) {}; | ||||
| } | ||||
| @@ -22,6 +23,9 @@ service Table { | ||||
| // Empty request | ||||
| message Request {} | ||||
|  | ||||
| // Empty response | ||||
| message Response {} | ||||
|  | ||||
| // ListResponse is returned by List | ||||
| message ListResponse { | ||||
| 	repeated Route routes = 1; | ||||
| @@ -37,10 +41,12 @@ message LookupResponse { | ||||
| 	repeated Route routes = 1; | ||||
| } | ||||
|  | ||||
| // QueryRequest queries Table for Routes | ||||
| message QueryRequest{ | ||||
| 	Query query = 1; | ||||
| } | ||||
|  | ||||
| // QueryResponse is returned by Query | ||||
| message QueryResponse { | ||||
| 	repeated Route routes = 1; | ||||
| } | ||||
| @@ -117,10 +123,12 @@ message Route { | ||||
| 	string gateway = 3; | ||||
| 	// the network for this destination | ||||
| 	string network = 4; | ||||
| 	// router if the router id | ||||
| 	string router = 5; | ||||
| 	// the network link | ||||
| 	string link = 5; | ||||
| 	string link = 6; | ||||
| 	// the metric / score of this route | ||||
| 	int64 metric = 6; | ||||
| 	int64 metric = 7; | ||||
| } | ||||
|  | ||||
| message Status { | ||||
|   | ||||
| @@ -11,29 +11,38 @@ type QueryOptions struct { | ||||
| 	Gateway string | ||||
| 	// Network is network address | ||||
| 	Network string | ||||
| 	// Router is router id | ||||
| 	Router string | ||||
| } | ||||
|  | ||||
| // QueryService sets destination address | ||||
| // QueryService sets service to query | ||||
| func QueryService(s string) QueryOption { | ||||
| 	return func(o *QueryOptions) { | ||||
| 		o.Service = s | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // QueryGateway sets route gateway | ||||
| // QueryGateway sets gateway address to query | ||||
| func QueryGateway(g string) QueryOption { | ||||
| 	return func(o *QueryOptions) { | ||||
| 		o.Gateway = g | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // QueryNetwork sets route network address | ||||
| // QueryNetwork sets network name to query | ||||
| func QueryNetwork(n string) QueryOption { | ||||
| 	return func(o *QueryOptions) { | ||||
| 		o.Network = n | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // QueryRouter sets router id to query | ||||
| func QueryRouter(r string) QueryOption { | ||||
| 	return func(o *QueryOptions) { | ||||
| 		o.Router = r | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Query is routing table query | ||||
| type Query interface { | ||||
| 	// Options returns query options | ||||
| @@ -52,6 +61,7 @@ func NewQuery(opts ...QueryOption) Query { | ||||
| 		Service: "*", | ||||
| 		Gateway: "*", | ||||
| 		Network: "*", | ||||
| 		Router:  "*", | ||||
| 	} | ||||
|  | ||||
| 	for _, o := range opts { | ||||
| @@ -67,8 +77,3 @@ func NewQuery(opts ...QueryOption) Query { | ||||
| func (q *query) Options() QueryOptions { | ||||
| 	return q.opts | ||||
| } | ||||
|  | ||||
| // String prints routing table query in human readable form | ||||
| func (q query) String() string { | ||||
| 	return "query" | ||||
| } | ||||
|   | ||||
| @@ -7,9 +7,9 @@ import ( | ||||
| var ( | ||||
| 	// DefaultLink is default network link | ||||
| 	DefaultLink = "local" | ||||
| 	// DefaultLocalMetric is default route cost metric for the local network | ||||
| 	// DefaultLocalMetric is default route cost for a local route | ||||
| 	DefaultLocalMetric = 1 | ||||
| 	// DefaultNetworkMetric is default route cost metric for the micro network | ||||
| 	// DefaultNetworkMetric is default route cost for a network route | ||||
| 	DefaultNetworkMetric = 10 | ||||
| ) | ||||
|  | ||||
| @@ -23,6 +23,8 @@ type Route struct { | ||||
| 	Gateway string | ||||
| 	// Network is network address | ||||
| 	Network string | ||||
| 	// Router is router id | ||||
| 	Router string | ||||
| 	// Link is network link | ||||
| 	Link string | ||||
| 	// Metric is the route cost metric | ||||
| @@ -33,6 +35,6 @@ type Route struct { | ||||
| func (r *Route) Hash() uint64 { | ||||
| 	h := fnv.New64() | ||||
| 	h.Reset() | ||||
| 	h.Write([]byte(r.Service + r.Address + r.Gateway + r.Network + r.Link)) | ||||
| 	h.Write([]byte(r.Service + r.Address + r.Gateway + r.Network + r.Router + r.Link)) | ||||
| 	return h.Sum64() | ||||
| } | ||||
|   | ||||
| @@ -5,6 +5,17 @@ import ( | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// DefaultAddress is default router address | ||||
| 	DefaultAddress = ":9093" | ||||
| 	// DefaultName is default router service name | ||||
| 	DefaultName = "go.micro.router" | ||||
| 	// DefaultNetwork is default micro network | ||||
| 	DefaultNetwork = "go.micro" | ||||
| 	// DefaultRouter is default network router | ||||
| 	DefaultRouter = NewRouter() | ||||
| ) | ||||
|  | ||||
| // Router is an interface for a routing control plane | ||||
| type Router interface { | ||||
| 	// Init initializes the router with options | ||||
| @@ -17,6 +28,8 @@ type Router interface { | ||||
| 	Advertise() (<-chan *Advert, error) | ||||
| 	// Process processes incoming adverts | ||||
| 	Process(*Advert) error | ||||
| 	// Solicit advertises the whole routing table to the network | ||||
| 	Solicit() error | ||||
| 	// Lookup queries routes in the routing table | ||||
| 	Lookup(Query) ([]Route, error) | ||||
| 	// Watch returns a watcher which tracks updates to the routing table | ||||
| @@ -31,16 +44,17 @@ type Router interface { | ||||
| 	String() string | ||||
| } | ||||
|  | ||||
| // Table is an interface for routing table | ||||
| type Table interface { | ||||
| 	// Create new route in the routing table | ||||
| 	Create(Route) error | ||||
| 	// Delete deletes existing route from the routing table | ||||
| 	// Delete existing route from the routing table | ||||
| 	Delete(Route) error | ||||
| 	// Update updates route in the routing table | ||||
| 	// Update route in the routing table | ||||
| 	Update(Route) error | ||||
| 	// List returns the list of all routes in the table | ||||
| 	// List all routes in the table | ||||
| 	List() ([]Route, error) | ||||
| 	// Query queries routes in the routing table | ||||
| 	// Query routes in the routing table | ||||
| 	Query(Query) ([]Route, error) | ||||
| } | ||||
|  | ||||
| @@ -125,17 +139,6 @@ type Advert struct { | ||||
| 	Events []*Event | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	// DefaultAddress is default router address | ||||
| 	DefaultAddress = ":9093" | ||||
| 	// DefaultName is default router service name | ||||
| 	DefaultName = "go.micro.router" | ||||
| 	// DefaultNetwork is default micro network | ||||
| 	DefaultNetwork = "go.micro" | ||||
| 	// DefaultRouter is default network router | ||||
| 	DefaultRouter = NewRouter() | ||||
| ) | ||||
|  | ||||
| // NewRouter creates new Router and returns it | ||||
| func NewRouter(opts ...Option) Router { | ||||
| 	return newRouter(opts...) | ||||
|   | ||||
| @@ -220,6 +220,42 @@ func (s *svc) Process(advert *router.Advert) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Solicit advertise all routes | ||||
| func (s *svc) Solicit() error { | ||||
| 	// list all the routes | ||||
| 	routes, err := s.table.List() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	// build events to advertise | ||||
| 	events := make([]*router.Event, len(routes)) | ||||
| 	for i, _ := range events { | ||||
| 		events[i] = &router.Event{ | ||||
| 			Type:      router.Update, | ||||
| 			Timestamp: time.Now(), | ||||
| 			Route:     routes[i], | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	advert := &router.Advert{ | ||||
| 		Id:        s.opts.Id, | ||||
| 		Type:      router.RouteUpdate, | ||||
| 		Timestamp: time.Now(), | ||||
| 		TTL:       time.Duration(router.DefaultAdvertTTL), | ||||
| 		Events:    events, | ||||
| 	} | ||||
|  | ||||
| 	select { | ||||
| 	case s.advertChan <- advert: | ||||
| 	case <-s.exit: | ||||
| 		close(s.advertChan) | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Status returns router status | ||||
| func (s *svc) Status() router.Status { | ||||
| 	s.Lock() | ||||
|   | ||||
| @@ -8,7 +8,14 @@ import ( | ||||
| 	"github.com/google/uuid" | ||||
| ) | ||||
|  | ||||
| // table is an in memory routing table | ||||
| var ( | ||||
| 	// ErrRouteNotFound is returned when no route was found in the routing table | ||||
| 	ErrRouteNotFound = errors.New("route not found") | ||||
| 	// ErrDuplicateRoute is returned when the route already exists | ||||
| 	ErrDuplicateRoute = errors.New("duplicate route") | ||||
| ) | ||||
|  | ||||
| // table is an in-memory routing table | ||||
| type table struct { | ||||
| 	sync.RWMutex | ||||
| 	// routes stores service routes | ||||
| @@ -25,6 +32,19 @@ func newTable(opts ...Option) *table { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // sendEvent sends events to all subscribed watchers | ||||
| func (t *table) sendEvent(e *Event) { | ||||
| 	t.RLock() | ||||
| 	defer t.RUnlock() | ||||
|  | ||||
| 	for _, w := range t.watchers { | ||||
| 		select { | ||||
| 		case w.resChan <- e: | ||||
| 		case <-w.done: | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Create creates new route in the routing table | ||||
| func (t *table) Create(r Route) error { | ||||
| 	service := r.Service | ||||
| @@ -63,8 +83,10 @@ func (t *table) Delete(r Route) error { | ||||
| 		return ErrRouteNotFound | ||||
| 	} | ||||
|  | ||||
| 	delete(t.routes[service], sum) | ||||
| 	go t.sendEvent(&Event{Type: Delete, Timestamp: time.Now(), Route: r}) | ||||
| 	if _, ok := t.routes[service][sum]; ok { | ||||
| 		delete(t.routes[service], sum) | ||||
| 		go t.sendEvent(&Event{Type: Delete, Timestamp: time.Now(), Route: r}) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
| @@ -85,8 +107,10 @@ func (t *table) Update(r Route) error { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	t.routes[service][sum] = r | ||||
| 	go t.sendEvent(&Event{Type: Update, Timestamp: time.Now(), Route: r}) | ||||
| 	if _, ok := t.routes[service][sum]; !ok { | ||||
| 		t.routes[service][sum] = r | ||||
| 		go t.sendEvent(&Event{Type: Update, Timestamp: time.Now(), Route: r}) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
| @@ -106,21 +130,23 @@ func (t *table) List() ([]Route, error) { | ||||
| 	return routes, nil | ||||
| } | ||||
|  | ||||
| // isMatch checks if the route matches given network and router | ||||
| func isMatch(route Route, network, router string) bool { | ||||
| 	if network == "*" || network == route.Network { | ||||
| 		if router == "*" || router == route.Gateway { | ||||
| 			return true | ||||
| // isMatch checks if the route matches given query options | ||||
| func isMatch(route Route, gateway, network, router string) bool { | ||||
| 	if gateway == "*" || gateway == route.Gateway { | ||||
| 		if network == "*" || network == route.Network { | ||||
| 			if router == "*" || router == route.Router { | ||||
| 				return true | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // findRoutes finds all the routes for given network and router and returns them | ||||
| func findRoutes(routes map[uint64]Route, network, router string) []Route { | ||||
| func findRoutes(routes map[uint64]Route, gateway, network, router string) []Route { | ||||
| 	var results []Route | ||||
| 	for _, route := range routes { | ||||
| 		if isMatch(route, network, router) { | ||||
| 		if isMatch(route, gateway, network, router) { | ||||
| 			results = append(results, route) | ||||
| 		} | ||||
| 	} | ||||
| @@ -136,13 +162,13 @@ func (t *table) Query(q Query) ([]Route, error) { | ||||
| 		if _, ok := t.routes[q.Options().Service]; !ok { | ||||
| 			return nil, ErrRouteNotFound | ||||
| 		} | ||||
| 		return findRoutes(t.routes[q.Options().Service], q.Options().Network, q.Options().Gateway), nil | ||||
| 		return findRoutes(t.routes[q.Options().Service], q.Options().Gateway, q.Options().Network, q.Options().Router), nil | ||||
| 	} | ||||
|  | ||||
| 	var results []Route | ||||
| 	// search through all destinations | ||||
| 	for _, routes := range t.routes { | ||||
| 		results = append(results, findRoutes(routes, q.Options().Network, q.Options().Gateway)...) | ||||
| 		results = append(results, findRoutes(routes, q.Options().Gateway, q.Options().Network, q.Options().Router)...) | ||||
| 	} | ||||
|  | ||||
| 	return results, nil | ||||
| @@ -181,23 +207,3 @@ func (t *table) Watch(opts ...WatchOption) (Watcher, error) { | ||||
|  | ||||
| 	return w, nil | ||||
| } | ||||
|  | ||||
| // sendEvent sends events to all subscribed watchers | ||||
| func (t *table) sendEvent(e *Event) { | ||||
| 	t.RLock() | ||||
| 	defer t.RUnlock() | ||||
|  | ||||
| 	for _, w := range t.watchers { | ||||
| 		select { | ||||
| 		case w.resChan <- e: | ||||
| 		case <-w.done: | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	// ErrRouteNotFound is returned when no route was found in the routing table | ||||
| 	ErrRouteNotFound = errors.New("route not found") | ||||
| 	// ErrDuplicateRoute is returned when the route already exists | ||||
| 	ErrDuplicateRoute = errors.New("duplicate route") | ||||
| ) | ||||
|   | ||||
| @@ -9,6 +9,7 @@ func testSetup() (*table, Route) { | ||||
| 		Service: "dest.svc", | ||||
| 		Gateway: "dest.gw", | ||||
| 		Network: "dest.network", | ||||
| 		Router:  "src.router", | ||||
| 		Link:    "det.link", | ||||
| 		Metric:  10, | ||||
| 	} | ||||
| @@ -109,11 +110,13 @@ func TestQuery(t *testing.T) { | ||||
| 	svc := []string{"svc1", "svc2", "svc3"} | ||||
| 	net := []string{"net1", "net2", "net1"} | ||||
| 	gw := []string{"gw1", "gw2", "gw3"} | ||||
| 	rtr := []string{"rtr1", "rt2", "rt3"} | ||||
|  | ||||
| 	for i := 0; i < len(svc); i++ { | ||||
| 		route.Service = svc[i] | ||||
| 		route.Network = net[i] | ||||
| 		route.Gateway = gw[i] | ||||
| 		route.Router = rtr[i] | ||||
| 		if err := table.Create(route); err != nil { | ||||
| 			t.Errorf("error adding route: %s", err) | ||||
| 		} | ||||
| @@ -127,8 +130,9 @@ func TestQuery(t *testing.T) { | ||||
| 		t.Errorf("error looking up routes: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	// query particular net | ||||
| 	query = NewQuery(QueryNetwork("net1")) | ||||
| 	// query routes particular network | ||||
| 	network := "net1" | ||||
| 	query = NewQuery(QueryNetwork(network)) | ||||
|  | ||||
| 	routes, err = table.Query(query) | ||||
| 	if err != nil { | ||||
| @@ -139,7 +143,13 @@ func TestQuery(t *testing.T) { | ||||
| 		t.Errorf("incorrect number of routes returned. Expected: %d, found: %d", 2, len(routes)) | ||||
| 	} | ||||
|  | ||||
| 	// query particular gateway | ||||
| 	for _, route := range routes { | ||||
| 		if route.Network != network { | ||||
| 			t.Errorf("incorrect route returned. Expected network: %s, found: %s", network, route.Network) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// query routes for particular gateway | ||||
| 	gateway := "gw1" | ||||
| 	query = NewQuery(QueryGateway(gateway)) | ||||
|  | ||||
| @@ -156,11 +166,28 @@ func TestQuery(t *testing.T) { | ||||
| 		t.Errorf("incorrect route returned. Expected gateway: %s, found: %s", gateway, routes[0].Gateway) | ||||
| 	} | ||||
|  | ||||
| 	// query particular route | ||||
| 	network := "net1" | ||||
| 	// query routes for particular router | ||||
| 	router := "rtr1" | ||||
| 	query = NewQuery(QueryRouter(router)) | ||||
|  | ||||
| 	routes, err = table.Query(query) | ||||
| 	if err != nil { | ||||
| 		t.Errorf("error looking up routes: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	if len(routes) != 1 { | ||||
| 		t.Errorf("incorrect number of routes returned. Expected: %d, found: %d", 1, len(routes)) | ||||
| 	} | ||||
|  | ||||
| 	if routes[0].Router != router { | ||||
| 		t.Errorf("incorrect route returned. Expected router: %s, found: %s", router, routes[0].Router) | ||||
| 	} | ||||
|  | ||||
| 	// query particular gateway and network | ||||
| 	query = NewQuery( | ||||
| 		QueryGateway(gateway), | ||||
| 		QueryNetwork(network), | ||||
| 		QueryRouter(router), | ||||
| 	) | ||||
|  | ||||
| 	routes, err = table.Query(query) | ||||
| @@ -180,7 +207,11 @@ func TestQuery(t *testing.T) { | ||||
| 		t.Errorf("incorrect network returned. Expected network: %s, found: %s", network, routes[0].Network) | ||||
| 	} | ||||
|  | ||||
| 	// bullshit route query | ||||
| 	if routes[0].Router != router { | ||||
| 		t.Errorf("incorrect route returned. Expected router: %s, found: %s", router, routes[0].Router) | ||||
| 	} | ||||
|  | ||||
| 	// non-existen route query | ||||
| 	query = NewQuery(QueryService("foobar")) | ||||
|  | ||||
| 	routes, err = table.Query(query) | ||||
|   | ||||
| @@ -6,6 +6,11 @@ import ( | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// ErrWatcherStopped is returned when routing table watcher has been stopped | ||||
| 	ErrWatcherStopped = errors.New("watcher stopped") | ||||
| ) | ||||
|  | ||||
| // EventType defines routing table event | ||||
| type EventType int | ||||
|  | ||||
| @@ -42,9 +47,6 @@ type Event struct { | ||||
| 	Route Route | ||||
| } | ||||
|  | ||||
| // WatchOption is used to define what routes to watch in the table | ||||
| type WatchOption func(*WatchOptions) | ||||
|  | ||||
| // Watcher defines routing table watcher interface | ||||
| // Watcher returns updates to the routing table | ||||
| type Watcher interface { | ||||
| @@ -56,7 +58,11 @@ type Watcher interface { | ||||
| 	Stop() | ||||
| } | ||||
|  | ||||
| // WatchOption is used to define what routes to watch in the table | ||||
| type WatchOption func(*WatchOptions) | ||||
|  | ||||
| // WatchOptions are table watcher options | ||||
| // TODO: expand the options to watch based on other criteria | ||||
| type WatchOptions struct { | ||||
| 	// Service allows to watch specific service routes | ||||
| 	Service string | ||||
| @@ -70,6 +76,7 @@ func WatchService(s string) WatchOption { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // tableWatcher implements routing table Watcher | ||||
| type tableWatcher struct { | ||||
| 	sync.RWMutex | ||||
| 	id      string | ||||
| @@ -113,8 +120,3 @@ func (w *tableWatcher) Stop() { | ||||
| 		close(w.done) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	// ErrWatcherStopped is returned when routing table watcher has been stopped | ||||
| 	ErrWatcherStopped = errors.New("watcher stopped") | ||||
| ) | ||||
|   | ||||
							
								
								
									
										21
									
								
								service.go
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								service.go
									
									
									
									
									
								
							| @@ -3,6 +3,7 @@ package micro | ||||
| import ( | ||||
| 	"os" | ||||
| 	"os/signal" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 	"syscall" | ||||
|  | ||||
| @@ -10,7 +11,9 @@ import ( | ||||
| 	"github.com/micro/go-micro/config/cmd" | ||||
| 	"github.com/micro/go-micro/debug/handler" | ||||
| 	"github.com/micro/go-micro/metadata" | ||||
| 	"github.com/micro/go-micro/plugin" | ||||
| 	"github.com/micro/go-micro/server" | ||||
| 	"github.com/micro/go-micro/util/log" | ||||
| ) | ||||
|  | ||||
| type service struct { | ||||
| @@ -44,6 +47,24 @@ func (s *service) Init(opts ...Option) { | ||||
| 	} | ||||
|  | ||||
| 	s.once.Do(func() { | ||||
| 		// setup the plugins | ||||
| 		for _, p := range strings.Split(os.Getenv("MICRO_PLUGIN"), ",") { | ||||
| 			if len(p) == 0 { | ||||
| 				continue | ||||
| 			} | ||||
|  | ||||
| 			// load the plugin | ||||
| 			c, err := plugin.Load(p) | ||||
| 			if err != nil { | ||||
| 				log.Fatal(err) | ||||
| 			} | ||||
|  | ||||
| 			// initialise the plugin | ||||
| 			if err := plugin.Init(c); err != nil { | ||||
| 				log.Fatal(err) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		// Initialise the command flags, overriding new service | ||||
| 		_ = s.opts.Cmd.Init( | ||||
| 			cmd.Broker(&s.opts.Broker), | ||||
|   | ||||
| @@ -58,7 +58,7 @@ func (t *tunBroker) Disconnect() error { | ||||
| func (t *tunBroker) Publish(topic string, m *broker.Message, opts ...broker.PublishOption) error { | ||||
| 	// TODO: this is probably inefficient, we might want to just maintain an open connection | ||||
| 	// it may be easier to add broadcast to the tunnel | ||||
| 	c, err := t.tunnel.Dial(topic) | ||||
| 	c, err := t.tunnel.Dial(topic, tunnel.DialMulticast()) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										101
									
								
								tunnel/link.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								tunnel/link.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| package tunnel | ||||
|  | ||||
| import ( | ||||
| 	"sync" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/google/uuid" | ||||
| 	"github.com/micro/go-micro/transport" | ||||
| ) | ||||
|  | ||||
| type link struct { | ||||
| 	transport.Socket | ||||
|  | ||||
| 	sync.RWMutex | ||||
|  | ||||
| 	// unique id of this link e.g uuid | ||||
| 	// which we define for ourselves | ||||
| 	id string | ||||
| 	// whether its a loopback connection | ||||
| 	// this flag is used by the transport listener | ||||
| 	// which accepts inbound quic connections | ||||
| 	loopback bool | ||||
| 	// whether its actually connected | ||||
| 	// dialled side sets it to connected | ||||
| 	// after sending the message. the | ||||
| 	// listener waits for the connect | ||||
| 	connected bool | ||||
| 	// the last time we received a keepalive | ||||
| 	// on this link from the remote side | ||||
| 	lastKeepAlive time.Time | ||||
| 	// channels keeps a mapping of channels and last seen | ||||
| 	channels map[string]time.Time | ||||
| 	// stop the link | ||||
| 	closed chan bool | ||||
| } | ||||
|  | ||||
| func newLink(s transport.Socket) *link { | ||||
| 	l := &link{ | ||||
| 		Socket:   s, | ||||
| 		id:       uuid.New().String(), | ||||
| 		channels: make(map[string]time.Time), | ||||
| 		closed:   make(chan bool), | ||||
| 	} | ||||
| 	go l.run() | ||||
| 	return l | ||||
| } | ||||
|  | ||||
| func (l *link) run() { | ||||
| 	t := time.NewTicker(time.Minute) | ||||
| 	defer t.Stop() | ||||
|  | ||||
| 	for { | ||||
| 		select { | ||||
| 		case <-l.closed: | ||||
| 			return | ||||
| 		case <-t.C: | ||||
| 			// drop any channel mappings older than 2 minutes | ||||
| 			var kill []string | ||||
| 			killTime := time.Minute * 2 | ||||
|  | ||||
| 			l.RLock() | ||||
| 			for ch, t := range l.channels { | ||||
| 				if d := time.Since(t); d > killTime { | ||||
| 					kill = append(kill, ch) | ||||
| 				} | ||||
| 			} | ||||
| 			l.RUnlock() | ||||
|  | ||||
| 			// if nothing to kill don't bother with a wasted lock | ||||
| 			if len(kill) == 0 { | ||||
| 				continue | ||||
| 			} | ||||
|  | ||||
| 			// kill the channels! | ||||
| 			l.Lock() | ||||
| 			for _, ch := range kill { | ||||
| 				delete(l.channels, ch) | ||||
| 			} | ||||
| 			l.Unlock() | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (l *link) Id() string { | ||||
| 	l.RLock() | ||||
| 	defer l.RUnlock() | ||||
|  | ||||
| 	return l.id | ||||
| } | ||||
|  | ||||
| func (l *link) Close() error { | ||||
| 	select { | ||||
| 	case <-l.closed: | ||||
| 		return nil | ||||
| 	default: | ||||
| 		close(l.closed) | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
| @@ -8,8 +8,13 @@ import ( | ||||
| 	"github.com/micro/go-micro/transport" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	// ErrLinkClosed is returned when attempting i/o operation on the closed link | ||||
| 	ErrLinkClosed = errors.New("link closed") | ||||
| ) | ||||
| 
 | ||||
| // Link is a layer on top of a transport socket with the | ||||
| // buffering send and recv queue's with the ability to | ||||
| // buffering send and recv queues with the ability to | ||||
| // measure the actual transport link and reconnect if | ||||
| // an address is specified. | ||||
| type Link interface { | ||||
| @@ -28,10 +33,6 @@ type Link interface { | ||||
| 	Length() int | ||||
| } | ||||
| 
 | ||||
| var ( | ||||
| 	ErrLinkClosed = errors.New("link closed") | ||||
| ) | ||||
| 
 | ||||
| // NewLink creates a new link on top of a socket | ||||
| func NewLink(opts ...options.Option) Link { | ||||
| 	return newLink(options.NewOptions(opts...)) | ||||
| @@ -2,79 +2,148 @@ package tunnel | ||||
|  | ||||
| import ( | ||||
| 	"io" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/micro/go-micro/util/log" | ||||
| ) | ||||
|  | ||||
| type tunListener struct { | ||||
| 	// address of the listener | ||||
| 	addr string | ||||
| 	channel string | ||||
| 	// the accept channel | ||||
| 	accept chan *socket | ||||
| 	accept chan *session | ||||
| 	// the channel to close | ||||
| 	closed chan bool | ||||
| 	// the tunnel closed channel | ||||
| 	tunClosed chan bool | ||||
| 	// the connection | ||||
| 	conn Conn | ||||
| 	// the listener socket | ||||
| 	socket *socket | ||||
| 	// the listener session | ||||
| 	session *session | ||||
| 	// del func to kill listener | ||||
| 	delFunc func() | ||||
| } | ||||
|  | ||||
| // periodically announce self | ||||
| func (t *tunListener) announce() { | ||||
| 	tick := time.NewTicker(time.Second * 30) | ||||
| 	defer tick.Stop() | ||||
|  | ||||
| 	// first announcement | ||||
| 	t.session.Announce() | ||||
|  | ||||
| 	for { | ||||
| 		select { | ||||
| 		case <-tick.C: | ||||
| 			t.session.Announce() | ||||
| 		case <-t.closed: | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (t *tunListener) process() { | ||||
| 	// our connection map for session | ||||
| 	conns := make(map[string]*socket) | ||||
| 	conns := make(map[string]*session) | ||||
|  | ||||
| 	defer func() { | ||||
| 		// close the sessions | ||||
| 		for _, conn := range conns { | ||||
| 			conn.Close() | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	for { | ||||
| 		select { | ||||
| 		case <-t.closed: | ||||
| 			return | ||||
| 		case <-t.tunClosed: | ||||
| 			t.Close() | ||||
| 			return | ||||
| 		// receive a new message | ||||
| 		case m := <-t.socket.recv: | ||||
| 			// get a socket | ||||
| 			sock, ok := conns[m.session] | ||||
| 			log.Debugf("Tunnel listener received id %s session %s exists: %t", m.id, m.session, ok) | ||||
| 		case m := <-t.session.recv: | ||||
| 			// get a session | ||||
| 			sess, ok := conns[m.session] | ||||
| 			log.Debugf("Tunnel listener received channel %s session %s exists: %t", m.channel, m.session, ok) | ||||
| 			if !ok { | ||||
| 				// create a new socket session | ||||
| 				sock = &socket{ | ||||
| 					// our tunnel id | ||||
| 					id: m.id, | ||||
| 				switch m.typ { | ||||
| 				case "open", "session": | ||||
| 				default: | ||||
| 					continue | ||||
| 				} | ||||
|  | ||||
| 				// create a new session session | ||||
| 				sess = &session{ | ||||
| 					// the id of the remote side | ||||
| 					tunnel: m.tunnel, | ||||
| 					// the channel | ||||
| 					channel: m.channel, | ||||
| 					// the session id | ||||
| 					session: m.session, | ||||
| 					// is loopback conn | ||||
| 					loopback: m.loopback, | ||||
| 					// the link the message was received on | ||||
| 					link: m.link, | ||||
| 					// set multicast | ||||
| 					multicast: m.multicast, | ||||
| 					// close chan | ||||
| 					closed: make(chan bool), | ||||
| 					// recv called by the acceptor | ||||
| 					recv: make(chan *message, 128), | ||||
| 					// use the internal send buffer | ||||
| 					send: t.socket.send, | ||||
| 					send: t.session.send, | ||||
| 					// wait | ||||
| 					wait: make(chan bool), | ||||
| 					// error channel | ||||
| 					errChan: make(chan error, 1), | ||||
| 				} | ||||
|  | ||||
| 				// save the socket | ||||
| 				conns[m.session] = sock | ||||
| 				// save the session | ||||
| 				conns[m.session] = sess | ||||
|  | ||||
| 				// send to accept chan | ||||
| 				select { | ||||
| 				case <-t.closed: | ||||
| 					return | ||||
| 				case t.accept <- sock: | ||||
| 				// send to accept chan | ||||
| 				case t.accept <- sess: | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			// an existing session was found | ||||
|  | ||||
| 			// received a close message | ||||
| 			switch m.typ { | ||||
| 			case "close": | ||||
| 				select { | ||||
| 				case <-sess.closed: | ||||
| 					// no op | ||||
| 					delete(conns, m.session) | ||||
| 				default: | ||||
| 					// close and delete session | ||||
| 					close(sess.closed) | ||||
| 					delete(conns, m.session) | ||||
| 				} | ||||
|  | ||||
| 				// continue | ||||
| 				continue | ||||
| 			case "session": | ||||
| 				// operate on this | ||||
| 			default: | ||||
| 				// non operational type | ||||
| 				continue | ||||
| 			} | ||||
|  | ||||
| 			// send this to the accept chan | ||||
| 			select { | ||||
| 			case <-sock.closed: | ||||
| 			case <-sess.closed: | ||||
| 				delete(conns, m.session) | ||||
| 			case sock.recv <- m: | ||||
| 				log.Debugf("Tunnel listener sent to recv chan id %s session %s", m.id, m.session) | ||||
| 			case sess.recv <- m: | ||||
| 				log.Debugf("Tunnel listener sent to recv chan channel %s session %s", m.channel, m.session) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (t *tunListener) Addr() string { | ||||
| 	return t.addr | ||||
| func (t *tunListener) Channel() string { | ||||
| 	return t.channel | ||||
| } | ||||
|  | ||||
| // Close closes tunnel listener | ||||
| @@ -83,26 +152,33 @@ func (t *tunListener) Close() error { | ||||
| 	case <-t.closed: | ||||
| 		return nil | ||||
| 	default: | ||||
| 		// close and delete | ||||
| 		t.delFunc() | ||||
| 		t.session.Close() | ||||
| 		close(t.closed) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Everytime accept is called we essentially block till we get a new connection | ||||
| func (t *tunListener) Accept() (Conn, error) { | ||||
| func (t *tunListener) Accept() (Session, error) { | ||||
| 	select { | ||||
| 	// if the socket is closed return | ||||
| 	// if the session is closed return | ||||
| 	case <-t.closed: | ||||
| 		return nil, io.EOF | ||||
| 	case <-t.tunClosed: | ||||
| 		// close the listener when the tunnel closes | ||||
| 		t.Close() | ||||
| 		return nil, io.EOF | ||||
| 	// wait for a new connection | ||||
| 	case c, ok := <-t.accept: | ||||
| 		// check if the accept chan is closed | ||||
| 		if !ok { | ||||
| 			return nil, io.EOF | ||||
| 		} | ||||
| 		// send back the accept | ||||
| 		if err := c.Accept(); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		return c, nil | ||||
| 	} | ||||
| 	return nil, nil | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| package tunnel | ||||
|  | ||||
| import ( | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/google/uuid" | ||||
| 	"github.com/micro/go-micro/transport" | ||||
| 	"github.com/micro/go-micro/transport/quic" | ||||
| @@ -9,6 +11,8 @@ import ( | ||||
| var ( | ||||
| 	// DefaultAddress is default tunnel bind address | ||||
| 	DefaultAddress = ":0" | ||||
| 	// The shared default token | ||||
| 	DefaultToken = "micro" | ||||
| ) | ||||
|  | ||||
| type Option func(*Options) | ||||
| @@ -21,10 +25,21 @@ type Options struct { | ||||
| 	Address string | ||||
| 	// Nodes are remote nodes | ||||
| 	Nodes []string | ||||
| 	// The shared auth token | ||||
| 	Token string | ||||
| 	// Transport listens to incoming connections | ||||
| 	Transport transport.Transport | ||||
| } | ||||
|  | ||||
| type DialOption func(*DialOptions) | ||||
|  | ||||
| type DialOptions struct { | ||||
| 	// specify a multicast connection | ||||
| 	Multicast bool | ||||
| 	// the dial timeout | ||||
| 	Timeout time.Duration | ||||
| } | ||||
|  | ||||
| // The tunnel id | ||||
| func Id(id string) Option { | ||||
| 	return func(o *Options) { | ||||
| @@ -46,6 +61,13 @@ func Nodes(n ...string) Option { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Token sets the shared token for auth | ||||
| func Token(t string) Option { | ||||
| 	return func(o *Options) { | ||||
| 		o.Token = t | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Transport listens for incoming connections | ||||
| func Transport(t transport.Transport) Option { | ||||
| 	return func(o *Options) { | ||||
| @@ -58,6 +80,22 @@ func DefaultOptions() Options { | ||||
| 	return Options{ | ||||
| 		Id:        uuid.New().String(), | ||||
| 		Address:   DefaultAddress, | ||||
| 		Token:     DefaultToken, | ||||
| 		Transport: quic.NewTransport(), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Dial options | ||||
|  | ||||
| // Dial multicast sets the multicast option to send only to those mapped | ||||
| func DialMulticast() DialOption { | ||||
| 	return func(o *DialOptions) { | ||||
| 		o.Multicast = true | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func DialTimeout(t time.Duration) DialOption { | ||||
| 	return func(o *DialOptions) { | ||||
| 		o.Timeout = t | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										286
									
								
								tunnel/session.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										286
									
								
								tunnel/session.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,286 @@ | ||||
| package tunnel | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"io" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/micro/go-micro/transport" | ||||
| 	"github.com/micro/go-micro/util/log" | ||||
| ) | ||||
|  | ||||
| // session is our pseudo session for transport.Socket | ||||
| type session struct { | ||||
| 	// the tunnel id | ||||
| 	tunnel string | ||||
| 	// the channel name | ||||
| 	channel string | ||||
| 	// the session id based on Micro.Tunnel-Session | ||||
| 	session string | ||||
| 	// closed | ||||
| 	closed chan bool | ||||
| 	// remote addr | ||||
| 	remote string | ||||
| 	// local addr | ||||
| 	local string | ||||
| 	// send chan | ||||
| 	send chan *message | ||||
| 	// recv chan | ||||
| 	recv chan *message | ||||
| 	// wait until we have a connection | ||||
| 	wait chan bool | ||||
| 	// if the discovery worked | ||||
| 	discovered bool | ||||
| 	// if the session was accepted | ||||
| 	accepted bool | ||||
| 	// outbound marks the session as outbound dialled connection | ||||
| 	outbound bool | ||||
| 	// lookback marks the session as a loopback on the inbound | ||||
| 	loopback bool | ||||
| 	// if the session is multicast | ||||
| 	multicast bool | ||||
| 	// if the session is broadcast | ||||
| 	broadcast bool | ||||
| 	// the timeout | ||||
| 	timeout time.Duration | ||||
| 	// the link on which this message was received | ||||
| 	link string | ||||
| 	// the error response | ||||
| 	errChan chan error | ||||
| } | ||||
|  | ||||
| // message is sent over the send channel | ||||
| type message struct { | ||||
| 	// type of message | ||||
| 	typ string | ||||
| 	// tunnel id | ||||
| 	tunnel string | ||||
| 	// channel name | ||||
| 	channel string | ||||
| 	// the session id | ||||
| 	session string | ||||
| 	// outbound marks the message as outbound | ||||
| 	outbound bool | ||||
| 	// loopback marks the message intended for loopback | ||||
| 	loopback bool | ||||
| 	// whether to send as multicast | ||||
| 	multicast bool | ||||
| 	// broadcast sets the broadcast type | ||||
| 	broadcast bool | ||||
| 	// the link to send the message on | ||||
| 	link string | ||||
| 	// transport data | ||||
| 	data *transport.Message | ||||
| 	// the error channel | ||||
| 	errChan chan error | ||||
| } | ||||
|  | ||||
| func (s *session) Remote() string { | ||||
| 	return s.remote | ||||
| } | ||||
|  | ||||
| func (s *session) Local() string { | ||||
| 	return s.local | ||||
| } | ||||
|  | ||||
| func (s *session) Id() string { | ||||
| 	return s.session | ||||
| } | ||||
|  | ||||
| func (s *session) Channel() string { | ||||
| 	return s.channel | ||||
| } | ||||
|  | ||||
| // newMessage creates a new message based on the session | ||||
| func (s *session) newMessage(typ string) *message { | ||||
| 	return &message{ | ||||
| 		typ:       typ, | ||||
| 		tunnel:    s.tunnel, | ||||
| 		channel:   s.channel, | ||||
| 		session:   s.session, | ||||
| 		outbound:  s.outbound, | ||||
| 		loopback:  s.loopback, | ||||
| 		multicast: s.multicast, | ||||
| 		link:      s.link, | ||||
| 		errChan:   s.errChan, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Open will fire the open message for the session. This is called by the dialler. | ||||
| func (s *session) Open() error { | ||||
| 	// create a new message | ||||
| 	msg := s.newMessage("open") | ||||
|  | ||||
| 	// send open message | ||||
| 	s.send <- msg | ||||
|  | ||||
| 	// wait for an error response for send | ||||
| 	select { | ||||
| 	case err := <-msg.errChan: | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	case <-s.closed: | ||||
| 		return io.EOF | ||||
| 	} | ||||
|  | ||||
| 	// we don't wait on multicast | ||||
| 	if s.multicast { | ||||
| 		s.accepted = true | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	// now wait for the accept | ||||
| 	select { | ||||
| 	case msg = <-s.recv: | ||||
| 		if msg.typ != "accept" { | ||||
| 			log.Debugf("Received non accept message in Open %s", msg.typ) | ||||
| 			return errors.New("failed to connect") | ||||
| 		} | ||||
| 		// set to accepted | ||||
| 		s.accepted = true | ||||
| 		// set link | ||||
| 		s.link = msg.link | ||||
| 	case <-time.After(s.timeout): | ||||
| 		return ErrDialTimeout | ||||
| 	case <-s.closed: | ||||
| 		return io.EOF | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Accept sends the accept response to an open message from a dialled connection | ||||
| func (s *session) Accept() error { | ||||
| 	msg := s.newMessage("accept") | ||||
|  | ||||
| 	// send the accept message | ||||
| 	select { | ||||
| 	case <-s.closed: | ||||
| 		return io.EOF | ||||
| 	case s.send <- msg: | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	// wait for send response | ||||
| 	select { | ||||
| 	case err := <-s.errChan: | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	case <-s.closed: | ||||
| 		return io.EOF | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Announce sends an announcement to notify that this session exists. This is primarily used by the listener. | ||||
| func (s *session) Announce() error { | ||||
| 	msg := s.newMessage("announce") | ||||
| 	// we don't need an error back | ||||
| 	msg.errChan = nil | ||||
| 	// announce to all | ||||
| 	msg.broadcast = true | ||||
| 	// we don't need the link | ||||
| 	msg.link = "" | ||||
|  | ||||
| 	select { | ||||
| 	case s.send <- msg: | ||||
| 		return nil | ||||
| 	case <-s.closed: | ||||
| 		return io.EOF | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Send is used to send a message | ||||
| func (s *session) Send(m *transport.Message) error { | ||||
| 	select { | ||||
| 	case <-s.closed: | ||||
| 		return io.EOF | ||||
| 	default: | ||||
| 		// no op | ||||
| 	} | ||||
|  | ||||
| 	// make copy | ||||
| 	data := &transport.Message{ | ||||
| 		Header: make(map[string]string), | ||||
| 		Body:   m.Body, | ||||
| 	} | ||||
|  | ||||
| 	for k, v := range m.Header { | ||||
| 		data.Header[k] = v | ||||
| 	} | ||||
|  | ||||
| 	// create a new message | ||||
| 	msg := s.newMessage("session") | ||||
| 	// set the data | ||||
| 	msg.data = data | ||||
|  | ||||
| 	// if multicast don't set the link | ||||
| 	if s.multicast { | ||||
| 		msg.link = "" | ||||
| 	} | ||||
|  | ||||
| 	log.Debugf("Appending %+v to send backlog", msg) | ||||
| 	// send the actual message | ||||
| 	s.send <- msg | ||||
|  | ||||
| 	// wait for an error response | ||||
| 	select { | ||||
| 	case err := <-msg.errChan: | ||||
| 		return err | ||||
| 	case <-s.closed: | ||||
| 		return io.EOF | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Recv is used to receive a message | ||||
| func (s *session) Recv(m *transport.Message) error { | ||||
| 	select { | ||||
| 	case <-s.closed: | ||||
| 		return errors.New("session is closed") | ||||
| 	default: | ||||
| 		// no op | ||||
| 	} | ||||
| 	// recv from backlog | ||||
| 	msg := <-s.recv | ||||
|  | ||||
| 	// check the error if one exists | ||||
| 	select { | ||||
| 	case err := <-msg.errChan: | ||||
| 		return err | ||||
| 	default: | ||||
| 	} | ||||
|  | ||||
| 	log.Debugf("Received %+v from recv backlog", msg) | ||||
| 	// set message | ||||
| 	*m = *msg.data | ||||
| 	// return nil | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Close closes the session by sending a close message | ||||
| func (s *session) Close() error { | ||||
| 	select { | ||||
| 	case <-s.closed: | ||||
| 		// no op | ||||
| 	default: | ||||
| 		close(s.closed) | ||||
|  | ||||
| 		// append to backlog | ||||
| 		msg := s.newMessage("close") | ||||
| 		// no error response on close | ||||
| 		msg.errChan = nil | ||||
|  | ||||
| 		// send the close message | ||||
| 		select { | ||||
| 		case s.send <- msg: | ||||
| 		default: | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										115
									
								
								tunnel/socket.go
									
									
									
									
									
								
							
							
						
						
									
										115
									
								
								tunnel/socket.go
									
									
									
									
									
								
							| @@ -1,115 +0,0 @@ | ||||
| package tunnel | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
|  | ||||
| 	"github.com/micro/go-micro/transport" | ||||
| 	"github.com/micro/go-micro/util/log" | ||||
| ) | ||||
|  | ||||
| // socket is our pseudo socket for transport.Socket | ||||
| type socket struct { | ||||
| 	// socket id based on Micro-Tunnel | ||||
| 	id string | ||||
| 	// the session id based on Micro.Tunnel-Session | ||||
| 	session string | ||||
| 	// closed | ||||
| 	closed chan bool | ||||
| 	// remote addr | ||||
| 	remote string | ||||
| 	// local addr | ||||
| 	local string | ||||
| 	// send chan | ||||
| 	send chan *message | ||||
| 	// recv chan | ||||
| 	recv chan *message | ||||
| 	// wait until we have a connection | ||||
| 	wait chan bool | ||||
| 	// outbound marks the socket as outbound | ||||
| 	outbound bool | ||||
| } | ||||
|  | ||||
| // message is sent over the send channel | ||||
| type message struct { | ||||
| 	// tunnel id | ||||
| 	id string | ||||
| 	// the session id | ||||
| 	session string | ||||
| 	// outbound marks the message as outbound | ||||
| 	outbound bool | ||||
| 	// transport data | ||||
| 	data *transport.Message | ||||
| } | ||||
|  | ||||
| func (s *socket) Remote() string { | ||||
| 	return s.remote | ||||
| } | ||||
|  | ||||
| func (s *socket) Local() string { | ||||
| 	return s.local | ||||
| } | ||||
|  | ||||
| func (s *socket) Id() string { | ||||
| 	return s.id | ||||
| } | ||||
|  | ||||
| func (s *socket) Session() string { | ||||
| 	return s.session | ||||
| } | ||||
|  | ||||
| func (s *socket) Send(m *transport.Message) error { | ||||
| 	select { | ||||
| 	case <-s.closed: | ||||
| 		return errors.New("socket is closed") | ||||
| 	default: | ||||
| 		// no op | ||||
| 	} | ||||
|  | ||||
| 	// make copy | ||||
| 	data := &transport.Message{ | ||||
| 		Header: make(map[string]string), | ||||
| 		Body:   m.Body, | ||||
| 	} | ||||
|  | ||||
| 	for k, v := range m.Header { | ||||
| 		data.Header[k] = v | ||||
| 	} | ||||
|  | ||||
| 	// append to backlog | ||||
| 	msg := &message{ | ||||
| 		id:       s.id, | ||||
| 		session:  s.session, | ||||
| 		outbound: s.outbound, | ||||
| 		data:     data, | ||||
| 	} | ||||
| 	log.Debugf("Appending %+v to send backlog", msg) | ||||
| 	s.send <- msg | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (s *socket) Recv(m *transport.Message) error { | ||||
| 	select { | ||||
| 	case <-s.closed: | ||||
| 		return errors.New("socket is closed") | ||||
| 	default: | ||||
| 		// no op | ||||
| 	} | ||||
| 	// recv from backlog | ||||
| 	msg := <-s.recv | ||||
| 	log.Debugf("Received %+v from recv backlog", msg) | ||||
| 	// set message | ||||
| 	*m = *msg.data | ||||
| 	// return nil | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Close closes the socket | ||||
| func (s *socket) Close() error { | ||||
| 	select { | ||||
| 	case <-s.closed: | ||||
| 		// no op | ||||
| 	default: | ||||
| 		close(s.closed) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| @@ -10,7 +10,7 @@ type tunListener struct { | ||||
| } | ||||
|  | ||||
| func (t *tunListener) Addr() string { | ||||
| 	return t.l.Addr() | ||||
| 	return t.l.Channel() | ||||
| } | ||||
|  | ||||
| func (t *tunListener) Close() error { | ||||
|   | ||||
| @@ -2,11 +2,23 @@ | ||||
| package tunnel | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/micro/go-micro/transport" | ||||
| ) | ||||
|  | ||||
| // Tunnel creates a gre network tunnel on top of a link. | ||||
| // It establishes multiple streams using the Micro-Tunnel-Id header | ||||
| var ( | ||||
| 	// DefaultDialTimeout is the dial timeout if none is specified | ||||
| 	DefaultDialTimeout = time.Second * 5 | ||||
| 	// ErrDialTimeout is returned by a call to Dial where the timeout occurs | ||||
| 	ErrDialTimeout = errors.New("dial timeout") | ||||
| 	// ErrDiscoverChan is returned when we failed to receive the "announce" back from a discovery | ||||
| 	ErrDiscoverChan = errors.New("failed to discover channel") | ||||
| ) | ||||
|  | ||||
| // Tunnel creates a gre tunnel on top of the go-micro/transport. | ||||
| // It establishes multiple streams using the Micro-Tunnel-Channel header | ||||
| // and Micro-Tunnel-Session header. The tunnel id is a hash of | ||||
| // the address being requested. | ||||
| type Tunnel interface { | ||||
| @@ -17,27 +29,37 @@ type Tunnel interface { | ||||
| 	Connect() error | ||||
| 	// Close closes the tunnel | ||||
| 	Close() error | ||||
| 	// Dial an endpoint | ||||
| 	Dial(addr string) (Conn, error) | ||||
| 	// Accept connections | ||||
| 	Listen(addr string) (Listener, error) | ||||
| 	// Connect to a channel | ||||
| 	Dial(channel string, opts ...DialOption) (Session, error) | ||||
| 	// Accept connections on a channel | ||||
| 	Listen(channel string) (Listener, error) | ||||
| 	// All the links the tunnel is connected to | ||||
| 	Links() []Link | ||||
| 	// Name of the tunnel implementation | ||||
| 	String() string | ||||
| } | ||||
|  | ||||
| // The listener provides similar constructs to the transport.Listener | ||||
| type Listener interface { | ||||
| 	Addr() string | ||||
| 	Close() error | ||||
| 	Accept() (Conn, error) | ||||
| // Link represents internal links to the tunnel | ||||
| type Link interface { | ||||
| 	// The id of the link | ||||
| 	Id() string | ||||
| 	// honours transport socket | ||||
| 	transport.Socket | ||||
| } | ||||
|  | ||||
| // Conn is a connection dialed or accepted which includes the tunnel id and session | ||||
| type Conn interface { | ||||
| 	// Specifies the tunnel id | ||||
| // The listener provides similar constructs to the transport.Listener | ||||
| type Listener interface { | ||||
| 	Accept() (Session, error) | ||||
| 	Channel() string | ||||
| 	Close() error | ||||
| } | ||||
|  | ||||
| // Session is a unique session created when dialling or accepting connections on the tunnel | ||||
| type Session interface { | ||||
| 	// The unique session id | ||||
| 	Id() string | ||||
| 	// The session | ||||
| 	Session() string | ||||
| 	// The channel name | ||||
| 	Channel() string | ||||
| 	// a transport socket | ||||
| 	transport.Socket | ||||
| } | ||||
|   | ||||
| @@ -187,30 +187,15 @@ func testBrokenTunAccept(t *testing.T, tun Tunnel, wait chan bool, wg *sync.Wait | ||||
| 	if err := c.Recv(m); err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	tun.Close() | ||||
|  | ||||
| 	// re-start tunnel | ||||
| 	err = tun.Connect() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	defer tun.Close() | ||||
|  | ||||
| 	// listen on some virtual address | ||||
| 	tl, err = tun.Listen("test-tunnel") | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	// close all the links | ||||
| 	for _, link := range tun.Links() { | ||||
| 		link.Close() | ||||
| 	} | ||||
|  | ||||
| 	// receiver ready; notify sender | ||||
| 	wait <- true | ||||
|  | ||||
| 	// accept a connection | ||||
| 	c, err = tl.Accept() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	// accept the message | ||||
| 	m = new(transport.Message) | ||||
| 	if err := c.Recv(m); err != nil { | ||||
| @@ -279,6 +264,7 @@ func TestReconnectTunnel(t *testing.T) { | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	defer tunB.Close() | ||||
|  | ||||
| 	// we manually override the tunnel.ReconnectTime value here | ||||
| 	// this is so that we make the reconnects faster than the default 5s | ||||
| @@ -289,6 +275,7 @@ func TestReconnectTunnel(t *testing.T) { | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	defer tunA.Close() | ||||
|  | ||||
| 	wait := make(chan bool) | ||||
|  | ||||
|   | ||||
| @@ -40,14 +40,20 @@ func Extract(addr string) (string, error) { | ||||
| 	} | ||||
|  | ||||
| 	var addrs []net.Addr | ||||
| 	var loAddrs []net.Addr | ||||
| 	for _, iface := range ifaces { | ||||
| 		ifaceAddrs, err := iface.Addrs() | ||||
| 		if err != nil { | ||||
| 			// ignore error, interface can dissapear from system | ||||
| 			continue | ||||
| 		} | ||||
| 		if iface.Flags&net.FlagLoopback != 0 { | ||||
| 			loAddrs = append(loAddrs, ifaceAddrs...) | ||||
| 			continue | ||||
| 		} | ||||
| 		addrs = append(addrs, ifaceAddrs...) | ||||
| 	} | ||||
| 	addrs = append(addrs, loAddrs...) | ||||
|  | ||||
| 	var ipAddr []byte | ||||
| 	var publicIP []byte | ||||
|   | ||||
| @@ -14,7 +14,7 @@ type Level int | ||||
| const ( | ||||
| 	LevelFatal Level = iota | ||||
| 	LevelInfo | ||||
| 	LevelWarn | ||||
| 	LevelError | ||||
| 	LevelDebug | ||||
| 	LevelTrace | ||||
| ) | ||||
| @@ -29,16 +29,16 @@ var ( | ||||
|  | ||||
| func init() { | ||||
| 	switch os.Getenv("MICRO_LOG_LEVEL") { | ||||
| 	case "trace": | ||||
| 		level = LevelTrace | ||||
| 	case "debug": | ||||
| 		level = LevelDebug | ||||
| 	case "info": | ||||
| 		level = LevelInfo | ||||
| 	case "trace": | ||||
| 		level = LevelTrace | ||||
| 	case "error": | ||||
| 		level = LevelError | ||||
| 	case "fatal": | ||||
| 		level = LevelFatal | ||||
| 	case "warn": | ||||
| 		level = LevelWarn | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -98,14 +98,14 @@ func Infof(format string, v ...interface{}) { | ||||
| 	WithLevelf(LevelInfo, format, v...) | ||||
| } | ||||
|  | ||||
| // Warn provides warn level logging | ||||
| func Warn(v ...interface{}) { | ||||
| 	WithLevel(LevelWarn, v...) | ||||
| // Error provides warn level logging | ||||
| func Error(v ...interface{}) { | ||||
| 	WithLevel(LevelError, v...) | ||||
| } | ||||
|  | ||||
| // Warnf provides warn level logging | ||||
| func Warnf(format string, v ...interface{}) { | ||||
| 	WithLevelf(LevelWarn, format, v...) | ||||
| // Errorf provides warn level logging | ||||
| func Errorf(format string, v ...interface{}) { | ||||
| 	WithLevelf(LevelError, format, v...) | ||||
| } | ||||
|  | ||||
| // Fatal logs with Log and then exits with os.Exit(1) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user