Adds network id. Skips processing routes when router is the origin.
This commit is contained in:
parent
470304ef87
commit
5e7208119e
@ -34,8 +34,8 @@ type network struct {
|
|||||||
proxy.Proxy
|
proxy.Proxy
|
||||||
// tun is network tunnel
|
// tun is network tunnel
|
||||||
tunnel.Tunnel
|
tunnel.Tunnel
|
||||||
// srv is network server
|
// server is network server
|
||||||
srv server.Server
|
server server.Server
|
||||||
// client is network client
|
// client is network client
|
||||||
client client.Client
|
client client.Client
|
||||||
|
|
||||||
@ -59,13 +59,19 @@ func newNetwork(opts ...Option) Network {
|
|||||||
tunnel.Address(options.Address),
|
tunnel.Address(options.Address),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// init router Id to the network id
|
||||||
|
options.Router.Init(
|
||||||
|
router.Id(options.Id),
|
||||||
|
)
|
||||||
|
|
||||||
// create tunnel client with tunnel transport
|
// create tunnel client with tunnel transport
|
||||||
tunTransport := trn.NewTransport(
|
tunTransport := trn.NewTransport(
|
||||||
trn.WithTunnel(options.Tunnel),
|
trn.WithTunnel(options.Tunnel),
|
||||||
)
|
)
|
||||||
|
|
||||||
// srv is network server
|
// server is network server
|
||||||
srv := server.NewServer(
|
server := server.NewServer(
|
||||||
|
server.Id(options.Id),
|
||||||
server.Address(options.Address),
|
server.Address(options.Address),
|
||||||
server.Name(options.Name),
|
server.Name(options.Name),
|
||||||
server.Transport(tunTransport),
|
server.Transport(tunTransport),
|
||||||
@ -86,7 +92,7 @@ func newNetwork(opts ...Option) Network {
|
|||||||
Router: options.Router,
|
Router: options.Router,
|
||||||
Proxy: options.Proxy,
|
Proxy: options.Proxy,
|
||||||
Tunnel: options.Tunnel,
|
Tunnel: options.Tunnel,
|
||||||
srv: srv,
|
server: server,
|
||||||
client: client,
|
client: client,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -333,7 +339,7 @@ func (n *network) Connect() error {
|
|||||||
go n.process(listener)
|
go n.process(listener)
|
||||||
|
|
||||||
// start the server
|
// start the server
|
||||||
if err := n.srv.Start(); err != nil {
|
if err := n.server.Start(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,7 +351,7 @@ func (n *network) Connect() error {
|
|||||||
|
|
||||||
func (n *network) close() error {
|
func (n *network) close() error {
|
||||||
// stop the server
|
// stop the server
|
||||||
if err := n.srv.Stop(); err != nil {
|
if err := n.server.Stop(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,5 +396,5 @@ func (n *network) Client() client.Client {
|
|||||||
|
|
||||||
// Server returns network server
|
// Server returns network server
|
||||||
func (n *network) Server() server.Server {
|
func (n *network) Server() server.Server {
|
||||||
return n.srv
|
return n.server
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package network
|
package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/micro/go-micro/network/resolver"
|
"github.com/micro/go-micro/network/resolver"
|
||||||
"github.com/micro/go-micro/network/resolver/registry"
|
"github.com/micro/go-micro/network/resolver/registry"
|
||||||
"github.com/micro/go-micro/proxy"
|
"github.com/micro/go-micro/proxy"
|
||||||
@ -13,6 +14,8 @@ type Option func(*Options)
|
|||||||
|
|
||||||
// Options configure network
|
// Options configure network
|
||||||
type Options struct {
|
type Options struct {
|
||||||
|
// Id of the node
|
||||||
|
Id string
|
||||||
// Name of the network
|
// Name of the network
|
||||||
Name string
|
Name string
|
||||||
// Address to bind to
|
// Address to bind to
|
||||||
@ -27,14 +30,21 @@ type Options struct {
|
|||||||
Resolver resolver.Resolver
|
Resolver resolver.Resolver
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name is the network name
|
// 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 {
|
func Name(n string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Name = n
|
o.Name = n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Address is the network address
|
// Address sets the network address
|
||||||
func Address(a string) Option {
|
func Address(a string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Address = a
|
o.Address = a
|
||||||
@ -72,6 +82,7 @@ func Resolver(r resolver.Resolver) Option {
|
|||||||
// DefaultOptions returns network default options
|
// DefaultOptions returns network default options
|
||||||
func DefaultOptions() Options {
|
func DefaultOptions() Options {
|
||||||
return Options{
|
return Options{
|
||||||
|
Id: uuid.New().String(),
|
||||||
Name: DefaultName,
|
Name: DefaultName,
|
||||||
Address: DefaultAddress,
|
Address: DefaultAddress,
|
||||||
Tunnel: tunnel.NewTunnel(),
|
Tunnel: tunnel.NewTunnel(),
|
||||||
|
@ -43,7 +43,7 @@ var (
|
|||||||
// router implements default router
|
// router implements default router
|
||||||
type router struct {
|
type router struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
opts Options
|
options Options
|
||||||
status Status
|
status Status
|
||||||
table *table
|
table *table
|
||||||
exit chan struct{}
|
exit chan struct{}
|
||||||
@ -70,7 +70,7 @@ func newRouter(opts ...Option) Router {
|
|||||||
status := Status{Code: Stopped, Error: nil}
|
status := Status{Code: Stopped, Error: nil}
|
||||||
|
|
||||||
return &router{
|
return &router{
|
||||||
opts: options,
|
options: options,
|
||||||
status: status,
|
status: status,
|
||||||
table: newTable(),
|
table: newTable(),
|
||||||
advertWg: &sync.WaitGroup{},
|
advertWg: &sync.WaitGroup{},
|
||||||
@ -85,7 +85,7 @@ func (r *router) Init(opts ...Option) error {
|
|||||||
defer r.Unlock()
|
defer r.Unlock()
|
||||||
|
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&r.opts)
|
o(&r.options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -94,10 +94,10 @@ func (r *router) Init(opts ...Option) error {
|
|||||||
// Options returns router options
|
// Options returns router options
|
||||||
func (r *router) Options() Options {
|
func (r *router) Options() Options {
|
||||||
r.Lock()
|
r.Lock()
|
||||||
opts := r.opts
|
options := r.options
|
||||||
r.Unlock()
|
r.Unlock()
|
||||||
|
|
||||||
return opts
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
// Table returns routing table
|
// Table returns routing table
|
||||||
@ -139,7 +139,8 @@ func (r *router) manageServiceRoutes(service *registry.Service, action string) e
|
|||||||
Service: service.Name,
|
Service: service.Name,
|
||||||
Address: node.Address,
|
Address: node.Address,
|
||||||
Gateway: "",
|
Gateway: "",
|
||||||
Network: r.opts.Network,
|
Network: r.options.Network,
|
||||||
|
Router: r.options.Id,
|
||||||
Link: DefaultLink,
|
Link: DefaultLink,
|
||||||
Metric: DefaultLocalMetric,
|
Metric: DefaultLocalMetric,
|
||||||
}
|
}
|
||||||
@ -278,7 +279,7 @@ func (r *router) publishAdvert(advType AdvertType, events []*Event) {
|
|||||||
defer r.advertWg.Done()
|
defer r.advertWg.Done()
|
||||||
|
|
||||||
a := &Advert{
|
a := &Advert{
|
||||||
Id: r.opts.Id,
|
Id: r.options.Id,
|
||||||
Type: advType,
|
Type: advType,
|
||||||
TTL: DefaultAdvertTTL,
|
TTL: DefaultAdvertTTL,
|
||||||
Timestamp: time.Now(),
|
Timestamp: time.Now(),
|
||||||
@ -529,20 +530,22 @@ func (r *router) Start() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add all local service routes into the routing table
|
// add all local service routes into the routing table
|
||||||
if err := r.manageRegistryRoutes(r.opts.Registry, "create"); err != nil {
|
if err := r.manageRegistryRoutes(r.options.Registry, "create"); err != nil {
|
||||||
e := fmt.Errorf("failed adding registry routes: %s", err)
|
e := fmt.Errorf("failed adding registry routes: %s", err)
|
||||||
r.status = Status{Code: Error, Error: e}
|
r.status = Status{Code: Error, Error: e}
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// add default gateway into routing table
|
// add default gateway into routing table
|
||||||
if r.opts.Gateway != "" {
|
if r.options.Gateway != "" {
|
||||||
// note, the only non-default value is the gateway
|
// note, the only non-default value is the gateway
|
||||||
route := Route{
|
route := Route{
|
||||||
Service: "*",
|
Service: "*",
|
||||||
Address: "*",
|
Address: "*",
|
||||||
Gateway: r.opts.Gateway,
|
Gateway: r.options.Gateway,
|
||||||
Network: "*",
|
Network: "*",
|
||||||
|
Router: r.options.Id,
|
||||||
|
Link: DefaultLink,
|
||||||
Metric: DefaultLocalMetric,
|
Metric: DefaultLocalMetric,
|
||||||
}
|
}
|
||||||
if err := r.table.Create(route); err != nil {
|
if err := r.table.Create(route); err != nil {
|
||||||
@ -557,7 +560,7 @@ func (r *router) Start() error {
|
|||||||
r.exit = make(chan struct{})
|
r.exit = make(chan struct{})
|
||||||
|
|
||||||
// registry watcher
|
// registry watcher
|
||||||
regWatcher, err := r.opts.Registry.Watch()
|
regWatcher, err := r.options.Registry.Watch()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e := fmt.Errorf("failed creating registry watcher: %v", err)
|
e := fmt.Errorf("failed creating registry watcher: %v", err)
|
||||||
r.status = Status{Code: Error, Error: e}
|
r.status = Status{Code: Error, Error: e}
|
||||||
@ -669,6 +672,10 @@ func (r *router) Process(a *Advert) error {
|
|||||||
})
|
})
|
||||||
|
|
||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
|
// skip if the router is the origin of this route
|
||||||
|
if event.Route.Router == r.options.Id {
|
||||||
|
continue
|
||||||
|
}
|
||||||
// create a copy of the route
|
// create a copy of the route
|
||||||
route := event.Route
|
route := event.Route
|
||||||
action := event.Type
|
action := event.Type
|
||||||
|
@ -11,29 +11,38 @@ type QueryOptions struct {
|
|||||||
Gateway string
|
Gateway string
|
||||||
// Network is network address
|
// Network is network address
|
||||||
Network string
|
Network string
|
||||||
|
// Router is router id
|
||||||
|
Router string
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryService sets destination address
|
// QueryService sets service to query
|
||||||
func QueryService(s string) QueryOption {
|
func QueryService(s string) QueryOption {
|
||||||
return func(o *QueryOptions) {
|
return func(o *QueryOptions) {
|
||||||
o.Service = s
|
o.Service = s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryGateway sets route gateway
|
// QueryGateway sets gateway address to query
|
||||||
func QueryGateway(g string) QueryOption {
|
func QueryGateway(g string) QueryOption {
|
||||||
return func(o *QueryOptions) {
|
return func(o *QueryOptions) {
|
||||||
o.Gateway = g
|
o.Gateway = g
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryNetwork sets route network address
|
// QueryNetwork sets network name to query
|
||||||
func QueryNetwork(n string) QueryOption {
|
func QueryNetwork(n string) QueryOption {
|
||||||
return func(o *QueryOptions) {
|
return func(o *QueryOptions) {
|
||||||
o.Network = n
|
o.Network = n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QueryRouter sets router id to query
|
||||||
|
func QueryRouter(r string) QueryOption {
|
||||||
|
return func(o *QueryOptions) {
|
||||||
|
o.Router = r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Query is routing table query
|
// Query is routing table query
|
||||||
type Query interface {
|
type Query interface {
|
||||||
// Options returns query options
|
// Options returns query options
|
||||||
@ -52,6 +61,7 @@ func NewQuery(opts ...QueryOption) Query {
|
|||||||
Service: "*",
|
Service: "*",
|
||||||
Gateway: "*",
|
Gateway: "*",
|
||||||
Network: "*",
|
Network: "*",
|
||||||
|
Router: "*",
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
@ -67,8 +77,3 @@ func NewQuery(opts ...QueryOption) Query {
|
|||||||
func (q *query) Options() QueryOptions {
|
func (q *query) Options() QueryOptions {
|
||||||
return q.opts
|
return q.opts
|
||||||
}
|
}
|
||||||
|
|
||||||
// String prints routing table query in human readable form
|
|
||||||
func (q query) String() string {
|
|
||||||
return "query"
|
|
||||||
}
|
|
||||||
|
@ -7,9 +7,9 @@ import (
|
|||||||
var (
|
var (
|
||||||
// DefaultLink is default network link
|
// DefaultLink is default network link
|
||||||
DefaultLink = "local"
|
DefaultLink = "local"
|
||||||
// DefaultLocalMetric is default route cost metric for the local network
|
// DefaultLocalMetric is default route cost for a local route
|
||||||
DefaultLocalMetric = 1
|
DefaultLocalMetric = 1
|
||||||
// DefaultNetworkMetric is default route cost metric for the micro network
|
// DefaultNetworkMetric is default route cost for a network route
|
||||||
DefaultNetworkMetric = 10
|
DefaultNetworkMetric = 10
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -23,6 +23,8 @@ type Route struct {
|
|||||||
Gateway string
|
Gateway string
|
||||||
// Network is network address
|
// Network is network address
|
||||||
Network string
|
Network string
|
||||||
|
// Router is router id
|
||||||
|
Router string
|
||||||
// Link is network link
|
// Link is network link
|
||||||
Link string
|
Link string
|
||||||
// Metric is the route cost metric
|
// Metric is the route cost metric
|
||||||
@ -33,6 +35,6 @@ type Route struct {
|
|||||||
func (r *Route) Hash() uint64 {
|
func (r *Route) Hash() uint64 {
|
||||||
h := fnv.New64()
|
h := fnv.New64()
|
||||||
h.Reset()
|
h.Reset()
|
||||||
h.Write([]byte(r.Service + r.Address + r.Gateway + r.Network + r.Link))
|
h.Write([]byte(r.Service + r.Address + r.Gateway + r.Network + r.Router + r.Link))
|
||||||
return h.Sum64()
|
return h.Sum64()
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,14 @@ import (
|
|||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
// table is an in memory routing table
|
var (
|
||||||
|
// ErrRouteNotFound is returned when no route was found in the routing table
|
||||||
|
ErrRouteNotFound = errors.New("route not found")
|
||||||
|
// ErrDuplicateRoute is returned when the route already exists
|
||||||
|
ErrDuplicateRoute = errors.New("duplicate route")
|
||||||
|
)
|
||||||
|
|
||||||
|
// table is an in-memory routing table
|
||||||
type table struct {
|
type table struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
// routes stores service routes
|
// routes stores service routes
|
||||||
@ -25,6 +32,19 @@ func newTable(opts ...Option) *table {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sendEvent sends events to all subscribed watchers
|
||||||
|
func (t *table) sendEvent(e *Event) {
|
||||||
|
t.RLock()
|
||||||
|
defer t.RUnlock()
|
||||||
|
|
||||||
|
for _, w := range t.watchers {
|
||||||
|
select {
|
||||||
|
case w.resChan <- e:
|
||||||
|
case <-w.done:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create creates new route in the routing table
|
// Create creates new route in the routing table
|
||||||
func (t *table) Create(r Route) error {
|
func (t *table) Create(r Route) error {
|
||||||
service := r.Service
|
service := r.Service
|
||||||
@ -106,21 +126,23 @@ func (t *table) List() ([]Route, error) {
|
|||||||
return routes, nil
|
return routes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// isMatch checks if the route matches given network and router
|
// isMatch checks if the route matches given query options
|
||||||
func isMatch(route Route, network, router string) bool {
|
func isMatch(route Route, gateway, network, router string) bool {
|
||||||
|
if gateway == "*" || gateway == route.Gateway {
|
||||||
if network == "*" || network == route.Network {
|
if network == "*" || network == route.Network {
|
||||||
if router == "*" || router == route.Gateway {
|
if router == "*" || router == route.Router {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// findRoutes finds all the routes for given network and router and returns them
|
// findRoutes finds all the routes for given network and router and returns them
|
||||||
func findRoutes(routes map[uint64]Route, network, router string) []Route {
|
func findRoutes(routes map[uint64]Route, gateway, network, router string) []Route {
|
||||||
var results []Route
|
var results []Route
|
||||||
for _, route := range routes {
|
for _, route := range routes {
|
||||||
if isMatch(route, network, router) {
|
if isMatch(route, gateway, network, router) {
|
||||||
results = append(results, route)
|
results = append(results, route)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,13 +158,13 @@ func (t *table) Query(q Query) ([]Route, error) {
|
|||||||
if _, ok := t.routes[q.Options().Service]; !ok {
|
if _, ok := t.routes[q.Options().Service]; !ok {
|
||||||
return nil, ErrRouteNotFound
|
return nil, ErrRouteNotFound
|
||||||
}
|
}
|
||||||
return findRoutes(t.routes[q.Options().Service], q.Options().Network, q.Options().Gateway), nil
|
return findRoutes(t.routes[q.Options().Service], q.Options().Gateway, q.Options().Network, q.Options().Router), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var results []Route
|
var results []Route
|
||||||
// search through all destinations
|
// search through all destinations
|
||||||
for _, routes := range t.routes {
|
for _, routes := range t.routes {
|
||||||
results = append(results, findRoutes(routes, q.Options().Network, q.Options().Gateway)...)
|
results = append(results, findRoutes(routes, q.Options().Gateway, q.Options().Network, q.Options().Router)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return results, nil
|
return results, nil
|
||||||
@ -181,23 +203,3 @@ func (t *table) Watch(opts ...WatchOption) (Watcher, error) {
|
|||||||
|
|
||||||
return w, nil
|
return w, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendEvent sends events to all subscribed watchers
|
|
||||||
func (t *table) sendEvent(e *Event) {
|
|
||||||
t.RLock()
|
|
||||||
defer t.RUnlock()
|
|
||||||
|
|
||||||
for _, w := range t.watchers {
|
|
||||||
select {
|
|
||||||
case w.resChan <- e:
|
|
||||||
case <-w.done:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrRouteNotFound is returned when no route was found in the routing table
|
|
||||||
ErrRouteNotFound = errors.New("route not found")
|
|
||||||
// ErrDuplicateRoute is returned when the route already exists
|
|
||||||
ErrDuplicateRoute = errors.New("duplicate route")
|
|
||||||
)
|
|
||||||
|
@ -9,6 +9,7 @@ func testSetup() (*table, Route) {
|
|||||||
Service: "dest.svc",
|
Service: "dest.svc",
|
||||||
Gateway: "dest.gw",
|
Gateway: "dest.gw",
|
||||||
Network: "dest.network",
|
Network: "dest.network",
|
||||||
|
Router: "src.router",
|
||||||
Link: "det.link",
|
Link: "det.link",
|
||||||
Metric: 10,
|
Metric: 10,
|
||||||
}
|
}
|
||||||
@ -109,11 +110,13 @@ func TestQuery(t *testing.T) {
|
|||||||
svc := []string{"svc1", "svc2", "svc3"}
|
svc := []string{"svc1", "svc2", "svc3"}
|
||||||
net := []string{"net1", "net2", "net1"}
|
net := []string{"net1", "net2", "net1"}
|
||||||
gw := []string{"gw1", "gw2", "gw3"}
|
gw := []string{"gw1", "gw2", "gw3"}
|
||||||
|
rtr := []string{"rtr1", "rt2", "rt3"}
|
||||||
|
|
||||||
for i := 0; i < len(svc); i++ {
|
for i := 0; i < len(svc); i++ {
|
||||||
route.Service = svc[i]
|
route.Service = svc[i]
|
||||||
route.Network = net[i]
|
route.Network = net[i]
|
||||||
route.Gateway = gw[i]
|
route.Gateway = gw[i]
|
||||||
|
route.Router = rtr[i]
|
||||||
if err := table.Create(route); err != nil {
|
if err := table.Create(route); err != nil {
|
||||||
t.Errorf("error adding route: %s", err)
|
t.Errorf("error adding route: %s", err)
|
||||||
}
|
}
|
||||||
@ -127,8 +130,9 @@ func TestQuery(t *testing.T) {
|
|||||||
t.Errorf("error looking up routes: %s", err)
|
t.Errorf("error looking up routes: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// query particular net
|
// query routes particular network
|
||||||
query = NewQuery(QueryNetwork("net1"))
|
network := "net1"
|
||||||
|
query = NewQuery(QueryNetwork(network))
|
||||||
|
|
||||||
routes, err = table.Query(query)
|
routes, err = table.Query(query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -139,7 +143,13 @@ func TestQuery(t *testing.T) {
|
|||||||
t.Errorf("incorrect number of routes returned. Expected: %d, found: %d", 2, len(routes))
|
t.Errorf("incorrect number of routes returned. Expected: %d, found: %d", 2, len(routes))
|
||||||
}
|
}
|
||||||
|
|
||||||
// query particular gateway
|
for _, route := range routes {
|
||||||
|
if route.Network != network {
|
||||||
|
t.Errorf("incorrect route returned. Expected network: %s, found: %s", network, route.Network)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// query routes for particular gateway
|
||||||
gateway := "gw1"
|
gateway := "gw1"
|
||||||
query = NewQuery(QueryGateway(gateway))
|
query = NewQuery(QueryGateway(gateway))
|
||||||
|
|
||||||
@ -156,11 +166,28 @@ func TestQuery(t *testing.T) {
|
|||||||
t.Errorf("incorrect route returned. Expected gateway: %s, found: %s", gateway, routes[0].Gateway)
|
t.Errorf("incorrect route returned. Expected gateway: %s, found: %s", gateway, routes[0].Gateway)
|
||||||
}
|
}
|
||||||
|
|
||||||
// query particular route
|
// query routes for particular router
|
||||||
network := "net1"
|
router := "rtr1"
|
||||||
|
query = NewQuery(QueryRouter(router))
|
||||||
|
|
||||||
|
routes, err = table.Query(query)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error looking up routes: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(routes) != 1 {
|
||||||
|
t.Errorf("incorrect number of routes returned. Expected: %d, found: %d", 1, len(routes))
|
||||||
|
}
|
||||||
|
|
||||||
|
if routes[0].Router != router {
|
||||||
|
t.Errorf("incorrect route returned. Expected router: %s, found: %s", router, routes[0].Router)
|
||||||
|
}
|
||||||
|
|
||||||
|
// query particular gateway and network
|
||||||
query = NewQuery(
|
query = NewQuery(
|
||||||
QueryGateway(gateway),
|
QueryGateway(gateway),
|
||||||
QueryNetwork(network),
|
QueryNetwork(network),
|
||||||
|
QueryRouter(router),
|
||||||
)
|
)
|
||||||
|
|
||||||
routes, err = table.Query(query)
|
routes, err = table.Query(query)
|
||||||
@ -180,7 +207,11 @@ func TestQuery(t *testing.T) {
|
|||||||
t.Errorf("incorrect network returned. Expected network: %s, found: %s", network, routes[0].Network)
|
t.Errorf("incorrect network returned. Expected network: %s, found: %s", network, routes[0].Network)
|
||||||
}
|
}
|
||||||
|
|
||||||
// bullshit route query
|
if routes[0].Router != router {
|
||||||
|
t.Errorf("incorrect route returned. Expected router: %s, found: %s", router, routes[0].Router)
|
||||||
|
}
|
||||||
|
|
||||||
|
// non-existen route query
|
||||||
query = NewQuery(QueryService("foobar"))
|
query = NewQuery(QueryService("foobar"))
|
||||||
|
|
||||||
routes, err = table.Query(query)
|
routes, err = table.Query(query)
|
||||||
|
@ -6,6 +6,11 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrWatcherStopped is returned when routing table watcher has been stopped
|
||||||
|
ErrWatcherStopped = errors.New("watcher stopped")
|
||||||
|
)
|
||||||
|
|
||||||
// EventType defines routing table event
|
// EventType defines routing table event
|
||||||
type EventType int
|
type EventType int
|
||||||
|
|
||||||
@ -42,9 +47,6 @@ type Event struct {
|
|||||||
Route Route
|
Route Route
|
||||||
}
|
}
|
||||||
|
|
||||||
// WatchOption is used to define what routes to watch in the table
|
|
||||||
type WatchOption func(*WatchOptions)
|
|
||||||
|
|
||||||
// Watcher defines routing table watcher interface
|
// Watcher defines routing table watcher interface
|
||||||
// Watcher returns updates to the routing table
|
// Watcher returns updates to the routing table
|
||||||
type Watcher interface {
|
type Watcher interface {
|
||||||
@ -56,7 +58,11 @@ type Watcher interface {
|
|||||||
Stop()
|
Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WatchOption is used to define what routes to watch in the table
|
||||||
|
type WatchOption func(*WatchOptions)
|
||||||
|
|
||||||
// WatchOptions are table watcher options
|
// WatchOptions are table watcher options
|
||||||
|
// TODO: expand the options to watch based on other criteria
|
||||||
type WatchOptions struct {
|
type WatchOptions struct {
|
||||||
// Service allows to watch specific service routes
|
// Service allows to watch specific service routes
|
||||||
Service string
|
Service string
|
||||||
@ -70,6 +76,7 @@ func WatchService(s string) WatchOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tableWatcher implements routing table Watcher
|
||||||
type tableWatcher struct {
|
type tableWatcher struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
id string
|
id string
|
||||||
@ -113,8 +120,3 @@ func (w *tableWatcher) Stop() {
|
|||||||
close(w.done)
|
close(w.done)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrWatcherStopped is returned when routing table watcher has been stopped
|
|
||||||
ErrWatcherStopped = errors.New("watcher stopped")
|
|
||||||
)
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user