示例#1
0
    def get_pending_messages(self, username = None):
        result = []
        if username is None:
            return result
        username = str(username)
        connection = self._get_blocking_amqp_conn()
        try:
            channel = connection.channel()
            logger.debug("Connecting to %s ", username)

            channel.queue_declare(queue = username,
                                  durable = True,
                                  exclusive = False,
                                  auto_delete = False)

            while connection.is_open:
                method, header, body = channel.basic_get(queue = username)
                if method.NAME == 'Basic.GetEmpty':
                    # queue empty, stop gathering.
                    connection.close()
                    return result
                else:
                    result.append(body)
                #channel.basic_ack(delivery_tag=method.delivery_tag)
        except Exception, e:
            logger.error("Crapsticks: %s" % str(e))
示例#2
0
    def send_broadcast(self, message, username):
        """ Send a message to all queues associated
        with the username exchange (1:N)"""
        user_exchange_name = username
        conn = self._get_blocking_amqp_conn()
        try:
            channel = conn.channel()

            logger.debug("Declaring exchange '%s'", user_exchange_name)
            channel.exchange_declare(
                exchange=user_exchange_name,
                durable=True,
                type='fanout',
            )

            # Send message to user exchange so all other clients receive it
            logger.debug("Publishing message to exchange '%s'",
                user_exchange_name)
            channel.basic_publish(
                exchange=user_exchange_name,
                routing_key='',
                body=message,
                properties=pika.BasicProperties(
                    content_type='text/plain',
                ),
            )
        except:
            logger.error("Error sending broadcast message")
            raise
        finally:
            logger.debug("Closing AMQP connection to broker")
            conn.disconnect()
示例#3
0
    def publish_message(self, message, token):
        """ send a message to a specific device. (1:1) """
        conn = self._get_blocking_amqp_conn()
        try:
            channel = conn.channel()

            logger.debug("Declaring incoming exchange '%s'",
                    self.incoming_exchange_name)
            channel.exchange_declare(
                exchange=self.incoming_exchange_name,
                durable=True,
                type='direct',
            )

            logger.debug("Publishing message to exchange '%s'",
                    self.incoming_exchange_name)
            channel.basic_publish(
                exchange=self.incoming_exchange_name,
                routing_key=token,
                body=message,
                properties=pika.BasicProperties(
                    content_type="text/plain",
                ),
            )
        except:
            logger.error("Error publishing message to exchange")
            raise
        finally:
            logger.debug("Disconnecting from message broker")
            conn.disconnect()
示例#4
0
    def queue_message(self, message, queue_name):
        """ send a message to a specific outbound queue (1:1) """
        conn = self._get_blocking_amqp_conn()
        try:
            channel = conn.channel()

            logger.debug("Declaring queue '%s' on message broker",
                    queue_name)
            channel.queue_declare(queue=queue_name)

            logger.debug("Sending message to queue '%s' for processing",
                    queue_name)
            channel.basic_publish(
                exchange='',
                routing_key=queue_name,
                body=message,
                properties=pika.BasicProperties(
                    content_type="text/plain",
                ),
            )
        except:
            logger.error("Error queueing message in message broker")
            raise
        finally:
            logger.debug("Disconnecting from message broker")
            conn.disconnect()
示例#5
0
文件: rabbitmq.py 项目: psawaya/notif
    def _delete_binding(self, source_exch, dest_exch, routing_key):
        http_conn = self._get_http_conn()
        try:
            auth_headers = {
                'Authorization': 'Basic ' +
                    base64.b64encode('%s:%s' % \
                        (self.broker_user, self.broker_pass)
                    ),
            }

            path = '/api/bindings/%s/e/%s/e/%s/%s' % (
                urllib.quote_plus(self.broker_vhost),
                urllib.quote_plus(source_exch),
                urllib.quote_plus(dest_exch),
                # Encode twice because binding "properties" are URL-encoded before stored
                urllib.quote_plus(urllib.quote_plus(routing_key))
            )

            logger.debug("Sending HTTP DELETE request to broker %s", path)
            http_conn.request('DELETE', path, '', auth_headers)

            response = http_conn.getresponse()
            logger.debug("Broker returned response with status %s", response.status)

            if response.status != httplib.NO_CONTENT:
                logger.error("Unexpected response status '%s'", response.status)
                raise Exception("Unexpected response status '%s'", response.status)
        except:
            logger.error("Error deleting binding via HTTP")
            raise
        finally:
            logger.debug("Closing HTTP connection to broker")
            http_conn.close()
