def email_worker():
    connection = get_mq_connection()
    if not connection:
        return
    channel = connection.channel()
    channel.basic_qos(prefetch_count=1)
    channel.basic_consume(email_notifications_callback,
                          queue="bungeni_email_queue")
    channel.start_consuming()
示例#2
0
def email_worker():
    connection = get_mq_connection()
    if not connection:
        return
    channel = connection.channel()
    channel.basic_qos(prefetch_count=1)
    channel.basic_consume(email_notifications_callback,
                          queue="bungeni_email_queue")
    channel.start_consuming()
示例#3
0
def serialization_worker():
    connection = get_mq_connection()
    if not connection:
        return
    channel = connection.channel()
    channel.basic_qos(prefetch_count=1)
    channel.basic_consume(serialization_notifications_callback,
                          queue=SERIALIZE_QUEUE)
    channel.start_consuming()
示例#4
0
def serialization_worker():
    connection = get_mq_connection()
    if not connection:
        return
    channel = connection.channel()
    channel.basic_qos(prefetch_count=1)
    channel.basic_consume(serialization_notifications_callback,
                          queue=SERIALIZE_QUEUE)
    channel.start_consuming()
示例#5
0
def serialization_notifications():
    """Set up bungeni serialization worker as a daemon.
    """
    mq_utility = zope.component.getUtility(IMessageQueueConfig)
    connection = get_mq_connection()
    if not connection:
        #delay
        delay = TIMER_DELAYS["serialize_setup"]
        if delay > MAX_DELAY:
            log.error(
                "Could not set up amqp workers - No rabbitmq "
                "connection found after %d seconds.", delay)
        else:
            log.info(
                "Attempting to setup serialization AMQP consumers "
                "in %d seconds", delay)
            timer = Timer(TIMER_DELAYS["serialize_setup"],
                          serialization_notifications)
            timer.daemon = True
            timer.start()
            TIMER_DELAYS["serialize_setup"] *= 2
        return
    channel = connection.channel()
    #create exchange
    channel.exchange_declare(exchange=SERIALIZE_EXCHANGE,
                             type="fanout",
                             durable=True)
    channel.queue_declare(queue=SERIALIZE_QUEUE, durable=True)
    channel.queue_bind(queue=SERIALIZE_QUEUE,
                       exchange=SERIALIZE_EXCHANGE,
                       routing_key=SERIALIZE_ROUTING_KEY)
    #xml outputs channel and queue
    channel.exchange_declare(exchange=SERIALIZE_OUTPUT_EXCHANGE,
                             type="direct",
                             passive=False)
    channel.queue_declare(queue=SERIALIZE_OUTPUT_QUEUE,
                          durable=True,
                          exclusive=False,
                          auto_delete=False)
    channel.queue_bind(queue=SERIALIZE_OUTPUT_QUEUE,
                       exchange=SERIALIZE_OUTPUT_EXCHANGE,
                       routing_key=SERIALIZE_OUTPUT_ROUTING_KEY)
    for i in range(mq_utility.get_number_of_workers()):
        init_thread()
def load_email():
    for type_key, ti in capi.iter_type_info():
        workflow = ti.workflow
        if workflow and workflow.has_feature("email"):
            if not workflow.has_feature("notification"):
                raise EmailError("Email notifications feature for %r cannot be "
                    "enabled without first enabling the notification "
                    "feature" % (type_key)) # !+FEATURE_DEPENDENCIES
    mq_utility = component.getUtility(IMessageQueueConfig)
    connection = get_mq_connection()
    if not connection:
        return
    channel = connection.channel()
    channel.queue_declare(queue="bungeni_email_queue", durable=True)
    channel.queue_bind(queue="bungeni_email_queue",
                       exchange=str(mq_utility.get_message_exchange()),
                       routing_key="")
    for i in range(mq_utility.get_number_of_workers()):
        task_thread = Thread(target=email_worker)
        task_thread.daemon = True
        task_thread.start()
