This repository has been archived by the owner on Dec 9, 2019. It is now read-only.
/
registration.go
86 lines (70 loc) · 2.48 KB
/
registration.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
package gbus
import (
"strings"
)
type MessageFilter struct {
Exchange string
RoutingKey string
MsgName string
}
func (filter *MessageFilter) Matches(exchange, routingKey, msgName string) bool {
targetExchange := strings.ToLower(exchange)
targetRoutingKey := strings.ToLower(routingKey)
targetMsgName := strings.ToLower(msgName)
//if the registration is for a command then routingkeys must exactly match
if filter.Exchange == "" && targetExchange == "" {
return (filter.RoutingKey == targetRoutingKey) && (filter.MsgName == targetMsgName)
}
//if the exchanges do not matche return false
if filter.Exchange != targetExchange {
return false
}
//to enable subscribers to handle different message types published to a topic or only receive message from a specific type check if the topic matches and regMsgName is empty
// or the topic matches and the msg types are the same
routingKeyMatches := wildcardMatch(targetRoutingKey, filter.RoutingKey)
return (routingKeyMatches && filter.MsgName == "") || (routingKeyMatches && filter.MsgName == targetMsgName)
}
func wildcardMatch(input, pattern string) bool {
linput := strings.ToLower(input)
lpattern := strings.ToLower(pattern)
in := strings.Split(linput, ".")
patt := strings.Split(lpattern, ".")
return matchWords(in, patt)
}
func matchWords(input, pattern []string) bool {
if len(input) == 0 && len(pattern) == 0 {
return true
}
if len(pattern) > 1 && pattern[0] == "*" && len(input) == 0 {
return false
}
if (len(pattern) >= 1 && pattern[0] == "?") || (len(pattern) != 0 && len(input) != 0 && pattern[0] == input[0]) {
return matchWords(input[1:], pattern[1:])
}
if len(pattern) != 0 && pattern[0] == "*" {
return matchWords(input, pattern[1:]) || matchWords(input[1:], pattern)
}
return false
}
type Registration struct {
info *MessageFilter
Handler MessageHandler
}
func (sub *Registration) Matches(exchange, routingKey, msgName string) bool {
return sub.info.Matches(exchange, routingKey, msgName)
}
func NewRegistration(exchange, routingKey string, message Message, handler MessageHandler) *Registration {
reg := Registration{
info: NewMessageFilter(exchange, routingKey, message),
Handler: handler}
return ®
}
func NewMessageFilter(exchange, routingKey string, message Message) *MessageFilter {
filter := &MessageFilter{
Exchange: strings.ToLower(exchange),
RoutingKey: strings.ToLower(routingKey)}
if message != nil {
filter.MsgName = strings.ToLower(message.SchemaName())
}
return filter
}