def __answer_if_service_available(self, service_type, agency_key, corr_id): if service_type in self.services: msg = SN.msg([SN.Response.ServiceAvailable, service_type]) else: msg = SN.msg([SN.Response.ServiceUnavailable, service_type]) self.__communication_lock.acquire() self.channel.basic_publish(exchange=SN.Exchanges.Main, routing_key=agency_key, properties=pika.BasicProperties( reply_to=self.key, correlation_id=corr_id), body=msg) self.__communication_lock.release()
def request_service(self, service_type): self.__set_corr_id() msg = SN.msg([SN.Request.ServiceAvailability, service_type]) self.__communication_lock.acquire() self.channel.basic_publish(exchange=SN.Exchanges.Main, routing_key=SN.key(SN.Key.Carriers), properties=pika.BasicProperties( reply_to=self.key, correlation_id=self.corr_id), body=msg) self.__communication_lock.release() self.__await_service_availability(service_type) self.__reset_corr_id()
def __init__(self, agency_name): self.__communication_lock = threading.RLock() self.orders = [] self.completed_orders = [] self.order_counter = 0 self.connection = pika.BlockingConnection( pika.ConnectionParameters(host=SN.Host)) self.channel = self.connection.channel() self.channel.exchange_declare(exchange=SN.Exchanges.Main, exchange_type='topic') self.key = SN.key(SN.Key.Direct, agency_name) result = self.channel.queue_declare(queue='', exclusive=True) self.queue = result.method.queue self.__bind_agency_queues() self.corr_id = 0 self.awaited_response = None self.awaited_responder = None self.channel.basic_consume(queue=self.queue, on_message_callback=self.__on_response, auto_ack=True)
def __bind_agency_queues(self): self.channel.queue_bind(exchange=SN.Exchanges.Main, queue=self.queue, routing_key=SN.key(SN.Key.Agencies)) self.channel.queue_bind(exchange=SN.Exchanges.Main, queue=self.queue, routing_key=self.key)
def __produce_service(self, service_type, agency_key) -> bool: if service_type in self.services: print(service_type.__str__() + " provided to " + SN.title(agency_key)) return True else: return False
def __bind_carrier_queues(self): self.channel.queue_bind(exchange=SN.Exchanges.Main, queue=self.queue, routing_key=SN.key(SN.Key.Carriers)) self.channel.queue_bind(exchange=SN.Exchanges.Main, queue=self.queue, routing_key=self.key)
def send_message_to_group(self, msg, group): self.__communication_lock.acquire() self.channel.basic_publish(exchange=SN.Exchanges.Main, routing_key=SN.key(group), properties=pika.BasicProperties( reply_to=self.key, ), body=msg) self.__communication_lock.release()
def __on_response(self, ch, method, props, body): msg = SN.msg_decode(body.decode()) if msg[0] == SN.Response.ServiceCompleted: order_no = int(msg[1]) self.__handle_order_completion(order_no) elif msg[0] == SN.Response.ServiceUnavailable: print( SN.title(props.reply_to) + ":" + msg[1].__str__() + " is unavailable") elif msg[0] == SN.Response.ServiceAvailable: print( SN.title(props.reply_to) + ": " + msg[1].__str__() + " is available") if self.corr_id != 0 and self.corr_id == props.correlation_id: self.awaited_response = body.decode() self.awaited_responder = props.reply_to else: print("Message\t" + SN.title(props.reply_to) + ": " + body.decode())
def __on_response(self, ch, method, props, body): msg = SN.msg_decode(body.decode()) if msg[0] == SN.Request.ServiceAvailability: service_type = msg[1] print( SN.title(props.reply_to) + " asked for " + service_type.__str__() + " availability") self.__answer_if_service_available(service_type, props.reply_to, props.correlation_id) elif msg[0] == SN.Request.RequestService: service_type = msg[1] order_no = msg[2] print( SN.title(props.reply_to) + " requested " + service_type.__str__()) self.__provide_service(service_type, props.reply_to, order_no) else: print("Message\t" + SN.title(props.reply_to) + ": " + body.decode())
def __order_service(self, service_type, carrier_key): order_no = self.__add_order_to_list() msg = SN.msg([SN.Request.RequestService, service_type, order_no]) self.__communication_lock.acquire() self.channel.basic_publish(exchange=SN.Exchanges.Main, routing_key=carrier_key, properties=pika.BasicProperties( reply_to=self.key, ), body=msg) print("Ordered(no." + order_no.__str__() + ") " + service_type) self.__communication_lock.release()
def __provide_service(self, service_type, agency_key, order_no): if self.__produce_service(service_type, agency_key) is False: return msg = SN.msg([SN.Response.ServiceCompleted, order_no]) self.__communication_lock.acquire() self.channel.basic_publish( exchange=SN.Exchanges.Main, routing_key=agency_key, properties=pika.BasicProperties(reply_to=self.key), body=msg) self.__communication_lock.release()
def __init__(self, admin_name): self.__communication_lock = threading.RLock() self.connection = pika.BlockingConnection( pika.ConnectionParameters(host=SN.Host)) self.channel = self.connection.channel() self.channel.exchange_declare(exchange=SN.Exchanges.Main, exchange_type='topic') self.key = SN.key(SN.Key.Direct, admin_name) result = self.channel.queue_declare(queue='', exclusive=True) self.queue = result.method.queue self.__bind_admin_queues() self.channel.basic_consume( queue=self.queue, on_message_callback=self.receive_messages_basic, auto_ack=True)
def __await_service_availability(self, service_type): if self.awaited_response is None: self.__consume_from_queue(3) if self.awaited_response is None: print("No response for \"" + service_type + "\" availability.") else: response = SN.msg_decode(self.awaited_response) if response[0] == SN.Response.ServiceUnavailable: self.__reset_response() self.__await_service_availability(service_type) elif response[0] == SN.Response.ServiceAvailable: self.__reset_corr_id() responder = self.awaited_responder self.__reset_response() self.__order_service(service_type, responder) else: print(self.awaited_responder + " send inappropriate message: " + response) self.__reset_response() self.__await_service_availability(service_type)