示例#1
0
文件: rabbitmq.go 项目: twm1010/todd
// ListenForResponses listens for responses from an agent
func (rmq rabbitMQComms) ListenForResponses(stopListeningForResponses *chan bool) {

	queueName := "agentresponses"

	conn, err := amqp.Dial(rmq.queueUrl)
	if err != nil {
		log.Error(err)
		log.Error("Failed to connect to RabbitMQ")
		os.Exit(1)
	}
	defer conn.Close()

	ch, err := conn.Channel()
	if err != nil {
		log.Error("Failed to open a channel")
		os.Exit(1)
	}
	defer ch.Close()

	_, err = ch.QueueDeclare(
		queueName, // name
		false,     // durable
		false,     // delete when usused
		false,     // exclusive
		false,     // no-wait
		nil,       // arguments
	)
	if err != nil {
		log.Error("Failed to declare a queue")
		os.Exit(1)
	}

	msgs, err := ch.Consume(
		queueName, // queue
		queueName, // consumer
		true,      // auto-ack
		false,     // exclusive
		false,     // no-local
		false,     // no-wait
		nil,       // args
	)
	if err != nil {
		log.Error("Failed to register a consumer")
		os.Exit(1)
	}

	tdb, err := db.NewToddDB(rmq.config) // TODO(vcabbage): Consider moving this into the rabbitMQComms struct
	if err != nil {
		log.Error("Failed to connect to DB")
		os.Exit(1)
	}

	go func() {
		for d := range msgs {

			// Unmarshal into BaseResponse to determine type
			var base_msg responses.BaseResponse
			err = json.Unmarshal(d.Body, &base_msg)
			// TODO(mierdin): Need to handle this error

			log.Debugf("Agent response received: %s", d.Body)

			// call agent response method based on type
			switch base_msg.Type {
			case "AgentStatus":

				var sasr responses.SetAgentStatusResponse
				err = json.Unmarshal(d.Body, &sasr)
				// TODO(mierdin): Need to handle this error

				log.Debugf("Agent %s is '%s' regarding test %s. Writing to DB.", sasr.AgentUuid, sasr.Status, sasr.TestUuid)
				err := tdb.SetAgentTestStatus(sasr.TestUuid, sasr.AgentUuid, sasr.Status)
				if err != nil {
					log.Errorf("Error writing agent status to DB: %v", err)
				}

			case "TestData":

				var utdr responses.UploadTestDataResponse
				err = json.Unmarshal(d.Body, &utdr)
				// TODO(mierdin): Need to handle this error

				err = tdb.SetAgentTestData(utdr.TestUuid, utdr.AgentUuid, utdr.TestData)
				// TODO(mierdin): Need to handle this error

				// Send task to the agent that says to delete the entry
				var dtdt tasks.DeleteTestDataTask
				dtdt.Type = "DeleteTestData" //TODO(mierdin): This is an extra step. Maybe a factory function for the task could help here?
				dtdt.TestUuid = utdr.TestUuid
				rmq.SendTask(utdr.AgentUuid, dtdt)

				// Finally, set the status for this agent in the test to "finished"
				err := tdb.SetAgentTestStatus(dtdt.TestUuid, utdr.AgentUuid, "finished")
				if err != nil {
					log.Errorf("Error writing agent status to DB: %v", err)
				}

			default:
				log.Errorf(fmt.Sprintf("Unexpected type value for received response: %s", base_msg.Type))
			}
		}
	}()

	log.Infof(" [*] Waiting for messages. To exit press CTRL+C")
	<-*stopListeningForResponses
}