Example #1
0
class NotificationBase(NotificationObject):
    """Base class for versioned notifications.

    Every subclass shall define a 'payload' field.
    """
    # Version 1.0: Initial version
    VERSION = '1.0'

    fields = {
        'priority': fields.EventNotificationPriorityField(),
        'event_type': fields.ObjectField('EventType'),
        'publisher': fields.ObjectField('NotificationPublisher'),
    }

    def _emit(self, context, event_type, publisher_id, payload):
        notifier = rpc.get_versioned_notifier(publisher_id)
        notify = getattr(notifier, self.priority)
        notify(context, event_type=event_type, payload=payload)

    def emit(self, context):
        """Send the notification."""
        assert self.payload.populated

        # notification payload will be a newly populated object
        # therefore every field of it will look changed so this does not carry
        # any extra information so we drop this from the payload.
        self.payload.obj_reset_changes(recursive=False)

        self._emit(context,
            event_type=self.event_type.to_notification_event_type_field(),
            publisher_id='%s:%s' %
                         (self.publisher.binary,
                          self.publisher.host),
            payload=self.payload.obj_to_primitive())
Example #2
0
class HostApiPayloadBase(base.NotificationPayloadBase):
    SCHEMA = {
        'id': ('host', 'id'),
        'uuid': ('host', 'uuid'),
        'name': ('host', 'name'),
        'failover_segment_id': ('host', 'failover_segment_id'),
        'failover_segment': ('host', 'failover_segment'),
        'type': ('host', 'type'),
        'reserved': ('host', 'reserved'),
        'control_attributes': ('host', 'control_attributes'),
        'on_maintenance': ('host', 'on_maintenance'),
    }
    # Version 1.0: Initial version
    VERSION = '1.0'
    fields = {
        'id': fields.IntegerField(),
        'uuid': fields.UUIDField(),
        'name': fields.StringField(),
        'failover_segment_id': fields.UUIDField(),
        'failover_segment': fields.ObjectField('FailoverSegment'),
        'type': fields.StringField(),
        'reserved': fields.BooleanField(),
        'control_attributes': fields.StringField(),
        'on_maintenance': fields.BooleanField(),
    }

    def __init__(self, host, **kwargs):
        super(HostApiPayloadBase, self).__init__(**kwargs)
        self.populate_schema(host=host)
Example #3
0
class HostApiPayload(HostApiPayloadBase):
    # No SCHEMA as all the additional fields are calculated

    VERSION = '1.0'
    fields = {
        'fault': fields.ObjectField('ExceptionPayload', nullable=True),
    }

    def __init__(self, host, fault, **kwargs):
        super(HostApiPayload, self).__init__(host=host, fault=fault, **kwargs)
Example #4
0
class NotificationApiPayload(NotificationApiPayloadBase):
    # No SCHEMA as all the additional fields are calculated

    VERSION = '1.0'
    fields = {
        'fault': fields.ObjectField('ExceptionPayload', nullable=True),
    }

    def __init__(self, notification, fault, **kwargs):
        super(NotificationApiPayload, self).__init__(notification=notification,
                                                     fault=fault,
                                                     **kwargs)
