)]}'
{"nova/exception.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"d70149c0553a168790d12719c92067b8a9a3a5f3","unresolved":false,"context_lines":[{"line_number":2126,"context_line":"    msg_fmt \u003d _(\"No inventory of class %(resource_class)s found.\")"},{"line_number":2127,"context_line":""},{"line_number":2128,"context_line":""},{"line_number":2129,"context_line":"class ResourceClassExists(Invalid):"},{"line_number":2130,"context_line":"    msg_fmt \u003d _(\"Resource class %(resource_class)s already exists.\")"},{"line_number":2131,"context_line":""},{"line_number":2132,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"7a77a97e_2d13acb9","line":2129,"range":{"start_line":2129,"start_character":26,"end_line":2129,"end_character":33},"updated":"2016-11-16 22:21:36.000000000","message":"Not sure we care, but this sets the code to 400 and I think at the end of this series you handle this in the REST API as a 409.","commit_id":"84414a1020553f23f3adcb3e91590e441754aba3"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"40650dceca44409d58834a81f923891bcb9d86ba","unresolved":false,"context_lines":[{"line_number":2126,"context_line":"    msg_fmt \u003d _(\"No inventory of class %(resource_class)s found.\")"},{"line_number":2127,"context_line":""},{"line_number":2128,"context_line":""},{"line_number":2129,"context_line":"class ResourceClassExists(Invalid):"},{"line_number":2130,"context_line":"    msg_fmt \u003d _(\"Resource class %(resource_class)s already exists.\")"},{"line_number":2131,"context_line":""},{"line_number":2132,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"7a77a97e_f4d311d3","line":2129,"range":{"start_line":2129,"start_character":26,"end_line":2129,"end_character":33},"in_reply_to":"7a77a97e_2d13acb9","updated":"2016-11-17 18:27:50.000000000","message":"Done","commit_id":"84414a1020553f23f3adcb3e91590e441754aba3"}],"nova/objects/resource_provider.py":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"ed4d26fe1f08015b7eb90142261422c51b60aa75","unresolved":false,"context_lines":[{"line_number":1072,"context_line":"                reason\u003d\u0027name must start with \u0027 + self.CUSTOM_NAMESPACE)"},{"line_number":1073,"context_line":""},{"line_number":1074,"context_line":"        updates \u003d self.obj_get_changes()"},{"line_number":1075,"context_line":"        next_id \u003d self._get_next_id(self._context)"},{"line_number":1076,"context_line":"        updates[\u0027id\u0027] \u003d next_id"},{"line_number":1077,"context_line":"        try:"},{"line_number":1078,"context_line":"            rc \u003d self._create_in_db(self._context, updates)"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba5da102_f010c4aa","line":1075,"updated":"2016-10-31 13:59:26.000000000","message":"I may be misunderstanding but:\n\nGetting the next id is happening outside the transaction that does the create. That, in itself, is a potential race, but also since _create_in_db is doing a session.add the resulting query could be an update not an insert, clobbering an existing class (that was  very recently created)?","commit_id":"8877ff84f62265c142489d853b82da2ae535404b"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"3aaa9d082b0a8774067115c7b3b4e61ba13d553c","unresolved":false,"context_lines":[{"line_number":1072,"context_line":"                reason\u003d\u0027name must start with \u0027 + self.CUSTOM_NAMESPACE)"},{"line_number":1073,"context_line":""},{"line_number":1074,"context_line":"        updates \u003d self.obj_get_changes()"},{"line_number":1075,"context_line":"        next_id \u003d self._get_next_id(self._context)"},{"line_number":1076,"context_line":"        updates[\u0027id\u0027] \u003d next_id"},{"line_number":1077,"context_line":"        try:"},{"line_number":1078,"context_line":"            rc \u003d self._create_in_db(self._context, updates)"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba5da102_9619408b","line":1075,"in_reply_to":"ba5da102_f010c4aa","updated":"2016-10-31 15:01:14.000000000","message":"Good catch on the trx context, Chris! I will fix this up pronto.","commit_id":"8877ff84f62265c142489d853b82da2ae535404b"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"1d952c71670281da6136899e03c27e9a160e1e99","unresolved":false,"context_lines":[{"line_number":1044,"context_line":"        \"\"\"Utility method to grab the next resource class identifier to use for"},{"line_number":1045,"context_line":"         user-defined resource classes."},{"line_number":1046,"context_line":"        \"\"\""},{"line_number":1047,"context_line":"        query \u003d context.session.query(func.max(models.ResourceClass.id))"},{"line_number":1048,"context_line":"        max_id \u003d query.one()[0]"},{"line_number":1049,"context_line":"        if not max_id:"},{"line_number":1050,"context_line":"            return ResourceClass.MIN_CUSTOM_RESOURCE_CLASS_ID"}],"source_content_type":"text/x-python","patch_set":12,"id":"7a77a97e_d34ca444","line":1047,"range":{"start_line":1047,"start_character":16,"end_line":1047,"end_character":72},"updated":"2016-11-16 18:24:25.000000000","message":"won\u0027t this be potentially racy?","commit_id":"b711f372548f3cb4daf3c60dfed6ab30cd4a4968"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"96a56ac4341fca2506245cdcc720ce0e9ac64a20","unresolved":false,"context_lines":[{"line_number":1044,"context_line":"        \"\"\"Utility method to grab the next resource class identifier to use for"},{"line_number":1045,"context_line":"         user-defined resource classes."},{"line_number":1046,"context_line":"        \"\"\""},{"line_number":1047,"context_line":"        query \u003d context.session.query(func.max(models.ResourceClass.id))"},{"line_number":1048,"context_line":"        max_id \u003d query.one()[0]"},{"line_number":1049,"context_line":"        if not max_id:"},{"line_number":1050,"context_line":"            return ResourceClass.MIN_CUSTOM_RESOURCE_CLASS_ID"}],"source_content_type":"text/x-python","patch_set":12,"id":"7a77a97e_3a004401","line":1047,"range":{"start_line":1047,"start_character":16,"end_line":1047,"end_character":72},"in_reply_to":"7a77a97e_7993b14f","updated":"2016-11-16 21:19:34.000000000","message":"I was thinking of automated tools that might, say, add a set of new ironic hardware classes at once. For that case, which won\u0027t happen regularly, I think the retry loop is cleaner. I can add that.","commit_id":"b711f372548f3cb4daf3c60dfed6ab30cd4a4968"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"31b9c6e2007ef382629a578c6420bbaa222dc1ae","unresolved":false,"context_lines":[{"line_number":1044,"context_line":"        \"\"\"Utility method to grab the next resource class identifier to use for"},{"line_number":1045,"context_line":"         user-defined resource classes."},{"line_number":1046,"context_line":"        \"\"\""},{"line_number":1047,"context_line":"        query \u003d context.session.query(func.max(models.ResourceClass.id))"},{"line_number":1048,"context_line":"        max_id \u003d query.one()[0]"},{"line_number":1049,"context_line":"        if not max_id:"},{"line_number":1050,"context_line":"            return ResourceClass.MIN_CUSTOM_RESOURCE_CLASS_ID"}],"source_content_type":"text/x-python","patch_set":12,"id":"7a77a97e_7993b14f","line":1047,"range":{"start_line":1047,"start_character":16,"end_line":1047,"end_character":72},"in_reply_to":"7a77a97e_d34ca444","updated":"2016-11-16 19:03:42.000000000","message":"Yes, there\u0027s a possibility that DbDuplicateEntry exception would be raised on line 1072. I suppose we (or you? :) ) can add a followup patch that adds a simple retry loop in the except: section in line 1075 that identifies when the primary key (the integer ID) and not the unique key on name is violated and if so, retry the _create_in_db() call.\n\nAlternatively, we could rewrite the _create_in_db() to be a pure SQLAlchemy core API insert() function call and set the value of the new record\u0027s ID column to the result of a subquery that does the essence of what _get_next_id() is doing here...","commit_id":"b711f372548f3cb4daf3c60dfed6ab30cd4a4968"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"1d952c71670281da6136899e03c27e9a160e1e99","unresolved":false,"context_lines":[{"line_number":1062,"context_line":"        if self.name in fields.ResourceClass.STANDARD:"},{"line_number":1063,"context_line":"            raise exception.ResourceClassExists(resource_class\u003dself.name)"},{"line_number":1064,"context_line":""},{"line_number":1065,"context_line":"        if not self.name.startswith(self.CUSTOM_NAMESPACE):"},{"line_number":1066,"context_line":"            raise exception.ObjectActionError("},{"line_number":1067,"context_line":"                action\u003d\u0027create\u0027,"},{"line_number":1068,"context_line":"                reason\u003d\u0027name must start with \u0027 + self.CUSTOM_NAMESPACE)"},{"line_number":1069,"context_line":""},{"line_number":1070,"context_line":"        updates \u003d self.obj_get_changes()"},{"line_number":1071,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":12,"id":"7a77a97e_13fe1c37","line":1068,"range":{"start_line":1065,"start_character":0,"end_line":1068,"end_character":71},"updated":"2016-11-16 18:24:25.000000000","message":"So the operator has to know the custom namespace string in order to create a new resource class?","commit_id":"b711f372548f3cb4daf3c60dfed6ab30cd4a4968"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"31b9c6e2007ef382629a578c6420bbaa222dc1ae","unresolved":false,"context_lines":[{"line_number":1062,"context_line":"        if self.name in fields.ResourceClass.STANDARD:"},{"line_number":1063,"context_line":"            raise exception.ResourceClassExists(resource_class\u003dself.name)"},{"line_number":1064,"context_line":""},{"line_number":1065,"context_line":"        if not self.name.startswith(self.CUSTOM_NAMESPACE):"},{"line_number":1066,"context_line":"            raise exception.ObjectActionError("},{"line_number":1067,"context_line":"                action\u003d\u0027create\u0027,"},{"line_number":1068,"context_line":"                reason\u003d\u0027name must start with \u0027 + self.CUSTOM_NAMESPACE)"},{"line_number":1069,"context_line":""},{"line_number":1070,"context_line":"        updates \u003d self.obj_get_changes()"},{"line_number":1071,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":12,"id":"7a77a97e_d9d20500","line":1068,"range":{"start_line":1065,"start_character":0,"end_line":1068,"end_character":71},"in_reply_to":"7a77a97e_13fe1c37","updated":"2016-11-16 19:03:42.000000000","message":"In the following patches you can see that calls to POST /resource_classes that pass a class name that doesn\u0027t start with CUSTOM_ will raise a 400 Bad Request and show the JSONSchema object that describes proper input format.","commit_id":"b711f372548f3cb4daf3c60dfed6ab30cd4a4968"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"96a56ac4341fca2506245cdcc720ce0e9ac64a20","unresolved":false,"context_lines":[{"line_number":1062,"context_line":"        if self.name in fields.ResourceClass.STANDARD:"},{"line_number":1063,"context_line":"            raise exception.ResourceClassExists(resource_class\u003dself.name)"},{"line_number":1064,"context_line":""},{"line_number":1065,"context_line":"        if not self.name.startswith(self.CUSTOM_NAMESPACE):"},{"line_number":1066,"context_line":"            raise exception.ObjectActionError("},{"line_number":1067,"context_line":"                action\u003d\u0027create\u0027,"},{"line_number":1068,"context_line":"                reason\u003d\u0027name must start with \u0027 + self.CUSTOM_NAMESPACE)"},{"line_number":1069,"context_line":""},{"line_number":1070,"context_line":"        updates \u003d self.obj_get_changes()"},{"line_number":1071,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":12,"id":"7a77a97e_f759855b","line":1068,"range":{"start_line":1065,"start_character":0,"end_line":1068,"end_character":71},"in_reply_to":"7a77a97e_d9d20500","updated":"2016-11-16 21:19:34.000000000","message":"Well, yes, that\u0027s what I was asking. The other option is that the namespace prefix is applied automatically; I wanted to confirm that we aren\u0027t going to do that.","commit_id":"b711f372548f3cb4daf3c60dfed6ab30cd4a4968"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"d70149c0553a168790d12719c92067b8a9a3a5f3","unresolved":false,"context_lines":[{"line_number":1051,"context_line":"    CUSTOM_NAMESPACE \u003d \u0027CUSTOM_\u0027"},{"line_number":1052,"context_line":"    \"\"\"All non-standard resource classes must begin with this string.\"\"\""},{"line_number":1053,"context_line":""},{"line_number":1054,"context_line":"    MIN_CUSTOM_RESOURCE_CLASS_ID \u003d 10000"},{"line_number":1055,"context_line":"    \"\"\"Any user-defined resource classes must have an identifier greater than"},{"line_number":1056,"context_line":"    or equal to this number."},{"line_number":1057,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":13,"id":"7a77a97e_10bb670f","line":1054,"updated":"2016-11-16 22:21:36.000000000","message":"Why do we care about this? The resource cache gets the standard resource classes from nova.objects.fields.ResourceClass.STANDARD, so we don\u0027t store those in the DB. So then wouldn\u0027t any custom resource class we store in the DB start at id\u003d1? Why do we need the 10000 buffer?","commit_id":"84414a1020553f23f3adcb3e91590e441754aba3"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"a149f54687aac388cb701518c68860c1bb72b4ab","unresolved":false,"context_lines":[{"line_number":1051,"context_line":"    CUSTOM_NAMESPACE \u003d \u0027CUSTOM_\u0027"},{"line_number":1052,"context_line":"    \"\"\"All non-standard resource classes must begin with this string.\"\"\""},{"line_number":1053,"context_line":""},{"line_number":1054,"context_line":"    MIN_CUSTOM_RESOURCE_CLASS_ID \u003d 10000"},{"line_number":1055,"context_line":"    \"\"\"Any user-defined resource classes must have an identifier greater than"},{"line_number":1056,"context_line":"    or equal to this number."},{"line_number":1057,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":13,"id":"7a77a97e_eb351cda","line":1054,"in_reply_to":"7a77a97e_10bb670f","updated":"2016-11-16 22:33:11.000000000","message":"cdent and edleafe straightened me out. I was confused on this because the id_cache and str_cache in the resource cache are only populated when calling _refresh_from_db for custom resource classes, but if we have a custom resource class with id\u003d1 that could cause string_from_id to return STANDARD.MEMORY_MB because we have an id collision, even though STANDARD.MEMORY_MB isn\u0027t in the db.","commit_id":"84414a1020553f23f3adcb3e91590e441754aba3"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"40650dceca44409d58834a81f923891bcb9d86ba","unresolved":false,"context_lines":[{"line_number":1051,"context_line":"    CUSTOM_NAMESPACE \u003d \u0027CUSTOM_\u0027"},{"line_number":1052,"context_line":"    \"\"\"All non-standard resource classes must begin with this string.\"\"\""},{"line_number":1053,"context_line":""},{"line_number":1054,"context_line":"    MIN_CUSTOM_RESOURCE_CLASS_ID \u003d 10000"},{"line_number":1055,"context_line":"    \"\"\"Any user-defined resource classes must have an identifier greater than"},{"line_number":1056,"context_line":"    or equal to this number."},{"line_number":1057,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":13,"id":"7a77a97e_476a5582","line":1054,"in_reply_to":"7a77a97e_eb351cda","updated":"2016-11-17 18:27:50.000000000","message":"yup, zactly.","commit_id":"84414a1020553f23f3adcb3e91590e441754aba3"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"d70149c0553a168790d12719c92067b8a9a3a5f3","unresolved":false,"context_lines":[{"line_number":1085,"context_line":""},{"line_number":1086,"context_line":"    @base.remotable"},{"line_number":1087,"context_line":"    def create(self):"},{"line_number":1088,"context_line":"        if \u0027id\u0027 in self:"},{"line_number":1089,"context_line":"            raise exception.ObjectActionError(action\u003d\u0027create\u0027,"},{"line_number":1090,"context_line":"                                              reason\u003d\u0027already created\u0027)"},{"line_number":1091,"context_line":"        if \u0027name\u0027 not in self:"},{"line_number":1092,"context_line":"            raise exception.ObjectActionError(action\u003d\u0027create\u0027,"},{"line_number":1093,"context_line":"                                              reason\u003d\u0027name is required\u0027)"},{"line_number":1094,"context_line":"        if self.name in fields.ResourceClass.STANDARD:"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a77a97e_1017e7ed","line":1091,"range":{"start_line":1088,"start_character":8,"end_line":1091,"end_character":30},"updated":"2016-11-16 22:21:36.000000000","message":"You don\u0027t have tests for these id and name conditions.","commit_id":"84414a1020553f23f3adcb3e91590e441754aba3"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"40650dceca44409d58834a81f923891bcb9d86ba","unresolved":false,"context_lines":[{"line_number":1085,"context_line":""},{"line_number":1086,"context_line":"    @base.remotable"},{"line_number":1087,"context_line":"    def create(self):"},{"line_number":1088,"context_line":"        if \u0027id\u0027 in self:"},{"line_number":1089,"context_line":"            raise exception.ObjectActionError(action\u003d\u0027create\u0027,"},{"line_number":1090,"context_line":"                                              reason\u003d\u0027already created\u0027)"},{"line_number":1091,"context_line":"        if \u0027name\u0027 not in self:"},{"line_number":1092,"context_line":"            raise exception.ObjectActionError(action\u003d\u0027create\u0027,"},{"line_number":1093,"context_line":"                                              reason\u003d\u0027name is required\u0027)"},{"line_number":1094,"context_line":"        if self.name in fields.ResourceClass.STANDARD:"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a77a97e_e7dfe137","line":1091,"range":{"start_line":1088,"start_character":8,"end_line":1091,"end_character":30},"in_reply_to":"7a77a97e_1017e7ed","updated":"2016-11-17 18:27:50.000000000","message":"Done","commit_id":"84414a1020553f23f3adcb3e91590e441754aba3"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"d70149c0553a168790d12719c92067b8a9a3a5f3","unresolved":false,"context_lines":[{"line_number":1088,"context_line":"        if \u0027id\u0027 in self:"},{"line_number":1089,"context_line":"            raise exception.ObjectActionError(action\u003d\u0027create\u0027,"},{"line_number":1090,"context_line":"                                              reason\u003d\u0027already created\u0027)"},{"line_number":1091,"context_line":"        if \u0027name\u0027 not in self:"},{"line_number":1092,"context_line":"            raise exception.ObjectActionError(action\u003d\u0027create\u0027,"},{"line_number":1093,"context_line":"                                              reason\u003d\u0027name is required\u0027)"},{"line_number":1094,"context_line":"        if self.name in fields.ResourceClass.STANDARD:"},{"line_number":1095,"context_line":"            raise exception.ResourceClassExists(resource_class\u003dself.name)"},{"line_number":1096,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"7a77a97e_0d035010","line":1093,"range":{"start_line":1091,"start_character":8,"end_line":1093,"end_character":72},"updated":"2016-11-16 22:21:36.000000000","message":"Hmm, seems we should make the name field nullable\u003dFalse...?","commit_id":"84414a1020553f23f3adcb3e91590e441754aba3"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"40650dceca44409d58834a81f923891bcb9d86ba","unresolved":false,"context_lines":[{"line_number":1088,"context_line":"        if \u0027id\u0027 in self:"},{"line_number":1089,"context_line":"            raise exception.ObjectActionError(action\u003d\u0027create\u0027,"},{"line_number":1090,"context_line":"                                              reason\u003d\u0027already created\u0027)"},{"line_number":1091,"context_line":"        if \u0027name\u0027 not in self:"},{"line_number":1092,"context_line":"            raise exception.ObjectActionError(action\u003d\u0027create\u0027,"},{"line_number":1093,"context_line":"                                              reason\u003d\u0027name is required\u0027)"},{"line_number":1094,"context_line":"        if self.name in fields.ResourceClass.STANDARD:"},{"line_number":1095,"context_line":"            raise exception.ResourceClassExists(resource_class\u003dself.name)"},{"line_number":1096,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"7a77a97e_07d05d1e","line":1093,"range":{"start_line":1091,"start_character":8,"end_line":1093,"end_character":72},"in_reply_to":"7a77a97e_0d035010","updated":"2016-11-17 18:27:50.000000000","message":"Done","commit_id":"84414a1020553f23f3adcb3e91590e441754aba3"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"c84e1284b2e7d8576f00a94d88106cb5891b6a34","unresolved":false,"context_lines":[{"line_number":1101,"context_line":"        updates \u003d self.obj_get_changes()"},{"line_number":1102,"context_line":"        try:"},{"line_number":1103,"context_line":"            rc \u003d self._create_in_db(self._context, updates)"},{"line_number":1104,"context_line":"            self._from_db_object(self._context, self, rc)"},{"line_number":1105,"context_line":"        except db_exc.DBDuplicateEntry:"},{"line_number":1106,"context_line":"            raise exception.ResourceClassExists(resource_class\u003dself.name)"},{"line_number":1107,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"5a74a57a_94743dfe","line":1104,"updated":"2016-11-23 05:31:11.000000000","message":"super nit, this should be out of exception block.","commit_id":"624f18417ba4707390754e780c524f86ed79cd7f"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"c84e1284b2e7d8576f00a94d88106cb5891b6a34","unresolved":false,"context_lines":[{"line_number":1103,"context_line":"            rc \u003d self._create_in_db(self._context, updates)"},{"line_number":1104,"context_line":"            self._from_db_object(self._context, self, rc)"},{"line_number":1105,"context_line":"        except db_exc.DBDuplicateEntry:"},{"line_number":1106,"context_line":"            raise exception.ResourceClassExists(resource_class\u003dself.name)"},{"line_number":1107,"context_line":""},{"line_number":1108,"context_line":"    @staticmethod"},{"line_number":1109,"context_line":"    @db_api.api_context_manager.writer"}],"source_content_type":"text/x-python","patch_set":17,"id":"5a74a57a_5451c561","line":1106,"updated":"2016-11-23 05:31:11.000000000","message":"Due to the next \u0027id\u0027 calculate in the python code, there may have conflict. The error message of this exception is good for resource class name conflict. But for the \u0027id\u0027 conflict, the message confuse people.","commit_id":"624f18417ba4707390754e780c524f86ed79cd7f"}],"nova/tests/functional/db/test_resource_provider.py":[{"author":{"_account_id":14511,"name":"Maciej Szankin","email":"maciej+review@szankin.pl","username":"mszankin"},"change_message_id":"3e5b1ddc1ee8f1e74c91e3136ed6f10a595434cd","unresolved":false,"context_lines":[{"line_number":950,"context_line":"            name\u003d\u0027CUSTOM_IRON_NFV\u0027,"},{"line_number":951,"context_line":"        )"},{"line_number":952,"context_line":"        rc.create()"},{"line_number":953,"context_line":"        self.assertEqual(objects.ResourceClass.MIN_CUSTOM_RESOURCE_CLASS_ID,"},{"line_number":954,"context_line":"                         rc.id)"},{"line_number":955,"context_line":""},{"line_number":956,"context_line":"    def test_create_duplicate_custom(self):"},{"line_number":957,"context_line":"        rc \u003d objects.ResourceClass("}],"source_content_type":"text/x-python","patch_set":12,"id":"9a629dbe_0a7bc27b","line":954,"range":{"start_line":953,"start_character":8,"end_line":954,"end_character":31},"updated":"2016-11-11 17:49:13.000000000","message":"Nit: maybe add another rc and check if the id has changed","commit_id":"b711f372548f3cb4daf3c60dfed6ab30cd4a4968"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"cec092f3aaf0a1c5623ffb14baa82a80d4973e2d","unresolved":false,"context_lines":[{"line_number":950,"context_line":"            name\u003d\u0027CUSTOM_IRON_NFV\u0027,"},{"line_number":951,"context_line":"        )"},{"line_number":952,"context_line":"        rc.create()"},{"line_number":953,"context_line":"        self.assertEqual(objects.ResourceClass.MIN_CUSTOM_RESOURCE_CLASS_ID,"},{"line_number":954,"context_line":"                         rc.id)"},{"line_number":955,"context_line":""},{"line_number":956,"context_line":"    def test_create_duplicate_custom(self):"},{"line_number":957,"context_line":"        rc \u003d objects.ResourceClass("}],"source_content_type":"text/x-python","patch_set":12,"id":"7a77a97e_f92181b5","line":954,"range":{"start_line":953,"start_character":8,"end_line":954,"end_character":31},"in_reply_to":"7a77a97e_79081192","updated":"2016-11-16 19:12:54.000000000","message":"Done","commit_id":"b711f372548f3cb4daf3c60dfed6ab30cd4a4968"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"31b9c6e2007ef382629a578c6420bbaa222dc1ae","unresolved":false,"context_lines":[{"line_number":950,"context_line":"            name\u003d\u0027CUSTOM_IRON_NFV\u0027,"},{"line_number":951,"context_line":"        )"},{"line_number":952,"context_line":"        rc.create()"},{"line_number":953,"context_line":"        self.assertEqual(objects.ResourceClass.MIN_CUSTOM_RESOURCE_CLASS_ID,"},{"line_number":954,"context_line":"                         rc.id)"},{"line_number":955,"context_line":""},{"line_number":956,"context_line":"    def test_create_duplicate_custom(self):"},{"line_number":957,"context_line":"        rc \u003d objects.ResourceClass("}],"source_content_type":"text/x-python","patch_set":12,"id":"7a77a97e_79081192","line":954,"range":{"start_line":953,"start_character":8,"end_line":954,"end_character":31},"in_reply_to":"9a629dbe_0a7bc27b","updated":"2016-11-16 19:03:42.000000000","message":"ah, good point.","commit_id":"b711f372548f3cb4daf3c60dfed6ab30cd4a4968"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"d70149c0553a168790d12719c92067b8a9a3a5f3","unresolved":false,"context_lines":[{"line_number":1021,"context_line":"            context\u003dself.context,"},{"line_number":1022,"context_line":"            name\u003d\u0027IRON_NFV\u0027,"},{"line_number":1023,"context_line":"        )"},{"line_number":1024,"context_line":"        self.assertRaises(exception.ObjectActionError, rc.create)"},{"line_number":1025,"context_line":""},{"line_number":1026,"context_line":"    def test_create_duplicate_standard(self):"},{"line_number":1027,"context_line":"        rc \u003d objects.ResourceClass("}],"source_content_type":"text/x-python","patch_set":13,"id":"7a77a97e_f056ebd0","line":1024,"updated":"2016-11-16 22:21:36.000000000","message":"nit: this would be better if you stringified the exception returned and made sure that \u0027name must start with\u0027 was in it.","commit_id":"84414a1020553f23f3adcb3e91590e441754aba3"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"40650dceca44409d58834a81f923891bcb9d86ba","unresolved":false,"context_lines":[{"line_number":1021,"context_line":"            context\u003dself.context,"},{"line_number":1022,"context_line":"            name\u003d\u0027IRON_NFV\u0027,"},{"line_number":1023,"context_line":"        )"},{"line_number":1024,"context_line":"        self.assertRaises(exception.ObjectActionError, rc.create)"},{"line_number":1025,"context_line":""},{"line_number":1026,"context_line":"    def test_create_duplicate_standard(self):"},{"line_number":1027,"context_line":"        rc \u003d objects.ResourceClass("}],"source_content_type":"text/x-python","patch_set":13,"id":"7a77a97e_aaa770bb","line":1024,"in_reply_to":"7a77a97e_f056ebd0","updated":"2016-11-17 18:27:50.000000000","message":"Done","commit_id":"84414a1020553f23f3adcb3e91590e441754aba3"}]}
