Example #1
0
    def reconnect(self, retry = True):
        if not config.REMOTE: return
        if not self.connection.is_closed: return

        quorum.info("Re-connecting to the AMQP system")

        self.connect(queue = self.queue, retry = retry)
Example #2
0
    def reconnect(self, retry=True):
        if not config.REMOTE: return
        if not self.connection.is_closed: return

        quorum.info("Re-connecting to the AMQP system")

        self.connect(queue=self.queue, retry=retry)
Example #3
0
    def connect(self, queue = "default", retry = True):
        if not config.REMOTE: return

        quorum.info("Connecting to the AMQP system")

        while True:
            try:
                self.connection = quorum.get_amqp(force = True)
                self.channel = self.connection.channel()
                self.channel.queue_declare(queue = queue, durable = True)
                self.queue = queue
                break
            except Exception as exception:
                if not retry: raise
                quorum.error(
                    "Exception while connecting - %s" % quorum.legacy.UNICODE(exception),
                    log_trace = True
                )
                quorum.info("Sleeping %d seconds before connect retry" % RETRY_TIMEOUT)
                time.sleep(RETRY_TIMEOUT)
Example #4
0
    def connect(self, queue="default", retry=True):
        if not config.REMOTE: return

        quorum.info("Connecting to the AMQP system")

        while True:
            try:
                self.connection = quorum.get_amqp(force=True)
                self.channel = self.connection.channel()
                self.channel.queue_declare(queue=queue, durable=True)
                self.queue = queue
                break
            except Exception as exception:
                if not retry: raise
                quorum.error("Exception while connecting - %s" %
                             quorum.legacy.UNICODE(exception),
                             log_trace=True)
                quorum.info("Sleeping %d seconds before connect retry" %
                            RETRY_TIMEOUT)
                time.sleep(RETRY_TIMEOUT)
Example #5
0
    def connect(self, queue="default"):
        if not config.REMOTE: return

        while True:
            try:
                quorum.debug("Starting loop cycle in slave ...")
                self.connection = quorum.get_amqp(force=True)
                self.channel = self.connection.channel()
                self.channel.queue_declare(queue=queue, durable=True)
                self.channel.basic_qos(prefetch_count=1)
                self.channel.basic_consume(queue=queue,
                                           on_message_callback=self.callback)
                self.channel.start_consuming()
            except Exception as exception:
                quorum.error("Exception while executing - %s" %
                             quorum.legacy.UNICODE(exception),
                             log_trace=True)

            quorum.info("Sleeping %d seconds before consume retry" %
                        RETRY_TIMEOUT)

            time.sleep(RETRY_TIMEOUT)
Example #6
0
    def callback(self, channel, method, properties, body):
        # prints a debug message about the callback call for the message, this
        # may be used latter for debugging purposes (as requested)
        quorum.debug("Received callback for message")

        # loads the contents of the body that is going to be submitted this
        # is considered the payload of the document to be submitted
        document = json.loads(body)

        # retrieves the various attributes of the document that is going to
        # be submitted, making sure that the issue date is correctly formatted
        type = document["_class"]
        object_id = document["object_id"]
        representation = document["representation"]
        issue_date = document["issue_date"]
        issue_date_d = datetime.datetime.utcfromtimestamp(issue_date)
        issue_date_s = issue_date_d.strftime("%d %b %Y %H:%M:%S")

        # verifies if the document is considered to be outdated (timeout passed)
        # in case it's returns immediately printing a message
        outdated = not properties.timestamp or\
            properties.timestamp < time.time() - MESSAGE_TIMEOUT
        if outdated:
            channel.basic_ack(delivery_tag=method.delivery_tag)
            quorum.info("Canceling/Dropping %s - %s (%s)" %
                        (type, representation, issue_date_s))
            return

        # retrieves the current time and uses it to print debug information
        # about the current document submission to at
        quorum.info("Submitting %s - %s (%s)" %
                    (type, representation, issue_date_s))

        # resolves the method for the currently retrieved data type (class)
        # this should raise an exception in case the type is invalid
        api_method = self._resolve_method(type)

        try:
            # calls the proper method for the submission of the document
            # described by the provided object id, in case there's a problem
            # in the request an exception should be raised and handled properly
            api_method(object_id)
        except Exception as exception:
            quorum.error("Exception while submitting document - %s" %
                         quorum.legacy.UNICODE(exception))
            retries = properties.priority or 0
            retries -= 1
            properties.priority = retries
            if retries >= 0:
                self.channel.basic_publish(exchange="",
                                           routing_key=config.QUEUE,
                                           body=body,
                                           properties=properties)
                quorum.error(
                    "Re-queueing for latter consumption (%d retries pending)" %
                    retries)
            else:
                quorum.error(
                    "No more retries left, the document will be discarded")
        else:
            quorum.info("Document submitted with success")

        # marks the message as acknowledged in the message queue server
        # and then prints a debug message about the action
        channel.basic_ack(delivery_tag=method.delivery_tag)
        quorum.debug("Marked as acknowledged in message queue")
