Example #1
0
 def close(self, reason):
     """The AMQClient protocol calls this as a result of a
     connectionLost event. The TwistedDelegate.close method finishes
     shutting off the client, and we get a chance to react to the event
     here.
     """
     TwistedDelegate.close(self, reason)
     log.err("AMQP Client Connection Closed")
     log.err(reason)
Example #2
0
 def do_auth():
     """Connect and authenticate."""
     delegate = TwistedDelegate()
     spec = load_spec(resource_stream('conn_check', 'amqp0-8.xml'))
     creator = ClientCreator(reactor, AMQClient, delegate, vhost, spec)
     client = yield creator.connectTCP(host, port, timeout=timeout)
     yield client.authenticate(username, password)
Example #3
0
 def __init__(self, spec, vumi_options=None, broker=None):
     WorkerAMQClient.__init__(self, TwistedDelegate(), '', spec)
     if vumi_options is not None:
         self.vumi_options = vumi_options
     if broker is None:
         broker = FakeAMQPBroker()
     self.broker = broker
Example #4
0
    def __init__(self, plugin):

        self.plugin = plugin
        self.service = self.plugin.service
        self.service.amqp_factory = self
        app_cfg = self.service.cfg.get("app")
        general_cfg = app_cfg.get("general", dict())
        amqp_cfg = app_cfg.get("amqp", dict())
        spec_file = amqp_cfg.get(
            "spec_file", "%s/rabbitmq.xml" % (os.path.dirname(__file__)))
        self.spec = txamqp.spec.load(spec_file)
        self.user = amqp_cfg.get("user", "guest")
        self.password = amqp_cfg.get("password", "guest")
        self.vhost = amqp_cfg.get("vhost", "/")
        self.host = amqp_cfg.get("host", "localhost")
        self.port = amqp_cfg.get("port", 5672)
        self.exchange = general_cfg.get("app_id")
        self.delegate = TwistedDelegate()
        self.deferred = Deferred()
        self.initial_deferred_fired = False
        self.logger = logging.getLogger("factory")

        self.p = None  # The protocol instance.
        self.client = None  # Alias for protocol instance

        self.queued_messages = []  # List of messages waiting to be sent.
        self.read_list = []  # List of queues to listen on.
Example #5
0
File: amqp.py Project: allo-/otfbot
    def __init__(self,
                 root,
                 parent,
                 spec_file=None,
                 vhost=None,
                 user=None,
                 password=None):
        spec_file = spec_file or 'amqp0-8.xml'
        self.spec = txamqp.spec.load(spec_file)
        self.user = user or 'guest'
        self.password = password or 'guest'
        self.vhost = vhost or '/'
        self.delegate = TwistedDelegate()
        self.deferred = Deferred()
        self.initial_deferred_fired = False

        self.p = None  # The protocol instance.
        self.client = None  # Alias for protocol instance

        self.queued_messages = []  # List of messages waiting to be sent.
        self.read_list = []  # List of queues to listen on.

        self.root = root
        self.parent = parent

        self.config = root.getServiceNamed('config')
        self.logger = logging.getLogger("amqp")
Example #6
0
    def startService(self):
        from twisted.internet import reactor
        
        creator = ClientCreator(reactor, AMQClient, delegate = TwistedDelegate(), 
                                vhost = self.amqp_vhost, spec = txamqp.spec.load(self.amqp_spec_path))
        supported_proto = {
                 "TCP": creator.connectTCP,
                 "SSL": creator.connectSSL,
                }
        if not (self.amqp_connect_proto in supported_proto):
            raise Exception("Unsupported amqp_connect_proto {}".format(self.amqp_connect_proto))

        #TODO: make loop to try reconnect on failure
        self._correlation_dict_init()
        # connect
        self.connection = yield supported_proto[self.amqp_connect_proto](**self.amqp_connect_kargs)
        # authenticate
        yield self.connection.start(self.amqp_start_args)
        # open channel
        self.channel = yield self.connection.channel(1)
        yield self.channel.channel_open()
        # declare exclusive queue
        self.r_queue = yield self.channel.queue_declare(exclusive=True, auto_delete=True)
        # setup queue to consume
        yield self.channel.basic_consume(queue=self.r_queue.queue, no_ack=True, consumer_tag='cmds')
        self.queue = yield self.connection.queue('cmds')
        
        # start consume
        self._update_queue_defer()
        returnValue(None)
