예제 #1
0
    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()
예제 #2
0
    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()
예제 #3
0
    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)
예제 #4
0
 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)
예제 #5
0
 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
예제 #6
0
 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)
예제 #7
0
 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()
예제 #8
0
    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())
예제 #9
0
    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())
예제 #10
0
    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()
예제 #11
0
    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()
예제 #12
0
    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)
예제 #13
0
    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)