)]}'
{"nova/objects/fields.py":[{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"4cc49c12d60c56b6f6b16450f4104243615ef985","unresolved":false,"context_lines":[{"line_number":442,"context_line":"            valid_values\u003dNotificationPriorityType.ALL)"},{"line_number":443,"context_line":""},{"line_number":444,"context_line":""},{"line_number":445,"context_line":"class NotificationEventTypePhaseType(Enum):"},{"line_number":446,"context_line":"    START \u003d \u0027start\u0027"},{"line_number":447,"context_line":"    END \u003d \u0027end\u0027"},{"line_number":448,"context_line":"    ERROR \u003d \u0027error\u0027"}],"source_content_type":"text/x-python","patch_set":4,"id":"ba8a016a_55717adf","line":445,"updated":"2015-11-20 22:38:18.000000000","message":"Nit: Both this and the following class can be named better by removing the redundant \u0027Type\u0027 from the name:\n\n\u0027NotificationEventTypePhaseType\u0027 -\u003e \u0027NotificationEventTypePhase\u0027\n\n\u0027NotificationEventTypeActionType\u0027 -\u003e \u0027NotificationEventTypeAction\u0027","commit_id":"8048f0c2a08787b00d8914340865892079a1b40b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"25c4c77405968360941fbf9d17b8870329bcf04d","unresolved":false,"context_lines":[{"line_number":442,"context_line":"            valid_values\u003dNotificationPriorityType.ALL)"},{"line_number":443,"context_line":""},{"line_number":444,"context_line":""},{"line_number":445,"context_line":"class NotificationEventTypePhaseType(Enum):"},{"line_number":446,"context_line":"    START \u003d \u0027start\u0027"},{"line_number":447,"context_line":"    END \u003d \u0027end\u0027"},{"line_number":448,"context_line":"    ERROR \u003d \u0027error\u0027"}],"source_content_type":"text/x-python","patch_set":4,"id":"ba8a016a_241a7c6f","line":445,"in_reply_to":"ba8a016a_55717adf","updated":"2015-11-21 21:23:34.000000000","message":"Good point. I also removed Type from the NotificationPriorityType for consistency.","commit_id":"8048f0c2a08787b00d8914340865892079a1b40b"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"05447e58cf3dd71c08761af5602097b9b52a0f92","unresolved":false,"context_lines":[{"line_number":442,"context_line":"            valid_values\u003dNotificationPriority.ALL)"},{"line_number":443,"context_line":""},{"line_number":444,"context_line":""},{"line_number":445,"context_line":"class NotificationEventTypePhase(Enum):"},{"line_number":446,"context_line":"    START \u003d \u0027start\u0027"},{"line_number":447,"context_line":"    END \u003d \u0027end\u0027"},{"line_number":448,"context_line":"    ERROR \u003d \u0027error\u0027"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_14be62ff","line":445,"updated":"2015-11-23 15:56:14.000000000","message":"It might just be a case of the Mondays, but while we\u0027re on the topic of naming: shouldn\u0027t this just be NotificationPhase?","commit_id":"82e243dcd6f68046cfa6b94b73469f542432418b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"4a84191ff5d3613c46c862202e174891013df365","unresolved":false,"context_lines":[{"line_number":442,"context_line":"            valid_values\u003dNotificationPriority.ALL)"},{"line_number":443,"context_line":""},{"line_number":444,"context_line":""},{"line_number":445,"context_line":"class NotificationEventTypePhase(Enum):"},{"line_number":446,"context_line":"    START \u003d \u0027start\u0027"},{"line_number":447,"context_line":"    END \u003d \u0027end\u0027"},{"line_number":448,"context_line":"    ERROR \u003d \u0027error\u0027"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a8ffd7b_f6e1a4ff","line":445,"in_reply_to":"ba8a016a_14be62ff","updated":"2015-11-24 17:06:24.000000000","message":"Done","commit_id":"82e243dcd6f68046cfa6b94b73469f542432418b"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"05447e58cf3dd71c08761af5602097b9b52a0f92","unresolved":false,"context_lines":[{"line_number":454,"context_line":"            valid_values\u003dNotificationEventTypePhase.ALL)"},{"line_number":455,"context_line":""},{"line_number":456,"context_line":""},{"line_number":457,"context_line":"class NotificationEventTypeAction(Enum):"},{"line_number":458,"context_line":"    UPDATE \u003d \u0027update\u0027"},{"line_number":459,"context_line":""},{"line_number":460,"context_line":"    ALL \u003d (UPDATE,)"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_9457b2c9","line":457,"updated":"2015-11-23 15:56:14.000000000","message":"and this just be NotificationAction?","commit_id":"82e243dcd6f68046cfa6b94b73469f542432418b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"4a84191ff5d3613c46c862202e174891013df365","unresolved":false,"context_lines":[{"line_number":454,"context_line":"            valid_values\u003dNotificationEventTypePhase.ALL)"},{"line_number":455,"context_line":""},{"line_number":456,"context_line":""},{"line_number":457,"context_line":"class NotificationEventTypeAction(Enum):"},{"line_number":458,"context_line":"    UPDATE \u003d \u0027update\u0027"},{"line_number":459,"context_line":""},{"line_number":460,"context_line":"    ALL \u003d (UPDATE,)"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a8ffd7b_36d88c53","line":457,"in_reply_to":"ba8a016a_9457b2c9","updated":"2015-11-24 17:06:24.000000000","message":"Done","commit_id":"82e243dcd6f68046cfa6b94b73469f542432418b"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"1d3886da2cec16901f26a335df888f8ad3834405","unresolved":false,"context_lines":[{"line_number":457,"context_line":"class NotificationEventTypeAction(Enum):"},{"line_number":458,"context_line":"    UPDATE \u003d \u0027update\u0027"},{"line_number":459,"context_line":""},{"line_number":460,"context_line":"    ALL \u003d (UPDATE,)"},{"line_number":461,"context_line":""},{"line_number":462,"context_line":"    def __init__(self):"},{"line_number":463,"context_line":"        super(NotificationEventTypeAction, self).__init__("}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_55b60f8b","line":460,"updated":"2015-11-23 21:13:55.000000000","message":"As a hypothetical here, what happens if we need to add a new action? Won\u0027t things start freaking out on the field\u0027s valid values check if an older compute doesn\u0027t know about the action yet, because it still has an older version of the enum?","commit_id":"82e243dcd6f68046cfa6b94b73469f542432418b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"4a84191ff5d3613c46c862202e174891013df365","unresolved":false,"context_lines":[{"line_number":457,"context_line":"class NotificationEventTypeAction(Enum):"},{"line_number":458,"context_line":"    UPDATE \u003d \u0027update\u0027"},{"line_number":459,"context_line":""},{"line_number":460,"context_line":"    ALL \u003d (UPDATE,)"},{"line_number":461,"context_line":""},{"line_number":462,"context_line":"    def __init__(self):"},{"line_number":463,"context_line":"        super(NotificationEventTypeAction, self).__init__("}],"source_content_type":"text/x-python","patch_set":5,"id":"9a8ffd7b_7617f4ed","line":460,"in_reply_to":"ba8a016a_55b60f8b","updated":"2015-11-24 17:06:24.000000000","message":"This enum is used in the event_type field of the notification envelop defined by oslo.messaging see https://github.com/openstack/oslo.messaging/blob/master/oslo_messaging/notify/notifier.py#L105 so this is not part of the versioned payload.","commit_id":"82e243dcd6f68046cfa6b94b73469f542432418b"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"89169d8e5989101d6eab346401b4e101eb447b1a","unresolved":false,"context_lines":[{"line_number":438,"context_line":"            valid_values\u003dPciDeviceType.ALL)"},{"line_number":439,"context_line":""},{"line_number":440,"context_line":""},{"line_number":441,"context_line":"class NotificationPriority(Enum):"},{"line_number":442,"context_line":"    AUDIT \u003d \u0027audit\u0027"},{"line_number":443,"context_line":"    CRITICAL \u003d \u0027critical\u0027"},{"line_number":444,"context_line":"    DEBUG \u003d \u0027debug\u0027"}],"source_content_type":"text/x-python","patch_set":22,"id":"fa69d971_55d140fa","line":441,"updated":"2016-01-08 11:40:02.000000000","message":"I am wondering if we actually want a separate set of objects for the notifications, maybe under nova/notification_objects/fields or nova/objects/notifications/... or similar.\n\nBut this is simple, lets go with this for now, given the use of the service object.","commit_id":"3c8ca003b3c992ef93521b4b1d18765b820d7cb8"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e6b9de6f562b11cf6d4c6e2c9af7ac355d870287","unresolved":false,"context_lines":[{"line_number":438,"context_line":"            valid_values\u003dPciDeviceType.ALL)"},{"line_number":439,"context_line":""},{"line_number":440,"context_line":""},{"line_number":441,"context_line":"class NotificationPriority(Enum):"},{"line_number":442,"context_line":"    AUDIT \u003d \u0027audit\u0027"},{"line_number":443,"context_line":"    CRITICAL \u003d \u0027critical\u0027"},{"line_number":444,"context_line":"    DEBUG \u003d \u0027debug\u0027"}],"source_content_type":"text/x-python","patch_set":22,"id":"fa69d971_55fe0f6c","line":441,"in_reply_to":"fa69d971_55d140fa","updated":"2016-01-09 12:38:58.000000000","message":"I feel that it is a small amount of fields and it will not grow in the future so I think it is OK to keep it here.","commit_id":"3c8ca003b3c992ef93521b4b1d18765b820d7cb8"}],"nova/objects/notification.py":[{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"05447e58cf3dd71c08761af5602097b9b52a0f92","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        \u0027phase\u0027: fields.NotificationEventTypePhaseField(),"},{"line_number":35,"context_line":"    }"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    def to_notification_event_type_field(self):"},{"line_number":38,"context_line":"        \"\"\"Serialize the object to the wire format.\"\"\""},{"line_number":39,"context_line":"        s \u003d \u0027%s.%s\u0027 % (self.object, self.action)"},{"line_number":40,"context_line":"        if self.obj_attr_is_set(\u0027phase\u0027):"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_f07883fa","line":37,"updated":"2015-11-23 15:56:14.000000000","message":"You should make 2 tests for this function, one where phase isn\u0027t set and one where it is.","commit_id":"82e243dcd6f68046cfa6b94b73469f542432418b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"4a84191ff5d3613c46c862202e174891013df365","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        \u0027phase\u0027: fields.NotificationEventTypePhaseField(),"},{"line_number":35,"context_line":"    }"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    def to_notification_event_type_field(self):"},{"line_number":38,"context_line":"        \"\"\"Serialize the object to the wire format.\"\"\""},{"line_number":39,"context_line":"        s \u003d \u0027%s.%s\u0027 % (self.object, self.action)"},{"line_number":40,"context_line":"        if self.obj_attr_is_set(\u0027phase\u0027):"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a8ffd7b_d6afc07b","line":37,"in_reply_to":"ba8a016a_f07883fa","updated":"2015-11-24 17:06:24.000000000","message":"This is covered in the test_emit_notification and test_emit_event_type_without_phase test cases in the nova/tests/unit/objects/test_notification.py file.","commit_id":"82e243dcd6f68046cfa6b94b73469f542432418b"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"05447e58cf3dd71c08761af5602097b9b52a0f92","unresolved":false,"context_lines":[{"line_number":68,"context_line":"        for field in self.filtered_fields:"},{"line_number":69,"context_line":"            attributes \u003d field.split(\u0027.\u0027)"},{"line_number":70,"context_line":"            sub_obj \u003d primitive[\u0027nova_object.data\u0027]"},{"line_number":71,"context_line":"            for attr in attributes[:-1]:"},{"line_number":72,"context_line":"                sub_obj \u003d sub_obj[attr][\u0027nova_object.data\u0027]"},{"line_number":73,"context_line":"            if attributes[-1] in sub_obj:"},{"line_number":74,"context_line":"                del sub_obj[attributes[-1]]"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_309feb60","line":71,"updated":"2015-11-23 15:56:14.000000000","message":"please document what\u0027s going on in here. This is super confusing.","commit_id":"82e243dcd6f68046cfa6b94b73469f542432418b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"4a84191ff5d3613c46c862202e174891013df365","unresolved":false,"context_lines":[{"line_number":68,"context_line":"        for field in self.filtered_fields:"},{"line_number":69,"context_line":"            attributes \u003d field.split(\u0027.\u0027)"},{"line_number":70,"context_line":"            sub_obj \u003d primitive[\u0027nova_object.data\u0027]"},{"line_number":71,"context_line":"            for attr in attributes[:-1]:"},{"line_number":72,"context_line":"                sub_obj \u003d sub_obj[attr][\u0027nova_object.data\u0027]"},{"line_number":73,"context_line":"            if attributes[-1] in sub_obj:"},{"line_number":74,"context_line":"                del sub_obj[attributes[-1]]"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a8ffd7b_d68260c8","line":71,"in_reply_to":"ba8a016a_309feb60","updated":"2015-11-24 17:06:24.000000000","message":"This is went away when I implemented the suggestion from alaski see http://lists.openstack.org/pipermail/openstack-dev/2015-November/080376.html","commit_id":"82e243dcd6f68046cfa6b94b73469f542432418b"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"05447e58cf3dd71c08761af5602097b9b52a0f92","unresolved":false,"context_lines":[{"line_number":78,"context_line":""},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":81,"context_line":"class NotificationBase(base.NovaObject):"},{"line_number":82,"context_line":"    \"\"\"Base class for versioned notifications."},{"line_number":83,"context_line":"    The reset_changes field defines if the wire format of the payload object"},{"line_number":84,"context_line":"    will contain the list of changed fields as well."}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_d7ea1974","line":81,"updated":"2015-11-23 15:56:14.000000000","message":"Should this be abstract? If not, it\u0027s going to blow up on the payload part below. Is there any way we can assert subclasses have a payload set?","commit_id":"82e243dcd6f68046cfa6b94b73469f542432418b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"4a84191ff5d3613c46c862202e174891013df365","unresolved":false,"context_lines":[{"line_number":78,"context_line":""},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":81,"context_line":"class NotificationBase(base.NovaObject):"},{"line_number":82,"context_line":"    \"\"\"Base class for versioned notifications."},{"line_number":83,"context_line":"    The reset_changes field defines if the wire format of the payload object"},{"line_number":84,"context_line":"    will contain the list of changed fields as well."}],"source_content_type":"text/x-python","patch_set":5,"id":"9a8ffd7b_eada1878","line":81,"in_reply_to":"ba8a016a_d7ea1974","updated":"2015-11-24 17:06:24.000000000","message":"Good point. However I don\u0027t see how can I express the abstractness of the payload field with abc module.\nSot he current code will fail runtime when emit() tries to access the payload field. But I\u0027m open to suggestions how to make it nicer","commit_id":"82e243dcd6f68046cfa6b94b73469f542432418b"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"05447e58cf3dd71c08761af5602097b9b52a0f92","unresolved":false,"context_lines":[{"line_number":84,"context_line":"    will contain the list of changed fields as well."},{"line_number":85,"context_line":"    \"\"\""},{"line_number":86,"context_line":"    reset_changes \u003d False"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    fields \u003d {"},{"line_number":89,"context_line":"        \u0027priority\u0027: fields.NotificationPriorityField(),"},{"line_number":90,"context_line":"        \u0027event_type\u0027: fields.ObjectField(\u0027EventType\u0027),"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_17666129","line":87,"updated":"2015-11-23 15:56:14.000000000","message":"This object has no version. We should explicitly set that.","commit_id":"82e243dcd6f68046cfa6b94b73469f542432418b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"4a84191ff5d3613c46c862202e174891013df365","unresolved":false,"context_lines":[{"line_number":84,"context_line":"    will contain the list of changed fields as well."},{"line_number":85,"context_line":"    \"\"\""},{"line_number":86,"context_line":"    reset_changes \u003d False"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    fields \u003d {"},{"line_number":89,"context_line":"        \u0027priority\u0027: fields.NotificationPriorityField(),"},{"line_number":90,"context_line":"        \u0027event_type\u0027: fields.ObjectField(\u0027EventType\u0027),"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a8ffd7b_8abeecfd","line":87,"in_reply_to":"ba8a016a_17666129","updated":"2015-11-24 17:06:24.000000000","message":"Done","commit_id":"82e243dcd6f68046cfa6b94b73469f542432418b"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"3c5f0c81c88a9d70eb35dff0f196ba77a79ca9a0","unresolved":false,"context_lines":[{"line_number":45,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":46,"context_line":"class NotificationPayloadBase(base.NovaObject):"},{"line_number":47,"context_line":"    \"\"\"Base class for the payload of versioned notifications.\"\"\""},{"line_number":48,"context_line":"    SCHEMA \u003d {}"},{"line_number":49,"context_line":"    # Version 1.0: Initial version"},{"line_number":50,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":51,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"9a8ffd7b_ceee3fec","line":48,"updated":"2015-11-24 19:40:51.000000000","message":"we have to figure out how to get changes here causing version errors in unit tests so we can require a version bump.","commit_id":"5a287dd14ee1bbdaf32b2edf7ff632ff9fb10ee1"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"bc9ac19400d8e72852120b60e3c72798dd0a7c37","unresolved":false,"context_lines":[{"line_number":45,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":46,"context_line":"class NotificationPayloadBase(base.NovaObject):"},{"line_number":47,"context_line":"    \"\"\"Base class for the payload of versioned notifications.\"\"\""},{"line_number":48,"context_line":"    SCHEMA \u003d {}"},{"line_number":49,"context_line":"    # Version 1.0: Initial version"},{"line_number":50,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":51,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"9a8ffd7b_e279a6fd","line":48,"in_reply_to":"9a8ffd7b_ceee3fec","updated":"2015-11-25 16:17:59.000000000","message":"I created a SCHEMA aware ObjectVersionChecker class as an attempt to solve this. That might not the best solution but that is what I found.","commit_id":"5a287dd14ee1bbdaf32b2edf7ff632ff9fb10ee1"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"3c5f0c81c88a9d70eb35dff0f196ba77a79ca9a0","unresolved":false,"context_lines":[{"line_number":100,"context_line":"                   publisher_id\u003d\u0027%s:%s\u0027 %"},{"line_number":101,"context_line":"                                (self.publisher.binary,"},{"line_number":102,"context_line":"                                 self.publisher.host),"},{"line_number":103,"context_line":"                   payload\u003dself.payload.obj_to_primitive())"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    @classmethod"},{"line_number":106,"context_line":"    def create(cls, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":6,"id":"9a8ffd7b_4e2b2f31","line":103,"updated":"2015-11-24 19:40:51.000000000","message":"As alaski was saying in the ML, I don\u0027t think we need to be using obj_to_primitive(). Or rather, we shouldn\u0027t be. Because we are, you need to hack around by deleting the fields above. So I think the generation of the payload should be isolated from obj_to_primitive(). We can use obj_to_primitive() to let nova talk to itself over the wire, but build a new dict that we generate from the schema. That way you don\u0027t have to dynamically be setting fields on the object also.","commit_id":"5a287dd14ee1bbdaf32b2edf7ff632ff9fb10ee1"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"bc9ac19400d8e72852120b60e3c72798dd0a7c37","unresolved":false,"context_lines":[{"line_number":100,"context_line":"                   publisher_id\u003d\u0027%s:%s\u0027 %"},{"line_number":101,"context_line":"                                (self.publisher.binary,"},{"line_number":102,"context_line":"                                 self.publisher.host),"},{"line_number":103,"context_line":"                   payload\u003dself.payload.obj_to_primitive())"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    @classmethod"},{"line_number":106,"context_line":"    def create(cls, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":6,"id":"9a8ffd7b_79856dab","line":103,"in_reply_to":"9a8ffd7b_4e2b2f31","updated":"2015-11-25 16:17:59.000000000","message":"I was able to remove the hacks around the serialization of the data source objects in the Payload object. So the actual Payload object can be serialized with the existing serialization mechanism without any side effects or hacks. So I think we can re-use the obj_to_primitive() to avoid duplicate serialization implementation.","commit_id":"5a287dd14ee1bbdaf32b2edf7ff632ff9fb10ee1"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"8243551067b923b0b1186012428c85f49bcd17cb","unresolved":false,"context_lines":[{"line_number":92,"context_line":"    def emit(self, context):"},{"line_number":93,"context_line":"        \"\"\"Send the notification. \"\"\""},{"line_number":94,"context_line":"        if self.reset_changes:"},{"line_number":95,"context_line":"            self.payload.obj_reset_changes(recursive\u003dTrue)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        self._emit(context,"},{"line_number":98,"context_line":"                   event_type\u003d"}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_b4030ab8","line":95,"updated":"2015-11-24 20:28:25.000000000","message":"Is this safe to do?  This may end up with unintended consequences with something like:\n\n    instance.foo \u003d baz\n    instance_notification.instance \u003d instance\n    instance_notification.reset_changes \u003d True\n    instance_notification.emit()\n    instance.save() # noop because changes were reset\n\nI think you\u0027ll need to just filter changed fields out rather than reset changes.","commit_id":"a6d6d4d072256a3eed9575e267d03357aaf6fead"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"16b5bba5ece6efc12b6f567557b51df9834f0109","unresolved":false,"context_lines":[{"line_number":92,"context_line":"    def emit(self, context):"},{"line_number":93,"context_line":"        \"\"\"Send the notification. \"\"\""},{"line_number":94,"context_line":"        if self.reset_changes:"},{"line_number":95,"context_line":"            self.payload.obj_reset_changes(recursive\u003dTrue)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        self._emit(context,"},{"line_number":98,"context_line":"                   event_type\u003d"}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_2ec4755d","line":95,"in_reply_to":"9a8ffd7b_80a1e0ab","updated":"2015-11-25 16:18:11.000000000","message":"After moving to the white listing solution this feature does not make sense. Originally it was here to be able to show what changed in the original object. As we are copying the data from the original object to a new Payload object every fields of the Payload object will always be marked as changed which does not give us any information, so I removed this feature.\nIf a specific notification wants to provide information what is changed in the original object then it can do it by adding extra fields to the specific Payload object and populating that before the notification was sent.","commit_id":"a6d6d4d072256a3eed9575e267d03357aaf6fead"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"b8df15a6b2c1da26cc6bd3ec40d113278b04557d","unresolved":false,"context_lines":[{"line_number":92,"context_line":"    def emit(self, context):"},{"line_number":93,"context_line":"        \"\"\"Send the notification. \"\"\""},{"line_number":94,"context_line":"        if self.reset_changes:"},{"line_number":95,"context_line":"            self.payload.obj_reset_changes(recursive\u003dTrue)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        self._emit(context,"},{"line_number":98,"context_line":"                   event_type\u003d"}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_80a1e0ab","line":95,"in_reply_to":"9a8ffd7b_b4030ab8","updated":"2015-11-24 21:55:39.000000000","message":"Do we want to do this non-recursively? Agree with alaski on this one. IMO as a notification, we shouldn\u0027t be changing anything within the contained objects (unless we\u0027re doing it on a copy).","commit_id":"a6d6d4d072256a3eed9575e267d03357aaf6fead"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"8d142efb051c1ce68a428e6353a42533418b1c05","unresolved":false,"context_lines":[{"line_number":108,"context_line":"                   publisher_id\u003d\u0027%s:%s\u0027 %"},{"line_number":109,"context_line":"                                (self.publisher.binary,"},{"line_number":110,"context_line":"                                 self.publisher.host),"},{"line_number":111,"context_line":"                   payload\u003dself.payload.obj_to_primitive())"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    @classmethod"},{"line_number":114,"context_line":"    def create(cls, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":14,"id":"9a8ffd7b_b0a15f48","line":111,"updated":"2015-12-02 17:43:40.000000000","message":"I don\u0027t think we should be using obj_to_primitive() when emitting. If we change how that works, then that may have some unintended consequences in the hydration/dehydration of the objects when being tossed across RPC between different nova services. I would prefer we use a different serialization function when exposing it over RPC outside of nova.\n\nThat also makes _populate_schema easier to handle, because then you won\u0027t be setting a bunch of attributes on self, we\u0027ll be storing it somewhere else.","commit_id":"52370dec0e465a03866f3281327380dcbab4cbde"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"cdaf5beae4ad0c5855f23bc7b6f9c1d3076d9745","unresolved":false,"context_lines":[{"line_number":108,"context_line":"                   publisher_id\u003d\u0027%s:%s\u0027 %"},{"line_number":109,"context_line":"                                (self.publisher.binary,"},{"line_number":110,"context_line":"                                 self.publisher.host),"},{"line_number":111,"context_line":"                   payload\u003dself.payload.obj_to_primitive())"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    @classmethod"},{"line_number":114,"context_line":"    def create(cls, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":14,"id":"7a740942_4ea3539f","line":111,"in_reply_to":"9a8ffd7b_b0a15f48","updated":"2015-12-03 15:04:49.000000000","message":"I don\u0027t see any need from notification point of view to change the obj_to_primitive() behavior so I cannot imagine a situation that notifications break the RPC communication. In the other case if the RPC format needs to be changed and that affects obj_to_primitive() behavior then of course that can break the notification interface contract. If I understand correctly you suggest to use a different code to convert the object to primitives. I agree that as soon as the two needs are diverge we need to diverge in the implementation but today the two needs are the same so I don\u0027t see why we should implement a new code to do the same thing. That would be a pure duplicate today.\nOr I misunderstand you and you have some concerns about the proposed wire format which means we would need to change obj_to_primitive(). Could you be more explicit if this is the case?\n\nBottom line I\u0027d like to understand your concern better here.","commit_id":"52370dec0e465a03866f3281327380dcbab4cbde"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"47590c8c69f60e59dc28a239d629cfb17ed327ea","unresolved":false,"context_lines":[{"line_number":68,"context_line":""},{"line_number":69,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":70,"context_line":"        super(NotificationPayloadBase, self).__init__(self, *args, **kwargs)"},{"line_number":71,"context_line":"        self._populate_schema()"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    def _populate_schema(self):"},{"line_number":74,"context_line":"        for key, (obj, field) in self.SCHEMA.items():"}],"source_content_type":"text/x-python","patch_set":15,"id":"7a740942_daa3724e","line":71,"updated":"2015-12-03 18:52:58.000000000","message":"If we try assigning something new on the object after creating the payload, those changes aren\u0027t reflected in the payload right? because this is called in __init__(). Is this desired behavior?","commit_id":"836e296e7043850769e3c666e13cd12ef30b4842"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"e364d8ab89ff4da7c0c22031bf61986378318daf","unresolved":false,"context_lines":[{"line_number":68,"context_line":""},{"line_number":69,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":70,"context_line":"        super(NotificationPayloadBase, self).__init__(self, *args, **kwargs)"},{"line_number":71,"context_line":"        self._populate_schema()"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    def _populate_schema(self):"},{"line_number":74,"context_line":"        for key, (obj, field) in self.SCHEMA.items():"}],"source_content_type":"text/x-python","patch_set":15,"id":"7a740942_fb74b868","line":71,"in_reply_to":"7a740942_daa3724e","updated":"2015-12-07 14:40:56.000000000","message":"Alright, I think I found the source of my confusion. The reason I thought everything was in fields was because you aren\u0027t passing anything to _populate_schema(). I wasn\u0027t sure how the \"subobjects\" were being set on the object (i.e. \"magic\" handled by super).\n\nNow that I really really know what\u0027s going on, I\u0027ll give my opinion. I\u0027m thinking you should make populate_schema() public, and you hand the objects with kwargs. That was it works out to be \"populate the schema with these objects\". Let me know if that makes sense to you, or if you think that\u0027s being too explicit about how this is done.","commit_id":"836e296e7043850769e3c666e13cd12ef30b4842"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"47590c8c69f60e59dc28a239d629cfb17ed327ea","unresolved":false,"context_lines":[{"line_number":74,"context_line":"        for key, (obj, field) in self.SCHEMA.items():"},{"line_number":75,"context_line":"            source \u003d getattr(self, obj)"},{"line_number":76,"context_line":"            if source.obj_attr_is_set(field):"},{"line_number":77,"context_line":"                setattr(self, key, getattr(source, field))"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"@base.NovaObjectRegistry.register"}],"source_content_type":"text/x-python","patch_set":15,"id":"7a740942_7a77ded4","line":77,"updated":"2015-12-03 18:52:58.000000000","message":"if we\u0027re setting stuff on ourselves, but we don\u0027t change any of the existing, then calling obj_to_primitive() on the payload object will dump all of the subobject stuff too, which we don\u0027t want.","commit_id":"836e296e7043850769e3c666e13cd12ef30b4842"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"47590c8c69f60e59dc28a239d629cfb17ed327ea","unresolved":false,"context_lines":[{"line_number":108,"context_line":"                   publisher_id\u003d\u0027%s:%s\u0027 %"},{"line_number":109,"context_line":"                                (self.publisher.binary,"},{"line_number":110,"context_line":"                                 self.publisher.host),"},{"line_number":111,"context_line":"                   payload\u003dself.payload.obj_to_primitive())"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    @classmethod"},{"line_number":114,"context_line":"    def create(cls, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":15,"id":"7a740942_3ae5d6a7","line":111,"updated":"2015-12-03 18:52:58.000000000","message":"Here\u0027s where alaski talked about it in the ML: http://lists.openstack.org/pipermail/openstack-dev/2015-November/080412.html\n\nThe relevant bit is: \"So I wouldn\u0027t expect \nnotification code to call obj_to_primitive() but perhaps a new emit() \nmethod which will do the transform to the schema.\"\n\nMaybe I\u0027m misunderstanding what alaski was talking about in that email, but the way I see it is we don\u0027t need to be using obj_to_primitive().\n\nBut, now that I think more about it, obj_to_primitive() does nicely give us versioning and such.","commit_id":"836e296e7043850769e3c666e13cd12ef30b4842"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"56f5bd4cfe7cd381610fd7cbc9ad1a4ee2e843a9","unresolved":false,"context_lines":[{"line_number":69,"context_line":""},{"line_number":70,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":71,"context_line":"        super(NotificationPayloadBase, self).__init__(self, *args, **kwargs)"},{"line_number":72,"context_line":"        self.populated \u003d not self.SCHEMA"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def populate_schema(self, **kwargs):"},{"line_number":75,"context_line":"        \"\"\"Populate the object based on the SCHEMA and the source objects"}],"source_content_type":"text/x-python","patch_set":16,"id":"7a740942_9339cdf4","line":72,"updated":"2015-12-07 18:51:12.000000000","message":"can we just initialize this to False? Are people really going to try and emit an empty notification? I see you have a test for it, so that\u0027s good, but this kind of makes things confusing to me.","commit_id":"7b93b069273011a66f75cc554258348ff0aa76a3"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"850e0c045939816d68c214968b025294931b00a6","unresolved":false,"context_lines":[{"line_number":69,"context_line":""},{"line_number":70,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":71,"context_line":"        super(NotificationPayloadBase, self).__init__(self, *args, **kwargs)"},{"line_number":72,"context_line":"        self.populated \u003d not self.SCHEMA"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def populate_schema(self, **kwargs):"},{"line_number":75,"context_line":"        \"\"\"Populate the object based on the SCHEMA and the source objects"}],"source_content_type":"text/x-python","patch_set":16,"id":"7a740942_ddf4145c","line":72,"in_reply_to":"7a740942_9339cdf4","updated":"2015-12-08 15:31:18.000000000","message":"An empty SCHEMA does not mean that the notification payload is empty. The notification payload can have two types of field defined in the fields member. 1) fields that are filled via the __init__ of the object in the same way as in normal o.vo objects. For example this can be used to send calculated information that are not directly present in any existing object. 2) fields that are not filled via __init__ but filled via the SCHEMA by the populate_schema() call. \nSo it seems wrong to require an empty populate_schema() call from the client if the SCHEMA is {} in the payload class but the fields is not {}","commit_id":"7b93b069273011a66f75cc554258348ff0aa76a3"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"56f5bd4cfe7cd381610fd7cbc9ad1a4ee2e843a9","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        self.populated \u003d not self.SCHEMA"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def populate_schema(self, **kwargs):"},{"line_number":75,"context_line":"        \"\"\"Populate the object based on the SCHEMA and the source objects"},{"line_number":76,"context_line":"        :param kwargs: A dict contains the source object at the key defined in"},{"line_number":77,"context_line":"        the SCHEMA"},{"line_number":78,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":16,"id":"7a740942_5305a543","line":75,"updated":"2015-12-07 18:51:12.000000000","message":"nit: put a blank line before the params for readability","commit_id":"7b93b069273011a66f75cc554258348ff0aa76a3"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"850e0c045939816d68c214968b025294931b00a6","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        self.populated \u003d not self.SCHEMA"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def populate_schema(self, **kwargs):"},{"line_number":75,"context_line":"        \"\"\"Populate the object based on the SCHEMA and the source objects"},{"line_number":76,"context_line":"        :param kwargs: A dict contains the source object at the key defined in"},{"line_number":77,"context_line":"        the SCHEMA"},{"line_number":78,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":16,"id":"7a740942_5d8824c5","line":75,"in_reply_to":"7a740942_5305a543","updated":"2015-12-08 15:31:18.000000000","message":"Done","commit_id":"7b93b069273011a66f75cc554258348ff0aa76a3"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"56f5bd4cfe7cd381610fd7cbc9ad1a4ee2e843a9","unresolved":false,"context_lines":[{"line_number":74,"context_line":"    def populate_schema(self, **kwargs):"},{"line_number":75,"context_line":"        \"\"\"Populate the object based on the SCHEMA and the source objects"},{"line_number":76,"context_line":"        :param kwargs: A dict contains the source object at the key defined in"},{"line_number":77,"context_line":"        the SCHEMA"},{"line_number":78,"context_line":"        \"\"\""},{"line_number":79,"context_line":"        for key, (obj, field) in self.SCHEMA.items():"},{"line_number":80,"context_line":"            source \u003d kwargs[obj]"}],"source_content_type":"text/x-python","patch_set":16,"id":"7a740942_f39cd110","line":77,"updated":"2015-12-07 18:51:12.000000000","message":"also nit: hang this indent in to line up with \"A dict\" for readability.","commit_id":"7b93b069273011a66f75cc554258348ff0aa76a3"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"850e0c045939816d68c214968b025294931b00a6","unresolved":false,"context_lines":[{"line_number":74,"context_line":"    def populate_schema(self, **kwargs):"},{"line_number":75,"context_line":"        \"\"\"Populate the object based on the SCHEMA and the source objects"},{"line_number":76,"context_line":"        :param kwargs: A dict contains the source object at the key defined in"},{"line_number":77,"context_line":"        the SCHEMA"},{"line_number":78,"context_line":"        \"\"\""},{"line_number":79,"context_line":"        for key, (obj, field) in self.SCHEMA.items():"},{"line_number":80,"context_line":"            source \u003d kwargs[obj]"}],"source_content_type":"text/x-python","patch_set":16,"id":"7a740942_fd9230f5","line":77,"in_reply_to":"7a740942_f39cd110","updated":"2015-12-08 15:31:18.000000000","message":"Done","commit_id":"7b93b069273011a66f75cc554258348ff0aa76a3"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"e777683ec7f591f02955eca4bb99f1ebfef2d6f9","unresolved":false,"context_lines":[{"line_number":69,"context_line":""},{"line_number":70,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":71,"context_line":"        super(NotificationPayloadBase, self).__init__(self, *args, **kwargs)"},{"line_number":72,"context_line":"        self.populated \u003d not self.SCHEMA"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def populate_schema(self, **kwargs):"},{"line_number":75,"context_line":"        \"\"\"Populate the object based on the SCHEMA and the source objects"}],"source_content_type":"text/x-python","patch_set":18,"id":"7a740942_d905f945","line":72,"updated":"2015-12-08 17:55:17.000000000","message":"Alright, now I\u0027m getting this better. So if schema is empty, but someone feels like putting in their own fields that don\u0027t come from other objects they can do that. And then when I want to emit my notification I would do it like so, right?\n\n    payload \u003d MyPayload(non_schema_thing\u003d\u0027foo\u0027)\n    # payload.populate_schema() \u003c-- I don\u0027t need this now because I don\u0027t have a schema right?\n    noti \u003d MyNotification(\u003cstuff\u003e, payload\u003dpayload)\n    noti.emit()\n\nIf it works this way, I\u0027m happy with it!","commit_id":"21c535a9dae660cae87dc836b931b1dd53124cc2"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"d4ab2a56344b2ce1d07e7c4f558a81eb5abd5b3e","unresolved":false,"context_lines":[{"line_number":69,"context_line":""},{"line_number":70,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":71,"context_line":"        super(NotificationPayloadBase, self).__init__(self, *args, **kwargs)"},{"line_number":72,"context_line":"        self.populated \u003d not self.SCHEMA"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def populate_schema(self, **kwargs):"},{"line_number":75,"context_line":"        \"\"\"Populate the object based on the SCHEMA and the source objects"}],"source_content_type":"text/x-python","patch_set":18,"id":"7a740942_6b43c813","line":72,"in_reply_to":"7a740942_d905f945","updated":"2015-12-08 18:00:19.000000000","message":"This works exactly as you described :)","commit_id":"21c535a9dae660cae87dc836b931b1dd53124cc2"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"8dd3c99ce8a7d3b5c7d3df5339ac30ca8ca871de","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2015 OpenStack Foundation"},{"line_number":2,"context_line":"# All Rights Reserved."},{"line_number":3,"context_line":"#"},{"line_number":4,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":22,"id":"fa69d971_9129023a","line":1,"updated":"2016-01-08 13:38:05.000000000","message":"Since copyright is implied and these dates go out of synch so easily, maybe just delete these two lines? At least fix the date.","commit_id":"3c8ca003b3c992ef93521b4b1d18765b820d7cb8"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e6b9de6f562b11cf6d4c6e2c9af7ac355d870287","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2015 OpenStack Foundation"},{"line_number":2,"context_line":"# All Rights Reserved."},{"line_number":3,"context_line":"#"},{"line_number":4,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":22,"id":"fa69d971_75155347","line":1,"in_reply_to":"fa69d971_9129023a","updated":"2016-01-09 12:38:58.000000000","message":"Done","commit_id":"3c8ca003b3c992ef93521b4b1d18765b820d7cb8"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"89169d8e5989101d6eab346401b4e101eb447b1a","unresolved":false,"context_lines":[{"line_number":31,"context_line":"    fields \u003d {"},{"line_number":32,"context_line":"        \u0027object\u0027: fields.StringField(),"},{"line_number":33,"context_line":"        \u0027action\u0027: fields.NotificationActionField(),"},{"line_number":34,"context_line":"        \u0027phase\u0027: fields.NotificationPhaseField(),"},{"line_number":35,"context_line":"    }"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    def to_notification_event_type_field(self):"}],"source_content_type":"text/x-python","patch_set":22,"id":"fa69d971_6a533e3a","line":34,"updated":"2016-01-08 11:40:02.000000000","message":"I am trying to think through things like the current instance update notification. we just get: \"compute.instance.update\"\n\ndoes that mean we now send start and end notifications, or we just send and end notification, or does it mean something else?","commit_id":"3c8ca003b3c992ef93521b4b1d18765b820d7cb8"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"985e320d98a47b9eaa0ba537a6b08a2c07def900","unresolved":false,"context_lines":[{"line_number":31,"context_line":"    fields \u003d {"},{"line_number":32,"context_line":"        \u0027object\u0027: fields.StringField(),"},{"line_number":33,"context_line":"        \u0027action\u0027: fields.NotificationActionField(),"},{"line_number":34,"context_line":"        \u0027phase\u0027: fields.NotificationPhaseField(),"},{"line_number":35,"context_line":"    }"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    def to_notification_event_type_field(self):"}],"source_content_type":"text/x-python","patch_set":22,"id":"fa69d971_d1bf7a5e","line":34,"in_reply_to":"fa69d971_6a533e3a","updated":"2016-01-08 13:45:13.000000000","message":"Ah, so I see with service.update we just make the phase optional.\n\nMaybe we should mark this as nullable\u003dTrue, and the others as False?","commit_id":"3c8ca003b3c992ef93521b4b1d18765b820d7cb8"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e6b9de6f562b11cf6d4c6e2c9af7ac355d870287","unresolved":false,"context_lines":[{"line_number":31,"context_line":"    fields \u003d {"},{"line_number":32,"context_line":"        \u0027object\u0027: fields.StringField(),"},{"line_number":33,"context_line":"        \u0027action\u0027: fields.NotificationActionField(),"},{"line_number":34,"context_line":"        \u0027phase\u0027: fields.NotificationPhaseField(),"},{"line_number":35,"context_line":"    }"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    def to_notification_event_type_field(self):"}],"source_content_type":"text/x-python","patch_set":22,"id":"fa69d971_58a5e601","line":34,"in_reply_to":"fa69d971_d1bf7a5e","updated":"2016-01-09 12:38:58.000000000","message":"Yes, good point, lets make the phase nullable.","commit_id":"3c8ca003b3c992ef93521b4b1d18765b820d7cb8"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"89169d8e5989101d6eab346401b4e101eb447b1a","unresolved":false,"context_lines":[{"line_number":93,"context_line":"    fields \u003d {"},{"line_number":94,"context_line":"        \u0027priority\u0027: fields.NotificationPriorityField(),"},{"line_number":95,"context_line":"        \u0027event_type\u0027: fields.ObjectField(\u0027EventType\u0027),"},{"line_number":96,"context_line":"        \u0027publisher\u0027: fields.ObjectField(\u0027Service\u0027),"},{"line_number":97,"context_line":"    }"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    def _emit(self, context, event_type, publisher_id, payload):"}],"source_content_type":"text/x-python","patch_set":22,"id":"fa69d971_67d617f3","line":96,"updated":"2016-01-08 11:40:02.000000000","message":"I am curious, if long term, we want this direct relationship. It seems simple enough though, and real.","commit_id":"3c8ca003b3c992ef93521b4b1d18765b820d7cb8"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e6b9de6f562b11cf6d4c6e2c9af7ac355d870287","unresolved":false,"context_lines":[{"line_number":93,"context_line":"    fields \u003d {"},{"line_number":94,"context_line":"        \u0027priority\u0027: fields.NotificationPriorityField(),"},{"line_number":95,"context_line":"        \u0027event_type\u0027: fields.ObjectField(\u0027EventType\u0027),"},{"line_number":96,"context_line":"        \u0027publisher\u0027: fields.ObjectField(\u0027Service\u0027),"},{"line_number":97,"context_line":"    }"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    def _emit(self, context, event_type, publisher_id, payload):"}],"source_content_type":"text/x-python","patch_set":22,"id":"fa69d971_38c6f249","line":96,"in_reply_to":"fa69d971_67d617f3","updated":"2016-01-09 12:38:58.000000000","message":"I\u0027m not sure if it is a problem or not. In one hand every piece of code in nova belongs to a service so the relationship to a service object seems logical, in other hand I can imagine that getting an actual service object has unwanted consequences like accessing the DB to query the object.","commit_id":"3c8ca003b3c992ef93521b4b1d18765b820d7cb8"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"89169d8e5989101d6eab346401b4e101eb447b1a","unresolved":false,"context_lines":[{"line_number":94,"context_line":"        \u0027priority\u0027: fields.NotificationPriorityField(),"},{"line_number":95,"context_line":"        \u0027event_type\u0027: fields.ObjectField(\u0027EventType\u0027),"},{"line_number":96,"context_line":"        \u0027publisher\u0027: fields.ObjectField(\u0027Service\u0027),"},{"line_number":97,"context_line":"    }"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    def _emit(self, context, event_type, publisher_id, payload):"},{"line_number":100,"context_line":"        assert rpc.NOTIFIER is not None"}],"source_content_type":"text/x-python","patch_set":22,"id":"fa69d971_4abe7a00","line":97,"updated":"2016-01-08 11:40:02.000000000","message":"Nit: I wonder about adding a comment here about requiring the payload filed in the subclass? Its probably not worth it.","commit_id":"3c8ca003b3c992ef93521b4b1d18765b820d7cb8"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e6b9de6f562b11cf6d4c6e2c9af7ac355d870287","unresolved":false,"context_lines":[{"line_number":94,"context_line":"        \u0027priority\u0027: fields.NotificationPriorityField(),"},{"line_number":95,"context_line":"        \u0027event_type\u0027: fields.ObjectField(\u0027EventType\u0027),"},{"line_number":96,"context_line":"        \u0027publisher\u0027: fields.ObjectField(\u0027Service\u0027),"},{"line_number":97,"context_line":"    }"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    def _emit(self, context, event_type, publisher_id, payload):"},{"line_number":100,"context_line":"        assert rpc.NOTIFIER is not None"}],"source_content_type":"text/x-python","patch_set":22,"id":"fa69d971_8b4d4674","line":97,"in_reply_to":"fa69d971_4abe7a00","updated":"2016-01-09 12:38:58.000000000","message":"Added it to the class doc","commit_id":"3c8ca003b3c992ef93521b4b1d18765b820d7cb8"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"89169d8e5989101d6eab346401b4e101eb447b1a","unresolved":false,"context_lines":[{"line_number":97,"context_line":"    }"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    def _emit(self, context, event_type, publisher_id, payload):"},{"line_number":100,"context_line":"        assert rpc.NOTIFIER is not None"},{"line_number":101,"context_line":"        notifier \u003d rpc.NOTIFIER.prepare(publisher_id\u003dpublisher_id)"},{"line_number":102,"context_line":"        notify \u003d getattr(notifier, self.priority)"},{"line_number":103,"context_line":"        notify(context, event_type\u003devent_type, payload\u003dpayload)"}],"source_content_type":"text/x-python","patch_set":22,"id":"fa69d971_a7916f9c","line":100,"updated":"2016-01-08 11:40:02.000000000","message":"Unsure about using assert, rather than raising an exception, but this is what the RPC layer already does in places, so lets copy that.","commit_id":"3c8ca003b3c992ef93521b4b1d18765b820d7cb8"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e6b9de6f562b11cf6d4c6e2c9af7ac355d870287","unresolved":false,"context_lines":[{"line_number":97,"context_line":"    }"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    def _emit(self, context, event_type, publisher_id, payload):"},{"line_number":100,"context_line":"        assert rpc.NOTIFIER is not None"},{"line_number":101,"context_line":"        notifier \u003d rpc.NOTIFIER.prepare(publisher_id\u003dpublisher_id)"},{"line_number":102,"context_line":"        notify \u003d getattr(notifier, self.priority)"},{"line_number":103,"context_line":"        notify(context, event_type\u003devent_type, payload\u003dpayload)"}],"source_content_type":"text/x-python","patch_set":22,"id":"fa69d971_4b7c2e72","line":100,"in_reply_to":"fa69d971_a7916f9c","updated":"2016-01-09 12:38:58.000000000","message":"This was put back to the rpc module in the next patch anyhow.","commit_id":"3c8ca003b3c992ef93521b4b1d18765b820d7cb8"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"89169d8e5989101d6eab346401b4e101eb447b1a","unresolved":false,"context_lines":[{"line_number":120,"context_line":"                   payload\u003dself.payload.obj_to_primitive())"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"    @classmethod"},{"line_number":123,"context_line":"    def create(cls, *args, **kwargs):"},{"line_number":124,"context_line":"        return cls(*args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":22,"id":"fa69d971_273a5f99","line":123,"updated":"2016-01-08 11:40:02.000000000","message":"do we need this?","commit_id":"3c8ca003b3c992ef93521b4b1d18765b820d7cb8"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e6b9de6f562b11cf6d4c6e2c9af7ac355d870287","unresolved":false,"context_lines":[{"line_number":120,"context_line":"                   payload\u003dself.payload.obj_to_primitive())"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"    @classmethod"},{"line_number":123,"context_line":"    def create(cls, *args, **kwargs):"},{"line_number":124,"context_line":"        return cls(*args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":22,"id":"fa69d971_cb77be00","line":123,"in_reply_to":"fa69d971_273a5f99","updated":"2016-01-09 12:38:58.000000000","message":"Good point, it just remained here from a previous iteration.","commit_id":"3c8ca003b3c992ef93521b4b1d18765b820d7cb8"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"bf12cf35e219f27998cb341c87972507acbe16f9","unresolved":false,"context_lines":[{"line_number":41,"context_line":"        return s"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":45,"context_line":"class NotificationPayloadBase(base.NovaObject):"},{"line_number":46,"context_line":"    \"\"\"Base class for the payload of versioned notifications.\"\"\""},{"line_number":47,"context_line":"    # SCHEMA defines how to populate the payload fields. It is a dictionary"}],"source_content_type":"text/x-python","patch_set":27,"id":"da6ed579_2d56bad2","line":44,"updated":"2016-01-13 11:40:45.000000000","message":"Part of me wonders if we should register this object or not.\n\nIt seems easier to test like this, in some ways.","commit_id":"a3479d4fd02fd1382ffdb2c333ad895b8a3b607c"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"8ced79199d3f248d5525f582c4e31ac0495f512d","unresolved":false,"context_lines":[{"line_number":41,"context_line":"        return s"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":45,"context_line":"class NotificationPayloadBase(base.NovaObject):"},{"line_number":46,"context_line":"    \"\"\"Base class for the payload of versioned notifications.\"\"\""},{"line_number":47,"context_line":"    # SCHEMA defines how to populate the payload fields. It is a dictionary"}],"source_content_type":"text/x-python","patch_set":27,"id":"da6ed579_413c16c8","line":44,"in_reply_to":"da6ed579_2d56bad2","updated":"2016-01-13 15:05:28.000000000","message":"As far as I see registering means that we detect if the version needs to be bumped. But every versioned notification needs to inherit from it so it does not really need its own version test separately. So I removed the registration of the NotificationPayloadBase and the NotificationBase classes.","commit_id":"a3479d4fd02fd1382ffdb2c333ad895b8a3b607c"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"bf12cf35e219f27998cb341c87972507acbe16f9","unresolved":false,"context_lines":[{"line_number":113,"context_line":"        \u0027publisher\u0027: fields.ObjectField(\u0027NotificationPublisher\u0027),"},{"line_number":114,"context_line":"    }"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"    def _emit(self, context, event_type, publisher_id, payload):"},{"line_number":117,"context_line":"        assert rpc.NOTIFIER is not None"},{"line_number":118,"context_line":"        notifier \u003d rpc.NOTIFIER.prepare(publisher_id\u003dpublisher_id)"},{"line_number":119,"context_line":"        notify \u003d getattr(notifier, self.priority)"}],"source_content_type":"text/x-python","patch_set":27,"id":"da6ed579_2dba3a24","line":116,"updated":"2016-01-13 11:40:45.000000000","message":"I do wonder about moving this into the rpc module, but thats done in a follow up, so thats cool.","commit_id":"a3479d4fd02fd1382ffdb2c333ad895b8a3b607c"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"8ced79199d3f248d5525f582c4e31ac0495f512d","unresolved":false,"context_lines":[{"line_number":113,"context_line":"        \u0027publisher\u0027: fields.ObjectField(\u0027NotificationPublisher\u0027),"},{"line_number":114,"context_line":"    }"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"    def _emit(self, context, event_type, publisher_id, payload):"},{"line_number":117,"context_line":"        assert rpc.NOTIFIER is not None"},{"line_number":118,"context_line":"        notifier \u003d rpc.NOTIFIER.prepare(publisher_id\u003dpublisher_id)"},{"line_number":119,"context_line":"        notify \u003d getattr(notifier, self.priority)"}],"source_content_type":"text/x-python","patch_set":27,"id":"da6ed579_e17d0ae8","line":116,"in_reply_to":"da6ed579_2dba3a24","updated":"2016-01-13 15:05:28.000000000","message":"I keep the pushback in the next commit as pushing it back now would need to change the get_notifier call (as it requires \u0027service\u0027 param now) and that call is used in a lot of places. In the next commit there is a new call get_versioned_notifier so there it is easy to introduce that with a good signature without impacting the legacy notification code path.","commit_id":"a3479d4fd02fd1382ffdb2c333ad895b8a3b607c"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"34593b13f238f1cfa72264e49f8b6872b01dd2a4","unresolved":false,"context_lines":[{"line_number":41,"context_line":"        return s"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"class NotificationPayloadBase(base.NovaObject):"},{"line_number":45,"context_line":"    \"\"\"Base class for the payload of versioned notifications.\"\"\""},{"line_number":46,"context_line":"    # SCHEMA defines how to populate the payload fields. It is a dictionary"},{"line_number":47,"context_line":"    # where every key value pair has the following format:"}],"source_content_type":"text/x-python","patch_set":28,"id":"da6ed579_cfe6e8b3","line":44,"updated":"2016-01-13 15:16:10.000000000","message":"I wonder if we want @base.NovaObjectRegistry.register_if(False) here?","commit_id":"e96e3b945a3e997479daa1127934904bd9870f6a"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"2a7c05a8ee801166526047b83a312027b62bfbf8","unresolved":false,"context_lines":[{"line_number":41,"context_line":"        return s"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"class NotificationPayloadBase(base.NovaObject):"},{"line_number":45,"context_line":"    \"\"\"Base class for the payload of versioned notifications.\"\"\""},{"line_number":46,"context_line":"    # SCHEMA defines how to populate the payload fields. It is a dictionary"},{"line_number":47,"context_line":"    # where every key value pair has the following format:"}],"source_content_type":"text/x-python","patch_set":28,"id":"da6ed579_ca67b623","line":44,"in_reply_to":"da6ed579_cfe6e8b3","updated":"2016-01-13 15:31:33.000000000","message":"Done","commit_id":"e96e3b945a3e997479daa1127934904bd9870f6a"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"d8cf0ea04b320eaf3eeb916778b5fb00f11ad666","unresolved":false,"context_lines":[{"line_number":43,"context_line":""},{"line_number":44,"context_line":"@base.NovaObjectRegistry.register_if(False)"},{"line_number":45,"context_line":"# Note(gibi): It is explicitly not registered as this class shall not be used"},{"line_number":46,"context_line":"# directly, it is just a base class for notification payloads."},{"line_number":47,"context_line":"class NotificationPayloadBase(base.NovaObject):"},{"line_number":48,"context_line":"    \"\"\"Base class for the payload of versioned notifications.\"\"\""},{"line_number":49,"context_line":"    # SCHEMA defines how to populate the payload fields. It is a dictionary"}],"source_content_type":"text/x-python","patch_set":29,"id":"da6ed579_e5baed22","line":46,"updated":"2016-01-13 15:35:20.000000000","message":"Nit: I would rather have the comment above the decorator, but its a minor thing.","commit_id":"2e0ad68b31390161ff87bdaee4c4899509611027"},{"author":{"_account_id":2271,"name":"Michael Still","email":"mikal@stillhq.com","username":"mikalstill"},"change_message_id":"d668dfa3adeb763d90fbf9e8ee839338e2642b62","unresolved":false,"context_lines":[{"line_number":12,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":13,"context_line":"#    under the License."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"from oslo_log import log as logging"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from nova.objects import base"}],"source_content_type":"text/x-python","patch_set":32,"id":"ba63e191_b1bb09c4","line":15,"updated":"2016-01-19 15:33:45.000000000","message":"I don\u0027t think you need this import at all?","commit_id":"5dfa2c2940881aa95b3de40dc0ed6e81bd6c3cde"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"36a76eeaf45cae49cb32a38945c554c34b8c000d","unresolved":false,"context_lines":[{"line_number":12,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":13,"context_line":"#    under the License."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"from oslo_log import log as logging"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from nova.objects import base"}],"source_content_type":"text/x-python","patch_set":32,"id":"ba63e191_578cf334","line":15,"in_reply_to":"ba63e191_b1bb09c4","updated":"2016-01-19 18:22:39.000000000","message":"Done","commit_id":"5dfa2c2940881aa95b3de40dc0ed6e81bd6c3cde"},{"author":{"_account_id":2271,"name":"Michael Still","email":"mikal@stillhq.com","username":"mikalstill"},"change_message_id":"d668dfa3adeb763d90fbf9e8ee839338e2642b62","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from nova.objects import fields"},{"line_number":20,"context_line":"from nova import rpc"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"@base.NovaObjectRegistry.register"}],"source_content_type":"text/x-python","patch_set":32,"id":"ba63e191_f1aae16f","line":22,"updated":"2016-01-19 15:33:45.000000000","message":"This isn\u0027t used anywhere in this file, so why have it here?","commit_id":"5dfa2c2940881aa95b3de40dc0ed6e81bd6c3cde"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"36a76eeaf45cae49cb32a38945c554c34b8c000d","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from nova.objects import fields"},{"line_number":20,"context_line":"from nova import rpc"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"@base.NovaObjectRegistry.register"}],"source_content_type":"text/x-python","patch_set":32,"id":"ba63e191_f782c7ff","line":22,"in_reply_to":"ba63e191_f1aae16f","updated":"2016-01-19 18:22:39.000000000","message":"Done","commit_id":"5dfa2c2940881aa95b3de40dc0ed6e81bd6c3cde"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"8d8f66622ddcaba916e04cbdae007472eae3982b","unresolved":false,"context_lines":[{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"@base.NovaObjectRegistry.register_if(False)"},{"line_number":45,"context_line":"# Note(gibi): It is explicitly not registered as this class shall not be used"},{"line_number":46,"context_line":"# directly, it is just a base class for notification payloads."},{"line_number":47,"context_line":"class NotificationPayloadBase(base.NovaObject):"},{"line_number":48,"context_line":"    \"\"\"Base class for the payload of versioned notifications.\"\"\""}],"source_content_type":"text/x-python","patch_set":32,"id":"ba63e191_dd4b3658","line":45,"updated":"2016-01-19 14:16:04.000000000","message":"As John said before, it would be nice to get this comment above the decorator, and now that you lost the +2 on it, I\u0027m wondering if you want to handle that now...","commit_id":"5dfa2c2940881aa95b3de40dc0ed6e81bd6c3cde"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"36a76eeaf45cae49cb32a38945c554c34b8c000d","unresolved":false,"context_lines":[{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"@base.NovaObjectRegistry.register_if(False)"},{"line_number":45,"context_line":"# Note(gibi): It is explicitly not registered as this class shall not be used"},{"line_number":46,"context_line":"# directly, it is just a base class for notification payloads."},{"line_number":47,"context_line":"class NotificationPayloadBase(base.NovaObject):"},{"line_number":48,"context_line":"    \"\"\"Base class for the payload of versioned notifications.\"\"\""}],"source_content_type":"text/x-python","patch_set":32,"id":"ba63e191_17867b13","line":45,"in_reply_to":"ba63e191_dd4b3658","updated":"2016-01-19 18:22:39.000000000","message":"Done","commit_id":"5dfa2c2940881aa95b3de40dc0ed6e81bd6c3cde"},{"author":{"_account_id":2271,"name":"Michael Still","email":"mikal@stillhq.com","username":"mikalstill"},"change_message_id":"d668dfa3adeb763d90fbf9e8ee839338e2642b62","unresolved":false,"context_lines":[{"line_number":53,"context_line":"    # The \u003cpayload_field_name\u003e is the name where the data will be stored in the"},{"line_number":54,"context_line":"    # payload object, this field has to be defined as a field of the payload."},{"line_number":55,"context_line":"    # The \u003cdata_source_name\u003e shall refer to name of the parameter passed as"},{"line_number":56,"context_line":"    # kwarg to the payolad\u0027s populate_schema() call and this object will be"},{"line_number":57,"context_line":"    # used as the source of the data. The \u003cfield_of_the_data_source\u003e shall be"},{"line_number":58,"context_line":"    # a valid field of the passed argument."},{"line_number":59,"context_line":"    # The SCHEMA needs to be applied with the populate_schema() call before the"}],"source_content_type":"text/x-python","patch_set":32,"id":"ba63e191_713a7138","line":56,"range":{"start_line":56,"start_character":19,"end_line":56,"end_character":26},"updated":"2016-01-19 15:33:45.000000000","message":"payload","commit_id":"5dfa2c2940881aa95b3de40dc0ed6e81bd6c3cde"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"36a76eeaf45cae49cb32a38945c554c34b8c000d","unresolved":false,"context_lines":[{"line_number":53,"context_line":"    # The \u003cpayload_field_name\u003e is the name where the data will be stored in the"},{"line_number":54,"context_line":"    # payload object, this field has to be defined as a field of the payload."},{"line_number":55,"context_line":"    # The \u003cdata_source_name\u003e shall refer to name of the parameter passed as"},{"line_number":56,"context_line":"    # kwarg to the payolad\u0027s populate_schema() call and this object will be"},{"line_number":57,"context_line":"    # used as the source of the data. The \u003cfield_of_the_data_source\u003e shall be"},{"line_number":58,"context_line":"    # a valid field of the passed argument."},{"line_number":59,"context_line":"    # The SCHEMA needs to be applied with the populate_schema() call before the"}],"source_content_type":"text/x-python","patch_set":32,"id":"ba63e191_d778e32d","line":56,"range":{"start_line":56,"start_character":19,"end_line":56,"end_character":26},"in_reply_to":"ba63e191_713a7138","updated":"2016-01-19 18:22:39.000000000","message":"Done","commit_id":"5dfa2c2940881aa95b3de40dc0ed6e81bd6c3cde"}],"nova/tests/unit/objects/test_fields.py":[{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"3c5f0c81c88a9d70eb35dff0f196ba77a79ca9a0","unresolved":false,"context_lines":[{"line_number":966,"context_line":"        self.assertRaises(ValueError, self.field.stringify, \u0027warning\u0027)"},{"line_number":967,"context_line":""},{"line_number":968,"context_line":""},{"line_number":969,"context_line":"class TestNotificationEventTypePhaseType(TestField):"},{"line_number":970,"context_line":"    def setUp(self):"},{"line_number":971,"context_line":"        super(TestNotificationEventTypePhaseType, self).setUp()"},{"line_number":972,"context_line":"        self.field \u003d fields.NotificationPhase()"}],"source_content_type":"text/x-python","patch_set":6,"id":"9a8ffd7b_eb6d3533","line":969,"updated":"2015-11-24 19:40:51.000000000","message":"All of these test names have diverged from the actual field names after the name changes.","commit_id":"5a287dd14ee1bbdaf32b2edf7ff632ff9fb10ee1"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"bc9ac19400d8e72852120b60e3c72798dd0a7c37","unresolved":false,"context_lines":[{"line_number":966,"context_line":"        self.assertRaises(ValueError, self.field.stringify, \u0027warning\u0027)"},{"line_number":967,"context_line":""},{"line_number":968,"context_line":""},{"line_number":969,"context_line":"class TestNotificationEventTypePhaseType(TestField):"},{"line_number":970,"context_line":"    def setUp(self):"},{"line_number":971,"context_line":"        super(TestNotificationEventTypePhaseType, self).setUp()"},{"line_number":972,"context_line":"        self.field \u003d fields.NotificationPhase()"}],"source_content_type":"text/x-python","patch_set":6,"id":"9a8ffd7b_8250da5f","line":969,"in_reply_to":"9a8ffd7b_eb6d3533","updated":"2015-11-25 16:17:59.000000000","message":"Good point, I need a better IDE which can automate the renaming fully. ;)","commit_id":"5a287dd14ee1bbdaf32b2edf7ff632ff9fb10ee1"}],"nova/tests/unit/objects/test_notification.py":[{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"05447e58cf3dd71c08761af5602097b9b52a0f92","unresolved":false,"context_lines":[{"line_number":49,"context_line":"            \u0027payload\u0027: fields.ObjectField(\u0027TestNotificationPayload\u0027)"},{"line_number":50,"context_line":"        }"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    fake_service \u003d {"},{"line_number":53,"context_line":"        \u0027created_at\u0027: timeutils.utcnow().replace(microsecond\u003d0),"},{"line_number":54,"context_line":"        \u0027updated_at\u0027: None,"},{"line_number":55,"context_line":"        \u0027deleted_at\u0027: None,"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_9a903850","line":52,"updated":"2015-11-23 15:56:14.000000000","message":"Not something you need to change, but it would be nice to have a fake service in Nova.","commit_id":"82e243dcd6f68046cfa6b94b73469f542432418b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"4a84191ff5d3613c46c862202e174891013df365","unresolved":false,"context_lines":[{"line_number":49,"context_line":"            \u0027payload\u0027: fields.ObjectField(\u0027TestNotificationPayload\u0027)"},{"line_number":50,"context_line":"        }"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    fake_service \u003d {"},{"line_number":53,"context_line":"        \u0027created_at\u0027: timeutils.utcnow().replace(microsecond\u003d0),"},{"line_number":54,"context_line":"        \u0027updated_at\u0027: None,"},{"line_number":55,"context_line":"        \u0027deleted_at\u0027: None,"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a8ffd7b_aa0090ab","line":52,"in_reply_to":"ba8a016a_9a903850","updated":"2015-11-24 17:06:24.000000000","message":"Agree. I guess if I have to copy this part over to some other test later in this series then I will add a fake instead.","commit_id":"82e243dcd6f68046cfa6b94b73469f542432418b"},{"author":{"_account_id":7634,"name":"Takashi Natsume","email":"takanattie@gmail.com","username":"natsumet"},"change_message_id":"c5131d458ebb50128fc840c0260a4542a4d7eb63","unresolved":false,"context_lines":[{"line_number":163,"context_line":"                                                          \u0027field_3\u0027)"},{"line_number":164,"context_line":"        new_hash \u003d checker._get_fingerprint(\u0027TestNotificationPayload\u0027)"},{"line_number":165,"context_line":""},{"line_number":166,"context_line":"        self.assertTrue(old_hash !\u003d new_hash)"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"        del self.TestNotificationPayload.SCHEMA[\u0027field_3\u0027]"}],"source_content_type":"text/x-python","patch_set":9,"id":"9a8ffd7b_35134a68","line":166,"updated":"2015-11-26 02:34:14.000000000","message":"\u0027assertNotEqual\u0027 would be better.","commit_id":"af8b432b2378c5337426350d478902b150dafece"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"8e065e5e9bf260c36b5628896e7ebed031523078","unresolved":false,"context_lines":[{"line_number":163,"context_line":"                                                          \u0027field_3\u0027)"},{"line_number":164,"context_line":"        new_hash \u003d checker._get_fingerprint(\u0027TestNotificationPayload\u0027)"},{"line_number":165,"context_line":""},{"line_number":166,"context_line":"        self.assertTrue(old_hash !\u003d new_hash)"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"        del self.TestNotificationPayload.SCHEMA[\u0027field_3\u0027]"}],"source_content_type":"text/x-python","patch_set":9,"id":"9a8ffd7b_edbf1ca8","line":166,"in_reply_to":"9a8ffd7b_35134a68","updated":"2015-11-26 13:54:16.000000000","message":"Done","commit_id":"af8b432b2378c5337426350d478902b150dafece"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"56f5bd4cfe7cd381610fd7cbc9ad1a4ee2e843a9","unresolved":false,"context_lines":[{"line_number":170,"context_line":"            expected_event_type\u003d\u0027test_object.update\u0027,"},{"line_number":171,"context_line":"            expected_payload\u003dself.expected_payload)"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"    def test_payload_version_depends_on_the_schema(self):"},{"line_number":174,"context_line":"        checker \u003d test_objects.NotificationAwareObjectVersionChecker("},{"line_number":175,"context_line":"            {\u0027TestNotificationPayload\u0027: (self.TestNotificationPayload,)})"},{"line_number":176,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"7a740942_161ceb68","line":173,"updated":"2015-12-07 18:51:12.000000000","message":"I think this test is in the wrong place. I think it should be in test_objects.py because it involves testing the VersionChecker more than notifications.","commit_id":"7b93b069273011a66f75cc554258348ff0aa76a3"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"850e0c045939816d68c214968b025294931b00a6","unresolved":false,"context_lines":[{"line_number":170,"context_line":"            expected_event_type\u003d\u0027test_object.update\u0027,"},{"line_number":171,"context_line":"            expected_payload\u003dself.expected_payload)"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"    def test_payload_version_depends_on_the_schema(self):"},{"line_number":174,"context_line":"        checker \u003d test_objects.NotificationAwareObjectVersionChecker("},{"line_number":175,"context_line":"            {\u0027TestNotificationPayload\u0027: (self.TestNotificationPayload,)})"},{"line_number":176,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"7a740942_20508bd3","line":173,"in_reply_to":"7a740942_161ceb68","updated":"2015-12-08 15:31:18.000000000","message":"Good point.","commit_id":"7b93b069273011a66f75cc554258348ff0aa76a3"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"1dc400c17d826ad3db08960a920c1705ba1eed88","unresolved":false,"context_lines":[{"line_number":47,"context_line":"            \u0027extra_field\u0027: fields.StringField(),  # filled by ctor"},{"line_number":48,"context_line":"            \u0027field_1\u0027: fields.StringField(),  # filled by the schema"},{"line_number":49,"context_line":"            \u0027field_2\u0027: fields.IntegerField(),   # filled by the schema"},{"line_number":50,"context_line":"        }"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    @base.NovaObjectRegistry.register_if(False)"},{"line_number":53,"context_line":"    class TestNotificationPayloadEmptySchema("}],"source_content_type":"text/x-python","patch_set":22,"id":"fa69d971_40adf986","line":50,"updated":"2016-01-08 12:04:18.000000000","message":"For readability, I wonder if we should override populate_schema here, so you get something like:\n\n def populate_schema(this, source_field):\n    super(self).populate_schema(source_field\u003dsource_field)","commit_id":"3c8ca003b3c992ef93521b4b1d18765b820d7cb8"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e6b9de6f562b11cf6d4c6e2c9af7ac355d870287","unresolved":false,"context_lines":[{"line_number":47,"context_line":"            \u0027extra_field\u0027: fields.StringField(),  # filled by ctor"},{"line_number":48,"context_line":"            \u0027field_1\u0027: fields.StringField(),  # filled by the schema"},{"line_number":49,"context_line":"            \u0027field_2\u0027: fields.IntegerField(),   # filled by the schema"},{"line_number":50,"context_line":"        }"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    @base.NovaObjectRegistry.register_if(False)"},{"line_number":53,"context_line":"    class TestNotificationPayloadEmptySchema("}],"source_content_type":"text/x-python","patch_set":22,"id":"fa69d971_ceb90c30","line":50,"in_reply_to":"fa69d971_40adf986","updated":"2016-01-09 12:38:58.000000000","message":"Done","commit_id":"3c8ca003b3c992ef93521b4b1d18765b820d7cb8"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"019caf228cc56b1bb2eddf120000373b77c06d80","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2015 OpenStack Foundation"},{"line_number":2,"context_line":"# All Rights Reserved."},{"line_number":3,"context_line":"#"},{"line_number":4,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":27,"id":"fa69d971_eb959431","line":1,"updated":"2016-01-11 17:13:05.000000000","message":"not a huge deal, but year is wrong here too","commit_id":"a3479d4fd02fd1382ffdb2c333ad895b8a3b607c"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"8ced79199d3f248d5525f582c4e31ac0495f512d","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2015 OpenStack Foundation"},{"line_number":2,"context_line":"# All Rights Reserved."},{"line_number":3,"context_line":"#"},{"line_number":4,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":27,"id":"da6ed579_01ddbe0d","line":1,"in_reply_to":"fa69d971_eb959431","updated":"2016-01-13 15:05:28.000000000","message":"Done","commit_id":"a3479d4fd02fd1382ffdb2c333ad895b8a3b607c"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"bf12cf35e219f27998cb341c87972507acbe16f9","unresolved":false,"context_lines":[{"line_number":49,"context_line":"            \u0027field_2\u0027: fields.IntegerField(),   # filled by the schema"},{"line_number":50,"context_line":"        }"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"        def populate_schema(self, source_field):"},{"line_number":53,"context_line":"            super(TestNotificationBase.TestNotificationPayload,"},{"line_number":54,"context_line":"                  self).populate_schema(source_field\u003dsource_field)"},{"line_number":55,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"da6ed579_6ddef26e","line":52,"updated":"2016-01-13 11:40:45.000000000","message":"ah, thanks. not required, but I like how its easier to read.","commit_id":"a3479d4fd02fd1382ffdb2c333ad895b8a3b607c"}],"nova/tests/unit/objects/test_objects.py":[{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"88c9914fb5a3f7f1d536f3094a5e84197f112d96","unresolved":false,"context_lines":[{"line_number":1388,"context_line":"            child_versions \u003d getattr(obj_class, \u0027child_versions\u0027, {})"},{"line_number":1389,"context_line":"            child_versions[\u0027schema\u0027] \u003d collections.OrderedDict("},{"line_number":1390,"context_line":"                sorted(obj_class.SCHEMA.items()))"},{"line_number":1391,"context_line":"            setattr(obj_class, \u0027child_versions\u0027, child_versions)"},{"line_number":1392,"context_line":""},{"line_number":1393,"context_line":"        return super(NotificationAwareObjectVersionChecker,"},{"line_number":1394,"context_line":"                     self)._get_fingerprint(obj_name)"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a8ffd7b_395dd8ec","line":1391,"updated":"2015-11-30 21:50:08.000000000","message":"hmmm.... putting all of this onto child_versions seems kinda hacky. I know what you\u0027re doing here because in order for the ObjectVersionChecker to be able to see it, it needs to either be a field, remotable method, or child_versions. I\u0027m going to work on the ObjectVersionChecker fixture in o.vo to see if I can\u0027t make that a little more customizable.\n\nUntil then, I would rather see SCHEMA plopped into the class\u0027s fields, as the schema is a little more \"relevant\" to fields rather than child_versions. Someone who is not familiar with the versioned object tests would have no idea what\u0027s going on here.","commit_id":"806f5d60bc6c5615c8730b8ec32b4eb7edf4db1b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"573343bec6a02fecf2dcff6a4f704b304ab6a0a2","unresolved":false,"context_lines":[{"line_number":1388,"context_line":"            child_versions \u003d getattr(obj_class, \u0027child_versions\u0027, {})"},{"line_number":1389,"context_line":"            child_versions[\u0027schema\u0027] \u003d collections.OrderedDict("},{"line_number":1390,"context_line":"                sorted(obj_class.SCHEMA.items()))"},{"line_number":1391,"context_line":"            setattr(obj_class, \u0027child_versions\u0027, child_versions)"},{"line_number":1392,"context_line":""},{"line_number":1393,"context_line":"        return super(NotificationAwareObjectVersionChecker,"},{"line_number":1394,"context_line":"                     self)._get_fingerprint(obj_name)"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a8ffd7b_462402c4","line":1391,"in_reply_to":"9a8ffd7b_395dd8ec","updated":"2015-12-02 17:01:29.000000000","message":"You are totally right. I followed your suggestion in the next patch set","commit_id":"806f5d60bc6c5615c8730b8ec32b4eb7edf4db1b"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"8d142efb051c1ce68a428e6353a42533418b1c05","unresolved":false,"context_lines":[{"line_number":1388,"context_line":"            extra_relevant_data \u003d collections.OrderedDict("},{"line_number":1389,"context_line":"                sorted(obj_class.SCHEMA.items()))"},{"line_number":1390,"context_line":"            fields \u003d getattr(obj_class, \u0027fields\u0027, {})"},{"line_number":1391,"context_line":"            fields[\u0027schema\u0027] \u003d extra_relevant_data"},{"line_number":1392,"context_line":"            setattr(obj_class, \u0027fields\u0027, fields)"},{"line_number":1393,"context_line":""},{"line_number":1394,"context_line":"        return super(NotificationAwareObjectVersionChecker,"}],"source_content_type":"text/x-python","patch_set":14,"id":"9a8ffd7b_1a472abd","line":1391,"updated":"2015-12-02 17:43:40.000000000","message":"much better in my opinion.","commit_id":"52370dec0e465a03866f3281327380dcbab4cbde"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"cdaf5beae4ad0c5855f23bc7b6f9c1d3076d9745","unresolved":false,"context_lines":[{"line_number":1388,"context_line":"            extra_relevant_data \u003d collections.OrderedDict("},{"line_number":1389,"context_line":"                sorted(obj_class.SCHEMA.items()))"},{"line_number":1390,"context_line":"            fields \u003d getattr(obj_class, \u0027fields\u0027, {})"},{"line_number":1391,"context_line":"            fields[\u0027schema\u0027] \u003d extra_relevant_data"},{"line_number":1392,"context_line":"            setattr(obj_class, \u0027fields\u0027, fields)"},{"line_number":1393,"context_line":""},{"line_number":1394,"context_line":"        return super(NotificationAwareObjectVersionChecker,"}],"source_content_type":"text/x-python","patch_set":14,"id":"9a8ffd7b_60f9c54d","line":1391,"in_reply_to":"9a8ffd7b_1a472abd","updated":"2015-12-03 15:04:49.000000000","message":"I just realized that I have to use a more artificial name than schema as somebody might want to use that as a valid field name. So I will use something like _schema_ instead to avoid collision.","commit_id":"52370dec0e465a03866f3281327380dcbab4cbde"}]}
