forked from micro/micro
-
Notifications
You must be signed in to change notification settings - Fork 1
/
query.go
executable file
·149 lines (127 loc) · 3.37 KB
/
query.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Original source: github.com/2637309949/micro/v3/router/query.go
package router
// LookupOption sets routing table query options
type LookupOption func(*LookupOptions)
// LookupOptions are routing table query options
// TODO replace with Filter(Route) bool
type LookupOptions struct {
// Address of the service
Address string
// Gateway is route gateway
Gateway string
// Network is network address
Network string
// Router is router id
Router string
// Link to query
Link string
}
// LookupAddress sets service to query
func LookupAddress(a string) LookupOption {
return func(o *LookupOptions) {
o.Address = a
}
}
// LookupGateway sets gateway address to query
func LookupGateway(g string) LookupOption {
return func(o *LookupOptions) {
o.Gateway = g
}
}
// LookupNetwork sets network name to query
func LookupNetwork(n string) LookupOption {
return func(o *LookupOptions) {
o.Network = n
}
}
// LookupRouter sets router id to query
func LookupRouter(r string) LookupOption {
return func(o *LookupOptions) {
o.Router = r
}
}
// LookupLink sets the link to query
func LookupLink(link string) LookupOption {
return func(o *LookupOptions) {
o.Link = link
}
}
// NewLookup creates new query and returns it
func NewLookup(opts ...LookupOption) LookupOptions {
// default options
qopts := LookupOptions{
Address: "*",
Gateway: "*",
Network: "*",
Router: "*",
Link: DefaultLink,
}
for _, o := range opts {
o(&qopts)
}
return qopts
}
// isMatch checks if the route matches given query options
func isMatch(route Route, address, gateway, network, rtr, link string) bool {
// matches the values provided
match := func(a, b string) bool {
if a == "*" || b == "*" || a == b {
return true
}
return false
}
// a simple struct to hold our values
type compare struct {
a string
b string
}
// compare the following values
values := []compare{
{gateway, route.Gateway},
{network, route.Network},
{rtr, route.Router},
{address, route.Address},
{link, route.Link},
}
for _, v := range values {
// attempt to match each value
if !match(v.a, v.b) {
return false
}
}
return true
}
// filterRoutes finds all the routes for given network and router and returns them
func Filter(routes []Route, opts LookupOptions) []Route {
address := opts.Address
gateway := opts.Gateway
network := opts.Network
rtr := opts.Router
link := opts.Link
// routeMap stores the routes we're going to advertise
routeMap := make(map[string][]Route)
for _, route := range routes {
if isMatch(route, address, gateway, network, rtr, link) {
// add matchihg route to the routeMap
routeKey := route.Service + "@" + route.Network
routeMap[routeKey] = append(routeMap[routeKey], route)
}
}
var results []Route
for _, route := range routeMap {
results = append(results, route...)
}
return results
}