)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"9169227b521f2b6d748cd1c066a65ba0a4710a24","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Adds support for versioned schema validation for query parameters"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The new decorator \u0027query_params_schemas\u0027 to support the validation"},{"line_number":10,"context_line":"of query parameters. It also support to specific the minimum and"},{"line_number":11,"context_line":"maximum API microversion of the schema against to."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":7,"id":"7a77a97e_0896294c","line":9,"updated":"2016-11-15 16:09:33.000000000","message":"s/to support/supports/","commit_id":"a4a040cf1ce826c835f0d0ed2553d556c41b93a0"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"9169227b521f2b6d748cd1c066a65ba0a4710a24","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Adds support for versioned schema validation for query parameters"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The new decorator \u0027query_params_schemas\u0027 to support the validation"},{"line_number":10,"context_line":"of query parameters. It also support to specific the minimum and"},{"line_number":11,"context_line":"maximum API microversion of the schema against to."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"The macro function \u0027multi_params\u0027 is added. Use \u0027oneOf\u0027 to support"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":7,"id":"7a77a97e_a8945537","line":10,"updated":"2016-11-15 16:09:33.000000000","message":"It also supports the specific minimum and maximum API microversion the schema will be used with.\n\nOr something like that","commit_id":"a4a040cf1ce826c835f0d0ed2553d556c41b93a0"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"9169227b521f2b6d748cd1c066a65ba0a4710a24","unresolved":false,"context_lines":[{"line_number":11,"context_line":"maximum API microversion of the schema against to."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"The macro function \u0027multi_params\u0027 is added. Use \u0027oneOf\u0027 to support"},{"line_number":14,"context_line":"multiple values parameter will be a pattern. The macro function is"},{"line_number":15,"context_line":"used to generate that pattern."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Partial of implementation blueprint consistent-query-parameters-validation"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":7,"id":"7a77a97e_08a469a4","line":14,"updated":"2016-11-15 16:09:33.000000000","message":"This second sentence doesn\u0027t make sense, and I\u0027m not able to provide a suggestion because I don\u0027t know what the intent is.","commit_id":"a4a040cf1ce826c835f0d0ed2553d556c41b93a0"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"5753d45e35a2a811808709fecb3512f7e36d588d","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The new decorator \u0027query_params_schemas\u0027 to support the validation"},{"line_number":10,"context_line":"of query parameters. It also support to specific the minimum and"},{"line_number":11,"context_line":"maximum API microversion of the schema against to."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"The macro function \u0027multi_params\u0027 is added. It will wrap the schema"},{"line_number":14,"context_line":"into the value of \u0027oneOf\u0027 keyword. It is used to support multiple"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"3a71b18c_778c0a80","line":11,"updated":"2016-12-07 12:22:53.000000000","message":"This might be more clear:\n\nThe new decorator \u0027query_params_schemas\u0027 supports the validation or query parameters. It also supports specifying the minimum and maximum API microversion of the schema used for validation.","commit_id":"c758a607626e9a2851728a6594bc85095b3a724a"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"2fe2c71fc46253648caca71197efa9693623eb6a","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Adds support for versioned schema validation for query parameters"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The new decorator \u0027query_params_schemas\u0027 supports the validation or"},{"line_number":10,"context_line":"query parameters. It also supports specifying the minimum and maximum"},{"line_number":11,"context_line":"API microversion of the schema used for validation."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":11,"id":"1a6eadb0_b5e85318","line":9,"updated":"2016-12-12 18:29:02.000000000","message":"I\u0027m sorry, my suggestion introduced a typo: s/or/of/\n\n:(","commit_id":"e9b5306f657703cecdaee3a50ff810b2921ad2d3"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Adds support for versioned schema validation for query parameters"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The new decorator \u0027query_params_schemas\u0027 supports the validation or"},{"line_number":10,"context_line":"query parameters. It also supports specifying the minimum and maximum"},{"line_number":11,"context_line":"API microversion of the schema used for validation."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":21,"id":"ba5201f7_950ec232","line":9,"range":{"start_line":9,"start_character":65,"end_line":9,"end_character":67},"updated":"2016-12-30 23:34:03.000000000","message":"of","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"51283a8b2fc79d57ba2f52b2edd6b939c07bdd16","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Adds support for versioned schema validation for query parameters"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The new decorator \u0027query_params_schemas\u0027 supports the validation or"},{"line_number":10,"context_line":"query parameters. It also supports specifying the minimum and maximum"},{"line_number":11,"context_line":"API microversion of the schema used for validation."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":21,"id":"ba5201f7_b9400a58","line":9,"range":{"start_line":9,"start_character":65,"end_line":9,"end_character":67},"in_reply_to":"ba5201f7_950ec232","updated":"2017-01-03 08:41:18.000000000","message":"Done","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"f97626d56ae4a76a3809c84387e88011fa332170","unresolved":false,"context_lines":[{"line_number":11,"context_line":"API microversion of the schema used for validation."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"The macro function \u0027multi_params\u0027 is added. It will wrap the schema into"},{"line_number":14,"context_line":"the value of \u0027oneOf\u0027 keyword. It is used to support multiple values"},{"line_number":15,"context_line":"parameter."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Partial of implementation blueprint consistent-query-parameters-validation"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":21,"id":"ba5201f7_b4880fe9","line":14,"range":{"start_line":14,"start_character":13,"end_line":14,"end_character":20},"updated":"2017-01-03 08:57:41.000000000","message":"I also forget to update this commit message.","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":11,"context_line":"API microversion of the schema used for validation."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"The macro function \u0027multi_params\u0027 is added. It will wrap the schema into"},{"line_number":14,"context_line":"the value of \u0027oneOf\u0027 keyword. It is used to support multiple values"},{"line_number":15,"context_line":"parameter."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Partial of implementation blueprint consistent-query-parameters-validation"},{"line_number":18,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":21,"id":"ba5201f7_f51d4e67","line":15,"range":{"start_line":14,"start_character":30,"end_line":15,"end_character":10},"updated":"2016-12-30 23:34:03.000000000","message":"nit: an example might be nice for context, e.g. sort_keys.","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"51283a8b2fc79d57ba2f52b2edd6b939c07bdd16","unresolved":false,"context_lines":[{"line_number":11,"context_line":"API microversion of the schema used for validation."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"The macro function \u0027multi_params\u0027 is added. It will wrap the schema into"},{"line_number":14,"context_line":"the value of \u0027oneOf\u0027 keyword. It is used to support multiple values"},{"line_number":15,"context_line":"parameter."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Partial of implementation blueprint consistent-query-parameters-validation"},{"line_number":18,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":21,"id":"ba5201f7_993b46eb","line":15,"range":{"start_line":14,"start_character":30,"end_line":15,"end_character":10},"in_reply_to":"ba5201f7_f51d4e67","updated":"2017-01-03 08:41:18.000000000","message":"Done","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"cb25b9eeb927f2b5539166ef19ad6549c8b4b25f","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Adds support for versioned schema validation for query parameters"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The new decorator \u0027query_params_schemas\u0027 supports the validation or"},{"line_number":10,"context_line":"query parameters. It also supports specifying the minimum and maximum"},{"line_number":11,"context_line":"API microversion of the schema used for validation."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":22,"id":"ba5201f7_c77224ad","line":9,"range":{"start_line":9,"start_character":65,"end_line":9,"end_character":67},"updated":"2017-01-04 03:18:05.000000000","message":"nit: of","commit_id":"789bd82a643d148a141938a102309c7d67a6a5e9"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"cb25b9eeb927f2b5539166ef19ad6549c8b4b25f","unresolved":false,"context_lines":[{"line_number":11,"context_line":"API microversion of the schema used for validation."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"The query parameters will be converted to a dict of lists. For single"},{"line_number":14,"context_line":"value or multiple values parameter, its value alwasy be a lists. For"},{"line_number":15,"context_line":"example, the \u0027name\u0027 parameter is single value parameter and the"},{"line_number":16,"context_line":"\u0027sort_key\u0027 is multiple values parameter. They will be converted to the"},{"line_number":17,"context_line":"dict as:"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":22,"id":"ba5201f7_879f3cb3","line":14,"range":{"start_line":14,"start_character":36,"end_line":14,"end_character":63},"updated":"2017-01-04 03:18:05.000000000","message":"its value will always be a list","commit_id":"789bd82a643d148a141938a102309c7d67a6a5e9"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"cb25b9eeb927f2b5539166ef19ad6549c8b4b25f","unresolved":false,"context_lines":[{"line_number":11,"context_line":"API microversion of the schema used for validation."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"The query parameters will be converted to a dict of lists. For single"},{"line_number":14,"context_line":"value or multiple values parameter, its value alwasy be a lists. For"},{"line_number":15,"context_line":"example, the \u0027name\u0027 parameter is single value parameter and the"},{"line_number":16,"context_line":"\u0027sort_key\u0027 is multiple values parameter. They will be converted to the"},{"line_number":17,"context_line":"dict as:"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"{\u0027name\u0027: [\u0027VM1\u0027], \u0027sort_key\u0027: [\u0027display_name\u0027, \u0027updated_at\u0027]}"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"Their JSON-Schema are as below:"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"name \u003d {\u0027type\u0027: \u0027array\u0027, \u0027items\u0027: {\u0027type\u0027: \u0027string\u0027}, \u0027maxItems\u0027: 1}"},{"line_number":24,"context_line":"sort_key \u003d {\u0027type\u0027: \u0027array\u0027, \u0027items\u0027: {\u0027type\u0027: \u0027string\u0027}}"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"To get rid of the duplicated part of JSON-Schema, the macro function"},{"line_number":27,"context_line":"\u0027single_param\u0027 and \u0027multi_params\u0027 are added. Their schema can be just"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":22,"id":"ba5201f7_27bbf028","line":24,"range":{"start_line":14,"start_character":65,"end_line":24,"end_character":57},"updated":"2017-01-04 03:18:05.000000000","message":"Thanks this is helpful.","commit_id":"789bd82a643d148a141938a102309c7d67a6a5e9"}],"nova/api/validation/__init__.py":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"9169227b521f2b6d748cd1c066a65ba0a4710a24","unresolved":false,"context_lines":[{"line_number":25,"context_line":"def _build_dict_for_query_params(req):"},{"line_number":26,"context_line":"    \"\"\"This helper method converts the query parameters into a flat dict. For"},{"line_number":27,"context_line":"    multiple values, it will be converted to an array."},{"line_number":28,"context_line":"    \"\"\""},{"line_number":29,"context_line":"    ret \u003d {}"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    # `req.GET.keys` will return duplicated keys for multiple values"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a77a97e_487821f3","line":28,"updated":"2016-11-15 16:09:33.000000000","message":"it seems weird to me to be using a data structure here that a) is different from the one that is used by parse_qs in the stdlib, b) mixes lists and scalars on the value side.\n\nThat\u0027s an invitation to confusion isn\u0027t it?\n\n    \u003e\u003e\u003e import urlparse\n    \u003e\u003e\u003e urlparse.parse_qs(\u0027foo\u003d2\u0026bar\u003d1\u0026foo\u003d3\u0027)\n    {\u0027foo\u0027: [\u00272\u0027, \u00273\u0027], \u0027bar\u0027: [\u00271\u0027]}","commit_id":"a4a040cf1ce826c835f0d0ed2553d556c41b93a0"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"acd3b5e62dcec933abe3b6a3a663f1255307437f","unresolved":false,"context_lines":[{"line_number":25,"context_line":"def _build_dict_for_query_params(req):"},{"line_number":26,"context_line":"    \"\"\"This helper method converts the query parameters into a flat dict. For"},{"line_number":27,"context_line":"    multiple values, it will be converted to an array."},{"line_number":28,"context_line":"    \"\"\""},{"line_number":29,"context_line":"    ret \u003d {}"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    # `req.GET.keys` will return duplicated keys for multiple values"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a77a97e_29a900e0","line":28,"in_reply_to":"7a77a97e_01b41ecf","updated":"2016-11-16 11:49:49.000000000","message":"Thanks for the reply, I ignore that we can just validate simple value parameter with limit length of array. That leads that I think we can\u0027t implement the single value validation. Validate with the length of the list is better and simpler.","commit_id":"a4a040cf1ce826c835f0d0ed2553d556c41b93a0"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"9dc37f2dfa8cfa339b0a731c564654a5943249df","unresolved":false,"context_lines":[{"line_number":25,"context_line":"def _build_dict_for_query_params(req):"},{"line_number":26,"context_line":"    \"\"\"This helper method converts the query parameters into a flat dict. For"},{"line_number":27,"context_line":"    multiple values, it will be converted to an array."},{"line_number":28,"context_line":"    \"\"\""},{"line_number":29,"context_line":"    ret \u003d {}"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    # `req.GET.keys` will return duplicated keys for multiple values"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a77a97e_e8547422","line":28,"in_reply_to":"7a77a97e_487821f3","updated":"2016-11-16 04:52:51.000000000","message":"Same reply as in the spec. It depends on if  the \"bar\" only accepts one value, whether we allow the user to input multiple values in the request.\n\nIf {\u0027bar\u0027: \u00271\u0027}, we can know user only specify one value. If it is a list, we can distinguish that.","commit_id":"a4a040cf1ce826c835f0d0ed2553d556c41b93a0"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"c7013acc38d050428456f6000b30671eaae434d3","unresolved":false,"context_lines":[{"line_number":25,"context_line":"def _build_dict_for_query_params(req):"},{"line_number":26,"context_line":"    \"\"\"This helper method converts the query parameters into a flat dict. For"},{"line_number":27,"context_line":"    multiple values, it will be converted to an array."},{"line_number":28,"context_line":"    \"\"\""},{"line_number":29,"context_line":"    ret \u003d {}"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    # `req.GET.keys` will return duplicated keys for multiple values"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a77a97e_01b41ecf","line":28,"in_reply_to":"7a77a97e_e8547422","updated":"2016-11-16 10:59:37.000000000","message":"My issue here is not that we shouldn\u0027t be distinguishing between things which allow multiple values and those that don\u0027t. We should be doing that.\n\nThe issue is with the data structure in this method. It has two issues:\n\n* It is a single level dict with values that have mixed types. The reason for that mixed typing is to be able to distinguish one from many (by type). We can do that with the length of the list just as well. Mixing types leads to type checking in code, which is often complex.\n* This method creates a data structure (dict for query params) which has the same purpose as an well known data structure in the python stdlib (the output of parse_qs) but uses a different format. That seems like it could cause confusion.\n\nHowever, I guess it is in fact the type different that you want to be visible when you pass the dict to the schema validator, so my concern may be misplaced.\n\nBut it suggests that perhaps the way the schema validation is being modelled is a bit off. I\u0027m not sure.\n\n(It is entirely possible you can just ignore my ramblings here...)","commit_id":"a4a040cf1ce826c835f0d0ed2553d556c41b93a0"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"910ce11db73c4d065c45d406bad797ca733aabd3","unresolved":false,"context_lines":[{"line_number":121,"context_line":"            # The request object is always the second argument."},{"line_number":122,"context_line":"            # However numerous unittests pass in the request object"},{"line_number":123,"context_line":"            # via kwargs instead so we handle that as well."},{"line_number":124,"context_line":"            # TODO(cyeoh): cleanup unittests so we don\u0027t have to"},{"line_number":125,"context_line":"            # to do this"},{"line_number":126,"context_line":"            if \u0027req\u0027 in kwargs:"},{"line_number":127,"context_line":"                req \u003d kwargs[\u0027req\u0027]"},{"line_number":128,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a77a97e_3c0e128c","line":125,"range":{"start_line":124,"start_character":0,"end_line":125,"end_character":24},"updated":"2016-11-19 01:05:45.000000000","message":"We can remove this comment by changing the corresponding unit tests because of current small unit tests.","commit_id":"86ac73407edd4314db9fb4e4604e2e72b0bcd7d7"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"e8b76ebf2c8e2f0af7bb555a6048d27041aa0319","unresolved":false,"context_lines":[{"line_number":121,"context_line":"            # The request object is always the second argument."},{"line_number":122,"context_line":"            # However numerous unittests pass in the request object"},{"line_number":123,"context_line":"            # via kwargs instead so we handle that as well."},{"line_number":124,"context_line":"            # TODO(cyeoh): cleanup unittests so we don\u0027t have to"},{"line_number":125,"context_line":"            # to do this"},{"line_number":126,"context_line":"            if \u0027req\u0027 in kwargs:"},{"line_number":127,"context_line":"                req \u003d kwargs[\u0027req\u0027]"},{"line_number":128,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":8,"id":"3a71b18c_66c3c189","line":125,"range":{"start_line":124,"start_character":0,"end_line":125,"end_character":24},"in_reply_to":"3a71b18c_a4d95924","updated":"2016-12-06 07:40:31.000000000","message":"I prefer leave that to the cleanup patch. Then people won\u0027t forget to cleanup something.","commit_id":"86ac73407edd4314db9fb4e4604e2e72b0bcd7d7"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"bc0776acddf350ff69b6ece6613c3b7da01efacc","unresolved":false,"context_lines":[{"line_number":121,"context_line":"            # The request object is always the second argument."},{"line_number":122,"context_line":"            # However numerous unittests pass in the request object"},{"line_number":123,"context_line":"            # via kwargs instead so we handle that as well."},{"line_number":124,"context_line":"            # TODO(cyeoh): cleanup unittests so we don\u0027t have to"},{"line_number":125,"context_line":"            # to do this"},{"line_number":126,"context_line":"            if \u0027req\u0027 in kwargs:"},{"line_number":127,"context_line":"                req \u003d kwargs[\u0027req\u0027]"},{"line_number":128,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":8,"id":"3a71b18c_a4d95924","line":125,"range":{"start_line":124,"start_character":0,"end_line":125,"end_character":24},"in_reply_to":"5a74a57a_ed512010","updated":"2016-12-06 03:51:07.000000000","message":"Humm, this commend is for a new method query_params_schema(), not the existing schema(). So it is not necessary to copy\u0026paste this comment for a new method, I feel.","commit_id":"86ac73407edd4314db9fb4e4604e2e72b0bcd7d7"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"e1a3980e53e948730c8ed4c303def215b3846574","unresolved":false,"context_lines":[{"line_number":121,"context_line":"            # The request object is always the second argument."},{"line_number":122,"context_line":"            # However numerous unittests pass in the request object"},{"line_number":123,"context_line":"            # via kwargs instead so we handle that as well."},{"line_number":124,"context_line":"            # TODO(cyeoh): cleanup unittests so we don\u0027t have to"},{"line_number":125,"context_line":"            # to do this"},{"line_number":126,"context_line":"            if \u0027req\u0027 in kwargs:"},{"line_number":127,"context_line":"                req \u003d kwargs[\u0027req\u0027]"},{"line_number":128,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":8,"id":"5a74a57a_ed512010","line":125,"range":{"start_line":124,"start_character":0,"end_line":125,"end_character":24},"in_reply_to":"7a77a97e_3c0e128c","updated":"2016-11-23 07:23:55.000000000","message":"@Ken\u0027ichi, do you mean the cleanup works already done? so the check is at line 126 can be removed also?\n\nIf yes, I feel this should be in separated patch.","commit_id":"86ac73407edd4314db9fb4e4604e2e72b0bcd7d7"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"561791767d0cf35fd8c4b19d9eea73fe4088db8b","unresolved":false,"context_lines":[{"line_number":129,"context_line":"                req \u003d args[1]"},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"            if _schema_validation_helper(query_params_schema,"},{"line_number":132,"context_line":"                                         req.GET.dict_of_lists(),"},{"line_number":133,"context_line":"                                         min_version, max_version,"},{"line_number":134,"context_line":"                                         args, kwargs):"},{"line_number":135,"context_line":"                _strip_additional_query_parameters(query_params_schema, req)"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a77a97e_f43dd1dd","line":132,"updated":"2016-11-17 17:46:00.000000000","message":"yay!","commit_id":"86ac73407edd4314db9fb4e4604e2e72b0bcd7d7"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"8e398f75c6fb4090cb90d4317fb1aa9df55d9001","unresolved":false,"context_lines":[{"line_number":129,"context_line":"                req \u003d args[1]"},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"            if _schema_validation_helper(query_params_schema,"},{"line_number":132,"context_line":"                                         req.GET.dict_of_lists(),"},{"line_number":133,"context_line":"                                         min_version, max_version,"},{"line_number":134,"context_line":"                                         args, kwargs):"},{"line_number":135,"context_line":"                _strip_additional_query_parameters(query_params_schema, req)"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a77a97e_df5f02e3","line":132,"in_reply_to":"7a77a97e_f43dd1dd","updated":"2016-11-17 23:53:54.000000000","message":"\\o/","commit_id":"86ac73407edd4314db9fb4e4604e2e72b0bcd7d7"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"5753d45e35a2a811808709fecb3512f7e36d588d","unresolved":false,"context_lines":[{"line_number":89,"context_line":"def _strip_additional_query_parameters(schema, req):"},{"line_number":90,"context_line":"    \"\"\"Strip the additional properties from the req.GET."},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    This helper method assumes the json-schema is only describe a flat dict."},{"line_number":93,"context_line":"    If the schema is not, the schema validation will fail before calling this"},{"line_number":94,"context_line":"    method."},{"line_number":95,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":10,"id":"3a71b18c_b73a2297","line":92,"updated":"2016-12-07 12:22:53.000000000","message":"...json-schema is described as a flat dict.","commit_id":"c758a607626e9a2851728a6594bc85095b3a724a"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"ea3e4f844647a59b4105101e23fc1f7ac7440826","unresolved":false,"context_lines":[{"line_number":89,"context_line":"def _strip_additional_query_parameters(schema, req):"},{"line_number":90,"context_line":"    \"\"\"Strip the additional properties from the req.GET."},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    This helper method assumes the json-schema is only describe a flat dict."},{"line_number":93,"context_line":"    If the schema is not, the schema validation will fail before calling this"},{"line_number":94,"context_line":"    method."},{"line_number":95,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":10,"id":"3a71b18c_394ed5c1","line":92,"in_reply_to":"3a71b18c_b73a2297","updated":"2016-12-08 11:23:13.000000000","message":"Done","commit_id":"c758a607626e9a2851728a6594bc85095b3a724a"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"c5203ef7fa0384723e3a2dee3d7311c87d59ba44","unresolved":false,"context_lines":[{"line_number":143,"context_line":"                req \u003d args[1]"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"            if _schema_validation_helper(query_params_schema,"},{"line_number":146,"context_line":"                                         req.GET.dict_of_lists(),"},{"line_number":147,"context_line":"                                         min_version, max_version,"},{"line_number":148,"context_line":"                                         args, kwargs):"},{"line_number":149,"context_line":"                _strip_additional_query_parameters(query_params_schema, req)"}],"source_content_type":"text/x-python","patch_set":14,"id":"1a6eadb0_fe221e51","line":146,"range":{"start_line":146,"start_character":41,"end_line":146,"end_character":64},"updated":"2016-12-15 07:48:46.000000000","message":"this is really cool.","commit_id":"a7f6a6f0a81a864ad72bb4b2e5d0ae8d48b0683f"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"cceb4e36fd15d8fb82a48b2c6e889962a2871979","unresolved":false,"context_lines":[{"line_number":55,"context_line":"        #  legacy_v2 | 2.0                | work"},{"line_number":56,"context_line":"        #  legacy_v2 | 2.1+               | don\u0027t"},{"line_number":57,"context_line":"        if min_version is None or min_version \u003d\u003d \u00272.0\u0027:"},{"line_number":58,"context_line":"            schema_validator \u003d validators._SchemaValidator("},{"line_number":59,"context_line":"                schema, legacy_v2)"},{"line_number":60,"context_line":"            schema_validator.validate(target)"},{"line_number":61,"context_line":"            return True"},{"line_number":62,"context_line":"    elif ver.matches(min_ver, max_ver):"}],"source_content_type":"text/x-python","patch_set":15,"id":"1a6eadb0_15f747f6","line":59,"range":{"start_line":58,"start_character":0,"end_line":59,"end_character":34},"updated":"2016-12-18 21:16:49.000000000","message":"Current error message between body and query is the same like\n\n Invalid input for field/attribute %(path)s. Value: %(value)s. %(message)s\n\nAnd the above message doesn\u0027t seem good for query request.\n\nSo how about switching the message by changing class _SchemaValidator like\n\n 241     validator \u003d None\n 242     validator_org \u003d jsonschema.Draft4Validator\n 243\n - 244     def __init__(self, schema, relax_additional_properties\u003dFalse):\n + 244     def __init__(self, schema, relax_additional_properties\u003dFalse, body\u003dTrue):\n 245         validators \u003d {\n 246             \u0027minimum\u0027: self._validate_minimum,\n 247             \u0027maximum\u0027: self._validate_maximum,\n 248         }\n +           if body:\n +               field_name \u003d \u0027field/attribute\u0027\n +           else:\n +               field_name \u003d \u0027query\u0027\n [..]\n - 267                 detail \u003d _(\"Invalid input for field/attribute %(path)s.\"\n + 267                 detail \u003d _(\"Invalid input for %(field_name)S %(path)s.\"","commit_id":"8495e27477620746a3fc8bdad0698dea4d800375"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"aea8285db978d92696fb371d1d3eebfee4fbc801","unresolved":false,"context_lines":[{"line_number":55,"context_line":"        #  legacy_v2 | 2.0                | work"},{"line_number":56,"context_line":"        #  legacy_v2 | 2.1+               | don\u0027t"},{"line_number":57,"context_line":"        if min_version is None or min_version \u003d\u003d \u00272.0\u0027:"},{"line_number":58,"context_line":"            schema_validator \u003d validators._SchemaValidator("},{"line_number":59,"context_line":"                schema, legacy_v2)"},{"line_number":60,"context_line":"            schema_validator.validate(target)"},{"line_number":61,"context_line":"            return True"},{"line_number":62,"context_line":"    elif ver.matches(min_ver, max_ver):"}],"source_content_type":"text/x-python","patch_set":15,"id":"1a6eadb0_ee4bd55d","line":59,"range":{"start_line":58,"start_character":0,"end_line":59,"end_character":34},"in_reply_to":"1a6eadb0_15f747f6","updated":"2016-12-19 06:23:30.000000000","message":"yea, thanks! better message is always good. Let me try your idea.","commit_id":"8495e27477620746a3fc8bdad0698dea4d800375"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"79a6fc875344f7ba24716dfa247cc14ca7f7c3bb","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        if min_version is None or min_version \u003d\u003d \u00272.0\u0027:"},{"line_number":58,"context_line":"            schema_validator \u003d validators._SchemaValidator("},{"line_number":59,"context_line":"                schema, legacy_v2, error_message\u003d_("},{"line_number":60,"context_line":"                    \"Invalid input for query parameters %(path)s. Value: \""},{"line_number":61,"context_line":"                    \"%(value)s. %(message)s\"))"},{"line_number":62,"context_line":"            schema_validator.validate(target)"},{"line_number":63,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":16,"id":"1a6eadb0_59401136","line":60,"range":{"start_line":60,"start_character":39,"end_line":60,"end_character":44},"updated":"2016-12-19 06:57:24.000000000","message":"This code is not only for query schema, but also for body schema on legacy code.\nSo this error_message should not be passed from this method, that should be passed from query_params_schema().\nIn addition, the difference between query schema and body schema messages is just \"query\" or \"field/attribute\" only.\nWhy don\u0027t we pass the string only instead of whole error message?","commit_id":"7ed8d73146d1c5bb2f2a37af49ed185a4bb06bc2"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"deb9b719804bfbfc1b535828b3d046ffbb5ce2f0","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        if min_version is None or min_version \u003d\u003d \u00272.0\u0027:"},{"line_number":58,"context_line":"            schema_validator \u003d validators._SchemaValidator("},{"line_number":59,"context_line":"                schema, legacy_v2, error_message\u003d_("},{"line_number":60,"context_line":"                    \"Invalid input for query parameters %(path)s. Value: \""},{"line_number":61,"context_line":"                    \"%(value)s. %(message)s\"))"},{"line_number":62,"context_line":"            schema_validator.validate(target)"},{"line_number":63,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":16,"id":"1a6eadb0_e445b1b3","line":60,"range":{"start_line":60,"start_character":39,"end_line":60,"end_character":44},"in_reply_to":"1a6eadb0_59401136","updated":"2016-12-19 09:27:10.000000000","message":"oops, I passed at wrong place.\n\nYes,  we can just pass string. I pass the whole message to avoid too much hard code. But maybe, we only have those two case \"body parameters\" and \"query parameters\".","commit_id":"7ed8d73146d1c5bb2f2a37af49ed185a4bb06bc2"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"61dd0fa597cd855c2d3f320eeea274f510705134","unresolved":false,"context_lines":[{"line_number":111,"context_line":"            if param not in schema[\u0027properties\u0027].keys():"},{"line_number":112,"context_line":"                ignored_params.append(param)"},{"line_number":113,"context_line":"                del req.GET[param]"},{"line_number":114,"context_line":"        if CONF.api.enable_query_parameters_ignore_warning and ignored_params:"},{"line_number":115,"context_line":"            ignored_params.sort()"},{"line_number":116,"context_line":"            LOG.warning(_LW(\"The invalid query parameters [%s] are ignored\"),"},{"line_number":117,"context_line":"                            \", \".join(ignored_params))"}],"source_content_type":"text/x-python","patch_set":17,"id":"1a6eadb0_c257c524","line":114,"updated":"2016-12-19 10:19:13.000000000","message":"we add too many confs, I would rather have this on for everyone.","commit_id":"bc0ccdd8001b5acb1e218b439209b9c2d86eea26"},{"author":{"_account_id":2750,"name":"Sean Dague","email":"sean@dague.net","username":"sdague"},"change_message_id":"e32476b00890f037351231b288eaa8ab4a7bdff1","unresolved":false,"context_lines":[{"line_number":111,"context_line":"            if param not in schema[\u0027properties\u0027].keys():"},{"line_number":112,"context_line":"                ignored_params.append(param)"},{"line_number":113,"context_line":"                del req.GET[param]"},{"line_number":114,"context_line":"        if CONF.api.enable_query_parameters_ignore_warning and ignored_params:"},{"line_number":115,"context_line":"            ignored_params.sort()"},{"line_number":116,"context_line":"            LOG.warning(_LW(\"The invalid query parameters [%s] are ignored\"),"},{"line_number":117,"context_line":"                            \", \".join(ignored_params))"}],"source_content_type":"text/x-python","patch_set":17,"id":"1a6eadb0_11e74041","line":114,"in_reply_to":"1a6eadb0_c257c524","updated":"2016-12-19 13:41:30.000000000","message":"I think on for everyone is going to be noisey.","commit_id":"bc0ccdd8001b5acb1e218b439209b9c2d86eea26"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"61dd0fa597cd855c2d3f320eeea274f510705134","unresolved":false,"context_lines":[{"line_number":113,"context_line":"                del req.GET[param]"},{"line_number":114,"context_line":"        if CONF.api.enable_query_parameters_ignore_warning and ignored_params:"},{"line_number":115,"context_line":"            ignored_params.sort()"},{"line_number":116,"context_line":"            LOG.warning(_LW(\"The invalid query parameters [%s] are ignored\"),"},{"line_number":117,"context_line":"                            \", \".join(ignored_params))"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"1a6eadb0_c280a58e","line":116,"range":{"start_line":116,"start_character":16,"end_line":116,"end_character":23},"updated":"2016-12-19 10:19:13.000000000","message":"Thinking about this more, is warning the right level?\n\nI know we do debug for other similar things. We use info for the return code. Maybe info is a better match, as the operator can\u0027t do much to fix the warning? Not sure.","commit_id":"bc0ccdd8001b5acb1e218b439209b9c2d86eea26"},{"author":{"_account_id":2750,"name":"Sean Dague","email":"sean@dague.net","username":"sdague"},"change_message_id":"e32476b00890f037351231b288eaa8ab4a7bdff1","unresolved":false,"context_lines":[{"line_number":113,"context_line":"                del req.GET[param]"},{"line_number":114,"context_line":"        if CONF.api.enable_query_parameters_ignore_warning and ignored_params:"},{"line_number":115,"context_line":"            ignored_params.sort()"},{"line_number":116,"context_line":"            LOG.warning(_LW(\"The invalid query parameters [%s] are ignored\"),"},{"line_number":117,"context_line":"                            \", \".join(ignored_params))"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"1a6eadb0_b1ce8cb2","line":116,"range":{"start_line":116,"start_character":16,"end_line":116,"end_character":23},"in_reply_to":"1a6eadb0_c280a58e","updated":"2016-12-19 13:41:30.000000000","message":"Info seems valid, we should is this logging with enough information to trace it back to the caller?","commit_id":"bc0ccdd8001b5acb1e218b439209b9c2d86eea26"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"61dd0fa597cd855c2d3f320eeea274f510705134","unresolved":false,"context_lines":[{"line_number":142,"context_line":"            else:"},{"line_number":143,"context_line":"                req \u003d args[1]"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"            if _schema_validation_helper(query_params_schema,"},{"line_number":146,"context_line":"                                         req.GET.dict_of_lists(),"},{"line_number":147,"context_line":"                                         min_version, max_version,"},{"line_number":148,"context_line":"                                         args, kwargs, False):"}],"source_content_type":"text/x-python","patch_set":17,"id":"1a6eadb0_07946fe6","line":145,"updated":"2016-12-19 10:19:13.000000000","message":"Nit: I wish this refactor was in a separate change somehow. Finding this tricky to review.","commit_id":"bc0ccdd8001b5acb1e218b439209b9c2d86eea26"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":22,"context_line":"from nova.api.validation import validators"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"def _schema_validation_helper(schema, target, min_version, max_version,"},{"line_number":26,"context_line":"                              args, kwargs, body\u003dTrue):"},{"line_number":27,"context_line":"    min_ver \u003d api_version.APIVersionRequest(min_version)"},{"line_number":28,"context_line":"    max_ver \u003d api_version.APIVersionRequest(max_version)"},{"line_number":29,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_151bb273","line":26,"range":{"start_line":25,"start_character":30,"end_line":26,"end_character":53},"updated":"2016-12-30 23:34:03.000000000","message":"At some point since this is a helper utility it would be good to docstring the formal parameters here. We should also document what the return value means.","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"def _schema_validation_helper(schema, target, min_version, max_version,"},{"line_number":26,"context_line":"                              args, kwargs, body\u003dTrue):"},{"line_number":27,"context_line":"    min_ver \u003d api_version.APIVersionRequest(min_version)"},{"line_number":28,"context_line":"    max_ver \u003d api_version.APIVersionRequest(max_version)"},{"line_number":29,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_3526f6ba","line":26,"range":{"start_line":26,"start_character":44,"end_line":26,"end_character":48},"updated":"2016-12-30 23:34:03.000000000","message":"nit: since body is a boolean, I might name it is_body.","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"51283a8b2fc79d57ba2f52b2edd6b939c07bdd16","unresolved":false,"context_lines":[{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"def _schema_validation_helper(schema, target, min_version, max_version,"},{"line_number":26,"context_line":"                              args, kwargs, body\u003dTrue):"},{"line_number":27,"context_line":"    min_ver \u003d api_version.APIVersionRequest(min_version)"},{"line_number":28,"context_line":"    max_ver \u003d api_version.APIVersionRequest(max_version)"},{"line_number":29,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_f92292b8","line":26,"range":{"start_line":26,"start_character":44,"end_line":26,"end_character":48},"in_reply_to":"ba5201f7_3526f6ba","updated":"2017-01-03 08:41:18.000000000","message":"I will add document at here.","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":89,"context_line":"def _strip_additional_query_parameters(schema, req):"},{"line_number":90,"context_line":"    \"\"\"Strip the additional properties from the req.GET."},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    This helper method assumes the json-schema is only describe as a flat dict."},{"line_number":93,"context_line":"    If the schema is not, the schema validation will fail before calling this"},{"line_number":94,"context_line":"    method."},{"line_number":95,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_354d1673","line":92,"range":{"start_line":92,"start_character":69,"end_line":92,"end_character":78},"updated":"2016-12-30 23:34:03.000000000","message":"What do you mean by flat dict? No nesting?","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":89,"context_line":"def _strip_additional_query_parameters(schema, req):"},{"line_number":90,"context_line":"    \"\"\"Strip the additional properties from the req.GET."},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    This helper method assumes the json-schema is only describe as a flat dict."},{"line_number":93,"context_line":"    If the schema is not, the schema validation will fail before calling this"},{"line_number":94,"context_line":"    method."},{"line_number":95,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_1532d2f1","line":92,"range":{"start_line":92,"start_character":55,"end_line":92,"end_character":63},"updated":"2016-12-30 23:34:03.000000000","message":"described","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"51283a8b2fc79d57ba2f52b2edd6b939c07bdd16","unresolved":false,"context_lines":[{"line_number":89,"context_line":"def _strip_additional_query_parameters(schema, req):"},{"line_number":90,"context_line":"    \"\"\"Strip the additional properties from the req.GET."},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    This helper method assumes the json-schema is only describe as a flat dict."},{"line_number":93,"context_line":"    If the schema is not, the schema validation will fail before calling this"},{"line_number":94,"context_line":"    method."},{"line_number":95,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_5918fe84","line":92,"range":{"start_line":92,"start_character":69,"end_line":92,"end_character":78},"in_reply_to":"ba5201f7_354d1673","updated":"2017-01-03 08:41:18.000000000","message":"Yes, no nesting. So I can write it as \"a dict without nesting\"?","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":90,"context_line":"    \"\"\"Strip the additional properties from the req.GET."},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    This helper method assumes the json-schema is only describe as a flat dict."},{"line_number":93,"context_line":"    If the schema is not, the schema validation will fail before calling this"},{"line_number":94,"context_line":"    method."},{"line_number":95,"context_line":"    \"\"\""},{"line_number":96,"context_line":"    additional_properties \u003d schema.get(\u0027addtionalProperties\u0027, True)"},{"line_number":97,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_d5376ae1","line":94,"range":{"start_line":93,"start_character":4,"end_line":94,"end_character":11},"updated":"2016-12-30 23:34:03.000000000","message":"So this is asserting that _schema_validation_helper must be called before this method. We might want to be explicit about that.","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"51283a8b2fc79d57ba2f52b2edd6b939c07bdd16","unresolved":false,"context_lines":[{"line_number":90,"context_line":"    \"\"\"Strip the additional properties from the req.GET."},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    This helper method assumes the json-schema is only describe as a flat dict."},{"line_number":93,"context_line":"    If the schema is not, the schema validation will fail before calling this"},{"line_number":94,"context_line":"    method."},{"line_number":95,"context_line":"    \"\"\""},{"line_number":96,"context_line":"    additional_properties \u003d schema.get(\u0027addtionalProperties\u0027, True)"},{"line_number":97,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_791dc272","line":94,"range":{"start_line":93,"start_character":4,"end_line":94,"end_character":11},"in_reply_to":"ba5201f7_d5376ae1","updated":"2017-01-03 08:41:18.000000000","message":"Done","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    if additional_properties:"},{"line_number":99,"context_line":"        # `req.GET.keys` will return duplicated keys for multiple values"},{"line_number":100,"context_line":"        # parameters. To get rid of duplicated keys, convert it to set."},{"line_number":101,"context_line":"        ignored_params \u003d []"},{"line_number":102,"context_line":"        for param in set(req.GET.keys()):"},{"line_number":103,"context_line":"            if param not in schema[\u0027properties\u0027].keys():"},{"line_number":104,"context_line":"                ignored_params.append(param)"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_75579e02","line":101,"range":{"start_line":101,"start_character":8,"end_line":101,"end_character":22},"updated":"2016-12-30 23:34:03.000000000","message":"What are we doing with this list besides adding things do it? It\u0027s not returned at all so I don\u0027t see the point...","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"51283a8b2fc79d57ba2f52b2edd6b939c07bdd16","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    if additional_properties:"},{"line_number":99,"context_line":"        # `req.GET.keys` will return duplicated keys for multiple values"},{"line_number":100,"context_line":"        # parameters. To get rid of duplicated keys, convert it to set."},{"line_number":101,"context_line":"        ignored_params \u003d []"},{"line_number":102,"context_line":"        for param in set(req.GET.keys()):"},{"line_number":103,"context_line":"            if param not in schema[\u0027properties\u0027].keys():"},{"line_number":104,"context_line":"                ignored_params.append(param)"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_54ffe300","line":101,"range":{"start_line":101,"start_character":8,"end_line":101,"end_character":22},"in_reply_to":"ba5201f7_75579e02","updated":"2017-01-03 08:41:18.000000000","message":"sorry, there is warning message in previous patchset. I removed the message, but I forget to remove this related variable.","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":112,"context_line":"    Registered schema will be used for validating request query params just"},{"line_number":113,"context_line":"    before API method executing."},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    :argument dict query_params_schema: a schema to validate request query"},{"line_number":116,"context_line":"    parameters"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_552b7a82","line":115,"range":{"start_line":115,"start_character":4,"end_line":115,"end_character":18},"updated":"2016-12-30 23:34:03.000000000","message":"nit: I think this is usually something like:\n\n:param query_params_schema: description...\n:type query_params_schema: dict","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"51283a8b2fc79d57ba2f52b2edd6b939c07bdd16","unresolved":false,"context_lines":[{"line_number":112,"context_line":"    Registered schema will be used for validating request query params just"},{"line_number":113,"context_line":"    before API method executing."},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    :argument dict query_params_schema: a schema to validate request query"},{"line_number":116,"context_line":"    parameters"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_7404e714","line":115,"range":{"start_line":115,"start_character":4,"end_line":115,"end_character":18},"in_reply_to":"ba5201f7_552b7a82","updated":"2017-01-03 08:41:18.000000000","message":"Done","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"cb25b9eeb927f2b5539166ef19ad6549c8b4b25f","unresolved":false,"context_lines":[{"line_number":27,"context_line":"    \"\"\"A helper method to execute JSON-Schema Validation."},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"    This method checks the request version whether matches the specified max"},{"line_number":30,"context_line":"    version and min_version. It\u0027s also take a care of legacy v2 request."},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    :param schema: A dict, the JSON-Schema is used to validate the target."},{"line_number":33,"context_line":"    :param target: A dict, the target is validated by the JSON-Schema."}],"source_content_type":"text/x-python","patch_set":22,"id":"ba5201f7_a77d2070","line":30,"range":{"start_line":30,"start_character":29,"end_line":30,"end_character":72},"updated":"2017-01-04 03:18:05.000000000","message":"nit: It also takes care of legacy v2 requests.","commit_id":"789bd82a643d148a141938a102309c7d67a6a5e9"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"cb25b9eeb927f2b5539166ef19ad6549c8b4b25f","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    :param schema: A dict, the JSON-Schema is used to validate the target."},{"line_number":33,"context_line":"    :param target: A dict, the target is validated by the JSON-Schema."},{"line_number":34,"context_line":"    :param min_version: A string of two numerals. X.Y indicating the minimum"},{"line_number":35,"context_line":"                        version of the JSON-Schema against to."},{"line_number":36,"context_line":"    :param max_version: A string of two numerals. X.Y indicating the maximum"},{"line_number":37,"context_line":"                        version of the JSON-Schema against to."},{"line_number":38,"context_line":"    :param args: Positional arguments which passed into original method."}],"source_content_type":"text/x-python","patch_set":22,"id":"ba5201f7_07da6c78","line":35,"range":{"start_line":35,"start_character":51,"end_line":35,"end_character":62},"updated":"2017-01-04 03:18:05.000000000","message":"to validate against?","commit_id":"789bd82a643d148a141938a102309c7d67a6a5e9"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"cb25b9eeb927f2b5539166ef19ad6549c8b4b25f","unresolved":false,"context_lines":[{"line_number":34,"context_line":"    :param min_version: A string of two numerals. X.Y indicating the minimum"},{"line_number":35,"context_line":"                        version of the JSON-Schema against to."},{"line_number":36,"context_line":"    :param max_version: A string of two numerals. X.Y indicating the maximum"},{"line_number":37,"context_line":"                        version of the JSON-Schema against to."},{"line_number":38,"context_line":"    :param args: Positional arguments which passed into original method."},{"line_number":39,"context_line":"    :param kwargs: Keyword arguments which passed into original method."},{"line_number":40,"context_line":"    :param is_body: A boolean. Indicating whether the target is HTTP request"}],"source_content_type":"text/x-python","patch_set":22,"id":"ba5201f7_27e93015","line":37,"range":{"start_line":37,"start_character":51,"end_line":37,"end_character":62},"updated":"2017-01-04 03:18:05.000000000","message":"same","commit_id":"789bd82a643d148a141938a102309c7d67a6a5e9"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"cb25b9eeb927f2b5539166ef19ad6549c8b4b25f","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    :param kwargs: Keyword arguments which passed into original method."},{"line_number":40,"context_line":"    :param is_body: A boolean. Indicating whether the target is HTTP request"},{"line_number":41,"context_line":"                    body or not."},{"line_number":42,"context_line":"    :retval A boolean. `True` if the JSON-Schema matches the request"},{"line_number":43,"context_line":"            version otherwise `False`."},{"line_number":44,"context_line":"    \"\"\""},{"line_number":45,"context_line":"    min_ver \u003d api_version.APIVersionRequest(min_version)"}],"source_content_type":"text/x-python","patch_set":22,"id":"ba5201f7_27c0507b","line":42,"range":{"start_line":42,"start_character":5,"end_line":42,"end_character":11},"updated":"2017-01-04 03:18:05.000000000","message":"nit: I think the docstring for return values is something like this:\n\n:return: A boolean.....","commit_id":"789bd82a643d148a141938a102309c7d67a6a5e9"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"f98cbca1aadb48b9be1a5936091345ffeaf4856c","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    :param kwargs: Keyword arguments which passed into original method."},{"line_number":40,"context_line":"    :param is_body: A boolean. Indicating whether the target is HTTP request"},{"line_number":41,"context_line":"                    body or not."},{"line_number":42,"context_line":"    :retval A boolean. `True` if the JSON-Schema matches the request"},{"line_number":43,"context_line":"            version otherwise `False`."},{"line_number":44,"context_line":"    \"\"\""},{"line_number":45,"context_line":"    min_ver \u003d api_version.APIVersionRequest(min_version)"}],"source_content_type":"text/x-python","patch_set":22,"id":"ba5201f7_98679924","line":42,"range":{"start_line":42,"start_character":5,"end_line":42,"end_character":11},"in_reply_to":"ba5201f7_27c0507b","updated":"2017-01-04 06:23:00.000000000","message":"Actually I copy this from other places....\n\nAnd check the code, looks like we have multiple styles....\n\nBut I found this, there is an example http://docs.openstack.org/developer/hacking/#docstrings\n\nIt use \u0027:returns\"","commit_id":"789bd82a643d148a141938a102309c7d67a6a5e9"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"cb25b9eeb927f2b5539166ef19ad6549c8b4b25f","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    :param kwargs: Keyword arguments which passed into original method."},{"line_number":40,"context_line":"    :param is_body: A boolean. Indicating whether the target is HTTP request"},{"line_number":41,"context_line":"                    body or not."},{"line_number":42,"context_line":"    :retval A boolean. `True` if the JSON-Schema matches the request"},{"line_number":43,"context_line":"            version otherwise `False`."},{"line_number":44,"context_line":"    \"\"\""},{"line_number":45,"context_line":"    min_ver \u003d api_version.APIVersionRequest(min_version)"},{"line_number":46,"context_line":"    max_ver \u003d api_version.APIVersionRequest(max_version)"}],"source_content_type":"text/x-python","patch_set":22,"id":"ba5201f7_275770cf","line":43,"range":{"start_line":42,"start_character":23,"end_line":43,"end_character":38},"updated":"2017-01-04 03:18:05.000000000","message":"This is True iff the version range matches the request AND the schema is validated, correct? Because if the version range matches the request, we validate the schema against the target and a failure will result in a ValidationError being raised. Returning False means the version range does not match the request and no validation is performed.","commit_id":"789bd82a643d148a141938a102309c7d67a6a5e9"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"f98cbca1aadb48b9be1a5936091345ffeaf4856c","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    :param kwargs: Keyword arguments which passed into original method."},{"line_number":40,"context_line":"    :param is_body: A boolean. Indicating whether the target is HTTP request"},{"line_number":41,"context_line":"                    body or not."},{"line_number":42,"context_line":"    :retval A boolean. `True` if the JSON-Schema matches the request"},{"line_number":43,"context_line":"            version otherwise `False`."},{"line_number":44,"context_line":"    \"\"\""},{"line_number":45,"context_line":"    min_ver \u003d api_version.APIVersionRequest(min_version)"},{"line_number":46,"context_line":"    max_ver \u003d api_version.APIVersionRequest(max_version)"}],"source_content_type":"text/x-python","patch_set":22,"id":"ba5201f7_587e11af","line":43,"range":{"start_line":42,"start_character":23,"end_line":43,"end_character":38},"in_reply_to":"ba5201f7_275770cf","updated":"2017-01-04 06:23:00.000000000","message":"yea, correct.","commit_id":"789bd82a643d148a141938a102309c7d67a6a5e9"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"cb25b9eeb927f2b5539166ef19ad6549c8b4b25f","unresolved":false,"context_lines":[{"line_number":132,"context_line":"    :param query_params_schema: A dict, the JSON-Schema for validating the"},{"line_number":133,"context_line":"                                query parameters."},{"line_number":134,"context_line":"    :param min_version: A string of two numerals. X.Y indicating the minimum"},{"line_number":135,"context_line":"                        version of the JSON-Schema against to."},{"line_number":136,"context_line":"    :param max_version: A string of two numerals. X.Y indicating the maximum"},{"line_number":137,"context_line":"                        version of the JSON-Schema against to."},{"line_number":138,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":22,"id":"ba5201f7_4769d48a","line":135,"range":{"start_line":135,"start_character":51,"end_line":135,"end_character":62},"updated":"2017-01-04 03:18:05.000000000","message":"same as above","commit_id":"789bd82a643d148a141938a102309c7d67a6a5e9"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"9a6fba24e4c1cfbd5db1770805070ee3ad592d67","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    :param args: Positional arguments which passed into original method."},{"line_number":39,"context_line":"    :param kwargs: Keyword arguments which passed into original method."},{"line_number":40,"context_line":"    :param is_body: A boolean. Indicating whether the target is HTTP request"},{"line_number":41,"context_line":"                    body or not."},{"line_number":42,"context_line":"    :returns: A boolean. `True` if the JSON-Schema matches the request"},{"line_number":43,"context_line":"            version otherwise `False`."},{"line_number":44,"context_line":"    :raises: ValidationError, when the validation fails."}],"source_content_type":"text/x-python","patch_set":24,"id":"ba5201f7_c5784a2e","line":41,"updated":"2017-01-04 14:13:52.000000000","message":"Nit: part of me wonders if we should mention its only used to tweak the error messages.","commit_id":"77ad8b89babc413a18f12280d3e0f3c97ee7be95"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"9a6fba24e4c1cfbd5db1770805070ee3ad592d67","unresolved":false,"context_lines":[{"line_number":109,"context_line":"    \"\"\"Strip the additional properties from the req.GET."},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    This helper method assumes the JSON-Schema is only described as a dict"},{"line_number":112,"context_line":"    without nesting. This method should be called after query parameters pass"},{"line_number":113,"context_line":"    the JSON-Schema validation. It also means this method only can be called"},{"line_number":114,"context_line":"    after _schema_validation_helper return `True`."},{"line_number":115,"context_line":"    \"\"\""},{"line_number":116,"context_line":"    additional_properties \u003d schema.get(\u0027addtionalProperties\u0027, True)"}],"source_content_type":"text/x-python","patch_set":24,"id":"ba5201f7_e5fd4e3b","line":113,"range":{"start_line":112,"start_character":21,"end_line":113,"end_character":31},"updated":"2017-01-04 14:13:52.000000000","message":"Nit: I guess this is correct, but its more subtle than that I think.\n\nI think return false means there is no match for the decorator, so no validation occurred. If validation failed we arise an exception, so it doesn\u0027t get run anyways. If it needs a respin, might be worth correcting the wording slightly.","commit_id":"77ad8b89babc413a18f12280d3e0f3c97ee7be95"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"e82fa2f846bf691cd773ec4631ccbf4f997363da","unresolved":false,"context_lines":[{"line_number":109,"context_line":"    \"\"\"Strip the additional properties from the req.GET."},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    This helper method assumes the JSON-Schema is only described as a dict"},{"line_number":112,"context_line":"    without nesting. This method should be called after query parameters pass"},{"line_number":113,"context_line":"    the JSON-Schema validation. It also means this method only can be called"},{"line_number":114,"context_line":"    after _schema_validation_helper return `True`."},{"line_number":115,"context_line":"    \"\"\""},{"line_number":116,"context_line":"    additional_properties \u003d schema.get(\u0027addtionalProperties\u0027, True)"}],"source_content_type":"text/x-python","patch_set":24,"id":"ba5201f7_8dc39256","line":113,"range":{"start_line":112,"start_character":21,"end_line":113,"end_character":31},"in_reply_to":"ba5201f7_2ca57ab4","updated":"2017-01-05 17:42:18.000000000","message":"https://review.openstack.org/#/c/417118/","commit_id":"77ad8b89babc413a18f12280d3e0f3c97ee7be95"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6156f1b5941d18cea28d83740af42f410bcc8ac2","unresolved":false,"context_lines":[{"line_number":109,"context_line":"    \"\"\"Strip the additional properties from the req.GET."},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    This helper method assumes the JSON-Schema is only described as a dict"},{"line_number":112,"context_line":"    without nesting. This method should be called after query parameters pass"},{"line_number":113,"context_line":"    the JSON-Schema validation. It also means this method only can be called"},{"line_number":114,"context_line":"    after _schema_validation_helper return `True`."},{"line_number":115,"context_line":"    \"\"\""},{"line_number":116,"context_line":"    additional_properties \u003d schema.get(\u0027addtionalProperties\u0027, True)"}],"source_content_type":"text/x-python","patch_set":24,"id":"ba5201f7_2ca57ab4","line":113,"range":{"start_line":112,"start_character":21,"end_line":113,"end_character":31},"in_reply_to":"ba5201f7_e5fd4e3b","updated":"2017-01-04 17:00:13.000000000","message":"I\u0027d clarify the wording using what I was saying here:\n\nhttps://review.openstack.org/#/c/389003/22/nova/api/validation/__init__.py@43\n\nI can do that in a follow up patch.","commit_id":"77ad8b89babc413a18f12280d3e0f3c97ee7be95"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6156f1b5941d18cea28d83740af42f410bcc8ac2","unresolved":false,"context_lines":[{"line_number":155,"context_line":"                                         req.GET.dict_of_lists(),"},{"line_number":156,"context_line":"                                         min_version, max_version,"},{"line_number":157,"context_line":"                                         args, kwargs, is_body\u003dFalse):"},{"line_number":158,"context_line":"                # NOTE(alex_xu): The additional query parameters were stripped"},{"line_number":159,"context_line":"                # out when `additionalProperties\u003dTrue`. This is for backward"},{"line_number":160,"context_line":"                # compatible with v2.1 API and legacy v2 API. But it makes the"},{"line_number":161,"context_line":"                # system more safe for no more unexpected parameters pass down"}],"source_content_type":"text/x-python","patch_set":24,"id":"ba5201f7_8c7d861e","line":158,"updated":"2017-01-04 17:00:13.000000000","message":"Thanks for adding this.","commit_id":"77ad8b89babc413a18f12280d3e0f3c97ee7be95"}],"nova/api/validation/parameter_types.py":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"5753d45e35a2a811808709fecb3512f7e36d588d","unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":"def single_param(schema):"},{"line_number":29,"context_line":"    \"\"\"This is macro function for extra the schema to support validating the"},{"line_number":30,"context_line":"    single value query parameter."},{"line_number":31,"context_line":"    \"\"\""},{"line_number":32,"context_line":"    ret \u003d multi_params(schema)"},{"line_number":33,"context_line":"    ret[\u0027maxItems\u0027] \u003d 1"}],"source_content_type":"text/x-python","patch_set":10,"id":"3a71b18c_17a2f69a","line":30,"updated":"2016-12-07 12:22:53.000000000","message":"Try:\n\nMacro function for use in JSONSchema to support query parameters that should have only one value.\n\nor something in that realm","commit_id":"c758a607626e9a2851728a6594bc85095b3a724a"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"ea3e4f844647a59b4105101e23fc1f7ac7440826","unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":"def single_param(schema):"},{"line_number":29,"context_line":"    \"\"\"This is macro function for extra the schema to support validating the"},{"line_number":30,"context_line":"    single value query parameter."},{"line_number":31,"context_line":"    \"\"\""},{"line_number":32,"context_line":"    ret \u003d multi_params(schema)"},{"line_number":33,"context_line":"    ret[\u0027maxItems\u0027] \u003d 1"}],"source_content_type":"text/x-python","patch_set":10,"id":"3a71b18c_9999a922","line":30,"in_reply_to":"3a71b18c_17a2f69a","updated":"2016-12-08 11:23:13.000000000","message":"Done","commit_id":"c758a607626e9a2851728a6594bc85095b3a724a"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"5753d45e35a2a811808709fecb3512f7e36d588d","unresolved":false,"context_lines":[{"line_number":36,"context_line":""},{"line_number":37,"context_line":"def multi_params(schema):"},{"line_number":38,"context_line":"    \"\"\"This is macro function for extra the schema to support validating the"},{"line_number":39,"context_line":"    multiple values query parameter."},{"line_number":40,"context_line":"    \"\"\""},{"line_number":41,"context_line":"    return {\u0027type\u0027: \u0027array\u0027, \u0027items\u0027: schema}"},{"line_number":42,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"3a71b18c_77a96a7b","line":39,"updated":"2016-12-07 12:22:53.000000000","message":"Macro function for use in JSONSchema to support query parameters that may have multiple values.","commit_id":"c758a607626e9a2851728a6594bc85095b3a724a"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"ea3e4f844647a59b4105101e23fc1f7ac7440826","unresolved":false,"context_lines":[{"line_number":36,"context_line":""},{"line_number":37,"context_line":"def multi_params(schema):"},{"line_number":38,"context_line":"    \"\"\"This is macro function for extra the schema to support validating the"},{"line_number":39,"context_line":"    multiple values query parameter."},{"line_number":40,"context_line":"    \"\"\""},{"line_number":41,"context_line":"    return {\u0027type\u0027: \u0027array\u0027, \u0027items\u0027: schema}"},{"line_number":42,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"3a71b18c_19ad9931","line":39,"in_reply_to":"3a71b18c_77a96a7b","updated":"2016-12-08 11:23:13.000000000","message":"Done","commit_id":"c758a607626e9a2851728a6594bc85095b3a724a"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    \"\"\"Macro function for use in JSONSchema to support query parameters that"},{"line_number":39,"context_line":"    may have multiple values."},{"line_number":40,"context_line":"    \"\"\""},{"line_number":41,"context_line":"    return {\u0027type\u0027: \u0027array\u0027, \u0027items\u0027: schema}"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"class ValidationRegex(object):"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_d53e8ab7","line":41,"range":{"start_line":41,"start_character":30,"end_line":41,"end_character":35},"updated":"2016-12-30 23:34:03.000000000","message":"We have to be careful about this since it assumes that everything in the array is going to be validated against the same schema, and not a tuple where the schema is applied on each individual element and those can be different - we ran into that problem with the block_device_mapping schema.\n\nThere are more details here:\n\nhttps://spacetelescope.github.io/understanding-json-schema/reference/array.html","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"51283a8b2fc79d57ba2f52b2edd6b939c07bdd16","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    \"\"\"Macro function for use in JSONSchema to support query parameters that"},{"line_number":39,"context_line":"    may have multiple values."},{"line_number":40,"context_line":"    \"\"\""},{"line_number":41,"context_line":"    return {\u0027type\u0027: \u0027array\u0027, \u0027items\u0027: schema}"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"class ValidationRegex(object):"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_34325ff2","line":41,"range":{"start_line":41,"start_character":30,"end_line":41,"end_character":35},"in_reply_to":"ba5201f7_d53e8ab7","updated":"2017-01-03 08:41:18.000000000","message":"Yea, we are good at here.","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"}],"nova/api/validation/validators.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":242,"context_line":"    validator_org \u003d jsonschema.Draft4Validator"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"    def __init__(self, schema, relax_additional_properties\u003dFalse, body\u003dTrue):"},{"line_number":245,"context_line":"        self.body \u003d body"},{"line_number":246,"context_line":"        validators \u003d {"},{"line_number":247,"context_line":"            \u0027minimum\u0027: self._validate_minimum,"},{"line_number":248,"context_line":"            \u0027maximum\u0027: self._validate_maximum,"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_1549f25f","line":245,"range":{"start_line":245,"start_character":13,"end_line":245,"end_character":17},"updated":"2016-12-30 23:34:03.000000000","message":"Again I\u0027d name this is_body or something to show it\u0027s a boolean and not the actual request body being validated.","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"51283a8b2fc79d57ba2f52b2edd6b939c07bdd16","unresolved":false,"context_lines":[{"line_number":242,"context_line":"    validator_org \u003d jsonschema.Draft4Validator"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"    def __init__(self, schema, relax_additional_properties\u003dFalse, body\u003dTrue):"},{"line_number":245,"context_line":"        self.body \u003d body"},{"line_number":246,"context_line":"        validators \u003d {"},{"line_number":247,"context_line":"            \u0027minimum\u0027: self._validate_minimum,"},{"line_number":248,"context_line":"            \u0027maximum\u0027: self._validate_maximum,"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_544d2371","line":245,"range":{"start_line":245,"start_character":13,"end_line":245,"end_character":17},"in_reply_to":"ba5201f7_1549f25f","updated":"2017-01-03 08:41:18.000000000","message":"Done","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":270,"context_line":"                    detail \u003d _(\"Invalid input for field/attribute %(path)s. \""},{"line_number":271,"context_line":"                               \"Value: %(value)s. %(message)s\")"},{"line_number":272,"context_line":"                else:"},{"line_number":273,"context_line":"                    detail \u003d _(\"Invalid input for query parameters %(path)s \""},{"line_number":274,"context_line":"                               \"Value: %(value)s. %(message)s\")"},{"line_number":275,"context_line":"                # NOTE: For whole OpenStack message consistency, this error"},{"line_number":276,"context_line":"                #       message has been written as the similar format of WSME."}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_3574369b","line":273,"range":{"start_line":273,"start_character":75,"end_line":273,"end_character":76},"updated":"2016-12-30 23:34:03.000000000","message":"Let\u0027s end this sentence with a period.","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"51283a8b2fc79d57ba2f52b2edd6b939c07bdd16","unresolved":false,"context_lines":[{"line_number":270,"context_line":"                    detail \u003d _(\"Invalid input for field/attribute %(path)s. \""},{"line_number":271,"context_line":"                               \"Value: %(value)s. %(message)s\")"},{"line_number":272,"context_line":"                else:"},{"line_number":273,"context_line":"                    detail \u003d _(\"Invalid input for query parameters %(path)s \""},{"line_number":274,"context_line":"                               \"Value: %(value)s. %(message)s\")"},{"line_number":275,"context_line":"                # NOTE: For whole OpenStack message consistency, this error"},{"line_number":276,"context_line":"                #       message has been written as the similar format of WSME."}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_b45c8f26","line":273,"range":{"start_line":273,"start_character":75,"end_line":273,"end_character":76},"in_reply_to":"ba5201f7_3574369b","updated":"2017-01-03 08:41:18.000000000","message":"Done","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"cb25b9eeb927f2b5539166ef19ad6549c8b4b25f","unresolved":false,"context_lines":[{"line_number":242,"context_line":"    validator_org \u003d jsonschema.Draft4Validator"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"    def __init__(self, schema, relax_additional_properties\u003dFalse,"},{"line_number":245,"context_line":"            is_body\u003dTrue):"},{"line_number":246,"context_line":"        self.is_body \u003d is_body"},{"line_number":247,"context_line":"        validators \u003d {"},{"line_number":248,"context_line":"            \u0027minimum\u0027: self._validate_minimum,"}],"source_content_type":"text/x-python","patch_set":22,"id":"ba5201f7_a710c002","line":245,"updated":"2017-01-04 03:18:05.000000000","message":"nit: please align this with the \"self\" arg above.","commit_id":"789bd82a643d148a141938a102309c7d67a6a5e9"}],"nova/conf/api.py":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"0ccd1daeca57cd0b4738d5ab563344a1deb111e2","unresolved":false,"context_lines":[{"line_number":241,"context_line":"        help\u003d\"\"\""},{"line_number":242,"context_line":"The invalid query parameter will be ignored to protect the system. When"},{"line_number":243,"context_line":"this option enabled, a warning message will be emitted about any invalid"},{"line_number":244,"context_line":"query parameter ignored."},{"line_number":245,"context_line":"\"\"\"),"},{"line_number":246,"context_line":"]"},{"line_number":247,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"1a6eadb0_26ae3fe6","line":244,"updated":"2016-12-15 13:42:15.000000000","message":"Invalid query parameters will be ignored to protect the system. When this option is set to True, a warning message will be emitted when invalid query parameters are used.","commit_id":"a7f6a6f0a81a864ad72bb4b2e5d0ae8d48b0683f"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"abea0a799b0e91e45bf4f942ef2bbb81937e2380","unresolved":false,"context_lines":[{"line_number":241,"context_line":"        help\u003d\"\"\""},{"line_number":242,"context_line":"The invalid query parameter will be ignored to protect the system. When"},{"line_number":243,"context_line":"this option enabled, a warning message will be emitted about any invalid"},{"line_number":244,"context_line":"query parameter ignored."},{"line_number":245,"context_line":"\"\"\"),"},{"line_number":246,"context_line":"]"},{"line_number":247,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"1a6eadb0_a684e10a","line":244,"in_reply_to":"1a6eadb0_26ae3fe6","updated":"2016-12-16 11:04:40.000000000","message":"thanks","commit_id":"a7f6a6f0a81a864ad72bb4b2e5d0ae8d48b0683f"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"cceb4e36fd15d8fb82a48b2c6e889962a2871979","unresolved":false,"context_lines":[{"line_number":237,"context_line":"* Any string, including an empty string (the default)."},{"line_number":238,"context_line":"\"\"\"),"},{"line_number":239,"context_line":"    cfg.BoolOpt(\"enable_query_parameters_ignore_warning\","},{"line_number":240,"context_line":"        default\u003dTrue,"},{"line_number":241,"context_line":"        help\u003d\"\"\""},{"line_number":242,"context_line":"Invalid query parameters will be ignored to protect the system. When"},{"line_number":243,"context_line":"this option is set to True, a warning message will be emitted when invalid"}],"source_content_type":"text/x-python","patch_set":15,"id":"1a6eadb0_155bc72f","line":240,"range":{"start_line":240,"start_character":16,"end_line":240,"end_character":20},"updated":"2016-12-18 21:16:49.000000000","message":"TBH, I don\u0027t think this option/warning bring much merit for us.\nThe invalid query is due to client side mistake, not operator side. So even if outputting the warning, the operator cannot do anything. They just know that.\nBecause of the above principle, Nova doesn\u0027t output any logs(including debug) when invalid inputs come.","commit_id":"8495e27477620746a3fc8bdad0698dea4d800375"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"aea8285db978d92696fb371d1d3eebfee4fbc801","unresolved":false,"context_lines":[{"line_number":237,"context_line":"* Any string, including an empty string (the default)."},{"line_number":238,"context_line":"\"\"\"),"},{"line_number":239,"context_line":"    cfg.BoolOpt(\"enable_query_parameters_ignore_warning\","},{"line_number":240,"context_line":"        default\u003dTrue,"},{"line_number":241,"context_line":"        help\u003d\"\"\""},{"line_number":242,"context_line":"Invalid query parameters will be ignored to protect the system. When"},{"line_number":243,"context_line":"this option is set to True, a warning message will be emitted when invalid"}],"source_content_type":"text/x-python","patch_set":15,"id":"1a6eadb0_41258108","line":240,"range":{"start_line":240,"start_character":16,"end_line":240,"end_character":20},"in_reply_to":"1a6eadb0_155bc72f","updated":"2016-12-19 06:23:30.000000000","message":"Yea, I have same point with you. This proposed by Sean and John. I talk with them, but finally I agree there is a little help for the admin to know what happened. It also gives a chance to the user turn it off.\n\nAs my understand, the purpose of this option is for reminding the admin user about there is change happened.","commit_id":"8495e27477620746a3fc8bdad0698dea4d800375"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"61dd0fa597cd855c2d3f320eeea274f510705134","unresolved":false,"context_lines":[{"line_number":236,"context_line":""},{"line_number":237,"context_line":"* Any string, including an empty string (the default)."},{"line_number":238,"context_line":"\"\"\"),"},{"line_number":239,"context_line":"    cfg.BoolOpt(\"enable_query_parameters_ignore_warning\","},{"line_number":240,"context_line":"        default\u003dTrue,"},{"line_number":241,"context_line":"        help\u003d\"\"\""},{"line_number":242,"context_line":"Invalid query parameters will be ignored to protect the system. When"}],"source_content_type":"text/x-python","patch_set":17,"id":"1a6eadb0_a7081b2f","line":239,"updated":"2016-12-19 10:19:13.000000000","message":"Honestly, I question the need to have a config, I would just always warn on this. It shouldn\u0027t happen very often.\n\nHow often does this happen in the gate tests, thats worth a quick check.","commit_id":"bc0ccdd8001b5acb1e218b439209b9c2d86eea26"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"fbc1e642cbfceba63657d996b8a2c62f68e5c309","unresolved":false,"context_lines":[{"line_number":236,"context_line":""},{"line_number":237,"context_line":"* Any string, including an empty string (the default)."},{"line_number":238,"context_line":"\"\"\"),"},{"line_number":239,"context_line":"    cfg.BoolOpt(\"enable_query_parameters_ignore_warning\","},{"line_number":240,"context_line":"        default\u003dTrue,"},{"line_number":241,"context_line":"        help\u003d\"\"\""},{"line_number":242,"context_line":"Invalid query parameters will be ignored to protect the system. When"},{"line_number":243,"context_line":"this option is set to True, a warning message will be emitted when invalid"},{"line_number":244,"context_line":"query parameters are used."},{"line_number":245,"context_line":"\"\"\"),"},{"line_number":246,"context_line":"]"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"allow_instance_snapshots_opts \u003d ["}],"source_content_type":"text/x-python","patch_set":18,"id":"1a6eadb0_2785bd58","line":245,"range":{"start_line":239,"start_character":0,"end_line":245,"end_character":5},"updated":"2016-12-20 04:54:41.000000000","message":"This option becomes unused on current PS.","commit_id":"0668fc99a00dc84a4e93725d2df4b22b9a87746d"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"0ac72b0bc15c5a972c0c462c9b19d1db771f049d","unresolved":false,"context_lines":[{"line_number":236,"context_line":""},{"line_number":237,"context_line":"* Any string, including an empty string (the default)."},{"line_number":238,"context_line":"\"\"\"),"},{"line_number":239,"context_line":"    cfg.BoolOpt(\"enable_query_parameters_ignore_warning\","},{"line_number":240,"context_line":"        default\u003dTrue,"},{"line_number":241,"context_line":"        help\u003d\"\"\""},{"line_number":242,"context_line":"Invalid query parameters will be ignored to protect the system. When"},{"line_number":243,"context_line":"this option is set to True, a warning message will be emitted when invalid"},{"line_number":244,"context_line":"query parameters are used."},{"line_number":245,"context_line":"\"\"\"),"},{"line_number":246,"context_line":"]"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"allow_instance_snapshots_opts \u003d ["}],"source_content_type":"text/x-python","patch_set":18,"id":"1a6eadb0_4e0f2ee1","line":245,"range":{"start_line":239,"start_character":0,"end_line":245,"end_character":5},"in_reply_to":"1a6eadb0_2785bd58","updated":"2016-12-20 07:38:55.000000000","message":"sorry, I forget to remove it.","commit_id":"0668fc99a00dc84a4e93725d2df4b22b9a87746d"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"33d19a92a5e980a315e7b1ecda4aecb1e6801b2a","unresolved":false,"context_lines":[{"line_number":236,"context_line":""},{"line_number":237,"context_line":"* Any string, including an empty string (the default)."},{"line_number":238,"context_line":"\"\"\"),"},{"line_number":239,"context_line":"    cfg.BoolOpt(\"enable_query_parameters_ignore_warning\","},{"line_number":240,"context_line":"        default\u003dTrue,"},{"line_number":241,"context_line":"        help\u003d\"\"\""},{"line_number":242,"context_line":"The invalid query parameter will be ignored to protect the system. When"},{"line_number":243,"context_line":"this option enabled, a warning message will be emitted about any invalid"},{"line_number":244,"context_line":"query parameter ignored."},{"line_number":245,"context_line":"\"\"\"),"},{"line_number":246,"context_line":"]"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"allow_instance_snapshots_opts \u003d ["}],"source_content_type":"text/x-python","patch_set":20,"id":"da4df55a_80f837e7","line":245,"range":{"start_line":239,"start_character":4,"end_line":245,"end_character":5},"updated":"2016-12-22 16:25:34.000000000","message":"I had to read the spec again to understand what this was for. The spec says:\n\nhttps://specs.openstack.org/openstack/nova-specs/specs/ocata/approved/consistent-query-parameters-validation.html\n\n\"The value of additionalProperties will be True until we decide to restrict the parameters in the future, and it will be changed with new microversion. For now we still need to enable the random input in the query string. But the extra parameters will be stripped out for protecting the system. Also for matching the current behaviour, we need to enable multiple values for all the parameters(using the macro function ‘multi_params’ to extract the schema for multiple values). For the legacy v2 API mode, the value of additionalProperties should be True also, it makes the legacy v2 API mode under the protection also.\"\n\nI\u0027m assuming the reason a config option was added here came up in a previous review, but I don\u0027t see the need for it, especially at warning level.\n\nThe invalid query parameters are really the client/user\u0027s issue, not the admin/operator of the cloud. So logging a warning is inappropriate when the client is making a bad request, as there isn\u0027t anything the operator can do about it. The spec says that we\u0027ll just ignore those extra query paramaters for now if additionalProperties is True, which I think is OK. And then in a later microversion once we have parameter validation on the APIs that have additionalProperties\u003dTrue, we can make that False and return a 400 for a bad request, which is really what it is from the client side.\n\nSo I\u0027m -1 on adding a config option for this and logging it as a warning. If anything, just log these at debug I guess in case a user submits an issue against the cloud provider saying they are making a certain request which doesn\u0027t behave as they expect.","commit_id":"46bb2f51efef43ba55da5361598fcad9a73ff58d"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"4886fa2ab35ab964a48c5e075871e57c9e87008e","unresolved":false,"context_lines":[{"line_number":236,"context_line":""},{"line_number":237,"context_line":"* Any string, including an empty string (the default)."},{"line_number":238,"context_line":"\"\"\"),"},{"line_number":239,"context_line":"    cfg.BoolOpt(\"enable_query_parameters_ignore_warning\","},{"line_number":240,"context_line":"        default\u003dTrue,"},{"line_number":241,"context_line":"        help\u003d\"\"\""},{"line_number":242,"context_line":"The invalid query parameter will be ignored to protect the system. When"},{"line_number":243,"context_line":"this option enabled, a warning message will be emitted about any invalid"},{"line_number":244,"context_line":"query parameter ignored."},{"line_number":245,"context_line":"\"\"\"),"},{"line_number":246,"context_line":"]"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"allow_instance_snapshots_opts \u003d ["}],"source_content_type":"text/x-python","patch_set":20,"id":"da4df55a_89b69288","line":245,"range":{"start_line":239,"start_character":4,"end_line":245,"end_character":5},"in_reply_to":"da4df55a_202ceb49","updated":"2016-12-23 01:16:19.000000000","message":"yea, it should INFO. And for the config opt, people have different opinion. Finally we move this bit to the later.\n\nI guess the patch just revert to old version accidentally","commit_id":"46bb2f51efef43ba55da5361598fcad9a73ff58d"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"0cef3003dec71f8e4cefb062e9daeb057a4bd578","unresolved":false,"context_lines":[{"line_number":236,"context_line":""},{"line_number":237,"context_line":"* Any string, including an empty string (the default)."},{"line_number":238,"context_line":"\"\"\"),"},{"line_number":239,"context_line":"    cfg.BoolOpt(\"enable_query_parameters_ignore_warning\","},{"line_number":240,"context_line":"        default\u003dTrue,"},{"line_number":241,"context_line":"        help\u003d\"\"\""},{"line_number":242,"context_line":"The invalid query parameter will be ignored to protect the system. When"},{"line_number":243,"context_line":"this option enabled, a warning message will be emitted about any invalid"},{"line_number":244,"context_line":"query parameter ignored."},{"line_number":245,"context_line":"\"\"\"),"},{"line_number":246,"context_line":"]"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"allow_instance_snapshots_opts \u003d ["}],"source_content_type":"text/x-python","patch_set":20,"id":"da4df55a_202ceb49","line":245,"range":{"start_line":239,"start_character":4,"end_line":245,"end_character":5},"in_reply_to":"da4df55a_80f837e7","updated":"2016-12-22 16:27:59.000000000","message":"As discussed here:\n\nhttps://review.openstack.org/#/c/389003/17/nova/api/validation/__init__.py@114\n\nI\u0027d be OK with INFO also as that\u0027s probably what most people are running in production so then they don\u0027t have to enable debug to see these if they get a ticket.","commit_id":"46bb2f51efef43ba55da5361598fcad9a73ff58d"}],"nova/tests/unit/test_api_validation.py":[{"author":{"_account_id":6062,"name":"jichenjc","email":"jichenjc@cn.ibm.com","username":"jichenjc"},"change_message_id":"8721d943ab873fceea4df282f9731e04e4cfaaf1","unresolved":false,"context_lines":[{"line_number":242,"context_line":""},{"line_number":243,"context_line":"    def test_validate_request_with_multiple_values_failes(self):"},{"line_number":244,"context_line":"        req \u003d fakes.HTTPRequest.blank("},{"line_number":245,"context_line":"            \"/tests?foo\u003d%s\u0026foo\u003d%s\" % (fakes.FAKE_UUID, fakes.FAKE_UUID))"},{"line_number":246,"context_line":"        self.assertRaises(exception.ValidationError, self.get, req\u003dreq)"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9a629dbe_316cb734","line":245,"range":{"start_line":245,"start_character":35,"end_line":245,"end_character":36},"updated":"2016-11-10 13:28:25.000000000","message":"maybe worthy add a \nfoo\u003dabc\u0026foo\u003dFAKE_UUID to make sure one valid and one invalid still fail in validation","commit_id":"6bf42c017c2d115d69094776f1f261752c574a27"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"9334f9651072a945c9b1f367909a45d1cfb7bb9e","unresolved":false,"context_lines":[{"line_number":242,"context_line":""},{"line_number":243,"context_line":"    def test_validate_request_with_multiple_values_failes(self):"},{"line_number":244,"context_line":"        req \u003d fakes.HTTPRequest.blank("},{"line_number":245,"context_line":"            \"/tests?foo\u003d%s\u0026foo\u003d%s\" % (fakes.FAKE_UUID, fakes.FAKE_UUID))"},{"line_number":246,"context_line":"        self.assertRaises(exception.ValidationError, self.get, req\u003dreq)"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9a629dbe_61af207d","line":245,"range":{"start_line":245,"start_character":35,"end_line":245,"end_character":36},"in_reply_to":"9a629dbe_316cb734","updated":"2016-11-11 05:32:58.000000000","message":"Emm...this case is for the single value parameter won\u0027t accept multiple value.","commit_id":"6bf42c017c2d115d69094776f1f261752c574a27"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":219,"context_line":"        }"},{"line_number":220,"context_line":""},{"line_number":221,"context_line":"        @validation.query_params_schema(schema, \u00272.3\u0027)"},{"line_number":222,"context_line":"        def get(req):"},{"line_number":223,"context_line":"            return list(set(req.GET.keys()))"},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"        self.get \u003d get"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_55a0daf4","line":222,"range":{"start_line":222,"start_character":16,"end_line":222,"end_character":19},"updated":"2016-12-30 23:34:03.000000000","message":"Make the args (self, req) so we don\u0027t need to use kwargs for passing req in? See below.","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":227,"context_line":"    def test_validate_request(self):"},{"line_number":228,"context_line":"        req \u003d fakes.HTTPRequest.blank(\"/tests?foo\u003d%s\" % fakes.FAKE_UUID)"},{"line_number":229,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.3\")"},{"line_number":230,"context_line":"        self.assertEqual(self.get(req\u003dreq),"},{"line_number":231,"context_line":"                         [\u0027foo\u0027])"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"    def test_validate_request_failed(self):"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_f562aed7","line":230,"range":{"start_line":230,"start_character":34,"end_line":230,"end_character":41},"updated":"2016-12-30 23:34:03.000000000","message":"Funny, there is a TODO in the code you\u0027ve added that says there are unit tests passing req as a kwarg and we should clean those up, but here you\u0027re doing it...","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"51283a8b2fc79d57ba2f52b2edd6b939c07bdd16","unresolved":false,"context_lines":[{"line_number":227,"context_line":"    def test_validate_request(self):"},{"line_number":228,"context_line":"        req \u003d fakes.HTTPRequest.blank(\"/tests?foo\u003d%s\" % fakes.FAKE_UUID)"},{"line_number":229,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.3\")"},{"line_number":230,"context_line":"        self.assertEqual(self.get(req\u003dreq),"},{"line_number":231,"context_line":"                         [\u0027foo\u0027])"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"    def test_validate_request_failed(self):"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_34609fce","line":230,"range":{"start_line":230,"start_character":34,"end_line":230,"end_character":41},"in_reply_to":"ba5201f7_f562aed7","updated":"2017-01-03 08:41:18.000000000","message":"Ah, sorry about that.","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":228,"context_line":"        req \u003d fakes.HTTPRequest.blank(\"/tests?foo\u003d%s\" % fakes.FAKE_UUID)"},{"line_number":229,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.3\")"},{"line_number":230,"context_line":"        self.assertEqual(self.get(req\u003dreq),"},{"line_number":231,"context_line":"                         [\u0027foo\u0027])"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"    def test_validate_request_failed(self):"},{"line_number":234,"context_line":"        req \u003d fakes.HTTPRequest.blank(\"/tests?foo\u003dabc\")"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_359b56cb","line":231,"range":{"start_line":231,"start_character":25,"end_line":231,"end_character":32},"updated":"2016-12-30 23:34:03.000000000","message":"The formal arguments to assertEqual are (expected, observed) so this order is backward in your assertion and if it fails, the MismatchError message will be confusing because the Actual and Reference values will be wrong, which makes debugging test failures difficult, so please fix the arg ordering here.","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"51283a8b2fc79d57ba2f52b2edd6b939c07bdd16","unresolved":false,"context_lines":[{"line_number":228,"context_line":"        req \u003d fakes.HTTPRequest.blank(\"/tests?foo\u003d%s\" % fakes.FAKE_UUID)"},{"line_number":229,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.3\")"},{"line_number":230,"context_line":"        self.assertEqual(self.get(req\u003dreq),"},{"line_number":231,"context_line":"                         [\u0027foo\u0027])"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"    def test_validate_request_failed(self):"},{"line_number":234,"context_line":"        req \u003d fakes.HTTPRequest.blank(\"/tests?foo\u003dabc\")"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_74a067f5","line":231,"range":{"start_line":231,"start_character":25,"end_line":231,"end_character":32},"in_reply_to":"ba5201f7_359b56cb","updated":"2017-01-03 08:41:18.000000000","message":"Done","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":231,"context_line":"                         [\u0027foo\u0027])"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"    def test_validate_request_failed(self):"},{"line_number":234,"context_line":"        req \u003d fakes.HTTPRequest.blank(\"/tests?foo\u003dabc\")"},{"line_number":235,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.3\")"},{"line_number":236,"context_line":"        self.assertRaises(exception.ValidationError, self.get, req\u003dreq)"},{"line_number":237,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_b5af46e2","line":234,"range":{"start_line":234,"start_character":50,"end_line":234,"end_character":53},"updated":"2016-12-30 23:34:03.000000000","message":"nit: Fails because it\u0027s not a uuid - I find adding a short comment about what the test is testing helpful for review and maintenance purposes.","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"51283a8b2fc79d57ba2f52b2edd6b939c07bdd16","unresolved":false,"context_lines":[{"line_number":231,"context_line":"                         [\u0027foo\u0027])"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"    def test_validate_request_failed(self):"},{"line_number":234,"context_line":"        req \u003d fakes.HTTPRequest.blank(\"/tests?foo\u003dabc\")"},{"line_number":235,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.3\")"},{"line_number":236,"context_line":"        self.assertRaises(exception.ValidationError, self.get, req\u003dreq)"},{"line_number":237,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_94a5cb05","line":234,"range":{"start_line":234,"start_character":50,"end_line":234,"end_character":53},"in_reply_to":"ba5201f7_b5af46e2","updated":"2017-01-03 08:41:18.000000000","message":"Done","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":238,"context_line":"    def test_validate_request_with_multiple_values(self):"},{"line_number":239,"context_line":"        req \u003d fakes.HTTPRequest.blank(\"/tests?foos\u003dabc\")"},{"line_number":240,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.3\")"},{"line_number":241,"context_line":"        self.assertEqual(self.get(req\u003dreq),"},{"line_number":242,"context_line":"                         [\u0027foos\u0027])"},{"line_number":243,"context_line":"        req \u003d fakes.HTTPRequest.blank(\"/tests?foos\u003dabc\u0026foos\u003ddef\")"},{"line_number":244,"context_line":"        self.assertEqual(self.get(req\u003dreq),"},{"line_number":245,"context_line":"                         [\u0027foos\u0027])"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_d5accaef","line":242,"range":{"start_line":241,"start_character":25,"end_line":242,"end_character":33},"updated":"2016-12-30 23:34:03.000000000","message":"fix the parameter order please - we could also have this on a single line.","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"51283a8b2fc79d57ba2f52b2edd6b939c07bdd16","unresolved":false,"context_lines":[{"line_number":238,"context_line":"    def test_validate_request_with_multiple_values(self):"},{"line_number":239,"context_line":"        req \u003d fakes.HTTPRequest.blank(\"/tests?foos\u003dabc\")"},{"line_number":240,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.3\")"},{"line_number":241,"context_line":"        self.assertEqual(self.get(req\u003dreq),"},{"line_number":242,"context_line":"                         [\u0027foos\u0027])"},{"line_number":243,"context_line":"        req \u003d fakes.HTTPRequest.blank(\"/tests?foos\u003dabc\u0026foos\u003ddef\")"},{"line_number":244,"context_line":"        self.assertEqual(self.get(req\u003dreq),"},{"line_number":245,"context_line":"                         [\u0027foos\u0027])"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_d4af53e1","line":242,"range":{"start_line":241,"start_character":25,"end_line":242,"end_character":33},"in_reply_to":"ba5201f7_d5accaef","updated":"2017-01-03 08:41:18.000000000","message":"Done","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":244,"context_line":"        self.assertEqual(self.get(req\u003dreq),"},{"line_number":245,"context_line":"                         [\u0027foos\u0027])"},{"line_number":246,"context_line":""},{"line_number":247,"context_line":"    def test_validate_request_with_multiple_values_failes(self):"},{"line_number":248,"context_line":"        req \u003d fakes.HTTPRequest.blank("},{"line_number":249,"context_line":"            \"/tests?foo\u003d%s\u0026foo\u003d%s\" % (fakes.FAKE_UUID, fakes.FAKE_UUID))"},{"line_number":250,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.3\")"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_15b7323a","line":247,"range":{"start_line":247,"start_character":51,"end_line":247,"end_character":57},"updated":"2016-12-30 23:34:03.000000000","message":"fails","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"51283a8b2fc79d57ba2f52b2edd6b939c07bdd16","unresolved":false,"context_lines":[{"line_number":244,"context_line":"        self.assertEqual(self.get(req\u003dreq),"},{"line_number":245,"context_line":"                         [\u0027foos\u0027])"},{"line_number":246,"context_line":""},{"line_number":247,"context_line":"    def test_validate_request_with_multiple_values_failes(self):"},{"line_number":248,"context_line":"        req \u003d fakes.HTTPRequest.blank("},{"line_number":249,"context_line":"            \"/tests?foo\u003d%s\u0026foo\u003d%s\" % (fakes.FAKE_UUID, fakes.FAKE_UUID))"},{"line_number":250,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.3\")"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_14babb23","line":247,"range":{"start_line":247,"start_character":51,"end_line":247,"end_character":57},"in_reply_to":"ba5201f7_15b7323a","updated":"2017-01-03 08:41:18.000000000","message":"Done","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":250,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.3\")"},{"line_number":251,"context_line":"        self.assertRaises(exception.ValidationError, self.get, req\u003dreq)"},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"    def test_strip_out_additional_properties(self):"},{"line_number":254,"context_line":"        req \u003d fakes.HTTPRequest.blank("},{"line_number":255,"context_line":"            \"/tests?foos\u003dabc\u0026foo\u003d%s\u0026bar\u003d123\u0026bar\u003d456\" % fakes.FAKE_UUID)"},{"line_number":256,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.3\")"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_35827653","line":253,"updated":"2016-12-30 23:34:03.000000000","message":"Just to confirm my understanding, this is the part where we are backward compatible with v2.1 and we don\u0027t fail on unexpected query parameters, but in a later microversion we might block this and make it a failure, correct?","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"51283a8b2fc79d57ba2f52b2edd6b939c07bdd16","unresolved":false,"context_lines":[{"line_number":250,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.3\")"},{"line_number":251,"context_line":"        self.assertRaises(exception.ValidationError, self.get, req\u003dreq)"},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"    def test_strip_out_additional_properties(self):"},{"line_number":254,"context_line":"        req \u003d fakes.HTTPRequest.blank("},{"line_number":255,"context_line":"            \"/tests?foos\u003dabc\u0026foo\u003d%s\u0026bar\u003d123\u0026bar\u003d456\" % fakes.FAKE_UUID)"},{"line_number":256,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.3\")"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_947ceb73","line":253,"in_reply_to":"ba5201f7_35827653","updated":"2017-01-03 08:41:18.000000000","message":"Yes, you are right.","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7b10f03fd1a55b6e0b49ec4ff673478df91d09a2","unresolved":false,"context_lines":[{"line_number":250,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.3\")"},{"line_number":251,"context_line":"        self.assertRaises(exception.ValidationError, self.get, req\u003dreq)"},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"    def test_strip_out_additional_properties(self):"},{"line_number":254,"context_line":"        req \u003d fakes.HTTPRequest.blank("},{"line_number":255,"context_line":"            \"/tests?foos\u003dabc\u0026foo\u003d%s\u0026bar\u003d123\u0026bar\u003d456\" % fakes.FAKE_UUID)"},{"line_number":256,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.3\")"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_a7b520ef","line":253,"in_reply_to":"ba5201f7_947ceb73","updated":"2017-01-04 03:18:11.000000000","message":"We might want to add a comment explaining that. I only really knew about it because I remember it from the spec.","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":256,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.3\")"},{"line_number":257,"context_line":"        res \u003d self.get(req\u003dreq)"},{"line_number":258,"context_line":"        res.sort()"},{"line_number":259,"context_line":"        self.assertEqual(res, [\u0027foo\u0027, \u0027foos\u0027])"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"    def test_no_strip_out_additional_properties_when_not_match_version(self):"},{"line_number":262,"context_line":"        req \u003d fakes.HTTPRequest.blank("}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_5587fa60","line":259,"range":{"start_line":259,"start_character":25,"end_line":259,"end_character":45},"updated":"2016-12-30 23:34:03.000000000","message":"fix the arg order please","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"51283a8b2fc79d57ba2f52b2edd6b939c07bdd16","unresolved":false,"context_lines":[{"line_number":256,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.3\")"},{"line_number":257,"context_line":"        res \u003d self.get(req\u003dreq)"},{"line_number":258,"context_line":"        res.sort()"},{"line_number":259,"context_line":"        self.assertEqual(res, [\u0027foo\u0027, \u0027foos\u0027])"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"    def test_no_strip_out_additional_properties_when_not_match_version(self):"},{"line_number":262,"context_line":"        req \u003d fakes.HTTPRequest.blank("}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_b481ef4c","line":259,"range":{"start_line":259,"start_character":25,"end_line":259,"end_character":45},"in_reply_to":"ba5201f7_5587fa60","updated":"2017-01-03 08:41:18.000000000","message":"Done","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":258,"context_line":"        res.sort()"},{"line_number":259,"context_line":"        self.assertEqual(res, [\u0027foo\u0027, \u0027foos\u0027])"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"    def test_no_strip_out_additional_properties_when_not_match_version(self):"},{"line_number":262,"context_line":"        req \u003d fakes.HTTPRequest.blank("},{"line_number":263,"context_line":"            \"/tests?foos\u003dabc\u0026foo\u003d%s\u0026bar\u003d123\u0026bar\u003d456\" % fakes.FAKE_UUID)"},{"line_number":264,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.1\")"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_757cfe72","line":261,"range":{"start_line":261,"start_character":8,"end_line":261,"end_character":70},"updated":"2016-12-30 23:34:03.000000000","message":"So this is the case where _schema_validation_helper returns False because the schema rule doesn\u0027t match the microversion range, correct? A comment along those lines to be clear would be helpful.","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"51283a8b2fc79d57ba2f52b2edd6b939c07bdd16","unresolved":false,"context_lines":[{"line_number":258,"context_line":"        res.sort()"},{"line_number":259,"context_line":"        self.assertEqual(res, [\u0027foo\u0027, \u0027foos\u0027])"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"    def test_no_strip_out_additional_properties_when_not_match_version(self):"},{"line_number":262,"context_line":"        req \u003d fakes.HTTPRequest.blank("},{"line_number":263,"context_line":"            \"/tests?foos\u003dabc\u0026foo\u003d%s\u0026bar\u003d123\u0026bar\u003d456\" % fakes.FAKE_UUID)"},{"line_number":264,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.1\")"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_f49377a1","line":261,"range":{"start_line":261,"start_character":8,"end_line":261,"end_character":70},"in_reply_to":"ba5201f7_757cfe72","updated":"2017-01-03 08:41:18.000000000","message":"Yes, correct. I will add comment.","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5724074469b379ca1693b86069394d40e640db38","unresolved":false,"context_lines":[{"line_number":264,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.1\")"},{"line_number":265,"context_line":"        res \u003d self.get(req\u003dreq)"},{"line_number":266,"context_line":"        res.sort()"},{"line_number":267,"context_line":"        self.assertEqual(res, [\u0027bar\u0027, \u0027foo\u0027, \u0027foos\u0027])"},{"line_number":268,"context_line":""},{"line_number":269,"context_line":""},{"line_number":270,"context_line":"class RequiredDisableTestCase(APIValidationTestCase):"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_9581624d","line":267,"range":{"start_line":267,"start_character":25,"end_line":267,"end_character":52},"updated":"2016-12-30 23:34:03.000000000","message":"fix the arg order please","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"51283a8b2fc79d57ba2f52b2edd6b939c07bdd16","unresolved":false,"context_lines":[{"line_number":264,"context_line":"        req.api_version_request \u003d api_version.APIVersionRequest(\"2.1\")"},{"line_number":265,"context_line":"        res \u003d self.get(req\u003dreq)"},{"line_number":266,"context_line":"        res.sort()"},{"line_number":267,"context_line":"        self.assertEqual(res, [\u0027bar\u0027, \u0027foo\u0027, \u0027foos\u0027])"},{"line_number":268,"context_line":""},{"line_number":269,"context_line":""},{"line_number":270,"context_line":"class RequiredDisableTestCase(APIValidationTestCase):"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba5201f7_f4da9777","line":267,"range":{"start_line":267,"start_character":25,"end_line":267,"end_character":52},"in_reply_to":"ba5201f7_9581624d","updated":"2017-01-03 08:41:18.000000000","message":"Done","commit_id":"d85b95e8ea562b57d40956f573f8b4a82bee7338"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"c63426812298ed01dab0704bf70115241e970c33","unresolved":false,"context_lines":[{"line_number":43,"context_line":"class FakeQueryParametersController(object):"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    @validation.query_params_schema(query_schema, \u00272.3\u0027)"},{"line_number":46,"context_line":"    def get(self, req):"},{"line_number":47,"context_line":"        return list(set(req.GET.keys()))"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"ba5201f7_b7472a4a","line":46,"updated":"2017-01-03 13:15:43.000000000","message":"I move this \u0027get\u0027 method out of QueryParamsSchemaTestCase. The way of the previous patch, the \u0027get\u0027 method isn\u0027t a member of QueryParamsSchemaTestCase. So I have to call it as \"self.get(self, req)\". Pass the self again seems strange and confuse.","commit_id":"789bd82a643d148a141938a102309c7d67a6a5e9"}]}
