def post(self): """ Add subscription """ data = request.get_json() app_name = request.headers["x-leek-app-name"] subscription = SubscriptionSchema.validate(data) subscription.update({ "org_name": g.org_name, "app_name": app_name, "app_key": settings.LEEK_AGENT_API_SECRET, "api_url": settings.LEEK_API_URL }) name = subscription.pop("name") # Check if there is already a subscription with the same name with open(SUBSCRIPTIONS_FILE) as s: subscriptions = json.load(s) s = subscriptions.get(name) if s: return responses.subscription_already_exist # Ensure connection try: connection = Connection(subscription["broker"]) connection.ensure_connection(max_retries=2) connection.release() except AccessRefused: return responses.wrong_access_refused except Exception: return responses.broker_not_reachable # Add subscription subscriptions[name] = subscription with open(SUBSCRIPTIONS_FILE, 'w') as f: json.dump(subscriptions, f, indent=4, sort_keys=False) return {"name": name, **subscription}, 200
def post(self): """ Add subscription """ data = request.get_json() subscription = SubscriptionSchema.validate(data) if subscription["batch_max_number_of_messages"] > subscription[ "prefetch_count"]: raise SchemaError( "Batch max number of messages should be <= prefetch count!") subscription.update({ "org_name": g.org_name, "app_name": g.app_name, "app_key": settings.LEEK_AGENT_API_SECRET, "api_url": settings.LEEK_API_URL }) # Check subscription already exist exist, _ = utils.lookup_subscription(subscription["app_name"], subscription["app_env"]) if exist: return responses.subscription_already_exist # Ensure connection try: connection = Connection(subscription["broker"]) connection.ensure_connection(max_retries=2) connection.release() except AccessRefused: return responses.wrong_access_refused except Exception: return responses.broker_not_reachable # Add subscription with open(SUBSCRIPTIONS_FILE, "r+") as subscriptions_file: subscriptions = json.load(subscriptions_file) subscriptions.append(subscription) subscriptions_file.seek(0) json.dump(subscriptions, subscriptions_file) return { "name": utils.infer_subscription_name(subscription), **subscription }, 200
class RPCListener(threading.Thread): """ RPC Listener """ def __init__(self, host, port, user_id, password, virt_host, exchange_name, routing_key, consumer_queue_name): super(RPCListener, self).__init__() self._exit = threading.Event() self._exchange_name = exchange_name self._routing_key = routing_key self._consumer_queue_name = consumer_queue_name self._exchange = Exchange(self._exchange_name, type='topic', durable=False) self._connection = Connection(host, user_id, password, virt_host, port) self._rpc_receive_queue = Queue(self._consumer_queue_name, durable=True, exchange=self._exchange, routing_key=self._routing_key) self._consumer = Consumer(self._connection, self._rpc_receive_queue) self._consumer.register_callback(self._callback) self._message_queue = selectable.ThreadQueue(consumer_queue_name) self._message_filters_lock = threading.RLock() self._message_filters = dict() self._message_handlers = dict() selobj.selobj_add_read_obj(self._message_queue.selobj, self._dispatch_messages) @coroutine def _dispatch_messages(self): """ Dispatch messages from the message queue """ while True: select_obj = (yield) if select_obj == self._message_queue.selobj: msg = self._message_queue.get_nowait() if msg is not None: msg_type = msg.get('type', None) if msg_type is not None: msg_handler = self._message_handlers.get( msg_type, None) if msg_handler is not None: msg_handler(msg['data']) def add_message_handler(self, msg_type, msg_filter, msg_handler): """ Add message handler """ self._message_filters_lock.acquire() try: self._message_filters[msg_type] = msg_filter finally: self._message_filters_lock.release() self._message_handlers[msg_type] = msg_handler def del_message_handler(self, msg_type): """ Delete message handler """ self._message_filters_lock.acquire() try: if msg_type in self._message_filters: del self._message_filters[msg_type] finally: self._message_filters_lock.release() if msg_type in self._message_handlers: del self._message_handlers[msg_type] def _callback(self, body, message): """ RPC Listener callback """ self._message_filters_lock.acquire() try: for msg_type, msg_filter in self._message_filters.iteritems(): msg_data = msg_filter(body) if msg_data is not None: msg = dict() msg['type'] = msg_type msg['data'] = msg_data self._message_queue.put(msg) else: import pprint pp_msg = pprint.pformat(body) DLOG.verbose("Ignoring message: %s" % pp_msg) finally: self._message_filters_lock.release() message.ack() def run(self): """ RPC Listener main """ def _connection_error(exc, interval): DLOG.info("Connection error, exception=%s" % exc) while not self._exit.is_set(): try: if not self._connection.connected: DLOG.info( "RPC-Listener not connected to exchange %s, queue=%s." % (self._exchange_name, self._consumer_queue_name)) self._connection.ensure_connection( errback=_connection_error, interval_start=2, interval_step=0, interval_max=2) self._consumer.revive(self._connection) DLOG.info( "RPC-Listener connected to exchange %s, queue=%s." % (self._exchange_name, self._consumer_queue_name)) self._consumer.consume() self._connection.drain_events(timeout=1) except exceptions.TimeoutError as e: DLOG.verbose("Timeout exception, exception=%s" % e) except Exception as e: DLOG.error("Exception received, exception=%s." % e) time.sleep(2) def stop(self): """ Stop RPC Listener """ self._exit.set()