-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathaddress.go
More file actions
161 lines (140 loc) · 4.83 KB
/
address.go
File metadata and controls
161 lines (140 loc) · 4.83 KB
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
150
151
152
153
154
155
156
157
158
159
160
161
package rabbitmqamqp
import (
"errors"
"fmt"
"net/url"
"strings"
)
// ITargetAddress is an interface that represents an address that can be used to send messages to.
// It can be either a Queue or an Exchange with a routing key.
type ITargetAddress interface {
toAddress() (string, error)
}
// QueueAddress represents the address of a queue.
type QueueAddress struct {
Queue string // The name of the queue
Parameters string // Additional parameters not related to the queue. Most of the time it is empty
}
func (qas *QueueAddress) toAddress() (string, error) {
q := &qas.Queue
if isStringNilOrEmpty(&qas.Queue) {
q = nil
}
return queueAddress(q)
}
// ExchangeAddress represents the address of an exchange with a routing key.
type ExchangeAddress struct {
Exchange string // The name of the exchange
Key string // The routing key. Can be empty
}
func (eas *ExchangeAddress) toAddress() (string, error) {
ex := &eas.Exchange
if isStringNilOrEmpty(&eas.Exchange) {
ex = nil
}
k := &eas.Key
if isStringNilOrEmpty(&eas.Key) {
k = nil
}
return exchangeAddress(ex, k)
}
// address Creates the address for the exchange or queue following the RabbitMQ conventions.
// see: https://www.rabbitmq.com/docs/amqp#address-v2
func address(exchange, key, queue *string, urlParameters *string) (string, error) {
if exchange == nil && queue == nil {
return "", errors.New("exchange or queue must be set")
}
urlAppend := ""
if !isStringNilOrEmpty(urlParameters) {
urlAppend = *urlParameters
}
if !isStringNilOrEmpty(exchange) && !isStringNilOrEmpty(queue) {
return "", errors.New("exchange and queue cannot be set together")
}
if !isStringNilOrEmpty(exchange) {
if !isStringNilOrEmpty(key) {
return fmt.Sprintf("/%s/%s/%s%s", exchanges, encodePathSegments(*exchange), encodePathSegments(*key), urlAppend), nil
}
return fmt.Sprintf("/%s/%s%s", exchanges, encodePathSegments(*exchange), urlAppend), nil
}
if queue == nil {
return "", nil
}
if isStringNilOrEmpty(queue) {
return "", errors.New("queue must be set")
}
return fmt.Sprintf("/%s/%s%s", queues, encodePathSegments(*queue), urlAppend), nil
}
// exchangeAddress Creates the address for the exchange
// See address for more information
func exchangeAddress(exchange, key *string) (string, error) {
return address(exchange, key, nil, nil)
}
// queueAddress Creates the address for the queue.
// See address for more information
func queueAddress(queue *string) (string, error) {
return address(nil, nil, queue, nil)
}
// PurgeQueueAddress Creates the address for purging the queue.
// See address for more information
func purgeQueueAddress(queue *string) (string, error) {
parameter := "/messages"
return address(nil, nil, queue, ¶meter)
}
// encodePathSegments takes a string and returns its percent-encoded representation.
func encodePathSegments(input string) string {
encoded := url.QueryEscape(input)
return strings.ReplaceAll(encoded, "+", "%20")
//var encoded strings.Builder
//
//// Iterate over each character in the input string
//for _, char := range input {
// // Check if the character is an unreserved character (i.e., it doesn't need encoding)
// if isUnreserved(char) {
// encoded.WriteRune(char) // Append as is
// } else {
// // Encode character To %HH format
// encoded.WriteString(fmt.Sprintf("%%%02X", char))
// }
//}
//
//return encoded.String()
}
//// Decode takes a percent-encoded string and returns its decoded representation.
//func decode(input string) (string, error) {
// // Use url.QueryUnescape which properly decodes percent-encoded strings
// decoded, err := url.QueryUnescape(input)
// if err != nil {
// return "", err
// }
//
// return decoded, nil
//}
//// isUnreserved checks if a character is an unreserved character in percent encoding
//// Unreserved characters are: A-Z, a-z, 0-9, -, ., _, ~
//func isUnreserved(char rune) bool {
// return (char >= 'A' && char <= 'Z') ||
// (char >= 'a' && char <= 'z') ||
// (char >= '0' && char <= '9') ||
// char == '-' || char == '.' || char == '_' || char == '~'
//}
func bindingPath() string {
return "/" + bindings
}
func bindingPathWithExchangeQueueKey(toQueue bool, sourceName, destinationName, key string) string {
sourceNameEncoded := encodePathSegments(sourceName)
destinationNameEncoded := encodePathSegments(destinationName)
keyEncoded := encodePathSegments(key)
destinationType := "dste"
if toQueue {
destinationType = "dstq"
}
format := "/%s/src=%s;%s=%s;key=%s;args="
return fmt.Sprintf(format, bindings, sourceNameEncoded, destinationType, destinationNameEncoded, keyEncoded)
}
func validateAddress(address string) error {
if strings.HasPrefix(address, fmt.Sprintf("/%s/", exchanges)) || strings.HasPrefix(address, fmt.Sprintf("/%s/", queues)) {
return nil
}
return fmt.Errorf("invalid destination address, the address should start with /%s/ or/%s/ ", exchanges, queues)
}