liusheng / liusheng.github.io

Liusheng's blog
http://liusheng.github.io
5 stars 1 forks source link

Versioned notification 介绍 #10

Open liusheng opened 5 years ago

liusheng commented 5 years ago
  1. versioned notification 本质上是versioned object的一个延伸。

  2. 一个versioned notification对象包括几个重要元素:

    • priority 包括:INFO,ERROR,枚举对象类型;
    • event_type 通常是个三段式:object.action.phase,对象定义包含这三个字段;
    • publisher_id 标识消息的发送者,通常格式:host:binary,对象定义包含这俩字段;
    • payload 消息载体,包含了发送消息实体的各个属性,根据需要定义字段;
    • 其他字段,例如message_id,_context_user,_context_tenant等,由oslo.message自动封装,在实现versioned notification时无需关注。

    注: priorty, event_type, publisher_id, payload在定义的时候也继承于各项目versioned object的基类,故本质上他们也是versioned object。

  3. notification_samples, 是项目文档目录中定义的一组json格式的notification消息样例,如下面的Nova删除虚拟机的样例,与api_samples类似。

  4. 消息载体pyaload,与versioned object中对应的资源定义类似,例如instance object的定义。包含了instance的各个属性定义(字段类型,是否允许空值)。准确的来说,其中每一个字段都是对象类型的定义,只不过有些字段是一些简单类型,例如string类型,int类型,有一些字段需要根据需要自己定义类型,如下面json样例中嵌套的flavor定义,flavor本身也是一个object的定义。 payload的定义中,除了对象自身的属性字段的定义,还需包括以下几个重要字段(见附1):

    • namesapces 定义了对象所属的范畴,例如nova_object,mogan_object
    • name 定义了对象类的名称,如InstanceActionPayload
    • version 版本号,具体的版本号锁定了该消息载体格式的唯一,需要和json样例中保持一致,且在UT中需要有唯一的hash值来保证版本的唯一性。
  5. versioned_notifications作为消息队列的topic,和老的unversioned notification不同,这里使用了一个新的topic的消息队列,也就是通常会有versioned_notifications.info 和versioned_notifications.error两个消息队列。

附1: 代码示例:

    @notification.notification_sample('myobject-update.json')
    @object_base.NovaObjectRegistry.register.register_notification
    class MyObjectNotification(notification.NotificationBase):
        # Version 1.0: Initial version
        VERSION = '1.0'

        fields = {
            'payload': fields.ObjectField('MyObjectUpdatePayload')
        }

    @object_base.NovaObjectRegistry.register.register_notification
    class MyObjectUpdatePayload(notification.NotificationPayloadBase):
        # Version 1.0: Initial version
        VERSION = '1.0'
        fields = {
            'some_data': fields.StringField(),
            'another_data': fields.StringField(),
        }

附2: Nova删除虚拟机完成实例

    {
    "event_type":"instance.delete.end",
    "payload":{
        "nova_object.data":{
            "architecture":"x86_64",
            "availability_zone":null,
            "created_at":"2012-10-29T13:42:11Z",
            "deleted_at":"2012-10-29T13:42:11Z",
            "display_name":"some-server",
            "display_description":"some-server",
            "fault":null,
            "host":"compute",
            "host_name":"some-server",
            "ip_addresses":[],
            "kernel_id":"",
            "launched_at":"2012-10-29T13:42:11Z",
            "image_uuid": "155d900f-4e14-4e4c-a73d-069cbf4541e6",
            "metadata":{},
            "locked":false,
            "node":"fake-mini",
            "os_type":null,
            "progress":0,
            "ramdisk_id":"",
            "reservation_id":"r-npxv0e40",
            "state":"deleted",
            "task_state":null,
            "power_state":"pending",
            "tenant_id":"6f70656e737461636b20342065766572",
            "terminated_at":"2012-10-29T13:42:11Z",
            "flavor": {
                "nova_object.name": "FlavorPayload",
                "nova_object.data": {
                    "flavorid": "a22d5517-147c-4147-a0d1-e698df5cd4e3",
                    "root_gb": 1,
                    "vcpus": 1,
                    "ephemeral_gb": 0,
                    "memory_mb": 512
                },
                "nova_object.version": "1.0",
                "nova_object.namespace": "nova"
            },
            "user_id":"fake",
            "uuid":"178b0921-8f85-4257-88b6-2e743b5a975c"
        },
        "nova_object.name":"InstanceActionPayload",
        "nova_object.namespace":"nova",
        "nova_object.version":"1.1"
    },
    "priority":"INFO",
    "publisher_id":"nova-compute:compute"
    }