-
Notifications
You must be signed in to change notification settings - Fork 0
/
router.go
133 lines (110 loc) · 3.37 KB
/
router.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
package main
import (
"encoding/json"
"fmt"
"regexp"
"strings"
)
type Route struct {
Type string
Endpoint string
Handler CarrierHandler
}
type Router struct {
gateway *Gateway
Routes []*Route
ClientMsgChan chan MsgQueueItem
CarrierMsgChan chan MsgQueueItem
MessageAckStatus chan MsgQueueItem
}
func (router *Router) ClientMsgConsumer() {
for {
client := router.gateway.AMPQClient
deliveries, err := client.ConsumeMessages("client")
if err != nil {
continue
}
for delivery := range deliveries {
var msgQueueItem MsgQueueItem
err := json.Unmarshal(delivery.Body, &msgQueueItem)
if err != nil {
client.logger.Error(err)
continue
}
msgQueueItem.Delivery = &delivery
//client.logger.Printf("Received message (%v) from %s", delivery.DeliveryTag, delivery.Body)
router.ClientMsgChan <- msgQueueItem
// todo only ack if was successful??
}
}
}
func (router *Router) CarrierMsgConsumer() {
for {
client := router.gateway.AMPQClient
deliveries, err := client.ConsumeMessages("carrier")
if err != nil {
//client.logger.Error(err)
continue
}
for delivery := range deliveries {
var msgQueueItem MsgQueueItem
err := json.Unmarshal(delivery.Body, &msgQueueItem)
if err != nil {
client.logger.Error(err)
continue
}
msgQueueItem.Delivery = &delivery
//client.logger.Printf("Received message (%v) from carrier %s", delivery.DeliveryTag, delivery.Body)
router.CarrierMsgChan <- msgQueueItem
// todo only ack if was successful??
}
}
}
func (router *Router) AddRoute(routeType, endpoint string, handler CarrierHandler) {
router.Routes = append(router.Routes, &Route{Type: routeType, Endpoint: endpoint, Handler: handler})
}
func (router *Router) findRouteByName(routeType, routeName string) *Route {
for _, route := range router.Routes {
if route.Type == routeType && route.Endpoint == routeName {
return route
}
}
return nil
}
// findClientByNumber searches for a client using an E.164 number.
// The client's number list does not have the `+` prefix.
func (router *Router) findClientByNumber(number string) (*Client, error) {
// Normalize the input number by removing the leading `+`, if present
searchNumber := strings.TrimPrefix(number, "+")
for _, client := range router.gateway.Clients {
for _, num := range client.Numbers {
// Compare the normalized input number with the stored number
if strings.Contains(searchNumber, num.Number) {
return client, nil
}
}
}
return nil, fmt.Errorf("unable to find client for number: %s", number)
}
func FormatToE164(number string) (string, error) {
// Preserve the original number
originalNumber := number
// Remove any metadata like "/TYPE=PLMN"
number = strings.Split(number, "/")[0]
// Regex to match a valid E.164 number
e164Regex := regexp.MustCompile(`^\+?[1-9]\d{1,14}$`)
// Remove any non-digit characters except the leading '+'
cleaned := strings.TrimLeft(number, "+")
cleaned = regexp.MustCompile(`\D`).ReplaceAllString(cleaned, "")
// Re-add the leading '+' if it was stripped
if strings.HasPrefix(number, "+") {
cleaned = "+" + cleaned
} else {
cleaned = "+" + cleaned // Add '+' if not already present
}
// Validate the cleaned number against E.164 format
if !e164Regex.MatchString(cleaned) {
return originalNumber, fmt.Errorf("unable to format to E.164: %s", originalNumber)
}
return cleaned, nil
}