func TestNewRemoteControl(t *testing.T) {
	Convey("Given a non-nil AMQP connection", t, func() {
		uri := os.Getenv("AMQP_URI")
		if len(uri) == 0 {
			uri = os.Getenv("PBOX_URI")
		}
		var amqpConn *amqp.Connection
		var err error
		Convey("The connection should be returned and err is nil", func() {
			amqpConn, err = amqp.Dial(uri)
			So(err, ShouldBeNil)
			So(amqpConn, ShouldNotBeNil)
			Convey("Given an exchange and routing key", func() {
				exchange := "amq.topic"
				rmtKey := []string{"testing.proc_box"}
				Convey("When agents.NewRemoteControl is invoked", func() {
					rc, err := NewRemoteControl(amqpConn, rmtKey, exchange)
					Convey("The handle should not be nil and the err is nil", func() {
						So(rc, ShouldNotBeNil)
						So(err, ShouldBeNil)
					})
				})
				rmtKey = []string{"key1", "key2"}
				Convey("Given multiple remote keys", func() {
					rc, err := NewRemoteControl(amqpConn, rmtKey, exchange)
					Convey("The handle should not be nil and the err is nil", func() {
						So(rc, ShouldNotBeNil)
						So(err, ShouldBeNil)
					})
				})
			})
			Convey("Given a non-existent exchange", func() {
				exchange := "this.doesnt.exist"
				rmtKey := []string{"testing"}
				Convey("When agents.NewRemoteControl is invoked", func() {
					rc, err := NewRemoteControl(amqpConn, rmtKey, exchange)
					Convey("The handle should be nil and the error is not nil", func() {
						So(rc, ShouldBeNil)
						So(err, ShouldNotBeNil)
					})
				})
			})
		})
	})
	Convey("When agents.NewRemoteControl is invoked with a nil AMQP connection", t, func() {
		rmtKey := []string{"testing"}
		rc, err := NewRemoteControl(nil, rmtKey, "amq.topic")
		Convey("The handle should be nil and the err is not nil", func() {
			So(rc, ShouldBeNil)
			So(err, ShouldNotBeNil)
		})
	})
}
// TestIntegrationDialAMQP tests a connection to an AMQP broker and quits
func TestDialAMQP(t *testing.T) {
	var amqpConn *amqp.Connection
	var err error
	Convey("Given an AMQP URI", t, func() {
		uri := os.Getenv("AMQP_URI")
		if len(uri) == 0 {
			uri = os.Getenv("PBOX_URI")
		}
		Convey("The connection should be returned and err is nil", func() {
			amqpConn, err = amqp.Dial(uri)
			So(err, ShouldBeNil)
		})
	})
}
Example #3
0
func publish(amqpURI, exchange, exchangeType, routingKey, body string, reliable bool) error {

	// This function dials, connects, declares, publishes, and tears down,
	// all in one go. In a real service, you probably want to maintain a
	// long-lived connection as state, and publish against that.

	log.Printf("dialing %q", amqpURI)
	connection, err := amqp.Dial(amqpURI)
	if err != nil {
		return fmt.Errorf("Dial: %s", err)
	}
	defer connection.Close()

	log.Printf("got Connection, getting Channel")
	channel, err := connection.Channel()
	if err != nil {
		return fmt.Errorf("Channel: %s", err)
	}

	log.Printf("got Channel, declaring %q Exchange (%q)", exchangeType, exchange)
	if err := channel.ExchangeDeclare(
		exchange,     // name
		exchangeType, // type
		true,         // durable
		false,        // auto-deleted
		false,        // internal
		false,        // noWait
		nil,          // arguments
	); err != nil {
		return fmt.Errorf("Exchange Declare: %s", err)
	}

	// Reliable publisher confirms require confirm.select support from the
	// connection.
	if reliable {
		log.Printf("enabling publishing confirms.")
		if err := channel.Confirm(false); err != nil {
			return fmt.Errorf("Channel could not be put into confirm mode: %s", err)
		}

		ack, nack := channel.NotifyConfirm(make(chan uint64, 1), make(chan uint64, 1))

		defer confirmOne(ack, nack)
	}

	log.Printf("declared Exchange, publishing %dB body (%q)", len(body), body)
	if err = channel.Publish(
		exchange,   // 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:            []byte(body),
			DeliveryMode:    amqp.Transient, // 1=non-persistent, 2=persistent
			Priority:        0,              // 0-9
			// a bunch of application/implementation-specific fields
		},
	); err != nil {
		return fmt.Errorf("Exchange Publish: %s", err)
	}

	return nil
}
Example #4
0
func NewConsumer(amqpURI, exchange, exchangeType, queueName, key, ctag string) (*Consumer, error) {
	c := &Consumer{
		conn:    nil,
		channel: nil,
		tag:     ctag,
		done:    make(chan error),
	}

	var err error

	log.Printf("dialing %q", amqpURI)
	c.conn, err = amqp.Dial(amqpURI)
	if err != nil {
		return nil, fmt.Errorf("Dial: %s", err)
	}

	go func() {
		fmt.Printf("closing: %s", <-c.conn.NotifyClose(make(chan *amqp.Error)))
	}()

	log.Printf("got Connection, getting Channel")
	c.channel, err = c.conn.Channel()
	if err != nil {
		return nil, fmt.Errorf("Channel: %s", err)
	}

	log.Printf("got Channel, declaring Exchange (%q)", exchange)
	if err = c.channel.ExchangeDeclare(
		exchange,     // name of the exchange
		exchangeType, // type
		true,         // durable
		false,        // delete when complete
		false,        // internal
		false,        // noWait
		nil,          // arguments
	); err != nil {
		return nil, fmt.Errorf("Exchange Declare: %s", err)
	}

	log.Printf("declared Exchange, declaring Queue %q", queueName)
	queue, err := c.channel.QueueDeclare(
		queueName, // name of the queue
		true,      // durable
		false,     // delete when usused
		false,     // exclusive
		false,     // noWait
		nil,       // arguments
	)
	if err != nil {
		return nil, fmt.Errorf("Queue Declare: %s", err)
	}

	log.Printf("declared Queue (%q %d messages, %d consumers), binding to Exchange (key %q)",
		queue.Name, queue.Messages, queue.Consumers, key)

	if err = c.channel.QueueBind(
		queue.Name, // name of the queue
		key,        // bindingKey
		exchange,   // sourceExchange
		false,      // noWait
		nil,        // arguments
	); err != nil {
		return nil, fmt.Errorf("Queue Bind: %s", err)
	}

	log.Printf("Queue bound to Exchange, starting Consume (consumer tag %q)", c.tag)
	deliveries, err := c.channel.Consume(
		queue.Name, // name
		c.tag,      // consumerTag,
		false,      // noAck
		false,      // exclusive
		false,      // noLocal
		false,      // noWait
		nil,        // arguments
	)
	if err != nil {
		return nil, fmt.Errorf("Queue Consume: %s", err)
	}

	go handle(deliveries, c.done)

	return c, nil
}