@ -7,6 +7,7 @@ import (
"log"
"log"
"os"
"os"
"os/signal"
"os/signal"
"strconv"
"strings"
"strings"
"syscall"
"syscall"
"time"
"time"
@ -16,7 +17,6 @@ import (
)
)
var publisher * rabbitmq . Publisher
var publisher * rabbitmq . Publisher
var consumer * rabbitmq . Consumer
var msgCatFilters [ ] string
var msgCatFilters [ ] string
var msgNameFilters [ ] string
var msgNameFilters [ ] string
@ -75,7 +75,7 @@ func handleAmqpMsg(d rabbitmq.Delivery) rabbitmq.Action {
return rabbitmq . Ack
return rabbitmq . Ack
}
}
func kazooPublish ( challenge , event string ) error {
func kazooPublish ( pub * rabbitmq . Publisher , challenge , event string ) error {
msg := KzMessage {
msg := KzMessage {
MsgId : uuid . New ( ) . String ( ) ,
MsgId : uuid . New ( ) . String ( ) ,
AppName : appname ,
AppName : appname ,
@ -92,7 +92,7 @@ func kazooPublish(challenge, event string) error {
return err
return err
}
}
err = publisher . Publish ( msg_json ,
err = pub . Publish ( msg_json ,
[ ] string { appconf . AmqpPubRoutingKey } ,
[ ] string { appconf . AmqpPubRoutingKey } ,
rabbitmq . WithPublishOptionsContentType ( "application/json" ) ,
rabbitmq . WithPublishOptionsContentType ( "application/json" ) ,
rabbitmq . WithPublishOptionsExchange ( appconf . AmqpPubExch ) ,
rabbitmq . WithPublishOptionsExchange ( appconf . AmqpPubExch ) ,
@ -114,11 +114,47 @@ func amqp() {
appconf . AmqpPubExch = appconf . AmqpExch
appconf . AmqpPubExch = appconf . AmqpExch
}
}
//parse config AMQP uri[s]
var amqpURIs [ ] string
amqpURIs = strings . Split ( appconf . AmqpURI , "," )
for n , uri := range amqpURIs {
go amqpConnect ( uri , n )
}
log . Println ( appnameFull + " system started.\n-----> [READY]" )
fmt . Println ( appnameFull + " system started.\n-----> [READY]" )
// block main thread - wait for shutdown signal
sigs := make ( chan os . Signal , 1 )
done := make ( chan bool , 1 )
signal . Notify ( sigs , syscall . SIGINT , syscall . SIGTERM )
go func ( ) {
sig := <- sigs
fmt . Printf ( "Received signal: " )
fmt . Println ( sig )
done <- true
} ( )
for {
select {
case <- done :
fmt . Println ( "Shutting myself down..." )
return
case <- time . After ( 100 * time . Millisecond ) :
//case <-time.After(time.Second):
//fmt.Println("tick")
}
}
}
func amqpConnect ( amqpURI string , connNumber int ) {
/////////////////////////////////////////////
/////////////////////////////////////////////
// RabbitMQ Setup Connection
// RabbitMQ Setup Connection
log . Println ( "Connecting to RabbitMQ: " + appconf . AmqpURI )
log . Println ( "Connecting to RabbitMQ: " + amqpURI )
amqpConn , err := rabbitmq . NewConn (
amqpConn , err := rabbitmq . NewConn (
appconf . AmqpURI ,
amqpURI ,
rabbitmq . WithConnectionOptionsLogging ,
rabbitmq . WithConnectionOptionsLogging ,
)
)
if err != nil {
if err != nil {
@ -140,6 +176,7 @@ func amqp() {
/////////////////////////////////////////////
/////////////////////////////////////////////
// RabbitMQ Setup Publisher
// RabbitMQ Setup Publisher
// NOTE: IF THERE ARE MULTILPLE AMQP CONNECTIONS, THE PUBLISHER WILL ONLY BE ON THE LAST ONE!
publisher , err = rabbitmq . NewPublisher (
publisher , err = rabbitmq . NewPublisher (
amqpConn ,
amqpConn ,
rabbitmq . WithPublisherOptionsLogging ,
rabbitmq . WithPublisherOptionsLogging ,
@ -162,18 +199,20 @@ func amqp() {
logit ( 7 , fmt . Sprintf ( "Message confirmed from RabbitMQ server. tag: %v, ack: %v\n" , c . DeliveryTag , c . Ack ) )
logit ( 7 , fmt . Sprintf ( "Message confirmed from RabbitMQ server. tag: %v, ack: %v\n" , c . DeliveryTag , c . Ack ) )
} )
} )
go publisher_loop ( )
go publisher_loop ( publisher )
queue := "q_w" + strconv . Itoa ( connNumber ) + "_" + appname + "_" + myHostname
/////////////////////////////////////////////
/////////////////////////////////////////////
// RabbitMQ Setup Consumer
// RabbitMQ Setup Consumer
var consumer * rabbitmq . Consumer
consumer , err = rabbitmq . NewConsumer (
consumer , err = rabbitmq . NewConsumer (
amqpConn ,
amqpConn ,
"q_" + appname + "_" + myHostnam e,
queu e,
rabbitmq . WithConsumerOptionsExchangeName ( appconf . AmqpSubExch ) ,
rabbitmq . WithConsumerOptionsExchangeName ( appconf . AmqpSubExch ) ,
rabbitmq . WithConsumerOptionsExchangeKind ( appconf . AmqpExchType ) ,
rabbitmq . WithConsumerOptionsExchangeKind ( appconf . AmqpExchType ) ,
rabbitmq . WithConsumerOptionsRoutingKey ( appconf . AmqpSubRoutingKey ) ,
rabbitmq . WithConsumerOptionsRoutingKey ( appconf . AmqpSubRoutingKey ) ,
rabbitmq . WithConsumerOptionsRoutingKey ( appconf . AmqpDirectRoutingKey ) ,
rabbitmq . WithConsumerOptionsRoutingKey ( appconf . AmqpDirectRoutingKey ) ,
rabbitmq . WithConsumerOptionsConsumerName ( "consumer_" + appname + "_" + myHostname ) ,
rabbitmq . WithConsumerOptionsConsumerName ( "consumer_w" + strconv . Itoa ( connNumber ) + "_ " + appname + "_" + myHostname ) ,
rabbitmq . WithConsumerOptionsQueueAutoDelete ,
rabbitmq . WithConsumerOptionsQueueAutoDelete ,
rabbitmq . WithConsumerOptionsConcurrency ( appconf . AmqpWorkers ) ,
rabbitmq . WithConsumerOptionsConcurrency ( appconf . AmqpWorkers ) ,
rabbitmq . WithConsumerOptionsExchangeDeclare ,
rabbitmq . WithConsumerOptionsExchangeDeclare ,
@ -187,14 +226,11 @@ func amqp() {
}
}
defer consumer . Close ( )
defer consumer . Close ( )
logit ( 6 , "Consuming on '" + appconf . AmqpExchType + "' exchange: '" + appconf . AmqpSubExch + "' with routing key: '" + appconf . AmqpSubRoutingKey + "' using queue: 'q_" + appname + "_" + myHostnam e+ "'." )
logit ( 6 , "Consuming on '" + appconf . AmqpExchType + "' exchange: '" + appconf . AmqpSubExch + "' with routing key: '" + appconf . AmqpSubRoutingKey + "' using queue: " + queu e+ "'." )
//logit(6, "Using "+fmt.Sprintf("%d", appconf.AmqpWorkers)+" concurrent workers to process inbound AMQP messages.")
//logit(6, "Using "+fmt.Sprintf("%d", appconf.AmqpWorkers)+" concurrent workers to process inbound AMQP messages.")
log . Println ( appnameFull + " system started.\n-----> [READY]" )
fmt . Println ( appnameFull + " system started.\n-----> [READY]" )
// block main thread
// block here
err = consumer . Run ( handleAmqpMsg ) //this is the function that we want to call to consume presence messages
err = consumer . Run ( handleAmqpMsg ) //this is the function that we want to call to consume presence messages
if err != nil {
if err != nil {
fmt . Println ( "Unable to start/run RabbitMQ consumer: " + err . Error ( ) )
fmt . Println ( "Unable to start/run RabbitMQ consumer: " + err . Error ( ) )
@ -203,7 +239,7 @@ func amqp() {
}
}
func publisher_loop ( ) {
func publisher_loop ( pub * rabbitmq . Publisher ) {
/////////////////////////////////////////////
/////////////////////////////////////////////
// RabbitMQ Publish Test
// RabbitMQ Publish Test
sigch := make ( chan os . Signal , 1 )
sigch := make ( chan os . Signal , 1 )
@ -218,7 +254,7 @@ func publisher_loop() {
EventName : "request" ,
EventName : "request" ,
ServerId : appname + "@" + myHostname ,
ServerId : appname + "@" + myHostname ,
Server : myHostname ,
Server : myHostname ,
Node : "freeswitch @" + myHostname ,
Node : "firewallagent_" + appconf . ServerType + " @" + myHostname ,
}
}
msg_pubtest , err := json . Marshal ( pubtest )
msg_pubtest , err := json . Marshal ( pubtest )
@ -237,7 +273,7 @@ func publisher_loop() {
msg_pubtest = msgFromFile
msg_pubtest = msgFromFile
}
}
log . Println ( "Publishing test message to exchange '" + appconf . AmqpPubExch + "' with routing key '" + appconf . AmqpPubRoutingKey + "': \n" + string ( msg_pubtest ) )
log . Println ( "Publishing test message to exchange '" + appconf . AmqpPubExch + "' with routing key '" + appconf . AmqpPubRoutingKey + "': \n" + string ( msg_pubtest ) )
err = publisher . Publish ( msg_pubtest ,
err = pub . Publish ( msg_pubtest ,
[ ] string { appconf . AmqpPubRoutingKey } ,
[ ] string { appconf . AmqpPubRoutingKey } ,
rabbitmq . WithPublishOptionsContentType ( "application/json" ) ,
rabbitmq . WithPublishOptionsContentType ( "application/json" ) ,
rabbitmq . WithPublishOptionsExchange ( appconf . AmqpPubExch ) ,
rabbitmq . WithPublishOptionsExchange ( appconf . AmqpPubExch ) ,