示例#6
0
    def _ensure_exchanges_exist(self, incoming_exchange_name,
            user_exchange_name):
        conn = self._get_blocking_amqp_conn()
        try:
            channel = conn.channel()

            # TODO: Decide if we should remove this call; the incoming exchange
            # should always exist before new_subscription is called
            logger.debug("Declaring incoming exchange %s",
                    incoming_exchange_name)
            channel.exchange_declare(
                exchange=incoming_exchange_name,
                durable=True,
                type='direct',
            )

            # TODO: Decide if we should remove this call; the user exchange
            # should always exist before new_subscription is called
            logger.debug("Declaring user exchange %s", user_exchange_name)
            channel.exchange_declare(
                exchange=user_exchange_name,
                durable=True,
                type='fanout',
            )
        except:
            logger.error("Error ensuring exchanges exist on broker")
            raise
        finally:
            logger.debug("Closing AMQP connection to broker")
            conn.disconnect()
示例#7
0
文件: rabbitmq.py 项目: psawaya/notif
    def create_client_queue(self, username):
        user_exchange_name = username

        # Create a unique client id to also be used as the name of the queue
        client_queue_name = "%x" % random.getrandbits(256)

        logger.info("Creating queue %s for user %s", client_queue_name, username)

        # Create the user exchange (if it doesn't already exist) and a client
        # queue with the generated name.
        conn = self._get_amqp_conn()
        try:
            channel = conn.channel()

            logger.debug("Declaring exchange %s", user_exchange_name)
            channel.exchange_declare(
                exchange=user_exchange_name,
                durable=True,
                type='fanout',
            )

            logger.debug("Declaring queue %s", client_queue_name)
            channel.queue_declare(queue=client_queue_name, durable=True)

            logger.debug("Binding queue %s to exchange %s",
                client_queue_name,
                user_exchange_name,
            )
            channel.queue_bind(
                exchange=user_exchange_name,
                queue=client_queue_name,
            )
        except:
            logger.error("Error creating new client queue")
            raise
        finally:
            logger.debug("Closing AMQP connection to broker")
            conn.disconnect()

        return {
            'queue_id': client_queue_name,
            'host': self.broker_host,
            'port': self.broker_amqp_port,
        }
示例#8
0
    def _add_binding(self, source_exch, dest_exch, routing_key):
        # XXX: OH EM GEE this is a hack. Creating Exchange-to-exchange (E2E)
        # bindings is a RabbitMQ-specific extension, so the pika AMQP
        # client doesn't support it. The RabbitMQ REST API does however,
        # so we do a quick HTTP POST here to create the binding.
        #
        # To do this properly, we'll probably have to roll our own version
        # of Pika which supports the exchange.bind method call.
        http_conn = self._get_http_conn()
        try:
            auth_headers = {
                'Authorization': 'Basic ' +
                    base64.b64encode('%s:%s' % \
                        (self.broker_user, self.broker_pass)
                    ),
                'Content-Type': 'application/json',
            }

            path = '/api/bindings/%s/e/%s/e/%s' % (
                urllib.quote_plus(self.broker_vhost),
                urllib.quote_plus(source_exch),
                urllib.quote_plus(dest_exch)
            )

            body = json.dumps({'routing_key': routing_key, 'arguments': []})

            logger.debug("Sending HTTP POST request to broker %s", path)
            http_conn.request('POST', path, body, auth_headers)

            response = http_conn.getresponse()
            logger.debug("Broker returned response with status %s",
                    response.status)

            if response.status != httplib.CREATED:
                logger.error("Unexpected response status '%s'",
                        response.status)
                raise Exception("Unexpected response status '%s'",
                        response.status)
        except:
            logger.error("Error adding binding via HTTP")
            raise
        finally:
            logger.debug("Closing HTTP connection to broker")
            http_conn.close()