Example #7
0
    def __init__(self,
                 spec_file=None,
                 vhost=None,
                 host=None,
                 port=None,
                 user=None,
                 password=None):
        spec_file = spec_file or 'amqp0-8.xml'
        self.spec = txamqp.spec.load(spec_file)
        self.user = user or 'guest'
        self.password = password or 'guest'
        self.vhost = vhost or '/'
        self.host = host or 'localhost'
        self.port = port or 5672
        self.delegate = TwistedDelegate()
        self.deferred = Deferred()
        self.initial_deferred_fired = False

        self.p = None  # The protocol instance.
        self.client = None  # Alias for protocol instance

        self.queued_messages = []  # List of messages waiting to be sent.
        self.read_list = []  # List of queues to listen on.

        # Make the TCP connection.
        reactor.connectTCP(self.host, self.port, self)
Example #8
0
def createAMQPListener(username,
                       password,
                       vhost,
                       exchange_name,
                       spec=None,
                       channel=1,
                       verbose=False):
    """
    Create an C{AMQPReconnectingFactory} configured with the specified options.
    """
    # use provided spec if not specified
    if not spec:
        spec = txamqp.spec.load(
            os.path.normpath(
                os.path.join(os.path.dirname(__file__), 'amqp0-8.xml')))

    delegate = TwistedDelegate()
    factory = AMQPReconnectingFactory(username,
                                      password,
                                      delegate,
                                      vhost,
                                      spec,
                                      channel,
                                      exchange_name,
                                      verbose=verbose)
    return factory
Example #9
0
    def __init__(self, config):
        self.reconnectTimer = None
        self.connectionRetry = True
        self.connected = False
        self.config = config
        self.channelReady = None

        self.delegate = TwistedDelegate()

        self.amqp = None  # The protocol instance.
        self.client = None  # Alias for protocol instance

        self.queues = []

        # Set up a dedicated logger
        self.log = logging.getLogger(LOG_CATEGORY)
        if len(self.log.handlers) != 1:
            self.log.setLevel(config.log_level)
            handler = TimedRotatingFileHandler(filename=self.config.log_file,
                                               when=self.config.log_rotate)
            formatter = logging.Formatter(config.log_format,
                                          config.log_date_format)
            handler.setFormatter(formatter)
            self.log.addHandler(handler)
            self.log.propagate = False
Example #10
0
 def setUp(self):
     super(AMQPumpTest, self).setUp()
     delegate = TwistedDelegate()
     spec = load(DEFAULT_SPEC)
     self.client = AMQClient(delegate, "/", spec, clock=Clock())
     self.transport = AMQPump()
     self.transport.connect(self.client)
Example #11
0
 def connect_to_exchange(self):
     """
     Connect to an AMQP exchange as a publisher.
     """
     exchange = self.pub_exchange
     vhost = self.pub_vhost
     user = self.pub_user
     passwd = self.pub_passwd
     endpoint_s = self.pub_endpoint_s
     spec = self.pub_spec
     e = clientFromString(self.reactor, endpoint_s)
     delegate = TwistedDelegate()
     amqp_protocol = AMQClient(
         delegate=delegate,
         vhost=vhost,
         spec=spec)
     try:
         conn = yield connectProtocol(e, amqp_protocol)
     except Exception:
         self.log.failure(
             "Failed to establish AMQP connection to endpoint '{0}'".format(
                 endpoint_s))
         raise
     yield conn.authenticate(user, passwd)
     self.pub_channel = yield conn.channel(1)
     yield self.pub_channel.channel_open()
Example #12
0
 def __init__(self, worker):
     self.options = worker.options
     self.config = worker.config
     self.spec = get_spec(vumi_resource_path(worker.options['specfile']))
     self.delegate = TwistedDelegate()
     self.worker = worker
     self.amqp_client = None