示例#7
0
def serialization_notifications():
    """Set up bungeni serialization worker as a daemon.
    """
    mq_utility = zope.component.getUtility(IMessageQueueConfig)
    connection = get_mq_connection()
    if not connection:
        #delay
        delay = TIMER_DELAYS["serialize_setup"]
        if delay > MAX_DELAY:
            log.error("Could not set up amqp workers - No rabbitmq " 
            "connection found after %d seconds.", delay)
        else:
            log.info("Attempting to setup serialization AMQP consumers "
                "in %d seconds", delay
            )
            timer = Timer(TIMER_DELAYS["serialize_setup"],
                serialization_notifications
            )
            timer.daemon = True
            timer.start()
            TIMER_DELAYS["serialize_setup"] *= 2
        return
    channel = connection.channel()
    #create exchange
    channel.exchange_declare(exchange=SERIALIZE_EXCHANGE,
        type="fanout", durable=True)
    channel.queue_declare(queue=SERIALIZE_QUEUE, durable=True)
    channel.queue_bind(queue=SERIALIZE_QUEUE,
       exchange=SERIALIZE_EXCHANGE,
       routing_key=SERIALIZE_ROUTING_KEY)
    #xml outputs channel and queue
    channel.exchange_declare(exchange=SERIALIZE_OUTPUT_EXCHANGE,
        type="direct", passive=False)
    channel.queue_declare(queue=SERIALIZE_OUTPUT_QUEUE, 
        durable=True, exclusive=False, auto_delete=False)
    channel.queue_bind(queue=SERIALIZE_OUTPUT_QUEUE,
        exchange=SERIALIZE_OUTPUT_EXCHANGE,
        routing_key=SERIALIZE_OUTPUT_ROUTING_KEY)
    for i in range(mq_utility.get_number_of_workers()):
        init_thread()
示例#8
0
def load_email():
    for type_key, ti in capi.iter_type_info():
        workflow = ti.workflow
        if workflow and workflow.has_feature("email"):
            if not workflow.has_feature("notification"):
                raise EmailError(
                    "Email notifications feature for %r cannot be "
                    "enabled without first enabling the notification "
                    "feature" % (type_key))  # !+FEATURE_DEPENDENCIES
    mq_utility = component.getUtility(IMessageQueueConfig)
    connection = get_mq_connection()
    if not connection:
        return
    channel = connection.channel()
    channel.queue_declare(queue="bungeni_email_queue", durable=True)
    channel.queue_bind(queue="bungeni_email_queue",
                       exchange=str(mq_utility.get_message_exchange()),
                       routing_key="")
    for i in range(mq_utility.get_number_of_workers()):
        task_thread = Thread(target=email_worker)
        task_thread.daemon = True
        task_thread.start()
示例#9
0
def queue_object_serialization(obj):
    """Send a message to the serialization queue for non-draft documents
    """
    connection = get_mq_connection()
    if not connection:
        log.warn("Could not get rabbitmq connection. Will not send "
                 "AMQP message for this change.")
        log.warn("Publishing XML directly - this will slow things down")
        try:
            publish_to_xml(obj)
        except Exception, e:
            notify_serialization_failure(SERIALIZE_FAILURE_TEMPLATE,
                                         obj=obj,
                                         message="",
                                         error=e)
            notify_serialization_failure(
                None,
                body="Failed to find running RabbitMQ",
                subject="Notice - RabbitMQ")
        notify_serialization_failure(None,
                                     body="Failed to find running RabbitMQ",
                                     subject="Notice - RabbitMQ")
        return
示例#10
0
def queue_object_serialization(obj):
    """Send a message to the serialization queue for non-draft documents
    """
    connection = get_mq_connection()
    if not connection:
        log.warn("Could not get rabbitmq connection. Will not send "
            "AMQP message for this change."
        )
        log.warn("Publishing XML directly - this will slow things down")
        try:
            publish_to_xml(obj)
        except Exception, e:
            notify_serialization_failure(SERIALIZE_FAILURE_TEMPLATE,
                obj=obj, message="", error=e
            )
            notify_serialization_failure(None, 
                body="Failed to find running RabbitMQ",
                subject="Notice - RabbitMQ"
            )
        notify_serialization_failure(None, 
            body="Failed to find running RabbitMQ",
            subject="Notice - RabbitMQ"
        )
        return
