/
dequeue.go
234 lines (168 loc) · 6.78 KB
/
dequeue.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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
package main
import (
"fmt"
"github.com/streadway/amqp"
"encoding/json"
"labix.org/v2/mgo"
"labix.org/v2/mgo/bson"
"log/syslog"
"math/rand"
"time"
)
func dequeue(syslogLog *syslog.Writer, mongoHref string, mongoDatabaseName string, mongoCollectionName string, amqpHref string, amqpExchange string, amqpExchangeType string) {
//DEBUG
syslogLog.Notice("[dequeue] BEGIN")
syslogLog.Notice( fmt.Sprintf(" [dequeue] mongoHref = [%v]", mongoHref) )
syslogLog.Notice( fmt.Sprintf(" [dequeue] mongoDatabaseName = [%v]", mongoDatabaseName) )
syslogLog.Notice( fmt.Sprintf(" [dequeue] mongoCollectionName = [%v]", mongoCollectionName) )
syslogLog.Notice( fmt.Sprintf(" [dequeue] amqpHref = [%v]", amqpHref) )
syslogLog.Notice( fmt.Sprintf(" [dequeue] amqpExchange = [%v]", amqpExchange) )
syslogLog.Notice( fmt.Sprintf(" [dequeue] amqpExchangeType = [%v]", amqpExchangeType) )
// Deal with parameters.
if "" == mongoHref {
errMsg := fmt.Sprintf(" [dequeue] Bad mongoHref. Received: [%v].", mongoHref)
syslogLog.Err(errMsg)
panic(errMsg)
/////////////////////// RETURN
return
}
if "" == mongoDatabaseName {
errMsg := fmt.Sprintf(" [dequeue] Bad mongoDatabaseName. Received: [%v].", mongoDatabaseName)
syslogLog.Err(errMsg)
panic(errMsg)
/////////////////////// RETURN
return
}
if "" == mongoCollectionName {
errMsg := fmt.Sprintf(" [dequeue] Bad mongoCollectionName. Received: [%v].", mongoCollectionName)
syslogLog.Err(errMsg)
panic(errMsg)
/////////////////////// RETURN
return
}
if "" == amqpHref {
errMsg := fmt.Sprintf(" [dequeue] Bad amqpHref. Received: [%v].", amqpHref)
syslogLog.Err(errMsg)
panic(errMsg)
/////////////////////// RETURN
return
}
// Connect to MongoDB
mongoSession, err := mgo.Dial(mongoHref)
if err != nil {
syslogLog.Err( fmt.Sprintf(" [dequeue] Could NOT connect to MongoDB at [%v], received err = [%v]", mongoHref, err) )
panic(err)
/////////////////////// RETURN
return
}
defer mongoSession.Close()
// Optional. Switch the session to a monotonic behavior.
mongoSession.SetMode(mgo.Monotonic, true)
mongoCollection := mongoSession.DB(mongoDatabaseName).C(mongoCollectionName)
//DEBUG
syslogLog.Notice( fmt.Sprintf(" [dequeue] Connected to MongoDB with %v.%v", mongoDatabaseName, mongoCollectionName) )
// Connect to AMQP.
amqpConnection, err := amqp.Dial(amqpHref)
if err != nil {
syslogLog.Err( fmt.Sprintf(" [dequeue] Could NOT connect to AMQP server (RabbitMQ?) at [%v], received err = [%v]", amqpHref, err) )
panic(err)
/////////////////////// RETURN
return
}
defer amqpConnection.Close()
amqpChannel, err := amqpConnection.Channel()
if err != nil {
syslogLog.Err(" [dequeue] Could NOT get AMQP channel")
panic(err)
/////////////////////// RETURN
return
}
//DEBUG
syslogLog.Notice( fmt.Sprintf(" [dequeue] amqpChannel = [%v]", amqpChannel) )
//DEBUG
syslogLog.Notice( fmt.Sprintf(" [dequeue] Connected to AMQP server (RabbitMQ?)", mongoDatabaseName, mongoCollectionName) )
// Forever
for {
//DEBUG
syslogLog.Notice(" [dequeue] =-<>-=-<>-=-<>-=-<>-=-<>-=-<>-=-<>-=-<>-=-<>-=-<>-= LOOP")
// Check MongoDB for items that are ready.
mongoCriteria := bson.M{ "when":bson.M{"$lte": bson.Now()} }
mongoQuery := mongoCollection.Find(mongoCriteria)
//DEBUG
syslogLog.Notice( fmt.Sprintf(" [dequeue] mongoQuery = [%v]", mongoQuery) )
if nil != err {
syslogLog.Err( fmt.Sprintf(" [dequeue] Error querying MongoDB with mongoCriteria = [%v] received err = [%v]", mongoCriteria, err) )
} else {
syslogLog.Notice( fmt.Sprintf(" [dequeue] Success querying MongoDB with mongoCriteria = [%v]", mongoCriteria, err) )
// var x struct{
// _Id bson.ObjectId
// When time.Time
// Target string
// Message map[string]interface{}
// }
x := map[string]interface{}{}
items := mongoQuery.Iter()
for items.Next(&x) {
//DEBUG
syslogLog.Notice( fmt.Sprintf(" [dequeue] Received row: [%v]", x) )
// routingKey := x.Target
routingKey := x["target"].(string)
//DEBUG
syslogLog.Notice( fmt.Sprintf(" [dequeue] Routing Key : [%v]", routingKey) )
// body, err := json.Marshal(x.Message)
body, err := json.Marshal(x["message"])
if nil != err {
//DEBUG
syslogLog.Err( fmt.Sprintf(" [dequeue] Error serializing body into JSON, received err = [%v]", err) )
//@TODO #############################################################################
}
//DEBUG
syslogLog.Notice( fmt.Sprintf(" [dequeue] Body : [%v]", body) )
//DEBUG
syslogLog.Notice( fmt.Sprintf(" [dequeue] Routing key: [%v]", routingKey) )
syslogLog.Notice( fmt.Sprintf(" [dequeue] declared Exchange, publishing %dB body (%s)", len(body), body) )
if err = amqpChannel.Publish(
amqpExchange, // publish to an exchange
routingKey, // routing to 0 or more queues
false, // mandatory
false, // immediate
amqp.Publishing{
Headers: amqp.Table{},
ContentType: "text/plain",
ContentEncoding: "",
Body: body,
DeliveryMode: amqp.Transient, // 1=non-persistent, 2=persistent
Priority: 0, // 0-9
// a bunch of application/implementation-specific fields
},
); err != nil {
//DEBUG
syslogLog.Err( fmt.Sprintf(" [dequeue] Error: Exchange Publish: [%v]", err) )
} else {
//DEBUG
syslogLog.Err(" [dequeue] Published")
}
// Delete from MongoDB.
// err = mongoCollection.RemoveId(x._Id)
err = mongoCollection.RemoveId(x["_id"])
if nil != err {
//DEBUG
// syslogLog.Err( fmt.Sprintf(" [dequeue] Could NOT remove item from Mongo with _id [%v], received err = [%v]", x._Id, err) )
syslogLog.Err( fmt.Sprintf(" [dequeue] Could NOT remove item from Mongo with _id [%v], received err = [%v]", x["_id"], err) )
} else {
//DEBUG
// syslogLog.Notice( fmt.Sprintf(" [dequeue] Removed item from Mongo with _id [%v]", x._Id) )
syslogLog.Notice( fmt.Sprintf(" [dequeue] Removed item from Mongo with _id [%v]", x["_id"]) )
}
} // for
syslogLog.Notice(" [dequeue] Done iterating through result of query.")
}
// Sleep for a while before checking again.
sleepTime := time.Duration(5 + rand.Intn(7)) * time.Second
//DEBUG
syslogLog.Notice( fmt.Sprintf(" [dequeue] sleep for %v", sleepTime) )
time.Sleep(sleepTime)
} // for
//DEBUG
syslogLog.Notice("[dequeue] END")
}