Example #13
0
def startReceiver(host,
                  port,
                  username,
                  password,
                  vhost,
                  exchange_name,
                  spec=None,
                  channel=1,
                  verbose=False):
    """Starts a twisted process that will read messages on the amqp broker
    and post them as metrics."""

    # use provided spec if not specified
    if not spec:
        spec = txamqp.spec.load(
            os.path.normpath(
                os.path.join(os.path.dirname(__file__), 'amqp0-8.xml')))

    delegate = TwistedDelegate()
    factory = AMQPReconnectingFactory(username,
                                      password,
                                      delegate,
                                      vhost,
                                      spec,
                                      channel,
                                      exchange_name,
                                      verbose=verbose)
    reactor.connectTCP(host, port, factory)
Example #14
0
 def buildProtocol(self, addr):
     self.resetDelay()
     delegate = TwistedDelegate()
     self.client = AMQClient(delegate=delegate,
                             vhost=self.VHOST,
                             spec=self.spec)
     self.client.start(self.creds)
     return self.client
Example #15
0
 def setUp(self):
     super(AMQClientTest, self).setUp()
     self.delegate = TwistedDelegate()
     self.clock = Clock()
     self.heartbeat = 1
     self.protocol = AMQClient(
         self.delegate, "/", load(DEFAULT_SPEC), clock=self.clock,
         heartbeat=self.heartbeat)
     self.transport = AMQPump(Logger())
     self.transport.connect(self.protocol)
Example #16
0
 def __init__(self, spec_path=None, vhost='/', username='******', \
     password='******', host='localhost', port=5672, delegate=None):
     self.username = username
     self.password = password
     self.delegate = delegate or TwistedDelegate()
     self.vhost = vhost
     self.spec = txamqp.spec.load(spec_path)
     self.is_connected = False
     self.host = host
     self.port = port
Example #17
0
 def __init__(self, user, password, vhost, connected_callback,
              disconnected_callback, failed_callback, spec=None):
     self.user = user
     self.password = password
     self.vhost = vhost
     self.delegate = TwistedDelegate()
     if spec is None:
         spec = AMQP0_8_SPEC
     self.spec = spec
     self.connected_callback = connected_callback
     self.disconnected_callback = disconnected_callback
     self.failed_callback = failed_callback
Example #18
0
    def __init__(self, host, port, login, password, vhost, spec):
        self.host = host
        self.port = port
        self.login = login
        self.password = password
        self.vhost = vhost
        self.spec = spec

        AMQClient.__init__(self,
                           delegate=TwistedDelegate(),
                           vhost=vhost,
                           spec=txamqp.spec.load(spec))
Example #19
0
 def __init__(
         self, specfile, amqp_config, connected_callback,
         disconnected_callback):
     '''Factory that creates JunebugAMQClients.
     specfile - string of specfile name
     amqp_config - connection details for amqp server
     '''
     self.connected_callback, self.disconnected_callback = (
         connected_callback, disconnected_callback)
     self.amqp_config = amqp_config
     self.spec = get_spec(vumi_resource_path(specfile))
     self.delegate = TwistedDelegate()
     super(AmqpFactory, self).__init__()
Example #20
0
 def __init__(self, spec_file=None, vhost=None,
              host=None, port=None, username=None,
              password=None, exchange_name="",
              exchange_type="fanout", channel=None):
     spec_file = spec_file or 'extras/rabbitmq-specification.xml'
     self.spec = txamqp.spec.load(spec_file)
     self.username = username or 'guest'
     self.password = password or 'guest'
     self.vhost = vhost or '/'
     self.chan = channel or 1
     self.delegate = TwistedDelegate()
     self.exchange_name = exchange_name
     self.exchange_type = exchange_type
    def start(self):
        vhost = self.amqp_conn['vhost']
        host = self.amqp_conn['host']
        port = self.amqp_conn['port']

        d = ClientCreator(reactor,
                          AMQClient,
                          delegate=TwistedDelegate(),
                          vhost=vhost,
                          spec=self.spec).connectTCP(host, port)

        d.addCallback(self.gotConnection)
        d.addErrback(self.whoops)
