=============
Notifications
=============

Like many other OpenStack services, nova emits notifications to the message
bus with the ``Notifier`` class provided by :oslo.messaging-doc:`oslo.messaging
<reference/notifier.html>`. From the notification consumer point of view, a
notification consists of two parts: an envelope with a fixed structure defined
by oslo.messaging and a payload defined by the service emitting the
notification. The envelope format is the following::

    {
        "priority": <string, selected from a predefined list by the sender>,
        "event_type": <string, defined by the sender>,
        "timestamp": <string, the isotime of when the notification emitted>,
        "publisher_id": <string, defined by the sender>,
        "message_id": <uuid, generated by oslo>,
        "payload": <json serialized dict, defined by the sender>
    }

There are two types of notifications in nova: legacy notifications which have
an unversioned payload and newer notifications which have a versioned payload.


Legacy (unversioned) notifications
----------------------------------

The unversioned notifications exist from the early days of nova and have mostly
grown organically. The structure of the payload of the unversioned
notifications is defined in the code that emits the notification and no
documentation or enforced backward compatibility contract exists for that
format.

Nova code uses the ``nova.rpc.get_notifier`` call to get a configured
oslo.messaging ``Notifier`` object and it uses the oslo-provided functions on
the ``Notifier`` object to emit notifications. The configuration of the
returned ``Notifier`` object depends on the parameters of the ``get_notifier``
call and the value of the oslo.messaging configuration options
:oslo.config:option:`oslo_messaging_notifications.driver` and
:oslo.config:option:`oslo_messaging_notifications.topics`.


Versioned notifications
-----------------------

The versioned notification concept was created to fix the shortcomings of the
unversioned notifications. The envelope structure of the emitted notification
is the same as in the unversioned notification case as it is provided by
oslo.messaging. However, the payload is not a free-form dictionary but a
serialized :oslo.versionedobjects-doc:`oslo versionedobjects object <>`.

.. _service.update:

For example the wire format of the ``service.update`` notification looks like
the following::

    {
        "priority": "INFO",
        "payload": {
            "nova_object.namespace": "nova",
            "nova_object.name": "ServiceStatusPayload",
            "nova_object.version": "1.0",
            "nova_object.data": {
                "host": "host1",
                "disabled": false,
                "last_seen_up": null,
                "binary": "nova-compute",
                "topic": "compute",
                "disabled_reason": null,
                "report_count": 1,
                "forced_down": false,
                "version": 2
            }
        },
        "event_type": "service.update",
        "publisher_id": "nova-compute:host1"
    }

The serialized oslo.versionedobject as a payload provides a version number to
the consumer so the consumer can detect if the structure of the payload has
changed. Nova provides the following contract regarding the versioned
notification payload:

* The payload version defined by the ``nova_object.version`` field of the
  payload will be increased if and only if the syntax or the semantics of the
  ``nova_object.data`` field of the payload is changed.

* A minor version bump indicates a backward compatible change which means that
  only new fields are added to the payload so a well written consumer can still
  consume the new payload without any change.

* A major version bump indicates a backward incompatible change of the payload
  which can mean removed fields, type change, etc in the payload.

* There is an additional field, ``nova_object.name``, for every payload
  alongside the ``nova_object.data`` and ``nova_object.version`` fields. This
  field contains the name of the nova internal representation of the payload
  type. Client code should not depend on this name.

A `presentation from the Train summit`__ goes over the background and usage of
versioned notifications, and provides a demo.

.. __: https://www.openstack.org/videos/summits/denver-2019/nova-versioned-notifications-the-result-of-a-3-year-journey


Configuration
-------------

The :oslo.config:option:`notifications.notification_format` config option can
be used to specify which notifications are emitted by nova.

The versioned notifications are emitted to a different topic than the legacy
notifications. By default they are emitted to ``versioned_notifications`` but
this can be configured using the
:oslo.config:option:`notifications.versioned_notifications_topics` config
option.

There are notification configuration options in nova which are specific for
certain notification types like
:oslo.config:option:`notifications.notify_on_state_change`,
:oslo.config:option:`notifications.default_level`, etc.

Notifications can be disabled entirely by setting the
:oslo.config:option:`oslo_messaging_notifications.driver` config option to
``noop``.


Reference
---------

A list of all currently supported versioned notifications can be found in
:doc:`/reference/notifications`.