Example #7
0
    def execute(self):
        # in case the current instance is not configured according to
        # the remote rules the queuing operation is ignored, and so
        # the control flow returns immediately
        if not config.REMOTE: return

        # creates a values map structure to retrieve the complete
        # set of inbound documents that have not yet been submitted
        # to at for the flush operation
        kwargs = {
            "session_id" : self.session_id,
            "filter_string" : "",
            "start_record" : 0,
            "number_records" : NUMBER_RECORDS,
            "sort" : "issue_date:ascending",
            "filters[]" : [
                "issue_date:greater:1356998400",
                "submitted_at:equals:2",
                "document_type:in:1;3"
            ]
        }
        documents = self.api.list_signed_documents(**kwargs)
        valid_documents = [value for value in documents\
            if value["_class"] in config.AT_SUBMIT_TYPES]

        # starts the counter value to zero, so that we're able to count
        # the number of messages that have been successfully queued to
        # the remote queueing mechanism (for debugging)
        count = 0

        # iterates over all the valid documents that have been found
        # as not submitted and creates a task for their submission
        # then adds the task to the AMQP queue to be processed
        for document in valid_documents:
            try:
                # tries to run the basic publish operation, this operation
                # may fail for a variety of reasons including errors in the
                # underlying library so a reconnection is attempted in case
                # there's an exception raised under this operation
                self.channel.basic_publish(
                    exchange = "",
                    routing_key = config.QUEUE,
                    body = json.dumps(document),
                    properties = quorum.properties_amqp(
                        delivery_mode = 2,
                        priority = MESSAGE_RETRIES,
                        expiration = str(MESSAGE_TIMEOUT * 1000),
                        timestamp = time.time()
                    )
                )
                count += 1
            except Exception as exception:
                # prints a warning message about the exception that has just occurred
                # so that it's possible to act on it
                quorum.warning(
                    "Exception in publish (will re-connect) - %s" % quorum.legacy.UNICODE(exception),
                    log_trace = True
                )

                # re-tries to connect with the AMQP channels using the currently
                # pre-defined queue system, this is a fallback of the error
                self.reconnect()

        # prints an information message about the new documents that
        # have been queued for submission by the "slaves"
        quorum.info("Queued %d (out of %d) documents for submission" % (count, len(valid_documents)))
Example #8
0
    def disconnect(self):
        if not config.REMOTE: return

        quorum.info("Disconnected from the AMQP system")

        self.connection.close()
Example #9
0
    def execute(self):
        # in case the current instance is not configured according to
        # the remote rules the queuing operation is ignored, and so
        # the control flow returns immediately
        if not config.REMOTE: return

        # creates a values map structure to retrieve the complete
        # set of inbound documents that have not yet been submitted
        # to at for the flush operation
        kwargs = {
            "session_id":
            self.session_id,
            "filter_string":
            "",
            "start_record":
            0,
            "number_records":
            NUMBER_RECORDS,
            "sort":
            "issue_date:ascending",
            "filters[]": [
                "issue_date:greater:1356998400", "submitted_at:equals:2",
                "document_type:in:1;3"
            ]
        }
        documents = self.api.list_signed_documents(**kwargs)
        valid_documents = [value for value in documents\
            if value["_class"] in config.AT_SUBMIT_TYPES]

        # starts the counter value to zero, so that we're able to count
        # the number of messages that have been successfully queued to
        # the remote queueing mechanism (for debugging)
        count = 0

        # iterates over all the valid documents that have been found
        # as not submitted and creates a task for their submission
        # then adds the task to the AMQP queue to be processed
        for document in valid_documents:
            try:
                # tries to run the basic publish operation, this operation
                # may fail for a variety of reasons including errors in the
                # underlying library so a reconnection is attempted in case
                # there's an exception raised under this operation
                self.channel.basic_publish(exchange="",
                                           routing_key=config.QUEUE,
                                           body=json.dumps(document),
                                           properties=quorum.properties_amqp(
                                               delivery_mode=2,
                                               priority=MESSAGE_RETRIES,
                                               expiration=str(MESSAGE_TIMEOUT *
                                                              1000),
                                               timestamp=time.time()))
                count += 1
            except Exception as exception:
                # prints a warning message about the exception that has just occurred
                # so that it's possible to act on it
                quorum.warning("Exception in publish (will re-connect) - %s" %
                               quorum.legacy.UNICODE(exception),
                               log_trace=True)

                # re-tries to connect with the AMQP channels using the currently
                # pre-defined queue system, this is a fallback of the error
                self.reconnect()

        # prints an information message about the new documents that
        # have been queued for submission by the "slaves"
        quorum.info("Queued %d (out of %d) documents for submission" %
                    (count, len(valid_documents)))
Example #10
0
    def disconnect(self):
        if not config.REMOTE: return

        quorum.info("Disconnected from the AMQP system")

        self.connection.close()