Example #22
0
    def __init__(self, specFilename, exchange='signals'):
        self.exchange = exchange
        spec = txamqp.spec.load(specFilename)

        delegate = TwistedDelegate()
        self.clientConnected = ClientCreator(reactor,
                                             AMQClient,
                                             delegate=delegate,
                                             vhost="/",
                                             spec=spec).connectTCP(
                                                 "localhost", 5672)
        self.conn = None
        self.chan = None
        self.finishLock = DeferredLock()
  def _connect(self):
    spec_path = os.path.dirname(__file__) + "/amqp0-8.stripped.rabbitmq.xml"
    spec = txamqp.spec.load(spec_path)
    self.delegate = TwistedDelegate()

    d = ClientCreator(reactor, AMQClient, delegate=self.delegate, vhost=self._configuration["vhost"], spec=spec).connectTCP(self._configuration["host"], self._configuration["port"])

    d.addCallback(self._connected)

    def whoops(err):
      if reactor.running:
        log.err(err)
        self.shutdown()
        reactor.stop()

    d.addErrback(whoops)
Example #24
0
def writeMetric(metric_path,
                value,
                timestamp,
                host,
                port,
                username,
                password,
                vhost,
                exchange,
                spec=None,
                channel_number=1,
                ssl=False):

    if not spec:
        spec = txamqp.spec.load(
            os.path.normpath(
                os.path.join(os.path.dirname(__file__), 'amqp0-8.xml')))

    delegate = TwistedDelegate()

    connector = ClientCreator(reactor,
                              AMQClient,
                              delegate=delegate,
                              vhost=vhost,
                              spec=spec)
    if ssl:
        from twisted.internet.ssl import ClientContextFactory
        conn = yield connector.connectSSL(host, port, ClientContextFactory())
    else:
        conn = yield connector.connectTCP(host, port)

    yield conn.authenticate(username, password)
    channel = yield conn.channel(channel_number)
    yield channel.channel_open()

    yield channel.exchange_declare(exchange=exchange,
                                   type="topic",
                                   durable=True,
                                   auto_delete=False)

    message = Content("%f %d" % (value, timestamp))
    message["delivery mode"] = 2

    channel.basic_publish(exchange=exchange,
                          content=message,
                          routing_key=metric_path)
    yield channel.channel_close()
Example #25
0
    def doTask(self):
        self.state = TaskStates.STATE_WAITING
        log.debug("Connecting to %s (%s)", self._devId, self._manageIp)

        spec = txamqp.spec.load(os.path.join(os.path.dirname(__file__), "lib/txamqp/specs/standard/amqp0-8.xml"))
        delegate = TwistedDelegate()
        d = ClientCreator(reactor,
                          AMQClient,
                          delegate=delegate,
                          spec=spec,
                          vhost=self._config.zAMQPVirtualHost).connectTCP(self._config.manageIp,
                                                                          self._config.zAMQPPort)
        d.addCallback(self._onConnSucc,
                      self._config.zAMQPQueue,
                      self._config.zAMQPUsername,
                      self._config.zAMQPPassword)
        d.addErrback(self._onConnFail)
        return d
    def connect_broker(self):
        delegate = TwistedDelegate()
        spec = txamqp.spec.load(self.config["rabbitmq"]["spec"])

        broker_client = ClientCreator(reactor, AMQClient, delegate=delegate, 
                                      vhost=self.config["rabbitmq"]["vhost"], 
                                      spec=spec)
        broker_conn = yield broker_client.connectTCP(self.config["rabbitmq"]["host"],
                                                     self.config["rabbitmq"]["port"])

        log.msg("Connected to broker.")
        yield broker_conn.authenticate(self.config["rabbitmq"]["user"],
                                       self.config["rabbitmq"]["password"])

        log.msg("Broker authenticated. Ready to send messages")
        chan = yield broker_conn.channel(1)
        yield chan.channel_open()

        self.broker = chan
        self.broker_conn = broker_conn


        yield self.broker.queue_declare(queue=self.queue_name)
        yield self.broker.exchange_declare(exchange=self.fanout_exchange_name, type="fanout", durable=True,
                                           auto_delete=False)
        yield self.broker.exchange_declare(exchange=self.direct_exchange_name, type="direct", durable=True,
                                           auto_delete=False)
        yield self.broker.queue_bind(queue=self.queue_name, exchange=self.direct_exchange_name,
                                     routing_key=self.direct_routing_key)
        yield self.broker.queue_bind(queue=self.queue_name, exchange=self.fanout_exchange_name,
                                     routing_key='')
        yield self.broker.basic_consume(queue=self.queue_name, no_ack=True, consumer_tag=self.queue_name)

        queue = yield self.broker_conn.queue(self.queue_name)
        self.do_queue_tasks(queue)



        result = yield self.broker.queue_declare(exclusive=True)
        self.callback_queue_name = result.queue
        yield self.broker.basic_consume(queue=self.callback_queue_name, no_ack=True,
                                        consumer_tag="callback_queue")
        self.callback_queue = yield self.broker_conn.queue("callback_queue")
        self.do_broker_callback_tasks(self.callback_queue)
