Skip to content

Commit

Permalink
messaging: Provide metadata for messages
Browse files Browse the repository at this point in the history
This patch introduces the necessities to provide message metadata.

The meta data can be useful to identify the time, phase, actor, topic
or hostname.

Example usage from an actor:
----------------------------
```
from leapp.libraries.stdlib import api
from leapp.models import MyModel

def needs_metadata():
    for model in api.consume(MyModel):
        md = model.message_metadata()
        if md and md.phase == 'facts':
            api.current_logger().info('Facts phase run at %s', md.timestamp)
```

Signed-off-by: Vinzenz Feenstra <[email protected]>
  • Loading branch information
vinzenz committed May 3, 2019
1 parent f766a84 commit de2291b
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 4 deletions.
2 changes: 1 addition & 1 deletion leapp/messaging/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,4 +189,4 @@ def consume(self, actor, *types):
if types:
filtered = set(requested.__name__ for requested in types)
messages = [message for message in messages if message['type'] in filtered]
return (lookup[message['type']].create(json.loads(message['message']['data'])) for message in messages)
return (lookup[msg['type']].create(msg, json.loads(msg['message']['data'])) for msg in messages)
51 changes: 48 additions & 3 deletions leapp/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,50 @@ def __init__(cls, name, bases, attrs):
super(ModelMeta, cls).__init__(name, bases, attrs)


class MetaData(object):
def __init__(self, data):
self._data = data

@property
def row_id(self):
""" Returns the row id of the message in the message table. """
return self._data.get('id')

@property
def actor(self):
""" Returns the name of the actor that has sent this message. """
return self._data.get('actor')

@property
def phase(self):
""" Returns the name of the phase in which this message has been sent. """
return self._data.get('phase')

@property
def timestamp(self):
""" Returns the timestamp string in ISO formst from when this message has been sent. """
return self._data.get('stamp')

@property
def topic(self):
""" Returns the name of the topic of this message. """
return self._data.get('topic')

@property
def hostname(self):
""" Returns the name of the host (FQDN) from where this message originates. """
return self._data.get('hostname')


class Model(with_metaclass(ModelMeta)):
"""
Model is a base class for all models.
Models are defining the data structure of the payload of messages and the
metadata required, such as a name and topic.
"""
def __init__(self, init_method='from_initialization', **kwargs):
def __init__(self, metadata=None, init_method='from_initialization', **kwargs):
self._metadata = metadata
super(Model, self).__init__()
defined_fields = type(self).fields
for key in kwargs.keys():
Expand All @@ -101,16 +137,25 @@ def __init__(self, init_method='from_initialization', **kwargs):
Note: Dynamically added fields are ignored by the framework.
"""

def message_metadata(self):
"""
Provides the message meta data of a message.
:returns: An instance of :py:class:`leapp.models.MetaData` or None
:rtype: :py:class:`leapp.models.MetaData` or `NoneType`
"""
return self._metadata

@classmethod
def create(cls, data):
def create(cls, metadata, data):
"""
Create an instance of this class and use the data to initialize the fields within.
:param data: Data to initialize the Model from deserialized data
:type data: dict
:return: Instance of this class
"""
return cls(init_method='to_model', **data)
return cls(metadata=MetaData(metadata), init_method='to_model', **data)

def dump(self):
"""
Expand Down

0 comments on commit de2291b

Please sign in to comment.