示例#11
0
def publish_to_xml(context):
    """Generates XML for object and saves it to the file. If object contains
    attachments - XML is saved in zip archive with all attached files. 
    """

    #create a fake interaction to ensure items requiring a participation
    #are serialized 
    #!+SERIALIZATION(mb, Jan-2013) review this approach
    try:
        zope.security.management.getInteraction()
    except zope.security.interfaces.NoInteraction:
        principal = zope.security.testing.Principal('user', 'manager', ())
        zope.security.management.newInteraction(create_participation(principal))

    include = []
    # list of files to zip
    files = []
    # data dict to be published
    data = {}
    
    context = zope.security.proxy.removeSecurityProxy(context)
    
    if interfaces.IFeatureVersion.providedBy(context):
        include.append("versions")
    if interfaces.IFeatureAudit.providedBy(context):
        include.append("event")
    
    exclude = ["data", "event", "attachments", "changes"]
    
    # include binary fields and include them in the zip of files for this object
    for column in class_mapper(context.__class__).columns:
        if column.type.__class__ == Binary:
            exclude.append(column.key)
            content = getattr(context, column.key, None)
            if content:
                bfile = tmp(delete=False)
                bfile.write(content)
                files.append(bfile.name)
                data[column.key] = dict(
                    saved_file=os.path.basename(bfile.name)
                )
                bfile.close()
    data.update(
        obj2dict(context, 1, 
            parent=None,
            include=include,
            exclude=exclude
        )
    )
    obj_type = IWorkflow(context).name    
    tags = IStateController(context).get_state().tags
    if tags:
        data["tags"] = tags
    permissions = get_object_state_rpm(context).permissions
    data["permissions"] = get_permissions_dict(permissions)
    data["changes"] = []
    for change in getattr(context, "changes", []):
        change_dict = obj2dict(change, 0, parent=context)
        change_permissions = get_head_object_state_rpm(change).permissions
        change_dict["permissions"] = get_permissions_dict(change_permissions)
        data["changes"].append(change_dict)
    
    # setup path to save serialized data 
    path = os.path.join(setupStorageDirectory(), obj_type)
    if not os.path.exists(path):
        os.makedirs(path)
    
    # xml file path
    file_path = os.path.join(path, stringKey(context)) 
    
    if interfaces.IFeatureAttachment.providedBy(context):
        attachments = getattr(context, "attachments", None)
        if attachments:
            data["attachments"] = []
            for attachment in attachments:
                # serializing attachment
                attachment_dict = obj2dict(attachment, 1,
                    parent=context,
                    exclude=["data", "event", "versions"])
                permissions = get_object_state_rpm(attachment).permissions
                attachment_dict["permissions"] = \
                    get_permissions_dict(permissions)
                # saving attachment to tmp
                attached_file = tmp(delete=False)
                attached_file.write(attachment.data)
                attached_file.flush()
                attached_file.close()
                files.append(attached_file.name)
                attachment_dict["saved_file"] = os.path.basename(
                    attached_file.name
                )
                data["attachments"].append(attachment_dict)

    
    # zipping xml, attached files plus any binary fields
    # also remove the temporary files
    if files:
        #generate temporary xml file
        temp_xml = tmp(delete=False)
        temp_xml.write(serialize(data, name=obj_type))
        temp_xml.close()
        #write attachments/binary fields to zip
        zip_file = ZipFile("%s.zip" % (file_path), "w")
        for f in files:
            zip_file.write(f, os.path.basename(f))
            os.remove(f)
        #write the xml
        zip_file.write(temp_xml.name, "%s.xml" % os.path.basename(file_path))
        zip_file.close()
        #placed remove after zip_file.close !+ZIP_FILE_CRC_FAILURE
        os.remove(temp_xml.name) 

    else:
        # save serialized xml to file
        with open("%s.xml" % (file_path), "w") as xml_file:
            xml_file.write(serialize(data, name=obj_type))
            xml_file.close()

    #publish to rabbitmq outputs queue
    connection = get_mq_connection()
    if not connection:
        return
    channel = connection.channel()
    publish_file_path = "%s.%s" %(file_path, ("zip" if files else "xml"))
    channel.basic_publish(
        exchange=SERIALIZE_OUTPUT_EXCHANGE,
        routing_key=SERIALIZE_OUTPUT_ROUTING_KEY,
        body=simplejson.dumps({"type": "file", "location": publish_file_path }),
        properties=pika.BasicProperties(content_type="text/plain",
            delivery_mode=2
        )
    )
    
    #clean up - remove any files if zip was created
    if files:
        prev_xml_file = "%s.%s" %(file_path, "xml")
        if os.path.exists(prev_xml_file):
            os.remove(prev_xml_file)