def writeMetric(metricList, host, port, username, password,
                vhost, exchange, queue, spec=None, channel_number=1, ssl=False):
    
    global conn
    if not spec:
        spec = txamqp.spec.load(os.path.normpath(
            os.path.join(os.path.dirname(__file__), 'amqp0-8.xml')))

    delegate = TwistedDelegate()
   
    connector = ClientCreator(reactor, AMQClient, delegate=delegate,
                              vhost=vhost, spec=spec)
    if ssl:
        from twisted.internet.ssl import ClientContextFactory
        conn = yield connector.connectSSL(host, port, ClientContextFactory())
    else:
        conn = yield connector.connectTCP(host, port, timeout=130)
            
    yield conn.authenticate(username, password)
       
    channel = yield conn.channel(channel_number)
    yield channel.channel_open()
  
    yield channel.exchange_declare(exchange=exchange, type="topic", durable=True, auto_delete=False)
    
    #reply = yield channel.queue_declare(queue = queue, durable = True)
    #my_queue = reply.queue

    #Pickup settings.BIND_PATTERNS somewhere else
    #for bind_pattern in settings.BIND_PATTERNS:
    #  yield channel.queue_bind(exchange=exchange, queue=my_queue, routing_key=bind_pattern)
    
    for (metric, datapoints) in metricList:
      body = ""
      for point in datapoints:
        temp = "%f %d\n"%(point[1], point[0])
        body = body + temp 
      message = Content(body)
      message["delivery mode"] = 2
      channel.basic_publish(exchange=exchange, content=message, routing_key=metric)       
      
    yield channel.channel_close()
    yield conn.close("Publish Done. Closing Connection.")
Example #28
0
    def __init__(self,
                 dispatcher,
                 username='******',
                 password='******',
                 vhost='/',
                 exchange='logs',
                 queueSize=None):
        self.dispatcher = dispatcher
        self.username = username
        self.password = password
        self.exchange = exchange
        self.queueSize = queueSize

        self.chan = None

        specDir = FilePath(__file__).parent()
        specFilePath = specDir.child('amqp0-9-1.extended.xml')
        spec = txamqp.spec.load(specFilePath.path)

        delegate = TwistedDelegate()
        AMQClient.__init__(self, delegate=delegate, vhost=vhost, spec=spec)
Example #29
0
    def __init__(self,
                 spec_file=None,
                 vhost=None,
                 host=None,
                 port=None,
                 credentials=None,
                 log_level=None):
        self._spec_file = spec_file
        self.spec = txamqp.spec.load(self.spec_file)
        self.credentials = credentials or common.credentials
        self.vhost = vhost or common.VHOST
        self.host = host or common.RABBIT_MQ_HOST
        self.port = port or common.RABBIT_MQ_PORT
        self.delegate = TwistedDelegate()
        self.deferred = Deferred()
        self.log_level = log_level

        self.instance = None  # The protocol instance.

        self.message_queue = []  # List of messages waiting to be sent.
        self.consumers = []  # List of message consumers to listen on.
Example #30
0
 def __init__(self, amqpConnectionInfo, queueSchema):
     with open(pathjoin(dirname(__file__), 'amqp0-9-1.xml')) as f:
         self.spec = spec.load(f)
         log.debug('Loaded AMQP spec')
     self.connectionInfo = amqpConnectionInfo
     self.queueSchema = queueSchema
     self.vhost = self.connectionInfo.vhost
     self.host = self.connectionInfo.host
     self.port = self.connectionInfo.port
     self.usessl = self.connectionInfo.usessl
     self.delegate = TwistedDelegate()
     self.queues = []
     self.messages = []
     self.p = None
     self._onInitialSend = self._createDeferred()
     self._onConnectionMade = self._createDeferred()
     self._onConnectionLost = self._createDeferred()
     self._onAuthenticated = self._createDeferred()
     self._onConnectionFailed = self._createDeferred()
     self.connector = reactor.connectTCP(self.host, self.port, self)
     self.heartbeat = self.connectionInfo.amqpconnectionheartbeat
