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