示例#9
0
    def create_client_queue(self, username):
        self.channel_info = {}
        self.channel_info['exchange_name'] = username
        self.channel_info['queue_name'] = new_token()

        # Create a unique client id to also be used as the name of the queue
        client_queue_name = new_token()

        logger.info("Creating queue %s for user %s",
                        self.channel_info.get('queue_name'),
                        self.channel_info.get('exchange_name'))

        # Create the user exchange (if it doesn't already exist) and a client
        # queue with the generated name.
        conn = self._get_blocking_amqp_conn()
        try:
            channel = conn.channel()

            logger.debug("Declaring exchange %s",
                        self.channel_info.get('exchange_name'))
            channel.exchange_declare(
                exchange=self.channel_info.get('exchange_name'),
                durable=True,
                type='fanout',
            )

            logger.debug("Declaring queue %s", client_queue_name)
            channel.queue_declare(queue=client_queue_name, durable=True)

            logger.debug("Binding queue %s to exchange %s",
                client_queue_name,
                self.channel_info.get('exchange_name'),
            )
            channel.queue_bind(
                exchange=self.channel_info.get('exchange_name'),
                queue=client_queue_name,
            )
        except Exception, e:
            logger.error("Error creating new client queue. %s" % e.message)
            raise NotifStorageException('Cannot create new client')
示例#10
0
            logger.debug("Declaring queue %s", client_queue_name)
            channel.queue_declare(queue=client_queue_name, durable=True)

            logger.debug("Binding queue %s to exchange %s",
                client_queue_name,
                self.channel_info.get('exchange_name'),
            )
            channel.queue_bind(
                exchange=self.channel_info.get('exchange_name'),
                queue=client_queue_name,
            )
        except Exception, e:
            logger.error("Error creating new client queue. %s" % e.message)
            raise NotifStorageException('Cannot create new client')
        finally:
            logger.debug("Closing AMQP connection to broker")
            conn.disconnect()

        return {
            'queue_id': client_queue_name,
            'host': self.broker_host,
            'port': self.broker_amqp_port,
        }

    def create_subscription(self, username, token):
        user_exchange_name = username

        # TODO: See if we can remove this call entirely
        self._ensure_exchanges_exist(self.incoming_exchange_name,
                user_exchange_name)
示例#11
0
        index_record = self.redis.lindex("u2m:%s" % username, 0)
        if index_record is not None:
            top_index = json.loads(index_record).get("id", 0)
        parsed_message = json.loads(message)
        message_body = json.loads(parsed_message.get('body'))
        now = int(time.time())
        timestamp = parsed_message.get('timestamp', int(time.time()))
        if timestamp > now:
            timestamp == now
        redStore = {'file': doc_file,
                    'origin': origin,
                    'expry': int(timestamp + message_body.get('ttl',
                        self.config.get('notifserver.max_ttl_seconds',
                                        259200))),
                    'id': top_index + 1}
        logger.debug('Adding message for %s' % username)
        self.redis.lpush("u2m:%s" % username, json.dumps(redStore))
        info = self.redis.hgetall("sin:%s:%s" % (username, queue))
        info.update({'lastmsg': time.time(),
                'lastorigin': origin}) 
        self.redis.hmset("sin:%s:%s" % (username, queue), info)
        old = self.redis.lrange("u2m:%s" % username, 0, 0-max_msgs)
        if len(old):
            for message in old:
                self._cleanMessage(username, message)
            self.redis.ltrim("u2m:%s" % username, 0, max_msgs)
        return {"id": top_index + 1}

    def get_pending_messages(self, username, since = None):
        """ send messages to user """
        doc_path = self._user_storage_path(username)