Example #31
0
    def dataReceived(self, data):

        self.transport.write(data)
	campo  = data.split(";")
	#print campo[0],";",campo[1],";",campo[2]

	# Send an SMS-MT with defined originating address


	host = '127.0.0.1'
	port = 5672
	vhost = '/'
	username = '******'
	password = '******'
	spec_file = '/etc/jasmin/resource/amqp0-9-1.xml'
	MO_dst = '24247'
	MO_src = campo[1]
	# transformation of the source address! :-)
	MOD_MO_src = '00' + MO_src[2:]
	texto = campo[0]
 
	spec = txamqp.spec.load(spec_file)

	delegate = TwistedDelegate()
 
	# Connect and authenticate
	d = ClientCreator(reactor, AMQClient, delegate=delegate, vhost=vhost,
	spec=spec).connectTCP(host, port)

	d.addCallback(gotConnection, username, password,MOD_MO_src,MO_dst,texto)
	
	def whoops(err):
	    if reactor.running:
		log.err(err)
                reactor.stop()
 
	d.addErrback(whoops)

	def __init__(self,  amqpBroker):      
	    self.amqpBroker = amqpBroker
Example #32
0
    def connect(self,
                host=None,
                port=None,
                spec=None,
                user=None,
                password=None,
                vhost=None,
                heartbeat=None,
                clientClass=None):
        host = host or self.host
        port = port or self.port
        spec = spec or self.spec
        user = user or self.user
        password = password or self.password
        vhost = vhost or self.vhost
        heartbeat = heartbeat or self.heartbeat
        clientClass = clientClass or self.clientClass

        delegate = TwistedDelegate()
        onConn = Deferred()
        p = clientClass(delegate,
                        vhost,
                        txamqp.spec.load(spec),
                        heartbeat=heartbeat)
        f = protocol._InstanceFactory(reactor, p, onConn)
        c = reactor.connectTCP(host, port, f)

        def errb(thefailure):
            thefailure.trap(error.ConnectionRefusedError)
            print "failed to connect to host: %s, port: %s; These tests are designed to run against a running instance" \
                  " of the %s AMQP broker on the given host and port.  failure: %r" % (host, port, self.broker, thefailure,)
            thefailure.raiseException()

        onConn.addErrback(errb)

        self.connectors.append(c)
        client = yield onConn

        yield self.authenticate(client, user, password)
        returnValue(client)
Example #33
0
 def __init__(self, disconnected, process):
     TwistedDelegate.__init__(self)
     self._disconnected = disconnected
     self._process = process
Example #34
0
 def close(self, reason):
     """
     We can do things here when the connection closes
     """
     #print "CLOSE"
     return TwistedDelegate.close(self, reason)
Example #35
0
 def dispatch(self, ch, msg):
     if msg.method.name == "deliver":
         if self._process:
             self._process(msg)
     else:
         TwistedDelegate.dispatch(self, ch, msg)
Example #36
0
 def channel_close(self, ch, msg):
     TwistedDelegate.channel_close(self, ch, msg)
     self._fireDisconnected(msg)
Example #37
0
 def connection_close(self, ch, msg):
     TwistedDelegate.connection_close(self, ch, msg)
     self._fireDisconnected(msg)
Example #38
0
 def close(self, reason):
     TwistedDelegate.close(self, reason)
     self._fireDisconnected(reason)
