Merge branch 'master' of github.com:micro/go-micro
This commit is contained in:
commit
ce18de2647
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
|
||||||
@ -332,6 +361,7 @@ func (m *mdnsRegistry) Watch(opts ...WatchOption) (Watcher, error) {
|
|||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if _, ok := t.routes[service][sum]; ok {
|
||||||
delete(t.routes[service], sum)
|
delete(t.routes[service], sum)
|
||||||
go t.sendEvent(&Event{Type: Delete, Timestamp: time.Now(), Route: r})
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if _, ok := t.routes[service][sum]; !ok {
|
||||||
t.routes[service][sum] = r
|
t.routes[service][sum] = r
|
||||||
go t.sendEvent(&Event{Type: Update, Timestamp: time.Now(), Route: 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 gateway == "*" || gateway == route.Gateway {
|
||||||
if network == "*" || network == route.Network {
|
if network == "*" || network == route.Network {
|
||||||
if router == "*" || router == route.Gateway {
|
if router == "*" || router == route.Router {
|
||||||
return true
|
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)
|
||||||
|
Loading…
Reference in New Issue
Block a user