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
 | 
					# Binaries for programs and plugins
 | 
				
			||||||
*.exe
 | 
					*.exe
 | 
				
			||||||
*.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/proto":        protoCodec{},
 | 
				
			||||||
		"application/protobuf":     protoCodec{},
 | 
							"application/protobuf":     protoCodec{},
 | 
				
			||||||
		"application/octet-stream": protoCodec{},
 | 
							"application/octet-stream": protoCodec{},
 | 
				
			||||||
 | 
							"application/grpc":         protoCodec{},
 | 
				
			||||||
		"application/grpc+json":    jsonCodec{},
 | 
							"application/grpc+json":    jsonCodec{},
 | 
				
			||||||
		"application/grpc+proto":   protoCodec{},
 | 
							"application/grpc+proto":   protoCodec{},
 | 
				
			||||||
		"application/grpc+bytes":   bytesCodec{},
 | 
							"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 {
 | 
						if err != nil {
 | 
				
			||||||
		return errors.InternalServerError("go.micro.client", "connection error: %v", err)
 | 
							return errors.InternalServerError("go.micro.client", "connection error: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,6 +44,6 @@ Load the source into config
 | 
				
			|||||||
// Create new config
 | 
					// Create new config
 | 
				
			||||||
conf := config.NewConfig()
 | 
					conf := config.NewConfig()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Load file source
 | 
					// Load consul source
 | 
				
			||||||
conf.Load(consulSource)
 | 
					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
 | 
					// Create new config
 | 
				
			||||||
conf := config.NewConfig()
 | 
					conf := config.NewConfig()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Load file source
 | 
					// Load env source
 | 
				
			||||||
conf.Load(src)
 | 
					conf.Load(src)
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,6 +42,6 @@ Load the source into config
 | 
				
			|||||||
// Create new config
 | 
					// Create new config
 | 
				
			||||||
conf := config.NewConfig()
 | 
					conf := config.NewConfig()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Load file source
 | 
					// Load flag source
 | 
				
			||||||
conf.Load(flagSource)
 | 
					conf.Load(flagSource)
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,6 +39,6 @@ Load the source into config
 | 
				
			|||||||
// Create new config
 | 
					// Create new config
 | 
				
			||||||
conf := config.NewConfig()
 | 
					conf := config.NewConfig()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Load file source
 | 
					// Load memory source
 | 
				
			||||||
conf.Load(memorySource)
 | 
					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 is for creating internetworks
 | 
				
			||||||
package network
 | 
					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"
 | 
						"github.com/micro/go-micro/network/resolver"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Resolver is a DNS network resolve
 | 
				
			||||||
type Resolver struct{}
 | 
					type Resolver struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Resolve assumes ID is a domain name e.g micro.mu
 | 
					// Resolve assumes ID is a domain name e.g micro.mu
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,7 @@ import (
 | 
				
			|||||||
	"github.com/micro/go-micro/network/resolver"
 | 
						"github.com/micro/go-micro/network/resolver"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Resolver is a HTTP network resolver
 | 
				
			||||||
type Resolver struct {
 | 
					type Resolver struct {
 | 
				
			||||||
	// If not set, defaults to http
 | 
						// If not set, defaults to http
 | 
				
			||||||
	Proto string
 | 
						Proto string
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,7 @@ import (
 | 
				
			|||||||
	"github.com/micro/go-micro/registry"
 | 
						"github.com/micro/go-micro/registry"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Resolver is a registry network resolver
 | 
				
			||||||
type Resolver struct {
 | 
					type Resolver struct {
 | 
				
			||||||
	// Registry is the registry to use otherwise we use the defaul
 | 
						// Registry is the registry to use otherwise we use the defaul
 | 
				
			||||||
	Registry registry.Registry
 | 
						Registry registry.Registry
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,7 @@ package resolver
 | 
				
			|||||||
// via the name to connect to. This is done based on Network.Name().
 | 
					// 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.
 | 
					// Before we can be part of any network, we have to connect to it.
 | 
				
			||||||
type Resolver interface {
 | 
					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)
 | 
						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
 | 
							p.Routes[route.Service][route.Hash()] = route
 | 
				
			||||||
	case "delete":
 | 
						case "delete":
 | 
				
			||||||
		if _, ok := p.Routes[route.Service]; !ok {
 | 
					 | 
				
			||||||
			return fmt.Errorf("route not found")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		delete(p.Routes[route.Service], route.Hash())
 | 
							delete(p.Routes[route.Service], route.Hash())
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return fmt.Errorf("unknown action: %s", action)
 | 
							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 to call
 | 
				
			||||||
	endpoint := req.Endpoint()
 | 
						endpoint := req.Endpoint()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(service) == 0 {
 | 
				
			||||||
 | 
							return errors.BadRequest("go.micro.proxy", "service name is blank")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// are we network routing or local routing
 | 
						// are we network routing or local routing
 | 
				
			||||||
	if len(p.Links) == 0 {
 | 
						if len(p.Links) == 0 {
 | 
				
			||||||
		local = true
 | 
							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
 | 
					package mdns
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/micro/go-micro/registry"
 | 
						"github.com/micro/go-micro/registry"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -9,3 +11,13 @@ import (
 | 
				
			|||||||
func NewRegistry(opts ...registry.Option) registry.Registry {
 | 
					func NewRegistry(opts ...registry.Option) registry.Registry {
 | 
				
			||||||
	return registry.NewRegistry(opts...)
 | 
						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"
 | 
						hash "github.com/mitchellh/hashstructure"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var (
 | 
				
			||||||
 | 
						// use a .micro domain rather than .local
 | 
				
			||||||
 | 
						mdnsDomain = "micro"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type mdnsTxt struct {
 | 
					type mdnsTxt struct {
 | 
				
			||||||
	Service   string
 | 
						Service   string
 | 
				
			||||||
	Version   string
 | 
						Version   string
 | 
				
			||||||
@@ -29,6 +34,8 @@ type mdnsEntry struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type mdnsRegistry struct {
 | 
					type mdnsRegistry struct {
 | 
				
			||||||
	opts Options
 | 
						opts Options
 | 
				
			||||||
 | 
						// the mdns domain
 | 
				
			||||||
 | 
						domain string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sync.Mutex
 | 
						sync.Mutex
 | 
				
			||||||
	services map[string][]*mdnsEntry
 | 
						services map[string][]*mdnsEntry
 | 
				
			||||||
@@ -36,11 +43,25 @@ type mdnsRegistry struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func newRegistry(opts ...Option) Registry {
 | 
					func newRegistry(opts ...Option) Registry {
 | 
				
			||||||
	options := Options{
 | 
						options := Options{
 | 
				
			||||||
 | 
							Context: context.Background(),
 | 
				
			||||||
		Timeout: time.Millisecond * 100,
 | 
							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{
 | 
						return &mdnsRegistry{
 | 
				
			||||||
		opts:     options,
 | 
							opts:     options,
 | 
				
			||||||
 | 
							domain:   domain,
 | 
				
			||||||
		services: make(map[string][]*mdnsEntry),
 | 
							services: make(map[string][]*mdnsEntry),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -66,7 +87,7 @@ func (m *mdnsRegistry) Register(service *Service, opts ...RegisterOption) error
 | 
				
			|||||||
		s, err := mdns.NewMDNSService(
 | 
							s, err := mdns.NewMDNSService(
 | 
				
			||||||
			service.Name,
 | 
								service.Name,
 | 
				
			||||||
			"_services",
 | 
								"_services",
 | 
				
			||||||
			"",
 | 
								m.domain+".",
 | 
				
			||||||
			"",
 | 
								"",
 | 
				
			||||||
			9999,
 | 
								9999,
 | 
				
			||||||
			[]net.IP{net.ParseIP("0.0.0.0")},
 | 
								[]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(
 | 
							s, err := mdns.NewMDNSService(
 | 
				
			||||||
			node.Id,
 | 
								node.Id,
 | 
				
			||||||
			service.Name,
 | 
								service.Name,
 | 
				
			||||||
			"",
 | 
								m.domain+".",
 | 
				
			||||||
			"",
 | 
								"",
 | 
				
			||||||
			port,
 | 
								port,
 | 
				
			||||||
			[]net.IP{net.ParseIP(host)},
 | 
								[]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)
 | 
						p.Context, _ = context.WithTimeout(context.Background(), m.opts.Timeout)
 | 
				
			||||||
	// set entries channel
 | 
						// set entries channel
 | 
				
			||||||
	p.Entries = entries
 | 
						p.Entries = entries
 | 
				
			||||||
 | 
						// set the domain
 | 
				
			||||||
 | 
						p.Domain = m.domain
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	go func() {
 | 
						go func() {
 | 
				
			||||||
		for {
 | 
							for {
 | 
				
			||||||
@@ -223,7 +246,9 @@ func (m *mdnsRegistry) GetService(service string) ([]*Service, error) {
 | 
				
			|||||||
				if p.Service == "_services" {
 | 
									if p.Service == "_services" {
 | 
				
			||||||
					continue
 | 
										continue
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
									if p.Domain != m.domain {
 | 
				
			||||||
 | 
										continue
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				if e.TTL == 0 {
 | 
									if e.TTL == 0 {
 | 
				
			||||||
					continue
 | 
										continue
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -288,6 +313,8 @@ func (m *mdnsRegistry) ListServices() ([]*Service, error) {
 | 
				
			|||||||
	p.Context, _ = context.WithTimeout(context.Background(), m.opts.Timeout)
 | 
						p.Context, _ = context.WithTimeout(context.Background(), m.opts.Timeout)
 | 
				
			||||||
	// set entries channel
 | 
						// set entries channel
 | 
				
			||||||
	p.Entries = entries
 | 
						p.Entries = entries
 | 
				
			||||||
 | 
						// set domain
 | 
				
			||||||
 | 
						p.Domain = m.domain
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var services []*Service
 | 
						var services []*Service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -298,7 +325,9 @@ func (m *mdnsRegistry) ListServices() ([]*Service, error) {
 | 
				
			|||||||
				if e.TTL == 0 {
 | 
									if e.TTL == 0 {
 | 
				
			||||||
					continue
 | 
										continue
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
									if !strings.HasSuffix(e.Name, p.Domain+".") {
 | 
				
			||||||
 | 
										continue
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				name := strings.TrimSuffix(e.Name, "."+p.Service+"."+p.Domain+".")
 | 
									name := strings.TrimSuffix(e.Name, "."+p.Service+"."+p.Domain+".")
 | 
				
			||||||
				if !serviceMap[name] {
 | 
									if !serviceMap[name] {
 | 
				
			||||||
					serviceMap[name] = true
 | 
										serviceMap[name] = true
 | 
				
			||||||
@@ -329,9 +358,10 @@ func (m *mdnsRegistry) Watch(opts ...WatchOption) (Watcher, error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	md := &mdnsWatcher{
 | 
						md := &mdnsWatcher{
 | 
				
			||||||
		wo:   wo,
 | 
							wo:     wo,
 | 
				
			||||||
		ch:   make(chan *mdns.ServiceEntry, 32),
 | 
							ch:     make(chan *mdns.ServiceEntry, 32),
 | 
				
			||||||
		exit: make(chan struct{}),
 | 
							exit:   make(chan struct{}),
 | 
				
			||||||
 | 
							domain: m.domain,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	go func() {
 | 
						go func() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,8 @@ type mdnsWatcher struct {
 | 
				
			|||||||
	wo   WatchOptions
 | 
						wo   WatchOptions
 | 
				
			||||||
	ch   chan *mdns.ServiceEntry
 | 
						ch   chan *mdns.ServiceEntry
 | 
				
			||||||
	exit chan struct{}
 | 
						exit chan struct{}
 | 
				
			||||||
 | 
						// the mdns domain
 | 
				
			||||||
 | 
						domain string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *mdnsWatcher) Next() (*Result, error) {
 | 
					func (m *mdnsWatcher) Next() (*Result, error) {
 | 
				
			||||||
@@ -46,13 +48,14 @@ func (m *mdnsWatcher) Next() (*Result, error) {
 | 
				
			|||||||
				Endpoints: txt.Endpoints,
 | 
									Endpoints: txt.Endpoints,
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// TODO: don't hardcode .local.
 | 
								// skip anything without the domain we care about
 | 
				
			||||||
			if !strings.HasSuffix(e.Name, "."+service.Name+".local.") {
 | 
								suffix := fmt.Sprintf(".%s.%s.", service.Name, m.domain)
 | 
				
			||||||
 | 
								if !strings.HasSuffix(e.Name, suffix) {
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			service.Nodes = append(service.Nodes, &Node{
 | 
								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),
 | 
									Address:  fmt.Sprintf("%s:%d", e.AddrV4.String(), e.Port),
 | 
				
			||||||
				Metadata: txt.Metadata,
 | 
									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/google/uuid"
 | 
				
			||||||
	"github.com/micro/go-micro/registry"
 | 
						"github.com/micro/go-micro/registry"
 | 
				
			||||||
 | 
						"github.com/micro/go-micro/util/log"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -43,7 +44,7 @@ var (
 | 
				
			|||||||
// router implements default router
 | 
					// router implements default router
 | 
				
			||||||
type router struct {
 | 
					type router struct {
 | 
				
			||||||
	sync.RWMutex
 | 
						sync.RWMutex
 | 
				
			||||||
	opts      Options
 | 
						options   Options
 | 
				
			||||||
	status    Status
 | 
						status    Status
 | 
				
			||||||
	table     *table
 | 
						table     *table
 | 
				
			||||||
	exit      chan struct{}
 | 
						exit      chan struct{}
 | 
				
			||||||
@@ -70,7 +71,7 @@ func newRouter(opts ...Option) Router {
 | 
				
			|||||||
	status := Status{Code: Stopped, Error: nil}
 | 
						status := Status{Code: Stopped, Error: nil}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return &router{
 | 
						return &router{
 | 
				
			||||||
		opts:        options,
 | 
							options:     options,
 | 
				
			||||||
		status:      status,
 | 
							status:      status,
 | 
				
			||||||
		table:       newTable(),
 | 
							table:       newTable(),
 | 
				
			||||||
		advertWg:    &sync.WaitGroup{},
 | 
							advertWg:    &sync.WaitGroup{},
 | 
				
			||||||
@@ -85,7 +86,7 @@ func (r *router) Init(opts ...Option) error {
 | 
				
			|||||||
	defer r.Unlock()
 | 
						defer r.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, o := range opts {
 | 
						for _, o := range opts {
 | 
				
			||||||
		o(&r.opts)
 | 
							o(&r.options)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
@@ -94,10 +95,10 @@ func (r *router) Init(opts ...Option) error {
 | 
				
			|||||||
// Options returns router options
 | 
					// Options returns router options
 | 
				
			||||||
func (r *router) Options() Options {
 | 
					func (r *router) Options() Options {
 | 
				
			||||||
	r.Lock()
 | 
						r.Lock()
 | 
				
			||||||
	opts := r.opts
 | 
						options := r.options
 | 
				
			||||||
	r.Unlock()
 | 
						r.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return opts
 | 
						return options
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Table returns routing table
 | 
					// 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 {
 | 
							if err := r.table.Delete(route); err != nil && err != ErrRouteNotFound {
 | 
				
			||||||
			return fmt.Errorf("failed deleting route for service %s: %s", route.Service, err)
 | 
								return fmt.Errorf("failed deleting route for service %s: %s", route.Service, err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						case "solicit":
 | 
				
			||||||
 | 
							// nothing to do here
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return fmt.Errorf("failed to manage route for service %s. Unknown action: %s", route.Service, action)
 | 
							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,
 | 
								Service: service.Name,
 | 
				
			||||||
			Address: node.Address,
 | 
								Address: node.Address,
 | 
				
			||||||
			Gateway: "",
 | 
								Gateway: "",
 | 
				
			||||||
			Network: r.opts.Network,
 | 
								Network: r.options.Network,
 | 
				
			||||||
 | 
								Router:  r.options.Id,
 | 
				
			||||||
			Link:    DefaultLink,
 | 
								Link:    DefaultLink,
 | 
				
			||||||
			Metric:  DefaultLocalMetric,
 | 
								Metric:  DefaultLocalMetric,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -278,13 +283,14 @@ func (r *router) publishAdvert(advType AdvertType, events []*Event) {
 | 
				
			|||||||
	defer r.advertWg.Done()
 | 
						defer r.advertWg.Done()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	a := &Advert{
 | 
						a := &Advert{
 | 
				
			||||||
		Id:        r.opts.Id,
 | 
							Id:        r.options.Id,
 | 
				
			||||||
		Type:      advType,
 | 
							Type:      advType,
 | 
				
			||||||
		TTL:       DefaultAdvertTTL,
 | 
							TTL:       DefaultAdvertTTL,
 | 
				
			||||||
		Timestamp: time.Now(),
 | 
							Timestamp: time.Now(),
 | 
				
			||||||
		Events:    events,
 | 
							Events:    events,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						log.Debugf("Router publishing advert; %+v", a)
 | 
				
			||||||
	r.RLock()
 | 
						r.RLock()
 | 
				
			||||||
	for _, sub := range r.subscribers {
 | 
						for _, sub := range r.subscribers {
 | 
				
			||||||
		// check the exit chan first
 | 
							// check the exit chan first
 | 
				
			||||||
@@ -529,20 +535,22 @@ func (r *router) Start() error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// add all local service routes into the routing table
 | 
						// 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)
 | 
							e := fmt.Errorf("failed adding registry routes: %s", err)
 | 
				
			||||||
		r.status = Status{Code: Error, Error: e}
 | 
							r.status = Status{Code: Error, Error: e}
 | 
				
			||||||
		return e
 | 
							return e
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// add default gateway into routing table
 | 
						// add default gateway into routing table
 | 
				
			||||||
	if r.opts.Gateway != "" {
 | 
						if r.options.Gateway != "" {
 | 
				
			||||||
		// note, the only non-default value is the gateway
 | 
							// note, the only non-default value is the gateway
 | 
				
			||||||
		route := Route{
 | 
							route := Route{
 | 
				
			||||||
			Service: "*",
 | 
								Service: "*",
 | 
				
			||||||
			Address: "*",
 | 
								Address: "*",
 | 
				
			||||||
			Gateway: r.opts.Gateway,
 | 
								Gateway: r.options.Gateway,
 | 
				
			||||||
			Network: "*",
 | 
								Network: "*",
 | 
				
			||||||
 | 
								Router:  r.options.Id,
 | 
				
			||||||
 | 
								Link:    DefaultLink,
 | 
				
			||||||
			Metric:  DefaultLocalMetric,
 | 
								Metric:  DefaultLocalMetric,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if err := r.table.Create(route); err != nil {
 | 
							if err := r.table.Create(route); err != nil {
 | 
				
			||||||
@@ -557,7 +565,7 @@ func (r *router) Start() error {
 | 
				
			|||||||
	r.exit = make(chan struct{})
 | 
						r.exit = make(chan struct{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// registry watcher
 | 
						// registry watcher
 | 
				
			||||||
	regWatcher, err := r.opts.Registry.Watch()
 | 
						regWatcher, err := r.options.Registry.Watch()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		e := fmt.Errorf("failed creating registry watcher: %v", err)
 | 
							e := fmt.Errorf("failed creating registry watcher: %v", err)
 | 
				
			||||||
		r.status = Status{Code: Error, Error: e}
 | 
							r.status = Status{Code: Error, Error: e}
 | 
				
			||||||
@@ -595,25 +603,14 @@ func (r *router) Advertise() (<-chan *Advert, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	switch r.status.Code {
 | 
						switch r.status.Code {
 | 
				
			||||||
	case Advertising:
 | 
						case Advertising:
 | 
				
			||||||
		advertChan := make(chan *Advert)
 | 
							advertChan := make(chan *Advert, 128)
 | 
				
			||||||
		r.subscribers[uuid.New().String()] = advertChan
 | 
							r.subscribers[uuid.New().String()] = advertChan
 | 
				
			||||||
		return advertChan, nil
 | 
							return advertChan, nil
 | 
				
			||||||
	case Running:
 | 
						case Running:
 | 
				
			||||||
		// list routing table routes to announce
 | 
							// list all the routes and pack them into even slice to advertise
 | 
				
			||||||
		routes, err := r.table.List()
 | 
							events, err := r.flushRouteEvents(Create)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, fmt.Errorf("failed listing routes: %s", err)
 | 
								return nil, fmt.Errorf("failed to flush 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
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// create event channels
 | 
							// create event channels
 | 
				
			||||||
@@ -646,7 +643,7 @@ func (r *router) Advertise() (<-chan *Advert, error) {
 | 
				
			|||||||
		r.status = Status{Code: Advertising, Error: nil}
 | 
							r.status = Status{Code: Advertising, Error: nil}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// create advert channel
 | 
							// create advert channel
 | 
				
			||||||
		advertChan := make(chan *Advert)
 | 
							advertChan := make(chan *Advert, 128)
 | 
				
			||||||
		r.subscribers[uuid.New().String()] = advertChan
 | 
							r.subscribers[uuid.New().String()] = advertChan
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return advertChan, nil
 | 
							return advertChan, nil
 | 
				
			||||||
@@ -669,6 +666,10 @@ func (r *router) Process(a *Advert) error {
 | 
				
			|||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, event := range events {
 | 
						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
 | 
							// create a copy of the route
 | 
				
			||||||
		route := event.Route
 | 
							route := event.Route
 | 
				
			||||||
		action := event.Type
 | 
							action := event.Type
 | 
				
			||||||
@@ -680,6 +681,43 @@ func (r *router) Process(a *Advert) error {
 | 
				
			|||||||
	return nil
 | 
						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
 | 
					// Lookup routes in the routing table
 | 
				
			||||||
func (r *router) Lookup(q Query) ([]Route, error) {
 | 
					func (r *router) Lookup(q Query) ([]Route, error) {
 | 
				
			||||||
	return r.table.Query(q)
 | 
						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,
 | 
								Address: route.Address,
 | 
				
			||||||
			Gateway: route.Gateway,
 | 
								Gateway: route.Gateway,
 | 
				
			||||||
			Network: route.Network,
 | 
								Network: route.Network,
 | 
				
			||||||
 | 
								Router:  route.Router,
 | 
				
			||||||
			Link:    route.Link,
 | 
								Link:    route.Link,
 | 
				
			||||||
			Metric:  int64(route.Metric),
 | 
								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,
 | 
									Address: event.Route.Address,
 | 
				
			||||||
				Gateway: event.Route.Gateway,
 | 
									Gateway: event.Route.Gateway,
 | 
				
			||||||
				Network: event.Route.Network,
 | 
									Network: event.Route.Network,
 | 
				
			||||||
 | 
									Router:  event.Route.Router,
 | 
				
			||||||
				Link:    event.Route.Link,
 | 
									Link:    event.Route.Link,
 | 
				
			||||||
				Metric:  int64(event.Route.Metric),
 | 
									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,
 | 
								Address: event.Route.Address,
 | 
				
			||||||
			Gateway: event.Route.Gateway,
 | 
								Gateway: event.Route.Gateway,
 | 
				
			||||||
			Network: event.Route.Network,
 | 
								Network: event.Route.Network,
 | 
				
			||||||
 | 
								Router:  event.Route.Router,
 | 
				
			||||||
			Link:    event.Route.Link,
 | 
								Link:    event.Route.Link,
 | 
				
			||||||
			Metric:  int(event.Route.Metric),
 | 
								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,
 | 
								Address: event.Route.Address,
 | 
				
			||||||
			Gateway: event.Route.Gateway,
 | 
								Gateway: event.Route.Gateway,
 | 
				
			||||||
			Network: event.Route.Network,
 | 
								Network: event.Route.Network,
 | 
				
			||||||
 | 
								Router:  event.Route.Router,
 | 
				
			||||||
			Link:    event.Route.Link,
 | 
								Link:    event.Route.Link,
 | 
				
			||||||
			Metric:  int64(event.Route.Metric),
 | 
								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,
 | 
							Address: route.Address,
 | 
				
			||||||
		Gateway: route.Gateway,
 | 
							Gateway: route.Gateway,
 | 
				
			||||||
		Network: route.Network,
 | 
							Network: route.Network,
 | 
				
			||||||
 | 
							Router:  route.Router,
 | 
				
			||||||
		Link:    route.Link,
 | 
							Link:    route.Link,
 | 
				
			||||||
		Metric:  int(route.Metric),
 | 
							Metric:  int(route.Metric),
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
@@ -34,6 +35,7 @@ func (t *Table) Update(ctx context.Context, route *pb.Route, resp *pb.UpdateResp
 | 
				
			|||||||
		Address: route.Address,
 | 
							Address: route.Address,
 | 
				
			||||||
		Gateway: route.Gateway,
 | 
							Gateway: route.Gateway,
 | 
				
			||||||
		Network: route.Network,
 | 
							Network: route.Network,
 | 
				
			||||||
 | 
							Router:  route.Router,
 | 
				
			||||||
		Link:    route.Link,
 | 
							Link:    route.Link,
 | 
				
			||||||
		Metric:  int(route.Metric),
 | 
							Metric:  int(route.Metric),
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
@@ -50,6 +52,7 @@ func (t *Table) Delete(ctx context.Context, route *pb.Route, resp *pb.DeleteResp
 | 
				
			|||||||
		Address: route.Address,
 | 
							Address: route.Address,
 | 
				
			||||||
		Gateway: route.Gateway,
 | 
							Gateway: route.Gateway,
 | 
				
			||||||
		Network: route.Network,
 | 
							Network: route.Network,
 | 
				
			||||||
 | 
							Router:  route.Router,
 | 
				
			||||||
		Link:    route.Link,
 | 
							Link:    route.Link,
 | 
				
			||||||
		Metric:  int(route.Metric),
 | 
							Metric:  int(route.Metric),
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
@@ -74,6 +77,7 @@ func (t *Table) List(ctx context.Context, req *pb.Request, resp *pb.ListResponse
 | 
				
			|||||||
			Address: route.Address,
 | 
								Address: route.Address,
 | 
				
			||||||
			Gateway: route.Gateway,
 | 
								Gateway: route.Gateway,
 | 
				
			||||||
			Network: route.Network,
 | 
								Network: route.Network,
 | 
				
			||||||
 | 
								Router:  route.Router,
 | 
				
			||||||
			Link:    route.Link,
 | 
								Link:    route.Link,
 | 
				
			||||||
			Metric:  int64(route.Metric),
 | 
								Metric:  int64(route.Metric),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -102,6 +106,7 @@ func (t *Table) Query(ctx context.Context, req *pb.QueryRequest, resp *pb.QueryR
 | 
				
			|||||||
			Address: route.Address,
 | 
								Address: route.Address,
 | 
				
			||||||
			Gateway: route.Gateway,
 | 
								Gateway: route.Gateway,
 | 
				
			||||||
			Network: route.Network,
 | 
								Network: route.Network,
 | 
				
			||||||
 | 
								Router:  route.Router,
 | 
				
			||||||
			Link:    route.Link,
 | 
								Link:    route.Link,
 | 
				
			||||||
			Metric:  int64(route.Metric),
 | 
								Metric:  int64(route.Metric),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -672,10 +672,12 @@ type Route struct {
 | 
				
			|||||||
	Gateway string `protobuf:"bytes,3,opt,name=gateway,proto3" json:"gateway,omitempty"`
 | 
						Gateway string `protobuf:"bytes,3,opt,name=gateway,proto3" json:"gateway,omitempty"`
 | 
				
			||||||
	// the network for this destination
 | 
						// the network for this destination
 | 
				
			||||||
	Network string `protobuf:"bytes,4,opt,name=network,proto3" json:"network,omitempty"`
 | 
						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
 | 
						// 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
 | 
						// 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_NoUnkeyedLiteral struct{} `json:"-"`
 | 
				
			||||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
						XXX_unrecognized     []byte   `json:"-"`
 | 
				
			||||||
	XXX_sizecache        int32    `json:"-"`
 | 
						XXX_sizecache        int32    `json:"-"`
 | 
				
			||||||
@@ -734,6 +736,13 @@ func (m *Route) GetNetwork() string {
 | 
				
			|||||||
	return ""
 | 
						return ""
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Route) GetRouter() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Router
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *Route) GetLink() string {
 | 
					func (m *Route) GetLink() string {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.Link
 | 
							return m.Link
 | 
				
			||||||
@@ -861,51 +870,51 @@ func init() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var fileDescriptor_6a36eee0b1adf739 = []byte{
 | 
					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,
 | 
						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,
 | 
						0x10, 0xb6, 0x9d, 0xd8, 0x91, 0xa7, 0xc1, 0xb8, 0xa3, 0x0a, 0xac, 0xb4, 0x40, 0xe4, 0x53, 0x84,
 | 
				
			||||||
	0xd4, 0xa9, 0xd2, 0x6b, 0xff, 0x02, 0xa5, 0xaa, 0x54, 0x0e, 0xad, 0x0b, 0xea, 0xd9, 0xd8, 0x23,
 | 
						0xa8, 0x53, 0xa5, 0xd7, 0xfe, 0x05, 0x4a, 0x55, 0xa9, 0x1c, 0x5a, 0x17, 0xd4, 0xb3, 0xb1, 0x57,
 | 
				
			||||||
	0x6a, 0x91, 0xd8, 0x66, 0x77, 0x03, 0xca, 0xb9, 0x8f, 0xd1, 0x27, 0xe8, 0x73, 0xf5, 0xda, 0x87,
 | 
						0xd4, 0x22, 0xb1, 0xcd, 0xee, 0x06, 0x94, 0x73, 0x9f, 0xa6, 0xe7, 0x3e, 0x52, 0xaf, 0x7d, 0x88,
 | 
				
			||||||
	0xa8, 0xbc, 0xbb, 0x0e, 0x21, 0xc6, 0x48, 0x70, 0xf2, 0xce, 0xdf, 0x37, 0xff, 0x63, 0x18, 0x4c,
 | 
						0xca, 0xbb, 0xeb, 0x10, 0x62, 0x8c, 0x44, 0x4e, 0xde, 0x99, 0xf9, 0xe6, 0x9b, 0x99, 0xdd, 0x99,
 | 
				
			||||||
	0x93, 0x88, 0x65, 0xc3, 0xf3, 0xec, 0xa5, 0x7a, 0xb0, 0x6c, 0x26, 0x88, 0x0d, 0x73, 0x96, 0x89,
 | 
						0x31, 0x0c, 0xa6, 0x69, 0x4c, 0xf3, 0xe1, 0x45, 0xfe, 0x52, 0x1e, 0x68, 0x3e, 0xe3, 0x84, 0x0e,
 | 
				
			||||||
	0x92, 0xf0, 0x25, 0x81, 0x1b, 0xe7, 0x99, 0x2f, 0x75, 0x7c, 0xc5, 0xf6, 0xda, 0xb0, 0x16, 0xd0,
 | 
						0x0b, 0x9a, 0xf3, 0x4a, 0x08, 0x84, 0x80, 0x9b, 0x17, 0x79, 0x20, 0x30, 0x81, 0x54, 0xfb, 0x36,
 | 
				
			||||||
	0xe5, 0x8c, 0xb8, 0xf0, 0xde, 0x41, 0xe7, 0x38, 0xe1, 0x22, 0x20, 0x9e, 0x67, 0x29, 0x27, 0xf4,
 | 
						0x74, 0x42, 0x72, 0x35, 0x23, 0x8c, 0xfb, 0xef, 0xa0, 0x7b, 0x92, 0x32, 0x1e, 0x12, 0x56, 0xe4,
 | 
				
			||||||
	0xc1, 0x96, 0x4a, 0xdc, 0x35, 0xfb, 0xcd, 0xc1, 0x93, 0xd1, 0xa6, 0xbf, 0x62, 0xec, 0x07, 0xc5,
 | 
						0x19, 0x23, 0x18, 0x80, 0x25, 0x40, 0xcc, 0xd3, 0xfb, 0xad, 0xc1, 0x93, 0xd1, 0x56, 0xb0, 0xe2,
 | 
				
			||||||
	0x27, 0xd0, 0x5a, 0xde, 0x5b, 0x58, 0x3f, 0xce, 0xb2, 0x8b, 0x59, 0xae, 0x01, 0x71, 0x1f, 0xac,
 | 
						0x1c, 0x84, 0xe5, 0x27, 0x54, 0x28, 0xff, 0x2d, 0x6c, 0x9c, 0xe4, 0xf9, 0xe5, 0xac, 0x50, 0x84,
 | 
				
			||||||
	0xcb, 0x19, 0xb1, 0xb9, 0x6b, 0xf6, 0xcd, 0x3b, 0xed, 0xbf, 0x15, 0xd2, 0x40, 0x29, 0x79, 0x1f,
 | 
						0x78, 0x00, 0xe6, 0xd5, 0x8c, 0xd0, 0xb9, 0xa7, 0xf7, 0xf5, 0x7b, 0xfd, 0xbf, 0x95, 0xd6, 0x50,
 | 
				
			||||||
	0xa0, 0x5b, 0x9a, 0x3f, 0x32, 0x80, 0x37, 0xd0, 0x51, 0x88, 0x8f, 0xf2, 0xff, 0x1e, 0xd6, 0xb5,
 | 
						0x82, 0xfc, 0x0f, 0xe0, 0x54, 0xee, 0x6b, 0x26, 0xf0, 0x06, 0xba, 0x92, 0x71, 0xad, 0xf8, 0xef,
 | 
				
			||||||
	0xf5, 0x23, 0xdd, 0x77, 0xa1, 0xf3, 0x23, 0x14, 0xd1, 0xcf, 0xb2, 0x9e, 0x7f, 0x4c, 0xb0, 0xc7,
 | 
						0x61, 0x43, 0x79, 0xaf, 0x19, 0xde, 0x81, 0xee, 0x8f, 0x88, 0xc7, 0x3f, 0xab, 0xfb, 0xfc, 0xad,
 | 
				
			||||||
	0xf1, 0x15, 0x31, 0x81, 0x5d, 0x68, 0x24, 0xb1, 0x0c, 0xa3, 0x1d, 0x34, 0x92, 0x18, 0x87, 0xd0,
 | 
						0x83, 0x35, 0x4e, 0xae, 0x09, 0xe5, 0xe8, 0x80, 0x91, 0x26, 0x22, 0x0d, 0x3b, 0x34, 0xd2, 0x04,
 | 
				
			||||||
	0x12, 0xf3, 0x9c, 0xdc, 0x46, 0xdf, 0x1c, 0x74, 0x47, 0xcf, 0x2b, 0xc0, 0xca, 0xec, 0x64, 0x9e,
 | 
						0x87, 0xd0, 0xe6, 0xf3, 0x82, 0x78, 0x46, 0x5f, 0x1f, 0x38, 0xa3, 0xe7, 0x35, 0x62, 0xe9, 0x76,
 | 
				
			||||||
	0x53, 0x20, 0x15, 0xf1, 0x05, 0xb4, 0x45, 0x32, 0x25, 0x2e, 0xc2, 0x69, 0xee, 0x36, 0xfb, 0xe6,
 | 
						0x3a, 0x2f, 0x48, 0x28, 0x80, 0xf8, 0x02, 0x6c, 0x9e, 0x4e, 0x09, 0xe3, 0xd1, 0xb4, 0xf0, 0x5a,
 | 
				
			||||||
	0xa0, 0x19, 0xdc, 0x30, 0xd0, 0x81, 0xa6, 0x10, 0x13, 0xb7, 0x25, 0xf9, 0xc5, 0xb3, 0x88, 0x9d,
 | 
						0x7d, 0x7d, 0xd0, 0x0a, 0x6f, 0x15, 0xe8, 0x42, 0x8b, 0xf3, 0x89, 0xd7, 0x16, 0xfa, 0xf2, 0x58,
 | 
				
			||||||
	0xae, 0x28, 0x15, 0xdc, 0xb5, 0x6a, 0x62, 0x3f, 0x2a, 0xc4, 0x81, 0xd6, 0xf2, 0x9e, 0xc2, 0xc6,
 | 
						0xe6, 0x4e, 0xae, 0x49, 0xc6, 0x99, 0x67, 0x36, 0xe4, 0x7e, 0x5c, 0x9a, 0x43, 0x85, 0xf2, 0x9f,
 | 
				
			||||||
	0x57, 0x96, 0x45, 0xc4, 0x79, 0x99, 0xbe, 0xe7, 0x40, 0xf7, 0x90, 0x51, 0x28, 0x68, 0x99, 0xf3,
 | 
						0xc2, 0xe6, 0x57, 0x9a, 0xc7, 0x84, 0xb1, 0xaa, 0x7c, 0xdf, 0x05, 0xe7, 0x88, 0x92, 0x88, 0x93,
 | 
				
			||||||
	0x91, 0x26, 0x74, 0x9b, 0x73, 0x9a, 0xc7, 0xcb, 0x3a, 0xbf, 0x4c, 0xb0, 0x24, 0x34, 0xfa, 0x3a,
 | 
						0x65, 0xcd, 0x47, 0x32, 0x21, 0x77, 0x35, 0x67, 0x45, 0xb2, 0x8c, 0xf9, 0xa5, 0x83, 0x29, 0xa8,
 | 
				
			||||||
	0x47, 0x53, 0xe6, 0xd8, 0xbb, 0x3b, 0x80, 0xba, 0x14, 0x1b, 0xab, 0x29, 0xee, 0x83, 0x25, 0xed,
 | 
						0x31, 0x50, 0x35, 0xea, 0xa2, 0xc6, 0xde, 0xfd, 0x09, 0x34, 0x95, 0x68, 0xac, 0x96, 0x78, 0x00,
 | 
				
			||||||
	0x64, 0xf2, 0xf5, 0xbd, 0x50, 0x4a, 0xde, 0x29, 0x58, 0xb2, 0x97, 0xe8, 0xc2, 0x1a, 0x27, 0x76,
 | 
						0xa6, 0xf0, 0x13, 0xc5, 0x37, 0xbf, 0x85, 0x04, 0xf9, 0x67, 0x60, 0x8a, 0xb7, 0x44, 0x0f, 0x3a,
 | 
				
			||||||
	0x95, 0x44, 0xa4, 0xab, 0x5f, 0x92, 0x85, 0xe4, 0x3c, 0x14, 0x74, 0x1d, 0xce, 0xa5, 0xb3, 0x76,
 | 
						0x8c, 0xd0, 0xeb, 0x34, 0x26, 0xea, 0xf6, 0x2b, 0xb1, 0xb4, 0x5c, 0x44, 0x9c, 0xdc, 0x44, 0x73,
 | 
				
			||||||
	0x50, 0x92, 0x85, 0x24, 0x25, 0x71, 0x9d, 0xb1, 0x0b, 0xe9, 0xac, 0x1d, 0x94, 0xa4, 0xf7, 0xdb,
 | 
						0x11, 0xcc, 0x0e, 0x2b, 0xb1, 0xb4, 0x64, 0x84, 0xdf, 0xe4, 0xf4, 0x52, 0x04, 0xb3, 0xc3, 0x4a,
 | 
				
			||||||
	0x04, 0x4b, 0xfa, 0xb9, 0x1f, 0x37, 0x8c, 0x63, 0x46, 0x9c, 0x97, 0xb8, 0x9a, 0x5c, 0xf6, 0xd8,
 | 
						0xf4, 0xff, 0xe8, 0x60, 0x8a, 0x38, 0x0f, 0xf3, 0x46, 0x49, 0x42, 0x09, 0x63, 0x15, 0xaf, 0x12,
 | 
				
			||||||
	0xac, 0xf5, 0xd8, 0xba, 0xe5, 0x11, 0x11, 0x5a, 0x93, 0x24, 0xbd, 0x70, 0x2d, 0xc9, 0x96, 0x6f,
 | 
						0x97, 0x23, 0xb6, 0x1a, 0x23, 0xb6, 0xef, 0x44, 0xc4, 0x2d, 0xd5, 0x83, 0xd4, 0x33, 0x85, 0x41,
 | 
				
			||||||
	0xdc, 0x04, 0x7b, 0x4a, 0x82, 0x25, 0x91, 0x6b, 0xcb, 0x2a, 0x69, 0xca, 0x1b, 0x81, 0xfd, 0x5d,
 | 
						0x49, 0x88, 0xd0, 0x9e, 0xa4, 0xd9, 0xa5, 0x67, 0x09, 0xad, 0x38, 0x97, 0xd8, 0x29, 0xe1, 0x34,
 | 
				
			||||||
	0x84, 0x62, 0xc6, 0x0b, 0xab, 0x28, 0x8b, 0xcb, 0xd0, 0xe4, 0x1b, 0x9f, 0x81, 0x45, 0x8c, 0x65,
 | 
						0x8d, 0xbd, 0x8e, 0xb8, 0x3d, 0x25, 0xf9, 0x23, 0xb0, 0xbe, 0xf3, 0x88, 0xcf, 0x58, 0xe9, 0x15,
 | 
				
			||||||
	0x4c, 0x47, 0xa5, 0x08, 0x6f, 0x0c, 0x5d, 0x65, 0xb3, 0x98, 0xfa, 0x21, 0xd8, 0x5c, 0x72, 0xf4,
 | 
						0xe7, 0x49, 0x95, 0xb2, 0x38, 0xe3, 0x33, 0x30, 0x09, 0xa5, 0x39, 0x55, 0xd9, 0x4a, 0xc1, 0x1f,
 | 
				
			||||||
	0xd6, 0x6c, 0x55, 0x2a, 0xad, 0x0d, 0xb4, 0xda, 0xde, 0x08, 0xe0, 0x66, 0x5c, 0x11, 0xa1, 0xab,
 | 
						0x83, 0x23, 0x7d, 0x16, 0xd3, 0x30, 0x04, 0x8b, 0x09, 0x8d, 0x9a, 0xa6, 0xed, 0xda, 0x0b, 0x28,
 | 
				
			||||||
	0xa8, 0x71, 0x9a, 0x66, 0xb3, 0x34, 0x22, 0xc7, 0x40, 0x07, 0x3a, 0x8a, 0xa7, 0x66, 0xc5, 0x31,
 | 
						0x07, 0x05, 0xdb, 0x1f, 0x01, 0xdc, 0xb6, 0x31, 0x22, 0x38, 0x52, 0x1a, 0x67, 0x59, 0x3e, 0xcb,
 | 
				
			||||||
	0xf7, 0x86, 0xd0, 0x5e, 0xb4, 0x1f, 0x01, 0x6c, 0x35, 0x68, 0x8e, 0x51, 0xbc, 0xd5, 0x88, 0x39,
 | 
						0x62, 0xe2, 0x6a, 0xe8, 0x42, 0x57, 0xea, 0x64, 0x0f, 0xb9, 0xfa, 0xfe, 0x10, 0xec, 0x45, 0x5b,
 | 
				
			||||||
	0x66, 0xf1, 0xd6, 0x06, 0x8d, 0xd1, 0xbf, 0x06, 0xd8, 0xb2, 0xf2, 0x0c, 0xbf, 0x80, 0xad, 0xee,
 | 
						0x20, 0x80, 0x25, 0x1b, 0xd0, 0xd5, 0xca, 0xb3, 0x6c, 0x3d, 0x57, 0x2f, 0xcf, 0xca, 0xc1, 0x18,
 | 
				
			||||||
	0x04, 0xee, 0x54, 0x42, 0xbb, 0x75, 0x7f, 0x7a, 0xbb, 0xb5, 0x72, 0x3d, 0xac, 0x06, 0x1e, 0x80,
 | 
						0xfd, 0x33, 0xc0, 0x0a, 0xe5, 0x95, 0x7c, 0x01, 0x4b, 0xee, 0x0f, 0xdc, 0xad, 0xa5, 0x76, 0x67,
 | 
				
			||||||
	0x25, 0x77, 0x16, 0xb7, 0x2b, 0xba, 0xcb, 0xbb, 0xdc, 0xab, 0xd9, 0x1f, 0xcf, 0x78, 0x65, 0xe2,
 | 
						0x2f, 0xf5, 0xf6, 0x1a, 0xed, 0xaa, 0x89, 0x35, 0x3c, 0x04, 0x53, 0xcc, 0x32, 0xee, 0xd4, 0xb0,
 | 
				
			||||||
	0x01, 0xb4, 0x55, 0x7a, 0x09, 0x27, 0x74, 0xab, 0x83, 0xa9, 0x21, 0xb6, 0x6a, 0xb6, 0x5c, 0x62,
 | 
						0xcb, 0x33, 0xde, 0x6b, 0x98, 0x2b, 0x5f, 0x7b, 0xa5, 0xe3, 0x21, 0xd8, 0xb2, 0xbc, 0x94, 0x11,
 | 
				
			||||||
	0x7c, 0x82, 0x35, 0xbd, 0x7f, 0x58, 0xa7, 0xd7, 0xeb, 0x57, 0x04, 0xab, 0x2b, 0x6b, 0xe0, 0xd1,
 | 
						0xf4, 0xea, 0x0d, 0xab, 0x28, 0xb6, 0x1b, 0xa6, 0x5f, 0x70, 0x7c, 0x82, 0x8e, 0x9a, 0x4b, 0x6c,
 | 
				
			||||||
	0x62, 0x06, 0xea, 0x03, 0xd9, 0xad, 0xeb, 0xe8, 0x02, 0x66, 0xf4, 0xb7, 0x01, 0xd6, 0x49, 0x78,
 | 
						0xc2, 0xf5, 0xfa, 0x35, 0xc3, 0xea, 0x28, 0x6b, 0x78, 0xbc, 0xe8, 0x81, 0xe6, 0x44, 0xf6, 0x9a,
 | 
				
			||||||
	0x36, 0x21, 0x3c, 0x2c, 0x9b, 0x83, 0x35, 0x2b, 0x77, 0x07, 0xdc, 0xca, 0xd9, 0x30, 0x0a, 0x10,
 | 
						0x5e, 0x74, 0x41, 0x33, 0xfa, 0x6b, 0x80, 0x79, 0x1a, 0x9d, 0x4f, 0x08, 0x1e, 0x55, 0x8f, 0x83,
 | 
				
			||||||
	0xd5, 0xd5, 0x07, 0x80, 0xac, 0x5c, 0x1a, 0x09, 0xa2, 0xc6, 0xe1, 0x01, 0x20, 0x2b, 0xc7, 0xc9,
 | 
						0x0d, 0xa3, 0x78, 0x0f, 0xdd, 0xca, 0x3a, 0xd1, 0x4a, 0x12, 0xf9, 0xaa, 0x8f, 0x20, 0x59, 0xd9,
 | 
				
			||||||
	0xc0, 0x31, 0xb4, 0x8a, 0x7f, 0xdc, 0x3d, 0xd5, 0xa9, 0x0e, 0xc2, 0xf2, 0x4f, 0xd1, 0x33, 0xf0,
 | 
						0x40, 0x82, 0x44, 0xb6, 0xc3, 0x23, 0x48, 0x56, 0x96, 0x96, 0x86, 0x63, 0x68, 0x97, 0xff, 0xbe,
 | 
				
			||||||
	0x73, 0x79, 0x5b, 0xb6, 0x6b, 0xfe, 0x27, 0x1a, 0x68, 0xa7, 0x4e, 0x5c, 0x22, 0x9d, 0xd9, 0xf2,
 | 
						0x07, 0x6e, 0xa7, 0xde, 0x08, 0xcb, 0x3f, 0x4b, 0x5f, 0xc3, 0xcf, 0xd5, 0xce, 0xd9, 0x69, 0xf8,
 | 
				
			||||||
	0x9f, 0xfc, 0xfa, 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8c, 0xd0, 0xc0, 0x27, 0xbf, 0x07, 0x00,
 | 
						0xcf, 0x28, 0xa2, 0xdd, 0x26, 0x73, 0xc5, 0x74, 0x6e, 0x89, 0x7f, 0xf5, 0xeb, 0xff, 0x01, 0x00,
 | 
				
			||||||
	0x00,
 | 
						0x00, 0xff, 0xff, 0xe2, 0xe9, 0xe2, 0x3b, 0xd7, 0x07, 0x00, 0x00,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Reference imports to suppress errors if they are not otherwise used.
 | 
					// Reference imports to suppress errors if they are not otherwise used.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,7 @@ service Router {
 | 
				
			|||||||
	rpc Lookup(LookupRequest) returns (LookupResponse) {};
 | 
						rpc Lookup(LookupRequest) returns (LookupResponse) {};
 | 
				
			||||||
        rpc Watch(WatchRequest) returns (stream Event) {};
 | 
					        rpc Watch(WatchRequest) returns (stream Event) {};
 | 
				
			||||||
        rpc Advertise(Request) returns (stream Advert) {};
 | 
					        rpc Advertise(Request) returns (stream Advert) {};
 | 
				
			||||||
 | 
					        rpc Solicit(Request) returns (Response) {};
 | 
				
			||||||
        rpc Process(Advert) returns (ProcessResponse) {};
 | 
					        rpc Process(Advert) returns (ProcessResponse) {};
 | 
				
			||||||
	rpc Status(Request) returns (StatusResponse) {};
 | 
						rpc Status(Request) returns (StatusResponse) {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -22,6 +23,9 @@ service Table {
 | 
				
			|||||||
// Empty request
 | 
					// Empty request
 | 
				
			||||||
message Request {}
 | 
					message Request {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Empty response
 | 
				
			||||||
 | 
					message Response {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ListResponse is returned by List
 | 
					// ListResponse is returned by List
 | 
				
			||||||
message ListResponse {
 | 
					message ListResponse {
 | 
				
			||||||
	repeated Route routes = 1;
 | 
						repeated Route routes = 1;
 | 
				
			||||||
@@ -37,10 +41,12 @@ message LookupResponse {
 | 
				
			|||||||
	repeated Route routes = 1;
 | 
						repeated Route routes = 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// QueryRequest queries Table for Routes
 | 
				
			||||||
message QueryRequest{
 | 
					message QueryRequest{
 | 
				
			||||||
	Query query = 1;
 | 
						Query query = 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// QueryResponse is returned by Query
 | 
				
			||||||
message QueryResponse {
 | 
					message QueryResponse {
 | 
				
			||||||
	repeated Route routes = 1;
 | 
						repeated Route routes = 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -117,10 +123,12 @@ message Route {
 | 
				
			|||||||
	string gateway = 3;
 | 
						string gateway = 3;
 | 
				
			||||||
	// the network for this destination
 | 
						// the network for this destination
 | 
				
			||||||
	string network = 4;
 | 
						string network = 4;
 | 
				
			||||||
 | 
						// router if the router id
 | 
				
			||||||
 | 
						string router = 5;
 | 
				
			||||||
	// the network link
 | 
						// the network link
 | 
				
			||||||
	string link = 5;
 | 
						string link = 6;
 | 
				
			||||||
	// the metric / score of this route
 | 
						// the metric / score of this route
 | 
				
			||||||
	int64 metric = 6;
 | 
						int64 metric = 7;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
message Status {
 | 
					message Status {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,29 +11,38 @@ type QueryOptions struct {
 | 
				
			|||||||
	Gateway string
 | 
						Gateway string
 | 
				
			||||||
	// Network is network address
 | 
						// Network is network address
 | 
				
			||||||
	Network string
 | 
						Network string
 | 
				
			||||||
 | 
						// Router is router id
 | 
				
			||||||
 | 
						Router string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// QueryService sets destination address
 | 
					// QueryService sets service to query
 | 
				
			||||||
func QueryService(s string) QueryOption {
 | 
					func QueryService(s string) QueryOption {
 | 
				
			||||||
	return func(o *QueryOptions) {
 | 
						return func(o *QueryOptions) {
 | 
				
			||||||
		o.Service = s
 | 
							o.Service = s
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// QueryGateway sets route gateway
 | 
					// QueryGateway sets gateway address to query
 | 
				
			||||||
func QueryGateway(g string) QueryOption {
 | 
					func QueryGateway(g string) QueryOption {
 | 
				
			||||||
	return func(o *QueryOptions) {
 | 
						return func(o *QueryOptions) {
 | 
				
			||||||
		o.Gateway = g
 | 
							o.Gateway = g
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// QueryNetwork sets route network address
 | 
					// QueryNetwork sets network name to query
 | 
				
			||||||
func QueryNetwork(n string) QueryOption {
 | 
					func QueryNetwork(n string) QueryOption {
 | 
				
			||||||
	return func(o *QueryOptions) {
 | 
						return func(o *QueryOptions) {
 | 
				
			||||||
		o.Network = n
 | 
							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
 | 
					// Query is routing table query
 | 
				
			||||||
type Query interface {
 | 
					type Query interface {
 | 
				
			||||||
	// Options returns query options
 | 
						// Options returns query options
 | 
				
			||||||
@@ -52,6 +61,7 @@ func NewQuery(opts ...QueryOption) Query {
 | 
				
			|||||||
		Service: "*",
 | 
							Service: "*",
 | 
				
			||||||
		Gateway: "*",
 | 
							Gateway: "*",
 | 
				
			||||||
		Network: "*",
 | 
							Network: "*",
 | 
				
			||||||
 | 
							Router:  "*",
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, o := range opts {
 | 
						for _, o := range opts {
 | 
				
			||||||
@@ -67,8 +77,3 @@ func NewQuery(opts ...QueryOption) Query {
 | 
				
			|||||||
func (q *query) Options() QueryOptions {
 | 
					func (q *query) Options() QueryOptions {
 | 
				
			||||||
	return q.opts
 | 
						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 (
 | 
					var (
 | 
				
			||||||
	// DefaultLink is default network link
 | 
						// DefaultLink is default network link
 | 
				
			||||||
	DefaultLink = "local"
 | 
						DefaultLink = "local"
 | 
				
			||||||
	// DefaultLocalMetric is default route cost metric for the local network
 | 
						// DefaultLocalMetric is default route cost for a local route
 | 
				
			||||||
	DefaultLocalMetric = 1
 | 
						DefaultLocalMetric = 1
 | 
				
			||||||
	// DefaultNetworkMetric is default route cost metric for the micro network
 | 
						// DefaultNetworkMetric is default route cost for a network route
 | 
				
			||||||
	DefaultNetworkMetric = 10
 | 
						DefaultNetworkMetric = 10
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -23,6 +23,8 @@ type Route struct {
 | 
				
			|||||||
	Gateway string
 | 
						Gateway string
 | 
				
			||||||
	// Network is network address
 | 
						// Network is network address
 | 
				
			||||||
	Network string
 | 
						Network string
 | 
				
			||||||
 | 
						// Router is router id
 | 
				
			||||||
 | 
						Router string
 | 
				
			||||||
	// Link is network link
 | 
						// Link is network link
 | 
				
			||||||
	Link string
 | 
						Link string
 | 
				
			||||||
	// Metric is the route cost metric
 | 
						// Metric is the route cost metric
 | 
				
			||||||
@@ -33,6 +35,6 @@ type Route struct {
 | 
				
			|||||||
func (r *Route) Hash() uint64 {
 | 
					func (r *Route) Hash() uint64 {
 | 
				
			||||||
	h := fnv.New64()
 | 
						h := fnv.New64()
 | 
				
			||||||
	h.Reset()
 | 
						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()
 | 
						return h.Sum64()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,17 @@ import (
 | 
				
			|||||||
	"time"
 | 
						"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
 | 
					// Router is an interface for a routing control plane
 | 
				
			||||||
type Router interface {
 | 
					type Router interface {
 | 
				
			||||||
	// Init initializes the router with options
 | 
						// Init initializes the router with options
 | 
				
			||||||
@@ -17,6 +28,8 @@ type Router interface {
 | 
				
			|||||||
	Advertise() (<-chan *Advert, error)
 | 
						Advertise() (<-chan *Advert, error)
 | 
				
			||||||
	// Process processes incoming adverts
 | 
						// Process processes incoming adverts
 | 
				
			||||||
	Process(*Advert) error
 | 
						Process(*Advert) error
 | 
				
			||||||
 | 
						// Solicit advertises the whole routing table to the network
 | 
				
			||||||
 | 
						Solicit() error
 | 
				
			||||||
	// Lookup queries routes in the routing table
 | 
						// Lookup queries routes in the routing table
 | 
				
			||||||
	Lookup(Query) ([]Route, error)
 | 
						Lookup(Query) ([]Route, error)
 | 
				
			||||||
	// Watch returns a watcher which tracks updates to the routing table
 | 
						// Watch returns a watcher which tracks updates to the routing table
 | 
				
			||||||
@@ -31,16 +44,17 @@ type Router interface {
 | 
				
			|||||||
	String() string
 | 
						String() string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Table is an interface for routing table
 | 
				
			||||||
type Table interface {
 | 
					type Table interface {
 | 
				
			||||||
	// Create new route in the routing table
 | 
						// Create new route in the routing table
 | 
				
			||||||
	Create(Route) error
 | 
						Create(Route) error
 | 
				
			||||||
	// Delete deletes existing route from the routing table
 | 
						// Delete existing route from the routing table
 | 
				
			||||||
	Delete(Route) error
 | 
						Delete(Route) error
 | 
				
			||||||
	// Update updates route in the routing table
 | 
						// Update route in the routing table
 | 
				
			||||||
	Update(Route) error
 | 
						Update(Route) error
 | 
				
			||||||
	// List returns the list of all routes in the table
 | 
						// List all routes in the table
 | 
				
			||||||
	List() ([]Route, error)
 | 
						List() ([]Route, error)
 | 
				
			||||||
	// Query queries routes in the routing table
 | 
						// Query routes in the routing table
 | 
				
			||||||
	Query(Query) ([]Route, error)
 | 
						Query(Query) ([]Route, error)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -125,17 +139,6 @@ type Advert struct {
 | 
				
			|||||||
	Events []*Event
 | 
						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
 | 
					// NewRouter creates new Router and returns it
 | 
				
			||||||
func NewRouter(opts ...Option) Router {
 | 
					func NewRouter(opts ...Option) Router {
 | 
				
			||||||
	return newRouter(opts...)
 | 
						return newRouter(opts...)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -220,6 +220,42 @@ func (s *svc) Process(advert *router.Advert) error {
 | 
				
			|||||||
	return nil
 | 
						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
 | 
					// Status returns router status
 | 
				
			||||||
func (s *svc) Status() router.Status {
 | 
					func (s *svc) Status() router.Status {
 | 
				
			||||||
	s.Lock()
 | 
						s.Lock()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,14 @@ import (
 | 
				
			|||||||
	"github.com/google/uuid"
 | 
						"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 {
 | 
					type table struct {
 | 
				
			||||||
	sync.RWMutex
 | 
						sync.RWMutex
 | 
				
			||||||
	// routes stores service routes
 | 
						// 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
 | 
					// Create creates new route in the routing table
 | 
				
			||||||
func (t *table) Create(r Route) error {
 | 
					func (t *table) Create(r Route) error {
 | 
				
			||||||
	service := r.Service
 | 
						service := r.Service
 | 
				
			||||||
@@ -63,8 +83,10 @@ func (t *table) Delete(r Route) error {
 | 
				
			|||||||
		return ErrRouteNotFound
 | 
							return ErrRouteNotFound
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	delete(t.routes[service], sum)
 | 
						if _, ok := t.routes[service][sum]; ok {
 | 
				
			||||||
	go t.sendEvent(&Event{Type: Delete, Timestamp: time.Now(), Route: r})
 | 
							delete(t.routes[service], sum)
 | 
				
			||||||
 | 
							go t.sendEvent(&Event{Type: Delete, Timestamp: time.Now(), Route: r})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -85,8 +107,10 @@ func (t *table) Update(r Route) error {
 | 
				
			|||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	t.routes[service][sum] = r
 | 
						if _, ok := t.routes[service][sum]; !ok {
 | 
				
			||||||
	go t.sendEvent(&Event{Type: Update, Timestamp: time.Now(), Route: r})
 | 
							t.routes[service][sum] = r
 | 
				
			||||||
 | 
							go t.sendEvent(&Event{Type: Update, Timestamp: time.Now(), Route: r})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -106,21 +130,23 @@ func (t *table) List() ([]Route, error) {
 | 
				
			|||||||
	return routes, nil
 | 
						return routes, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// isMatch checks if the route matches given network and router
 | 
					// isMatch checks if the route matches given query options
 | 
				
			||||||
func isMatch(route Route, network, router string) bool {
 | 
					func isMatch(route Route, gateway, network, router string) bool {
 | 
				
			||||||
	if network == "*" || network == route.Network {
 | 
						if gateway == "*" || gateway == route.Gateway {
 | 
				
			||||||
		if router == "*" || router == route.Gateway {
 | 
							if network == "*" || network == route.Network {
 | 
				
			||||||
			return true
 | 
								if router == "*" || router == route.Router {
 | 
				
			||||||
 | 
									return true
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return false
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// findRoutes finds all the routes for given network and router and returns them
 | 
					// 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
 | 
						var results []Route
 | 
				
			||||||
	for _, route := range routes {
 | 
						for _, route := range routes {
 | 
				
			||||||
		if isMatch(route, network, router) {
 | 
							if isMatch(route, gateway, network, router) {
 | 
				
			||||||
			results = append(results, route)
 | 
								results = append(results, route)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -136,13 +162,13 @@ func (t *table) Query(q Query) ([]Route, error) {
 | 
				
			|||||||
		if _, ok := t.routes[q.Options().Service]; !ok {
 | 
							if _, ok := t.routes[q.Options().Service]; !ok {
 | 
				
			||||||
			return nil, ErrRouteNotFound
 | 
								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
 | 
						var results []Route
 | 
				
			||||||
	// search through all destinations
 | 
						// search through all destinations
 | 
				
			||||||
	for _, routes := range t.routes {
 | 
						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
 | 
						return results, nil
 | 
				
			||||||
@@ -181,23 +207,3 @@ func (t *table) Watch(opts ...WatchOption) (Watcher, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return w, nil
 | 
						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",
 | 
							Service: "dest.svc",
 | 
				
			||||||
		Gateway: "dest.gw",
 | 
							Gateway: "dest.gw",
 | 
				
			||||||
		Network: "dest.network",
 | 
							Network: "dest.network",
 | 
				
			||||||
 | 
							Router:  "src.router",
 | 
				
			||||||
		Link:    "det.link",
 | 
							Link:    "det.link",
 | 
				
			||||||
		Metric:  10,
 | 
							Metric:  10,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -109,11 +110,13 @@ func TestQuery(t *testing.T) {
 | 
				
			|||||||
	svc := []string{"svc1", "svc2", "svc3"}
 | 
						svc := []string{"svc1", "svc2", "svc3"}
 | 
				
			||||||
	net := []string{"net1", "net2", "net1"}
 | 
						net := []string{"net1", "net2", "net1"}
 | 
				
			||||||
	gw := []string{"gw1", "gw2", "gw3"}
 | 
						gw := []string{"gw1", "gw2", "gw3"}
 | 
				
			||||||
 | 
						rtr := []string{"rtr1", "rt2", "rt3"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for i := 0; i < len(svc); i++ {
 | 
						for i := 0; i < len(svc); i++ {
 | 
				
			||||||
		route.Service = svc[i]
 | 
							route.Service = svc[i]
 | 
				
			||||||
		route.Network = net[i]
 | 
							route.Network = net[i]
 | 
				
			||||||
		route.Gateway = gw[i]
 | 
							route.Gateway = gw[i]
 | 
				
			||||||
 | 
							route.Router = rtr[i]
 | 
				
			||||||
		if err := table.Create(route); err != nil {
 | 
							if err := table.Create(route); err != nil {
 | 
				
			||||||
			t.Errorf("error adding route: %s", err)
 | 
								t.Errorf("error adding route: %s", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -127,8 +130,9 @@ func TestQuery(t *testing.T) {
 | 
				
			|||||||
		t.Errorf("error looking up routes: %s", err)
 | 
							t.Errorf("error looking up routes: %s", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// query particular net
 | 
						// query routes particular network
 | 
				
			||||||
	query = NewQuery(QueryNetwork("net1"))
 | 
						network := "net1"
 | 
				
			||||||
 | 
						query = NewQuery(QueryNetwork(network))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	routes, err = table.Query(query)
 | 
						routes, err = table.Query(query)
 | 
				
			||||||
	if err != nil {
 | 
						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))
 | 
							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"
 | 
						gateway := "gw1"
 | 
				
			||||||
	query = NewQuery(QueryGateway(gateway))
 | 
						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)
 | 
							t.Errorf("incorrect route returned. Expected gateway: %s, found: %s", gateway, routes[0].Gateway)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// query particular route
 | 
						// query routes for particular router
 | 
				
			||||||
	network := "net1"
 | 
						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(
 | 
						query = NewQuery(
 | 
				
			||||||
		QueryGateway(gateway),
 | 
							QueryGateway(gateway),
 | 
				
			||||||
		QueryNetwork(network),
 | 
							QueryNetwork(network),
 | 
				
			||||||
 | 
							QueryRouter(router),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	routes, err = table.Query(query)
 | 
						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)
 | 
							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"))
 | 
						query = NewQuery(QueryService("foobar"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	routes, err = table.Query(query)
 | 
						routes, err = table.Query(query)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,11 @@ import (
 | 
				
			|||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var (
 | 
				
			||||||
 | 
						// ErrWatcherStopped is returned when routing table watcher has been stopped
 | 
				
			||||||
 | 
						ErrWatcherStopped = errors.New("watcher stopped")
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// EventType defines routing table event
 | 
					// EventType defines routing table event
 | 
				
			||||||
type EventType int
 | 
					type EventType int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -42,9 +47,6 @@ type Event struct {
 | 
				
			|||||||
	Route Route
 | 
						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 defines routing table watcher interface
 | 
				
			||||||
// Watcher returns updates to the routing table
 | 
					// Watcher returns updates to the routing table
 | 
				
			||||||
type Watcher interface {
 | 
					type Watcher interface {
 | 
				
			||||||
@@ -56,7 +58,11 @@ type Watcher interface {
 | 
				
			|||||||
	Stop()
 | 
						Stop()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// WatchOption is used to define what routes to watch in the table
 | 
				
			||||||
 | 
					type WatchOption func(*WatchOptions)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// WatchOptions are table watcher options
 | 
					// WatchOptions are table watcher options
 | 
				
			||||||
 | 
					// TODO: expand the options to watch based on other criteria
 | 
				
			||||||
type WatchOptions struct {
 | 
					type WatchOptions struct {
 | 
				
			||||||
	// Service allows to watch specific service routes
 | 
						// Service allows to watch specific service routes
 | 
				
			||||||
	Service string
 | 
						Service string
 | 
				
			||||||
@@ -70,6 +76,7 @@ func WatchService(s string) WatchOption {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// tableWatcher implements routing table Watcher
 | 
				
			||||||
type tableWatcher struct {
 | 
					type tableWatcher struct {
 | 
				
			||||||
	sync.RWMutex
 | 
						sync.RWMutex
 | 
				
			||||||
	id      string
 | 
						id      string
 | 
				
			||||||
@@ -113,8 +120,3 @@ func (w *tableWatcher) Stop() {
 | 
				
			|||||||
		close(w.done)
 | 
							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 (
 | 
					import (
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"os/signal"
 | 
						"os/signal"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
	"syscall"
 | 
						"syscall"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -10,7 +11,9 @@ import (
 | 
				
			|||||||
	"github.com/micro/go-micro/config/cmd"
 | 
						"github.com/micro/go-micro/config/cmd"
 | 
				
			||||||
	"github.com/micro/go-micro/debug/handler"
 | 
						"github.com/micro/go-micro/debug/handler"
 | 
				
			||||||
	"github.com/micro/go-micro/metadata"
 | 
						"github.com/micro/go-micro/metadata"
 | 
				
			||||||
 | 
						"github.com/micro/go-micro/plugin"
 | 
				
			||||||
	"github.com/micro/go-micro/server"
 | 
						"github.com/micro/go-micro/server"
 | 
				
			||||||
 | 
						"github.com/micro/go-micro/util/log"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type service struct {
 | 
					type service struct {
 | 
				
			||||||
@@ -44,6 +47,24 @@ func (s *service) Init(opts ...Option) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	s.once.Do(func() {
 | 
						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
 | 
							// Initialise the command flags, overriding new service
 | 
				
			||||||
		_ = s.opts.Cmd.Init(
 | 
							_ = s.opts.Cmd.Init(
 | 
				
			||||||
			cmd.Broker(&s.opts.Broker),
 | 
								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 {
 | 
					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
 | 
						// TODO: this is probably inefficient, we might want to just maintain an open connection
 | 
				
			||||||
	// it may be easier to add broadcast to the tunnel
 | 
						// 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 {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							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"
 | 
						"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
 | 
					// 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
 | 
					// measure the actual transport link and reconnect if
 | 
				
			||||||
// an address is specified.
 | 
					// an address is specified.
 | 
				
			||||||
type Link interface {
 | 
					type Link interface {
 | 
				
			||||||
@@ -28,10 +33,6 @@ type Link interface {
 | 
				
			|||||||
	Length() int
 | 
						Length() int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	ErrLinkClosed = errors.New("link closed")
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewLink creates a new link on top of a socket
 | 
					// NewLink creates a new link on top of a socket
 | 
				
			||||||
func NewLink(opts ...options.Option) Link {
 | 
					func NewLink(opts ...options.Option) Link {
 | 
				
			||||||
	return newLink(options.NewOptions(opts...))
 | 
						return newLink(options.NewOptions(opts...))
 | 
				
			||||||
@@ -2,79 +2,148 @@ package tunnel
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/micro/go-micro/util/log"
 | 
						"github.com/micro/go-micro/util/log"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type tunListener struct {
 | 
					type tunListener struct {
 | 
				
			||||||
	// address of the listener
 | 
						// address of the listener
 | 
				
			||||||
	addr string
 | 
						channel string
 | 
				
			||||||
	// the accept channel
 | 
						// the accept channel
 | 
				
			||||||
	accept chan *socket
 | 
						accept chan *session
 | 
				
			||||||
	// the channel to close
 | 
						// the channel to close
 | 
				
			||||||
	closed chan bool
 | 
						closed chan bool
 | 
				
			||||||
	// the tunnel closed channel
 | 
						// the tunnel closed channel
 | 
				
			||||||
	tunClosed chan bool
 | 
						tunClosed chan bool
 | 
				
			||||||
	// the connection
 | 
						// the listener session
 | 
				
			||||||
	conn Conn
 | 
						session *session
 | 
				
			||||||
	// the listener socket
 | 
						// del func to kill listener
 | 
				
			||||||
	socket *socket
 | 
						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() {
 | 
					func (t *tunListener) process() {
 | 
				
			||||||
	// our connection map for session
 | 
						// 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 {
 | 
						for {
 | 
				
			||||||
		select {
 | 
							select {
 | 
				
			||||||
		case <-t.closed:
 | 
							case <-t.closed:
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
 | 
							case <-t.tunClosed:
 | 
				
			||||||
 | 
								t.Close()
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
		// receive a new message
 | 
							// receive a new message
 | 
				
			||||||
		case m := <-t.socket.recv:
 | 
							case m := <-t.session.recv:
 | 
				
			||||||
			// get a socket
 | 
								// get a session
 | 
				
			||||||
			sock, ok := conns[m.session]
 | 
								sess, ok := conns[m.session]
 | 
				
			||||||
			log.Debugf("Tunnel listener received id %s session %s exists: %t", m.id, m.session, ok)
 | 
								log.Debugf("Tunnel listener received channel %s session %s exists: %t", m.channel, m.session, ok)
 | 
				
			||||||
			if !ok {
 | 
								if !ok {
 | 
				
			||||||
				// create a new socket session
 | 
									switch m.typ {
 | 
				
			||||||
				sock = &socket{
 | 
									case "open", "session":
 | 
				
			||||||
					// our tunnel id
 | 
									default:
 | 
				
			||||||
					id: m.id,
 | 
										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
 | 
										// the session id
 | 
				
			||||||
					session: m.session,
 | 
										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
 | 
										// close chan
 | 
				
			||||||
					closed: make(chan bool),
 | 
										closed: make(chan bool),
 | 
				
			||||||
					// recv called by the acceptor
 | 
										// recv called by the acceptor
 | 
				
			||||||
					recv: make(chan *message, 128),
 | 
										recv: make(chan *message, 128),
 | 
				
			||||||
					// use the internal send buffer
 | 
										// use the internal send buffer
 | 
				
			||||||
					send: t.socket.send,
 | 
										send: t.session.send,
 | 
				
			||||||
					// wait
 | 
										// wait
 | 
				
			||||||
					wait: make(chan bool),
 | 
										wait: make(chan bool),
 | 
				
			||||||
 | 
										// error channel
 | 
				
			||||||
 | 
										errChan: make(chan error, 1),
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// save the socket
 | 
									// save the session
 | 
				
			||||||
				conns[m.session] = sock
 | 
									conns[m.session] = sess
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// send to accept chan
 | 
					 | 
				
			||||||
				select {
 | 
									select {
 | 
				
			||||||
				case <-t.closed:
 | 
									case <-t.closed:
 | 
				
			||||||
					return
 | 
										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
 | 
								// send this to the accept chan
 | 
				
			||||||
			select {
 | 
								select {
 | 
				
			||||||
			case <-sock.closed:
 | 
								case <-sess.closed:
 | 
				
			||||||
				delete(conns, m.session)
 | 
									delete(conns, m.session)
 | 
				
			||||||
			case sock.recv <- m:
 | 
								case sess.recv <- m:
 | 
				
			||||||
				log.Debugf("Tunnel listener sent to recv chan id %s session %s", m.id, m.session)
 | 
									log.Debugf("Tunnel listener sent to recv chan channel %s session %s", m.channel, m.session)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (t *tunListener) Addr() string {
 | 
					func (t *tunListener) Channel() string {
 | 
				
			||||||
	return t.addr
 | 
						return t.channel
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Close closes tunnel listener
 | 
					// Close closes tunnel listener
 | 
				
			||||||
@@ -83,26 +152,33 @@ func (t *tunListener) Close() error {
 | 
				
			|||||||
	case <-t.closed:
 | 
						case <-t.closed:
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
 | 
							// close and delete
 | 
				
			||||||
 | 
							t.delFunc()
 | 
				
			||||||
 | 
							t.session.Close()
 | 
				
			||||||
		close(t.closed)
 | 
							close(t.closed)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Everytime accept is called we essentially block till we get a new connection
 | 
					// 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 {
 | 
						select {
 | 
				
			||||||
	// if the socket is closed return
 | 
						// if the session is closed return
 | 
				
			||||||
	case <-t.closed:
 | 
						case <-t.closed:
 | 
				
			||||||
		return nil, io.EOF
 | 
							return nil, io.EOF
 | 
				
			||||||
	case <-t.tunClosed:
 | 
						case <-t.tunClosed:
 | 
				
			||||||
		// close the listener when the tunnel closes
 | 
							// close the listener when the tunnel closes
 | 
				
			||||||
		t.Close()
 | 
					 | 
				
			||||||
		return nil, io.EOF
 | 
							return nil, io.EOF
 | 
				
			||||||
	// wait for a new connection
 | 
						// wait for a new connection
 | 
				
			||||||
	case c, ok := <-t.accept:
 | 
						case c, ok := <-t.accept:
 | 
				
			||||||
 | 
							// check if the accept chan is closed
 | 
				
			||||||
		if !ok {
 | 
							if !ok {
 | 
				
			||||||
			return nil, io.EOF
 | 
								return nil, io.EOF
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							// send back the accept
 | 
				
			||||||
 | 
							if err := c.Accept(); err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return c, nil
 | 
							return c, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,8 @@
 | 
				
			|||||||
package tunnel
 | 
					package tunnel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/google/uuid"
 | 
						"github.com/google/uuid"
 | 
				
			||||||
	"github.com/micro/go-micro/transport"
 | 
						"github.com/micro/go-micro/transport"
 | 
				
			||||||
	"github.com/micro/go-micro/transport/quic"
 | 
						"github.com/micro/go-micro/transport/quic"
 | 
				
			||||||
@@ -9,6 +11,8 @@ import (
 | 
				
			|||||||
var (
 | 
					var (
 | 
				
			||||||
	// DefaultAddress is default tunnel bind address
 | 
						// DefaultAddress is default tunnel bind address
 | 
				
			||||||
	DefaultAddress = ":0"
 | 
						DefaultAddress = ":0"
 | 
				
			||||||
 | 
						// The shared default token
 | 
				
			||||||
 | 
						DefaultToken = "micro"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Option func(*Options)
 | 
					type Option func(*Options)
 | 
				
			||||||
@@ -21,10 +25,21 @@ type Options struct {
 | 
				
			|||||||
	Address string
 | 
						Address string
 | 
				
			||||||
	// Nodes are remote nodes
 | 
						// Nodes are remote nodes
 | 
				
			||||||
	Nodes []string
 | 
						Nodes []string
 | 
				
			||||||
 | 
						// The shared auth token
 | 
				
			||||||
 | 
						Token string
 | 
				
			||||||
	// Transport listens to incoming connections
 | 
						// Transport listens to incoming connections
 | 
				
			||||||
	Transport transport.Transport
 | 
						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
 | 
					// The tunnel id
 | 
				
			||||||
func Id(id string) Option {
 | 
					func Id(id string) Option {
 | 
				
			||||||
	return func(o *Options) {
 | 
						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
 | 
					// Transport listens for incoming connections
 | 
				
			||||||
func Transport(t transport.Transport) Option {
 | 
					func Transport(t transport.Transport) Option {
 | 
				
			||||||
	return func(o *Options) {
 | 
						return func(o *Options) {
 | 
				
			||||||
@@ -58,6 +80,22 @@ func DefaultOptions() Options {
 | 
				
			|||||||
	return Options{
 | 
						return Options{
 | 
				
			||||||
		Id:        uuid.New().String(),
 | 
							Id:        uuid.New().String(),
 | 
				
			||||||
		Address:   DefaultAddress,
 | 
							Address:   DefaultAddress,
 | 
				
			||||||
 | 
							Token:     DefaultToken,
 | 
				
			||||||
		Transport: quic.NewTransport(),
 | 
							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 {
 | 
					func (t *tunListener) Addr() string {
 | 
				
			||||||
	return t.l.Addr()
 | 
						return t.l.Channel()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (t *tunListener) Close() error {
 | 
					func (t *tunListener) Close() error {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,11 +2,23 @@
 | 
				
			|||||||
package tunnel
 | 
					package tunnel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/micro/go-micro/transport"
 | 
						"github.com/micro/go-micro/transport"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tunnel creates a gre network tunnel on top of a link.
 | 
					var (
 | 
				
			||||||
// It establishes multiple streams using the Micro-Tunnel-Id header
 | 
						// 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
 | 
					// and Micro-Tunnel-Session header. The tunnel id is a hash of
 | 
				
			||||||
// the address being requested.
 | 
					// the address being requested.
 | 
				
			||||||
type Tunnel interface {
 | 
					type Tunnel interface {
 | 
				
			||||||
@@ -17,27 +29,37 @@ type Tunnel interface {
 | 
				
			|||||||
	Connect() error
 | 
						Connect() error
 | 
				
			||||||
	// Close closes the tunnel
 | 
						// Close closes the tunnel
 | 
				
			||||||
	Close() error
 | 
						Close() error
 | 
				
			||||||
	// Dial an endpoint
 | 
						// Connect to a channel
 | 
				
			||||||
	Dial(addr string) (Conn, error)
 | 
						Dial(channel string, opts ...DialOption) (Session, error)
 | 
				
			||||||
	// Accept connections
 | 
						// Accept connections on a channel
 | 
				
			||||||
	Listen(addr string) (Listener, error)
 | 
						Listen(channel string) (Listener, error)
 | 
				
			||||||
 | 
						// All the links the tunnel is connected to
 | 
				
			||||||
 | 
						Links() []Link
 | 
				
			||||||
	// Name of the tunnel implementation
 | 
						// Name of the tunnel implementation
 | 
				
			||||||
	String() string
 | 
						String() string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// The listener provides similar constructs to the transport.Listener
 | 
					// Link represents internal links to the tunnel
 | 
				
			||||||
type Listener interface {
 | 
					type Link interface {
 | 
				
			||||||
	Addr() string
 | 
						// The id of the link
 | 
				
			||||||
	Close() error
 | 
						Id() string
 | 
				
			||||||
	Accept() (Conn, error)
 | 
						// honours transport socket
 | 
				
			||||||
 | 
						transport.Socket
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Conn is a connection dialed or accepted which includes the tunnel id and session
 | 
					// The listener provides similar constructs to the transport.Listener
 | 
				
			||||||
type Conn interface {
 | 
					type Listener interface {
 | 
				
			||||||
	// Specifies the tunnel id
 | 
						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
 | 
						Id() string
 | 
				
			||||||
	// The session
 | 
						// The channel name
 | 
				
			||||||
	Session() string
 | 
						Channel() string
 | 
				
			||||||
	// a transport socket
 | 
						// a transport socket
 | 
				
			||||||
	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 {
 | 
						if err := c.Recv(m); err != nil {
 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	tun.Close()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// re-start tunnel
 | 
						// close all the links
 | 
				
			||||||
	err = tun.Connect()
 | 
						for _, link := range tun.Links() {
 | 
				
			||||||
	if err != nil {
 | 
							link.Close()
 | 
				
			||||||
		t.Fatal(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer tun.Close()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// listen on some virtual address
 | 
					 | 
				
			||||||
	tl, err = tun.Listen("test-tunnel")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		t.Fatal(err)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// receiver ready; notify sender
 | 
						// receiver ready; notify sender
 | 
				
			||||||
	wait <- true
 | 
						wait <- true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// accept a connection
 | 
					 | 
				
			||||||
	c, err = tl.Accept()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		t.Fatal(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// accept the message
 | 
						// accept the message
 | 
				
			||||||
	m = new(transport.Message)
 | 
						m = new(transport.Message)
 | 
				
			||||||
	if err := c.Recv(m); err != nil {
 | 
						if err := c.Recv(m); err != nil {
 | 
				
			||||||
@@ -279,6 +264,7 @@ func TestReconnectTunnel(t *testing.T) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						defer tunB.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// we manually override the tunnel.ReconnectTime value here
 | 
						// we manually override the tunnel.ReconnectTime value here
 | 
				
			||||||
	// this is so that we make the reconnects faster than the default 5s
 | 
						// 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 {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						defer tunA.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wait := make(chan bool)
 | 
						wait := make(chan bool)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,14 +40,20 @@ func Extract(addr string) (string, error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var addrs []net.Addr
 | 
						var addrs []net.Addr
 | 
				
			||||||
 | 
						var loAddrs []net.Addr
 | 
				
			||||||
	for _, iface := range ifaces {
 | 
						for _, iface := range ifaces {
 | 
				
			||||||
		ifaceAddrs, err := iface.Addrs()
 | 
							ifaceAddrs, err := iface.Addrs()
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			// ignore error, interface can dissapear from system
 | 
								// ignore error, interface can dissapear from system
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if iface.Flags&net.FlagLoopback != 0 {
 | 
				
			||||||
 | 
								loAddrs = append(loAddrs, ifaceAddrs...)
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		addrs = append(addrs, ifaceAddrs...)
 | 
							addrs = append(addrs, ifaceAddrs...)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						addrs = append(addrs, loAddrs...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var ipAddr []byte
 | 
						var ipAddr []byte
 | 
				
			||||||
	var publicIP []byte
 | 
						var publicIP []byte
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ type Level int
 | 
				
			|||||||
const (
 | 
					const (
 | 
				
			||||||
	LevelFatal Level = iota
 | 
						LevelFatal Level = iota
 | 
				
			||||||
	LevelInfo
 | 
						LevelInfo
 | 
				
			||||||
	LevelWarn
 | 
						LevelError
 | 
				
			||||||
	LevelDebug
 | 
						LevelDebug
 | 
				
			||||||
	LevelTrace
 | 
						LevelTrace
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -29,16 +29,16 @@ var (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	switch os.Getenv("MICRO_LOG_LEVEL") {
 | 
						switch os.Getenv("MICRO_LOG_LEVEL") {
 | 
				
			||||||
 | 
						case "trace":
 | 
				
			||||||
 | 
							level = LevelTrace
 | 
				
			||||||
	case "debug":
 | 
						case "debug":
 | 
				
			||||||
		level = LevelDebug
 | 
							level = LevelDebug
 | 
				
			||||||
	case "info":
 | 
						case "info":
 | 
				
			||||||
		level = LevelInfo
 | 
							level = LevelInfo
 | 
				
			||||||
	case "trace":
 | 
						case "error":
 | 
				
			||||||
		level = LevelTrace
 | 
							level = LevelError
 | 
				
			||||||
	case "fatal":
 | 
						case "fatal":
 | 
				
			||||||
		level = LevelFatal
 | 
							level = LevelFatal
 | 
				
			||||||
	case "warn":
 | 
					 | 
				
			||||||
		level = LevelWarn
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -98,14 +98,14 @@ func Infof(format string, v ...interface{}) {
 | 
				
			|||||||
	WithLevelf(LevelInfo, format, v...)
 | 
						WithLevelf(LevelInfo, format, v...)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Warn provides warn level logging
 | 
					// Error provides warn level logging
 | 
				
			||||||
func Warn(v ...interface{}) {
 | 
					func Error(v ...interface{}) {
 | 
				
			||||||
	WithLevel(LevelWarn, v...)
 | 
						WithLevel(LevelError, v...)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Warnf provides warn level logging
 | 
					// Errorf provides warn level logging
 | 
				
			||||||
func Warnf(format string, v ...interface{}) {
 | 
					func Errorf(format string, v ...interface{}) {
 | 
				
			||||||
	WithLevelf(LevelWarn, format, v...)
 | 
						WithLevelf(LevelError, format, v...)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Fatal logs with Log and then exits with os.Exit(1)
 | 
					// Fatal logs with Log and then exits with os.Exit(1)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user