class MessageHelper(object):
  _output_channel = None
  _pending = []
  _channel_in = None
  _channel_out = None
  _last_time_called = 0
  _min_interval = 0.5
  _later = None
  _shutdown = False

  def __init__(self, configuration, sender_ready, receiver_ready, message_received):
    """
      Kicks off configuration and connections.
      sender_ready will be called when the sender is ready, and message_received will
      be called with the plaintext body of a message.
    """

    self._configuration = configuration

    self.sender_ready = sender_ready
    self.receiver_ready = receiver_ready
    self.message_received = message_received

    self._connect()

  def _connect(self):
    spec_path = os.path.dirname(__file__) + "/amqp0-8.stripped.rabbitmq.xml"
    spec = txamqp.spec.load(spec_path)
    self.delegate = TwistedDelegate()

    d = ClientCreator(reactor, AMQClient, delegate=self.delegate, vhost=self._configuration["vhost"], spec=spec).connectTCP(self._configuration["host"], self._configuration["port"])

    d.addCallback(self._connected)

    def whoops(err):
      if reactor.running:
        log.err(err)
        self.shutdown()
        reactor.stop()

    d.addErrback(whoops)

  def shutdown(self):
    self._shutdown = True

    if self._later:
      self._later.reset()

    self.delegate.connection_close(None, "Shutting down")

  @inlineCallbacks
  def _connected(self, connection):
    self._connection = connection

    yield self._connection.authenticate(self._configuration["username"], self._configuration["password"])

    yield self._set_up_sender()
    yield self._set_up_receiver()

  @inlineCallbacks
  def _set_up_sender(self):
    self._channel_out = yield self._connection.channel(1)
    yield self._channel_out.channel_open()

    yield self._channel_out.exchange_declare(
      exchange=self._configuration["outgoing"]["exchange"],
      type=self._configuration["outgoing"]["exchange_type"],
      durable=self._configuration["outgoing"]["durable"],
      auto_delete=False
    )

    yield self._sender_ready(self._channel_out)

  @inlineCallbacks
  def _set_up_receiver(self):
    self._channel_in = yield self._connection.channel(2)
    yield self._channel_in.channel_open()
    yield self._channel_in.basic_qos(prefetch_count=self._configuration["incoming"]["prefetch_count"])

    yield self._channel_in.queue_declare(
      queue=self._configuration["incoming"]["queue"],
      durable=self._configuration["incoming"]["durable"],
      exclusive=self._configuration["incoming"]["exclusive"],
      auto_delete=False
    )

    yield self._channel_in.exchange_declare(
      exchange=self._configuration["incoming"]["exchange"],
      type=self._configuration["incoming"]["exchange_type"],
      durable=self._configuration["incoming"]["durable"],
      auto_delete=False
    )

    yield self._channel_in.queue_bind(
      queue=self._configuration["incoming"]["queue"],
      exchange=self._configuration["incoming"]["exchange"],
      routing_key=self._configuration["incoming"]["routing_key"]
    )

    yield self._channel_in.basic_consume(
      queue=self._configuration["incoming"]["queue"],
      no_ack=False,
      consumer_tag=self._configuration["incoming"]["routing_key"]
    )

    self._queue_in = yield self._connection.queue(self._configuration["incoming"]["routing_key"])
    self._receiveMessages()
    self.receiver_ready()

  def _ack(self, raw_message):
    self._channel_in.basic_ack(delivery_tag=raw_message.delivery_tag)

  @inlineCallbacks
  def _receiveMessages(self):
    elapsed = time.time() - self._last_time_called
    left_to_wait = self._min_interval - elapsed

    if self._shutdown:
      return

    if left_to_wait > 0:
      self._later = self.callLater(left_to_wait, self._receiveMessages)
    else:
      self._last_time_called = time.time()

      message = yield self._queue_in.get()
      self._message_received(message)

      elapsed = time.time() - self._last_time_called
      left_to_wait = self._min_interval - elapsed

      if left_to_wait < 0:
        left_to_wait = 0

      self._later = self.callLater(left_to_wait*1.01, self._receiveMessages)

  def _send_queued_messages(self):
    if self._channel_out:
      while self._pending:
        message = Content(json.dumps(self._pending.pop()))

        self._channel_out.basic_publish(
          exchange=self._configuration["outgoing"]["exchange"],
          routing_key=self._configuration["outgoing"]["routing_key"],
          content=message
        )

  def _sender_ready(self, output_channel):
    self._send_queued_messages()
    self.sender_ready()

  def _message_received(self, message):
    self._ack(message)

    body = json.loads(message.content.body)

    self.message_received(body)

  def callLater(self, *args, **kwargs):
    return reactor.callLater(*args, **kwargs)

  def send(self, message):
    self._pending.append(message)
    self._send_queued_messages()

  def sender_ready(self):
    raise Exception("message_received in message_helper has not been set")

  def message_received(self, message):
    raise Exception("message_received in message_helper has not been set")