Beispiel #1
0
func connect(conn *amqp.Connection, exchange string, wg *sync.WaitGroup) {
	ch, err := conn.Channel()
	utils.FailOnError(err, "Failed to open a channel")
	defer conn.Close()

	err = ch.ExchangeDeclare(
		exchange, // name
		"direct", // type
		true,     // durable
		false,    // auto-deleted
		false,    // internal
		false,    // no-wait
		nil,      // arguments
	)
	utils.FailOnError(err, "Failed to declare an exchange")

	keys := []string{"create", "update"}
	for {
		for _, key := range keys {
			go connectKey(ch, key, exchange)
		}
		log.Printf("Break \n \n")
		time.Sleep(40 * time.Second)
	}
}
func monitoring(uri string, queueName string, mgmtUri string, prefix string) {
	var (
		queueConn *amqp.Connection
		queueChan *amqp.Channel
		err       error
	)
	queueConn, queueChan, err = rabbitmqConnect(uri, queueName)
	if err != nil {
		return
	}
	for {
		log.Printf("fetch rabbitmq stats")
		var metrics []graphite.Metric
		for _, metric := range fetchQueueMetrics(mgmtUri, prefix) {
			metrics = append(metrics, metric)
		}
		for _, metric := range fetchExchangeMetrics(mgmtUri, prefix) {
			metrics = append(metrics, metric)
		}
		for _, metric := range metrics {
			body := []byte(metric.Name + "\t" + metric.Value + "\t" + strconv.FormatInt(metric.Timestamp, 10))
			msg := amqp.Publishing{ContentType: "text/plain", Body: body}
			err = queueChan.Publish("", queueName, false, false, msg)
			if err != nil {
				log.Printf("publish err: %s", err)
				return
			}
			//log.Printf("metric\t%s\t\t%s", metric.Name, metric.Value)
		}
		time.Sleep(time.Second * 5)
	}
	queueChan.Close()
	queueConn.Close()
}
Beispiel #3
0
// redial continually connects to the URL, exiting the program when no longer possible
func redial(ctx context.Context, url, exchange string) chan chan session {
	sessions := make(chan chan session)

	go func() {
		sess := make(chan session)
		defer close(sessions)

		for {
			select {
			case sessions <- sess:
			case <-ctx.Done():
				log.Info("shutting down session factory")
				return
			}

			connected := false
			var conn *amqp.Connection
			var ch *amqp.Channel
			var err error
			for !connected {
				log.Debug("dialing amqp url: %s", url)
				conn, err = amqp.Dial(url)
				if err != nil {
					log.Error(3, "cannot (re)dial: %v: %q", err, url)
					time.Sleep(time.Second)
					continue
				}
				log.Debug("connected to %s", url)

				log.Debug("creating new channel on AMQP connection.")
				ch, err = conn.Channel()
				if err != nil {
					log.Error(3, "cannot create channel: %v", err)
					conn.Close()
					time.Sleep(time.Second)
					continue
				}
				log.Debug("Ensuring that %s topic exchange exists on AMQP server.", exchange)
				if err := ch.ExchangeDeclare(exchange, "topic", true, false, false, false, nil); err != nil {
					log.Error(3, "cannot declare topic exchange: %v", err)
					conn.Close()
					time.Sleep(time.Second)
				}
				log.Debug("Successfully connected to RabbitMQ.")
				connected = true
			}

			select {
			case sess <- session{conn, ch}:
			case <-ctx.Done():
				log.Info("shutting down new session")
				return
			}
		}
	}()

	return sessions
}
Beispiel #4
0
// shutdown is a general closer function for handling close gracefully
// Mostly here for both consumers and producers
// After a reconnection scenerio we are gonna call shutdown before connection
func shutdown(conn *amqp.Connection) error {
	if err := conn.Close(); err != nil {
		if amqpError, isAmqpError := err.(*amqp.Error); isAmqpError && amqpError.Code != 504 {
			return fmt.Errorf("AMQP connection close error: %s", err)
		}
	}

	return nil
}
Beispiel #5
0
// Closes the connection
func (amqpBackend *AMQPBackend) close(channel *amqp.Channel, conn *amqp.Connection) error {
	if err := channel.Close(); err != nil {
		return fmt.Errorf("Channel Close: %s", err)
	}

	if err := conn.Close(); err != nil {
		return fmt.Errorf("Connection Close: %s", err)
	}

	return nil
}
Beispiel #6
0
func Publish(messages chan *amqp.Publishing, connectionUri, exchange,
	routingKey string, mandatory, immediate bool, results chan *PublishResult) {

	var err error
	var conn *amqp.Connection
	var channel *amqp.Channel

	defer close(results)

	if conn, err = amqp.Dial(connectionUri); err != nil {
		results <- &PublishResult{"Failed to connect", err, true}
		return
	}

	defer conn.Close()

	if channel, err = conn.Channel(); err != nil {
		results <- &PublishResult{"Failed to get channel", err, true}
		return
	}

	pubAcks, pubNacks := channel.NotifyConfirm(make(chan uint64), make(chan uint64))
	chanClose := channel.NotifyClose(make(chan *amqp.Error))
	if err = channel.Confirm(false); err != nil {
		results <- &PublishResult{
			"Failed to put channel into confirm mode",
			err,
			true,
		}
		return
	}

	for message := range messages {
		err = channel.Publish(exchange, routingKey, mandatory, immediate, *message)
		if err != nil {
			results <- &PublishResult{"Failed to publish message", err, false}
			continue
		}

		select {
		case err = <-chanClose:
			results <- &PublishResult{"Channel closed!", err, true}
		case <-pubAcks:
			results <- &PublishResult{
				fmt.Sprintf("Published to exchange '%s' routing key '%v': %+v", exchange, routingKey, message),
				nil,
				false,
			}
		case <-pubNacks:
			results <- &PublishResult{"Received basic.nack for message", errors.New("'basic.nack'"), false}
		}
	}
}
Beispiel #7
0
// Closes the connection
func (amqpBroker *AMQPBroker) close(channel *amqp.Channel, conn *amqp.Connection) error {
	if channel != nil {
		if err := channel.Close(); err != nil {
			return fmt.Errorf("Channel Close: %s", err)
		}
	}

	if conn != nil {
		if err := conn.Close(); err != nil {
			return fmt.Errorf("Connection Close: %s", err)
		}
	}

	return nil
}
Beispiel #8
0
// Function to restart everything
func restart(reset chan *amqp.Error, config Configuration, conn *amqp.Connection, ch_gcm_log, ch_db_log, ch_apn_log, ch_gcm_log_success, ch_apn_log_success chan []byte, logger *log.Logger,
	killWorker, killStatusInactive, killTokenUpd, killStatusInactiveAck, killTokenUpdAck, killApnStatusInactive, killApnStatusInactiveAck chan int) {
	// Kill all Worker
	killAllWorkers(config, killWorker, killStatusInactive, killTokenUpd, killStatusInactiveAck, killTokenUpdAck, killApnStatusInactive, killApnStatusInactiveAck)

	conn.Close()
	conn = initConn(config)
	defer conn.Close()

	olog(fmt.Sprintf("Spinning up workers"), config.DebugMode)
	// For all GcmQueues start new goroutines
	for i := 0; i < len(config.GcmQueues); i++ {
		for j := 0; j < config.GcmQueues[i].Numworkers; j++ {
			go gcm_processor(j, config, conn, config.GcmQueues[i].GcmTokenUpdateQueue, config.GcmQueues[i].GcmStatusInactiveQueue,
				config.GcmQueues[i].Name, ch_gcm_log, ch_gcm_log_success, logger, killWorker, config.GcmQueues[i])
		}
		go gcm_error_processor_status_inactive(config, conn, config.GcmQueues[i].GcmStatusInactiveQueue, ch_db_log, logger, killStatusInactive, killStatusInactiveAck, config.GcmQueues[i])
		go gcm_error_processor_token_update(config, conn, config.GcmQueues[i].GcmTokenUpdateQueue, ch_db_log, logger, killTokenUpd, killTokenUpdAck, config.GcmQueues[i])
	}
	//For all APN Queues start workers
	for i := 0; i < len(config.ApnQueues); i++ {
		// For all GCM Queues start workers
		for j := 0; j < config.ApnQueues[i].NumWorkers; j++ {
			go apn_processor(j, config, conn, config.ApnQueues[i].ApnStatusInactiveQueue,
				config.ApnQueues[i].Name, ch_apn_log, ch_apn_log_success, logger, killWorker, config.ApnQueues[i])
		}

		olog(fmt.Sprintf("Startting workers for status_inactive for APN %s", config.GcmQueues[i].Identifier), config.DebugMode)
		go apn_error_processor_status_inactive(config, conn, config.ApnQueues[i].ApnStatusInactiveQueue, ch_db_log, logger, killApnStatusInactive, killApnStatusInactiveAck, config.ApnQueues[i])
	}

	olog("Starting error processors", config.DebugMode)

	reset = conn.NotifyClose(make(chan *amqp.Error))
	for range reset {
		go restart(reset, config, conn, ch_gcm_log, ch_db_log, ch_apn_log, ch_gcm_log_success, ch_apn_log_success, logger, killWorker, killStatusInactive, killTokenUpd, killStatusInactiveAck, killTokenUpdAck, killApnStatusInactive, killApnStatusInactiveAck)
	}
}
Beispiel #9
0
// connects to an AMQP topic and emits each message into streamtools.
func (b *FromAMQP) Run() {
	var err error
	var conn *amqp.Connection
	var amqp_chan *amqp.Channel
	toOut := make(blocks.MsgChan)
	toError := make(chan error)

	host := "localhost"
	port := "5672"
	username := "******"
	password := "******"
	routingkey := "#"
	exchange := "amq.topic"
	exchange_type := "topic"

	for {
		select {
		case msg := <-toOut:
			b.out <- msg
		case err := <-toError:
			b.Error(err)
		case ruleI := <-b.inrule:
			rule := ruleI.(map[string]interface{})

			routingkey, err = util.ParseString(rule, "RoutingKey")
			if err != nil {
				b.Error(err)
				continue
			}
			exchange, err = util.ParseString(rule, "Exchange")
			if err != nil {
				b.Error(err)
				continue
			}
			exchange_type, err = util.ParseString(rule, "ExchangeType")
			if err != nil {
				b.Error(err)
				continue
			}
			host, err = util.ParseString(rule, "Host")
			if err != nil {
				b.Error(err)
				continue
			}
			port, err = util.ParseString(rule, "Port")
			if err != nil {
				b.Error(err)
				continue
			}
			username, err = util.ParseString(rule, "Username")
			if err != nil {
				b.Error(err)
				continue
			}
			password, err = util.ParseString(rule, "Password")
			if err != nil {
				b.Error(err)
				continue
			}

			conn, err = amqp.Dial("amqp://" + username + ":" + password + "@" + host + ":" + port + "/")
			if err != nil {
				b.Error(err)
				continue
			}

			amqp_chan, err = conn.Channel()
			if err != nil {
				b.Error(err)
				continue
			}

			err = amqp_chan.ExchangeDeclare(
				exchange,      // name
				exchange_type, // type
				true,          // durable
				false,         // auto-deleted
				false,         // internal
				false,         // noWait
				nil,           // arguments
			)
			if err != nil {
				b.Error(err)
				continue
			}

			queue, err := amqp_chan.QueueDeclare(
				"",    // name
				false, // durable
				true,  // delete when unused
				false, // exclusive
				false, // noWait
				nil,   // arguments
			)
			if err != nil {
				b.Error(err)
				continue
			}

			err = amqp_chan.QueueBind(
				queue.Name, // queue name
				routingkey, // routing key
				exchange,   // exchange
				false,
				nil,
			)

			if err != nil {
				b.Error(err)
				continue
			}

			deliveries, err := amqp_chan.Consume(
				queue.Name, // name
				"",         // consumerTag
				true,       // noAck
				false,      // exclusive
				false,      // noLocal
				false,      // noWait
				nil,        // arguments
			)
			if err != nil {
				b.Error(err)
				continue
			}

			h := readWriteAMQPHandler{toOut, toError}
			go h.handle(deliveries)
		case <-b.quit:
			if amqp_chan != nil {
				amqp_chan.Close()
			}
			if conn != nil {
				conn.Close()
			}
			return
		case c := <-b.queryrule:
			c <- map[string]interface{}{
				"Host":         host,
				"Port":         port,
				"Username":     username,
				"Password":     password,
				"Exchange":     exchange,
				"ExchangeType": exchange_type,
				"RoutingKey":   routingkey,
			}
		}
	}
}
Beispiel #10
0
func newRPCQueue(uri string) (*rpcQueue, error) {
	fmt.Println("newRPCQueue")
	var conn *amqp.Connection
	var err error

	for try := 0; try < 10; try++ {
		log.Infof("Attempt to connect to RabbitMQ: %d", try+1)
		conn, err = amqp.Dial(uri)
		if err == nil {
			break
		}
		time.Sleep(time.Second * 5)
	}
	if err != nil {
		return nil, err
	}

	amqpChannel, err := conn.Channel()
	if err != nil {
		conn.Close()
		return nil, err
	}

	queue, err := amqpChannel.QueueDeclare(
		"",    // name
		false, // durable
		false, // delete when usused
		true,  // exclusive
		false, // noWait
		nil,   // arguments
	)
	if err != nil {
		amqpChannel.Close()
		conn.Close()
		return nil, err
	}

	name := queue.Name

	msgs, err := amqpChannel.Consume(
		name,  // queue
		"",    // consumer
		true,  // auto-ack
		false, // exclusive
		false, // no-local
		false, // no-wait
		nil,   // args
	)
	if err != nil {
		amqpChannel.Close()
		conn.Close()
		return nil, err
	}

	q := rpcQueue{
		name:          name,
		channels:      cmap.New(),
		amqpChannel:   amqpChannel,
		correlationId: 0,
	}

	go func() {
		for d := range msgs {
			corrId := d.CorrelationId
			context, exists := q.channels.Get(corrId)
			if exists {
				q.channels.Remove(corrId)
				context.(chan *amqp.Delivery) <- &d
			} else {
				log.Errorf("Cannot handle RPC request (correlation id = %s)", corrId)
			}
		}
	}()

	return &q, nil
}
Beispiel #11
0
func main() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, usageString, filepath.Base(os.Args[0]))
		flag.PrintDefaults()
	}
	flag.Parse()

	if *versionFlag {
		progName := path.Base(os.Args[0])
		if VersionString == "" {
			VersionString = "<unknown>"
		}
		fmt.Printf("%s %s\n", progName, VersionString)
		os.Exit(0)
	}

	if *revFlag {
		if RevString == "" {
			RevString = "<unknown>"
		}
		fmt.Println(RevString)
		os.Exit(0)
	}

	files := flag.Args()

	if len(files) == 0 {
		flag.Usage()
		os.Exit(5)
	}

	var conn *amqp.Connection
	var channel *amqp.Channel
	var err error

	conn, err = amqp.Dial(*uriFlag)
	debugger.Print(fmt.Sprintf("uri: %s\n", *uriFlag))
	if debugger.WithError(err, "Failed to connect ", err) {
		os.Exit(2)
	}
	debugger.Print("connection made")

	defer conn.Close()

	channel, err = conn.Channel()
	if debugger.WithError(err, "Failed to open channel ", err) {
		os.Exit(3)
	}
	debugger.Print("channel.established")

	var bytes []byte

	if len(files) == 1 && files[0] == "-" {
		stdin := bufio.NewReader(os.Stdin)
		for {
			myBytes, err := stdin.ReadString('\n')
			bytes = []byte(myBytes)
			if err != nil {
				if err != io.EOF {
					debugger.Print("ERROR:", err)
				}
				break
			}
			HandleMessageBytes(bytes, channel, debugger)
		}

	} else {
		for _, file := range files {
			bytes, err = ioutil.ReadFile(file)
			if debugger.WithError(err, fmt.Sprintf("Unable to read file %s: ", file), err) {
				os.Exit(13)
			}
			HandleMessageBytes(bytes, channel, debugger)
		}
	}
}
Beispiel #12
0
// connects to an AMQP topic and emits each message into streamtools.
func (b *ToAMQP) Run() {
	var err error
	var conn *amqp.Connection
	var amqp_chan *amqp.Channel

	host := "localhost"
	port := "5672"
	username := "******"
	password := "******"
	routingkey := "streamtools"
	exchange := "amq.topic"
	exchange_type := "topic"

	for {
		select {
		case ruleI := <-b.inrule:

			routingkey, err = util.ParseString(ruleI, "RoutingKey")
			if err != nil {
				b.Error(err)
				continue
			}
			exchange, err = util.ParseString(ruleI, "Exchange")
			if err != nil {
				b.Error(err)
				continue
			}
			exchange_type, err = util.ParseString(ruleI, "ExchangeType")
			if err != nil {
				b.Error(err)
				continue
			}
			host, err = util.ParseString(ruleI, "Host")
			if err != nil {
				b.Error(err)
				continue
			}
			port, err = util.ParseString(ruleI, "Port")
			if err != nil {
				b.Error(err)
				continue
			}
			username, err = util.ParseString(ruleI, "Username")
			if err != nil {
				b.Error(err)
				continue
			}
			password, err = util.ParseString(ruleI, "Password")
			if err != nil {
				b.Error(err)
				continue
			}

			conn, err = amqp.Dial("amqp://" + username + ":" + password + "@" + host + ":" + port + "/")
			if err != nil {
				b.Error(err)
				continue
			}

			amqp_chan, err = conn.Channel()
			if err != nil {
				b.Error(err)
				continue
			}

			err = amqp_chan.ExchangeDeclare(
				exchange,      // name
				exchange_type, // type
				true,          // durable
				false,         // auto-deleted
				false,         // internal
				false,         // noWait
				nil,           // arguments
			)
			if err != nil {
				b.Error(err)
				continue
			}

		case msg := <-b.in:
			if conn == nil || amqp_chan == nil {
				continue
			}

			msgBytes, err := json.Marshal(msg)

			// Make the output JSON if msg wasn't JSON already
			if err != nil {
				json_msg := map[string]interface{}{
					"data": msg,
				}
				msgBytes, err = json.Marshal(json_msg)

				if err != nil {
					b.Error(err)
					continue
				}
			}

			if len(msgBytes) == 0 {
				b.Error("Zero byte length message")
				continue
			}

			err = amqp_chan.Publish(
				exchange,
				routingkey,
				false,
				false,
				amqp.Publishing{
					Headers:         amqp.Table{},
					ContentType:     "text/plain",
					ContentEncoding: "",
					Body:            msgBytes,
					DeliveryMode:    amqp.Transient,
					Priority:        0,
				},
			)
			if err != nil {
				b.Error(err)
				continue
			}
		case <-b.quit:
			if amqp_chan != nil {
				amqp_chan.Close()
			}
			if conn != nil {
				conn.Close()
			}
			return
		case c := <-b.queryrule:
			c <- map[string]interface{}{
				"Host":         host,
				"Port":         port,
				"Username":     username,
				"Password":     password,
				"Exchange":     exchange,
				"ExchangeType": exchange_type,
				"RoutingKey":   routingkey,
			}
		}
	}
}
Beispiel #13
0
Datei: mq.go Projekt: Cepave/fe
func Start() {
	mq := g.Config().Mq
	nodes := map[string]interface{}{}

	// Retry RetriedLimit times if there is some problem during connecting
	var ch *amqp.Channel
	var conn *amqp.Connection
	var err error
	for i := 0; i < RetriedLimit; i++ {
		if conn, ch, err = setup(mq.Queue); err != nil {
			time.Sleep(time.Second * SleepTimePeriod)
		}
	}
	if err != nil {
		log.Println(ExitStringPrefix + "retried too many times.")
		return
	}
	defer conn.Close()
	defer ch.Close()

	q, err := ch.QueueDeclare(
		"mute", // name
		false,  // durable
		false,  // delete when usused
		false,  // exclusive
		false,  // no-wait
		nil,    // arguments
	)
	if err != nil {
		log.Printf(LogStringFormat, ExitStringPrefix+"failed to declare a queue", err)
		return
	}

	msgs, err := ch.Consume(
		q.Name, // queue
		"",     // consumer
		true,   // auto-ack
		false,  // exclusive
		false,  // no-local
		false,  // no-wait
		nil,    // args
	)
	if err != nil {
		log.Printf(LogStringFormat, ExitStringPrefix+"failed to register a consumer", err)
		return
	}

	forever := make(chan bool)

	var pkt Message
	go func() {
		for d := range msgs {
			json.Unmarshal(d.Body, &pkt)
			log.Printf("Received a message: %v", pkt)
			params := map[string]string{
				"host": pkt.Hostname,
				"mute": "",
			}
			if pkt.Mute {
				params["mute"] = "1"
			} else {
				params["mute"] = "0"
			}
			payload := map[string]interface{}{
				"method": "host.update",
				"params": params,
			}
			log.Println("payload =", payload)

			s, err := json.Marshal(payload)
			if err != nil {
				log.Println("json.Marshal Error:", err.Error())
			}

			url := mq.Consumer
			log.Println("url =", url)
			reqPost, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte(s)))
			if err != nil {
				log.Println("reqPost Error:", err.Error())
			}
			reqPost.Header.Set("Content-Type", "application/json")

			client := &http.Client{}
			resp, err := client.Do(reqPost)
			if err != nil {
				log.Println("resp Error:", err.Error())
			} else {
				defer resp.Body.Close()
				body, _ := ioutil.ReadAll(resp.Body)
				err = json.Unmarshal(body, &nodes)
				if err != nil {
					log.Println("Unmarshal Error:", err.Error())
				}
				log.Println("nodes =", nodes)
			}
		}
	}()
	log.Println("mq.Start ok. Waiting for messages.")
	<-forever
}