示例#12
0
def publish_to_xml(context):
    """Generates XML for object and saves it to the file. If object contains
    attachments - XML is saved in zip archive with all attached files. 
    """

    #create a fake interaction to ensure items requiring a participation
    #are serialized
    #!+SERIALIZATION(mb, Jan-2013) review this approach
    try:
        zope.security.management.getInteraction()
    except zope.security.interfaces.NoInteraction:
        principal = zope.security.testing.Principal('user', 'manager', ())
        zope.security.management.newInteraction(
            create_participation(principal))

    include = []
    # list of files to zip
    files = []
    # data dict to be published
    data = {}

    context = zope.security.proxy.removeSecurityProxy(context)

    if interfaces.IFeatureVersion.providedBy(context):
        include.append("versions")
    if interfaces.IFeatureAudit.providedBy(context):
        include.append("event")

    exclude = ["data", "event", "attachments", "changes"]

    # include binary fields and include them in the zip of files for this object
    for column in class_mapper(context.__class__).columns:
        if column.type.__class__ == Binary:
            exclude.append(column.key)
            content = getattr(context, column.key, None)
            if content:
                bfile = tmp(delete=False)
                bfile.write(content)
                files.append(bfile.name)
                data[column.key] = dict(
                    saved_file=os.path.basename(bfile.name))
                bfile.close()
    data.update(
        obj2dict(context, 1, parent=None, include=include, exclude=exclude))
    obj_type = IWorkflow(context).name
    tags = IStateController(context).get_state().tags
    if tags:
        data["tags"] = tags
    permissions = get_object_state_rpm(context).permissions
    data["permissions"] = get_permissions_dict(permissions)
    data["changes"] = []
    for change in getattr(context, "changes", []):
        change_dict = obj2dict(change, 0, parent=context)
        change_permissions = get_head_object_state_rpm(change).permissions
        change_dict["permissions"] = get_permissions_dict(change_permissions)
        data["changes"].append(change_dict)

    # setup path to save serialized data
    path = os.path.join(setupStorageDirectory(), obj_type)
    if not os.path.exists(path):
        os.makedirs(path)

    # xml file path
    file_path = os.path.join(path, stringKey(context))

    if interfaces.IFeatureAttachment.providedBy(context):
        attachments = getattr(context, "attachments", None)
        if attachments:
            data["attachments"] = []
            for attachment in attachments:
                # serializing attachment
                attachment_dict = obj2dict(
                    attachment,
                    1,
                    parent=context,
                    exclude=["data", "event", "versions"])
                permissions = get_object_state_rpm(attachment).permissions
                attachment_dict["permissions"] = \
                    get_permissions_dict(permissions)
                # saving attachment to tmp
                attached_file = tmp(delete=False)
                attached_file.write(attachment.data)
                attached_file.flush()
                attached_file.close()
                files.append(attached_file.name)
                attachment_dict["saved_file"] = os.path.basename(
                    attached_file.name)
                data["attachments"].append(attachment_dict)

    # zipping xml, attached files plus any binary fields
    # also remove the temporary files
    if files:
        #generate temporary xml file
        temp_xml = tmp(delete=False)
        temp_xml.write(serialize(data, name=obj_type))
        temp_xml.close()
        #write attachments/binary fields to zip
        zip_file = ZipFile("%s.zip" % (file_path), "w")
        for f in files:
            zip_file.write(f, os.path.basename(f))
            os.remove(f)
        #write the xml
        zip_file.write(temp_xml.name, "%s.xml" % os.path.basename(file_path))
        zip_file.close()
        #placed remove after zip_file.close !+ZIP_FILE_CRC_FAILURE
        os.remove(temp_xml.name)

    else:
        # save serialized xml to file
        with open("%s.xml" % (file_path), "w") as xml_file:
            xml_file.write(serialize(data, name=obj_type))
            xml_file.close()

    #publish to rabbitmq outputs queue
    connection = get_mq_connection()
    if not connection:
        return
    channel = connection.channel()
    publish_file_path = "%s.%s" % (file_path, ("zip" if files else "xml"))
    channel.basic_publish(exchange=SERIALIZE_OUTPUT_EXCHANGE,
                          routing_key=SERIALIZE_OUTPUT_ROUTING_KEY,
                          body=simplejson.dumps({
                              "type": "file",
                              "location": publish_file_path
                          }),
                          properties=pika.BasicProperties(
                              content_type="text/plain", delivery_mode=2))

    #clean up - remove any files if zip was created
    if files:
        prev_xml_file = "%s.%s" % (file_path, "xml")
        if os.path.exists(prev_xml_file):
            os.remove(prev_xml_file)