Example #5
0
class Host(base.MasakariPersistentObject, base.MasakariObject,
           base.MasakariObjectDictCompat):

    # Version 1.0: Initial version
    # Version 1.1: Added 'segment_uuid' parameter to 'get_by_uuid' method
    VERSION = '1.1'

    fields = {
        'id': fields.IntegerField(),
        'uuid': fields.UUIDField(),
        'name': fields.StringField(),
        'failover_segment_id': fields.UUIDField(),
        'failover_segment': fields.ObjectField('FailoverSegment'),
        'type': fields.StringField(),
        'reserved': fields.BooleanField(),
        'control_attributes': fields.StringField(),
        'on_maintenance': fields.BooleanField(),
    }

    @staticmethod
    def _from_db_object(context, host, db_host):

        for key in host.fields:
            db_value = db_host.get(key)
            if key == "failover_segment":
                db_value = objects.FailoverSegment._from_db_object(
                    host._context, objects.FailoverSegment(), db_value)

            setattr(host, key, db_value)

        host.obj_reset_changes()
        host._context = context
        return host

    @base.remotable_classmethod
    def get_by_id(cls, context, id):
        db_inst = db.host_get_by_id(context, id)
        return cls._from_db_object(context, cls(), db_inst)

    @base.remotable_classmethod
    def get_by_uuid(cls, context, uuid, segment_uuid=None):
        db_inst = db.host_get_by_uuid(context, uuid, segment_uuid=segment_uuid)
        return cls._from_db_object(context, cls(), db_inst)

    @base.remotable_classmethod
    def get_by_name(cls, context, name):
        db_inst = db.host_get_by_name(context, name)
        return cls._from_db_object(context, cls(), db_inst)

    @base.remotable
    def create(self):
        if self.obj_attr_is_set('id'):
            raise exception.ObjectActionError(action='create',
                                              reason='already created')
        updates = self.masakari_obj_get_changes()

        if 'uuid' not in updates:
            updates['uuid'] = uuidutils.generate_uuid()
            LOG.debug('Generated uuid %(uuid)s for host',
                      dict(uuid=updates['uuid']))

        if 'failover_segment' in updates:
            raise exception.ObjectActionError(action='create',
                                              reason='failover segment '
                                              'assigned')

        api_utils.notify_about_host_api(
            self._context,
            self,
            action=fields.EventNotificationAction.HOST_CREATE,
            phase=fields.EventNotificationPhase.START)

        db_host = db.host_create(self._context, updates)

        api_utils.notify_about_host_api(
            self._context,
            self,
            action=fields.EventNotificationAction.HOST_CREATE,
            phase=fields.EventNotificationPhase.END)

        self._from_db_object(self._context, self, db_host)

    @base.remotable
    def save(self):
        updates = self.masakari_obj_get_changes()
        if 'failover_segment' in updates:
            raise exception.ObjectActionError(action='save',
                                              reason='failover segment '
                                              'changed')
        updates.pop('id', None)

        api_utils.notify_about_host_api(
            self._context,
            self,
            action=fields.EventNotificationAction.HOST_UPDATE,
            phase=fields.EventNotificationPhase.START)

        db_host = db.host_update(self._context, self.uuid, updates)

        api_utils.notify_about_host_api(
            self._context,
            self,
            action=fields.EventNotificationAction.HOST_UPDATE,
            phase=fields.EventNotificationPhase.END)

        self._from_db_object(self._context, self, db_host)

    @base.remotable
    def destroy(self):
        if not self.obj_attr_is_set('id'):
            raise exception.ObjectActionError(action='destroy',
                                              reason='already destroyed')
        if not self.obj_attr_is_set('uuid'):
            raise exception.ObjectActionError(action='destroy',
                                              reason='no uuid')

        api_utils.notify_about_host_api(
            self._context,
            self,
            action=fields.EventNotificationAction.HOST_DELETE,
            phase=fields.EventNotificationPhase.START)

        db.host_delete(self._context, self.uuid)

        api_utils.notify_about_host_api(
            self._context,
            self,
            action=fields.EventNotificationAction.HOST_DELETE,
            phase=fields.EventNotificationPhase.END)

        delattr(self, base.get_attrname('id'))
Example #6
0
class NotificationApiNotification(base.NotificationBase):
    # Version 1.0: Initial version
    VERSION = '1.0'

    fields = {'payload': fields.ObjectField('NotificationApiPayload')}
Example #7
0
 class MyOwner(base.MasakariObject):
     VERSION = '1.2'
     fields = {'mylist': fields.ObjectField('MyList')}
     obj_relationships = {
         'mylist': [('1.1', '1.1')],
     }
Example #8
0
 class ParentObject(base.MasakariObject):
     fields = {
         'foo': fields.IntegerField(),
         'bar': fields.ObjectField('MyObj'),
     }
Example #9
0
class MyObj(base.MasakariPersistentObject, base.MasakariObject,
            base.MasakariObjectDictCompat):
    VERSION = '1.6'
    fields = {
        'foo': fields.IntegerField(default=1),
        'bar': fields.StringField(),
        'missing': fields.StringField(),
        'readonly': fields.IntegerField(read_only=True),
        'rel_object': fields.ObjectField('MyOwnedObject', nullable=True),
        'rel_objects': fields.ListOfObjectsField('MyOwnedObject',
                                                 nullable=True),
        'mutable_default': fields.ListOfStringsField(default=[]),
    }

    @staticmethod
    def _from_db_object(context, obj, db_obj):
        self = MyObj()
        self.foo = db_obj['foo']
        self.bar = db_obj['bar']
        self.missing = db_obj['missing']
        self.readonly = 1
        self._context = context
        return self

    def obj_load_attr(self, attrname):
        setattr(self, attrname, 'loaded!')

    @base.remotable_classmethod
    def query(cls, context):
        obj = cls(context=context, foo=1, bar='bar')
        obj.obj_reset_changes()
        return obj

    @base.remotable
    def marco(self):
        return 'polo'

    @base.remotable
    def _update_test(self):
        self.bar = 'updated'

    @base.remotable
    def save(self):
        self.obj_reset_changes()

    @base.remotable
    def refresh(self):
        self.foo = 321
        self.bar = 'refreshed'
        self.obj_reset_changes()

    @base.remotable
    def modify_save_modify(self):
        self.bar = 'meow'
        self.save()
        self.foo = 42
        self.rel_object = MyOwnedObject(baz=42)

    def obj_make_compatible(self, primitive, target_version):
        super(MyObj, self).obj_make_compatible(primitive, target_version)
        if target_version == '1.0' and 'bar' in primitive:
            primitive['bar'] = 'old%s' % primitive['bar']
Example #10
0
 class TestNotificationEmptySchema(notification.NotificationBase):
     VERSION = '1.0'
     fields = {
         'payload': fields.ObjectField('TestNotificationPayloadEmptySchema')
     }
Example #11
0
class ExceptionNotification(base.NotificationBase):
    # Version 1.0: Initial version
    VERSION = '1.0'
    fields = {
        'payload': fields.ObjectField('ExceptionPayload')
    }