)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"dc6ef16161db8c505074ad003a07cc7d5ab35a0c","unresolved":false,"context_lines":[{"line_number":25,"context_line":"if needed, but in most cases there is no need to set up headers"},{"line_number":26,"context_line":"at all in service clients."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"Also added unit-tests for rest-client changes."},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"Implements bp refactor-rest-client"},{"line_number":31,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":12,"id":"AAAAUH%2F%2BOnk%3D","line":28,"updated":"2014-01-28 22:03:00.000000000","message":"This commit message needs a bit of cleanup :) First, there\u0027s no need to talk about all the specific steps that were taken in the patch -- since we can and will look at the diff in the commit.\n\nWhat the commit message should focus on is the *why* of the patch, and reasoning about the particular strategy used in the patch to solve the problem.\n\nHow\u0027s this look for a commit message?\n\n Simplify rest client bases into a single base client class\n\n There is a lot of duplicated code in the way the REST client classes are\n constructed to enable both JSON and XML requests. Duplicate code leads\n to subtle errors and inconsistencies in the way that client classes behave.\n\n This patch aims to simplify the class hierarchy for the REST client classes\n by making the XML client class inherit from the JSON base class.","commit_id":"2dd318a7a962e927b62f14e361df87d40698da70"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"585ef73b65d12c11c95d6c04533af7e8ffadece2","unresolved":false,"context_lines":[{"line_number":25,"context_line":"if needed, but in most cases there is no need to set up headers"},{"line_number":26,"context_line":"at all in service clients."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"Also added unit-tests for rest-client changes."},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"Implements bp refactor-rest-client"},{"line_number":31,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":12,"id":"AAAAUH%2F%2BMEU%3D","line":28,"in_reply_to":"AAAAUH%2F%2BOnk%3D","updated":"2014-01-29 10:05:10.000000000","message":"Thanks, will change it.","commit_id":"2dd318a7a962e927b62f14e361df87d40698da70"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"34a073b90faeb8b8c1c71d887f1c008371c3c7b6","unresolved":false,"context_lines":[{"line_number":23,"context_line":"if needed, but in most cases there is no need to set up headers"},{"line_number":24,"context_line":"at all in service clients."},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"Implements bp refactor-rest-client"},{"line_number":27,"context_line":"Closes-Bug: 1269489"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"Change-Id: Ie43d10affc981d3446b1296cf05ef595154276a9"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"AAAAUH%2F94As%3D","line":26,"updated":"2014-02-02 20:24:30.000000000","message":"s/Implements/Partially-implements:/","commit_id":"ad153433e02a862b036bc757f8f278d767146bcc"}],"tempest/api/identity/admin/test_tokens.py":[{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"dc6ef16161db8c505074ad003a07cc7d5ab35a0c","unresolved":false,"context_lines":[{"line_number":47,"context_line":"                         tenant[\u0027name\u0027])"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"        # then delete the token"},{"line_number":50,"context_line":"        token_id \u003d body[\u0027token\u0027][\u0027id\u0027]"},{"line_number":51,"context_line":"        resp, body \u003d self.client.delete_token(token_id)"},{"line_number":52,"context_line":"        self.assertEqual(resp[\u0027status\u0027], \u0027204\u0027)"},{"line_number":53,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2BOmw%3D","line":50,"updated":"2014-01-28 22:03:00.000000000","message":"I don\u0027t understand how you removed the \u0027access\u0027 section of the returned body from the token_client...","commit_id":"2dd318a7a962e927b62f14e361df87d40698da70"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"585ef73b65d12c11c95d6c04533af7e8ffadece2","unresolved":false,"context_lines":[{"line_number":47,"context_line":"                         tenant[\u0027name\u0027])"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"        # then delete the token"},{"line_number":50,"context_line":"        token_id \u003d body[\u0027token\u0027][\u0027id\u0027]"},{"line_number":51,"context_line":"        resp, body \u003d self.client.delete_token(token_id)"},{"line_number":52,"context_line":"        self.assertEqual(resp[\u0027status\u0027], \u0027204\u0027)"},{"line_number":53,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2BMEE%3D","line":50,"in_reply_to":"AAAAUH%2F%2BOmw%3D","updated":"2014-01-29 10:05:10.000000000","message":"Cause is in changes to \u0027_parse_resp\u0027 method, that is used in \u0027self.token_client.auth\u0027.","commit_id":"2dd318a7a962e927b62f14e361df87d40698da70"}],"tempest/api/orchestration/stacks/test_limits.py":[{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"4f1c730554446d24dde8e6782304523739c02229","unresolved":false,"context_lines":[{"line_number":42,"context_line":"  Foo: bar\u0027\u0027\u0027 % fill"},{"line_number":43,"context_line":"        ex \u003d self.assertRaises(exceptions.BadRequest, self.create_stack,"},{"line_number":44,"context_line":"                               self.stack_name, template)"},{"line_number":45,"context_line":"        self.assertIn(\u0027Template exceeds maximum allowed size\u0027, str(ex))"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAUH%2F%2B7S0%3D","side":"PARENT","line":45,"updated":"2014-01-20 17:38:17.000000000","message":"Same here, what does this have to do with your rest client refactor?","commit_id":"09daa4e9b15c3ba01706271f533cf7673773af21"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"fffd5c4e16df73ec5e0102d63b3a1c0db6d1f6cc","unresolved":false,"context_lines":[{"line_number":42,"context_line":"  Foo: bar\u0027\u0027\u0027 % fill"},{"line_number":43,"context_line":"        ex \u003d self.assertRaises(exceptions.BadRequest, self.create_stack,"},{"line_number":44,"context_line":"                               self.stack_name, template)"},{"line_number":45,"context_line":"        self.assertIn(\u0027Template exceeds maximum allowed size\u0027, str(ex))"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAUH%2F%2B7BM%3D","side":"PARENT","line":45,"in_reply_to":"AAAAUH%2F%2B7S0%3D","updated":"2014-01-20 18:25:02.000000000","message":"That\u0027s right, it isn\u0027t related to rest client refactor.\n\nThis change should be done in separate patch, because asserting the exception string will fail, if service change some letters in its answer...\n\nRemoved.","commit_id":"09daa4e9b15c3ba01706271f533cf7673773af21"},{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"4f1c730554446d24dde8e6782304523739c02229","unresolved":false,"context_lines":[{"line_number":32,"context_line":"        cls.client \u003d cls.orchestration_client"},{"line_number":33,"context_line":"        cls.stack_name \u003d data_utils.rand_name(\u0027heat\u0027)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    @attr(type\u003d[\u0027negative\u0027, \u0027gate\u0027])"},{"line_number":36,"context_line":"    def test_exceed_max_template_size_fails(self):"},{"line_number":37,"context_line":"        fill \u003d \u0027A\u0027 * self.orchestration_cfg.max_template_size"},{"line_number":38,"context_line":"        template \u003d \u0027\u0027\u0027"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAUH%2F%2B7S8%3D","line":35,"updated":"2014-01-20 17:38:17.000000000","message":"This looks like an unrelated change","commit_id":"1ac0c93ea74c0771d84d8a6990a26370b3cb0589"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"fffd5c4e16df73ec5e0102d63b3a1c0db6d1f6cc","unresolved":false,"context_lines":[{"line_number":32,"context_line":"        cls.client \u003d cls.orchestration_client"},{"line_number":33,"context_line":"        cls.stack_name \u003d data_utils.rand_name(\u0027heat\u0027)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    @attr(type\u003d[\u0027negative\u0027, \u0027gate\u0027])"},{"line_number":36,"context_line":"    def test_exceed_max_template_size_fails(self):"},{"line_number":37,"context_line":"        fill \u003d \u0027A\u0027 * self.orchestration_cfg.max_template_size"},{"line_number":38,"context_line":"        template \u003d \u0027\u0027\u0027"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAUH%2F%2B69s%3D","line":35,"in_reply_to":"AAAAUH%2F%2B7S8%3D","updated":"2014-01-20 18:25:02.000000000","message":"Agree. Removed.","commit_id":"1ac0c93ea74c0771d84d8a6990a26370b3cb0589"}],"tempest/common/rest_client.py":[{"author":{"_account_id":5689,"name":"Masayuki Igawa","email":"masayuki@igawa.io","username":"igawa"},"change_message_id":"cf13c57645b2f6867881ca615b85a27c48b92c03","unresolved":false,"context_lines":[{"line_number":324,"context_line":"            headers \u003d self.get_headers()"},{"line_number":325,"context_line":"        return self.request(\u0027POST\u0027, url, headers, body)"},{"line_number":326,"context_line":""},{"line_number":327,"context_line":"    def get(self, url, headers\u003dNone):"},{"line_number":328,"context_line":"        return self.request(\u0027GET\u0027, url, headers)"},{"line_number":329,"context_line":""},{"line_number":330,"context_line":"    def delete(self, url, headers\u003dNone):"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAT3%2F%2F7FA%3D","line":327,"updated":"2013-12-27 02:55:02.000000000","message":"Why not do you \n\n if headers is None:\n     headers \u003d self.get_headers()\n\nhere and delete(), head(), copy()..?\nIs there any particular reason? If so, I think it\u0027s better to put the comment for that.","commit_id":"f6ec7d1948dd7aac4abd4c7140906ce081bbf5ac"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"5c61dda2bd0aa376dd8a87fdf99206cb7a494216","unresolved":false,"context_lines":[{"line_number":324,"context_line":"            headers \u003d self.get_headers()"},{"line_number":325,"context_line":"        return self.request(\u0027POST\u0027, url, headers, body)"},{"line_number":326,"context_line":""},{"line_number":327,"context_line":"    def get(self, url, headers\u003dNone):"},{"line_number":328,"context_line":"        return self.request(\u0027GET\u0027, url, headers)"},{"line_number":329,"context_line":""},{"line_number":330,"context_line":"    def delete(self, url, headers\u003dNone):"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAT3%2F%2F6Uo%3D","line":327,"in_reply_to":"AAAAT3%2F%2F7FA%3D","updated":"2013-12-27 10:26:38.000000000","message":"Because headers should be set only if request sends data/body. Easy way - look at args of methods, no body - no dependency on data.\n\nAlso, it can cause some service clients with error, as it was with patch-set 4, where object client returns non-json-like answer if success, so it shoudn\u0027t get headers with any type at all. Yes, it should be handled by its service client - redefining headers as it expected, but it must be another patch.","commit_id":"f6ec7d1948dd7aac4abd4c7140906ce081bbf5ac"},{"author":{"_account_id":5689,"name":"Masayuki Igawa","email":"masayuki@igawa.io","username":"igawa"},"change_message_id":"cf13c57645b2f6867881ca615b85a27c48b92c03","unresolved":false,"context_lines":[{"line_number":349,"context_line":"    def get_versions(self):"},{"line_number":350,"context_line":"        resp, body \u003d self.get(\u0027\u0027)"},{"line_number":351,"context_line":"        body \u003d self._parse_resp(body)"},{"line_number":352,"context_line":"        #body \u003d body[\u0027versions\u0027]"},{"line_number":353,"context_line":"        versions \u003d map(lambda x: x[\u0027id\u0027], body)"},{"line_number":354,"context_line":"        return resp, versions"},{"line_number":355,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAT3%2F%2F7E8%3D","line":352,"updated":"2013-12-27 02:55:02.000000000","message":"Please remove this line.","commit_id":"f6ec7d1948dd7aac4abd4c7140906ce081bbf5ac"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"5c61dda2bd0aa376dd8a87fdf99206cb7a494216","unresolved":false,"context_lines":[{"line_number":349,"context_line":"    def get_versions(self):"},{"line_number":350,"context_line":"        resp, body \u003d self.get(\u0027\u0027)"},{"line_number":351,"context_line":"        body \u003d self._parse_resp(body)"},{"line_number":352,"context_line":"        #body \u003d body[\u0027versions\u0027]"},{"line_number":353,"context_line":"        versions \u003d map(lambda x: x[\u0027id\u0027], body)"},{"line_number":354,"context_line":"        return resp, versions"},{"line_number":355,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAT3%2F%2F6Vw%3D","line":352,"in_reply_to":"AAAAT3%2F%2F7E8%3D","updated":"2013-12-27 10:26:38.000000000","message":"Done","commit_id":"f6ec7d1948dd7aac4abd4c7140906ce081bbf5ac"},{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"67ec4a77b0891a03d7e676fbf1203a0430962ed5","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    # This is used by _parse_resp method too"},{"line_number":51,"context_line":"    # Used for selection of dict-like xmls,"},{"line_number":52,"context_line":"    # like metadata for Vms in nova, and volumes in cinder"},{"line_number":53,"context_line":"    dict_tags \u003d [\"metadata\", ]"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    LOG \u003d logging.getLogger(__name__)"},{"line_number":56,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAT3%2F%2F6UQ%3D","line":53,"updated":"2013-12-27 10:32:57.000000000","message":"this is xml-specific, per your comment. Hence it should reside in xml client class and used there.","commit_id":"4863c2cef758f4ac7e68f54dfa5b1c69b2036972"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"2c5f592c993d8e0b58131840c7943282297c2742","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    # This is used by _parse_resp method too"},{"line_number":51,"context_line":"    # Used for selection of dict-like xmls,"},{"line_number":52,"context_line":"    # like metadata for Vms in nova, and volumes in cinder"},{"line_number":53,"context_line":"    dict_tags \u003d [\"metadata\", ]"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    LOG \u003d logging.getLogger(__name__)"},{"line_number":56,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAT3%2F%2F6Pc%3D","line":53,"in_reply_to":"AAAAT3%2F%2F6UQ%3D","updated":"2013-12-27 10:54:54.000000000","message":"This XML rest-client is considered to work with both container types, so, both type-dependent things should be here.","commit_id":"4863c2cef758f4ac7e68f54dfa5b1c69b2036972"},{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"67ec4a77b0891a03d7e676fbf1203a0430962ed5","unresolved":false,"context_lines":[{"line_number":398,"context_line":"                self.LOG.debug(\"Large body (%d) md5 summary: %s\", length,"},{"line_number":399,"context_line":"                               hashlib.md5(str_body).hexdigest())"},{"line_number":400,"context_line":""},{"line_number":401,"context_line":"    def _parse_resp(self, body):"},{"line_number":402,"context_line":"        if self._get_type() is \"json\":"},{"line_number":403,"context_line":"            body \u003d json.loads(body)"},{"line_number":404,"context_line":"            if isinstance(body, dict):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAT3%2F%2F6U8%3D","line":401,"updated":"2013-12-27 10:32:57.000000000","message":"I think you should not be parsing response in the rest client.\nYou have json and xml clients which should define their own deserialization methods.\n\nIn that case _parse_resp cold be omitted from rest client.","commit_id":"4863c2cef758f4ac7e68f54dfa5b1c69b2036972"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"2c5f592c993d8e0b58131840c7943282297c2742","unresolved":false,"context_lines":[{"line_number":398,"context_line":"                self.LOG.debug(\"Large body (%d) md5 summary: %s\", length,"},{"line_number":399,"context_line":"                               hashlib.md5(str_body).hexdigest())"},{"line_number":400,"context_line":""},{"line_number":401,"context_line":"    def _parse_resp(self, body):"},{"line_number":402,"context_line":"        if self._get_type() is \"json\":"},{"line_number":403,"context_line":"            body \u003d json.loads(body)"},{"line_number":404,"context_line":"            if isinstance(body, dict):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAT3%2F%2F6PY%3D","line":401,"in_reply_to":"AAAAT3%2F%2F6U8%3D","updated":"2013-12-27 10:54:54.000000000","message":"This is common deserialisation for xml clients. \n\nIf someone wants to redefine, he can do it, but, mostly, there is no reason for this, having such method in rest-client.","commit_id":"4863c2cef758f4ac7e68f54dfa5b1c69b2036972"},{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"67ec4a77b0891a03d7e676fbf1203a0430962ed5","unresolved":false,"context_lines":[{"line_number":406,"context_line":"            else:"},{"line_number":407,"context_line":"                return body"},{"line_number":408,"context_line":"        elif self._get_type() is \"xml\":"},{"line_number":409,"context_line":"            element \u003d etree.fromstring(body)"},{"line_number":410,"context_line":"            if any(s in element.tag for s in self.dict_tags):"},{"line_number":411,"context_line":"                # Parse dictionary-like xmls (metadata, etc)"},{"line_number":412,"context_line":"                dictionary \u003d {}"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAT3%2F%2F6UY%3D","line":409,"updated":"2013-12-27 10:32:57.000000000","message":"L409-424: it\u0027s better to extract that logic into a separate method defined for xml client class.\n\nAlso, could you check tempest code to see if this has been already implemented for some other clients? It seems like a common task. If it has been implemented, then you could use it, if in other clients it is done differently, then it would be a good matter for further improvement (but not in the scope of this patch)","commit_id":"4863c2cef758f4ac7e68f54dfa5b1c69b2036972"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"2c5f592c993d8e0b58131840c7943282297c2742","unresolved":false,"context_lines":[{"line_number":406,"context_line":"            else:"},{"line_number":407,"context_line":"                return body"},{"line_number":408,"context_line":"        elif self._get_type() is \"xml\":"},{"line_number":409,"context_line":"            element \u003d etree.fromstring(body)"},{"line_number":410,"context_line":"            if any(s in element.tag for s in self.dict_tags):"},{"line_number":411,"context_line":"                # Parse dictionary-like xmls (metadata, etc)"},{"line_number":412,"context_line":"                dictionary \u003d {}"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAT3%2F%2F6PI%3D","line":409,"in_reply_to":"AAAAT3%2F%2F6UY%3D","updated":"2013-12-27 10:54:54.000000000","message":"Because of absence such method here, lots of clients has its own parsing in the same way.\n\nThe idea - make one method, as interface, that will be used in json and xml service clients to remove differencies between their methods.\n\nAnd, regarding to your comment in patch-set 5 about moving _parse_resp into post/put/get methods - this is will cause errors for service clients, that returns non json/xml data, like Swift\u0027s object_client.","commit_id":"4863c2cef758f4ac7e68f54dfa5b1c69b2036972"},{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"67ec4a77b0891a03d7e676fbf1203a0430962ed5","unresolved":false,"context_lines":[{"line_number":474,"context_line":"            # This is useful to avoid the need to provide"},{"line_number":475,"context_line":"            # new headers for inherited json methods by"},{"line_number":476,"context_line":"            # some xml service client"},{"line_number":477,"context_line":"            if self._get_type() is \"xml\":"},{"line_number":478,"context_line":"                headers \u003d self.get_headers()"},{"line_number":479,"context_line":"            else:"},{"line_number":480,"context_line":"                headers \u003d {}"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAT3%2F%2F6Ts%3D","line":477,"updated":"2013-12-27 10:32:57.000000000","message":"why type matters? It\u0027s not good to check type because it means that something should have been delegated to subclasses but parent class is doing this work instead.","commit_id":"4863c2cef758f4ac7e68f54dfa5b1c69b2036972"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"2c5f592c993d8e0b58131840c7943282297c2742","unresolved":false,"context_lines":[{"line_number":474,"context_line":"            # This is useful to avoid the need to provide"},{"line_number":475,"context_line":"            # new headers for inherited json methods by"},{"line_number":476,"context_line":"            # some xml service client"},{"line_number":477,"context_line":"            if self._get_type() is \"xml\":"},{"line_number":478,"context_line":"                headers \u003d self.get_headers()"},{"line_number":479,"context_line":"            else:"},{"line_number":480,"context_line":"                headers \u003d {}"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAT3%2F%2F6RA%3D","line":477,"in_reply_to":"AAAAT3%2F%2F6Ts%3D","updated":"2013-12-27 10:54:54.000000000","message":"As I wrote in patch-set 8, it causes error, at least, for Swift\u0027s object_client, which returns non-json/xml-like response if success. See errors for patch-set 4","commit_id":"4863c2cef758f4ac7e68f54dfa5b1c69b2036972"},{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"67ec4a77b0891a03d7e676fbf1203a0430962ed5","unresolved":false,"context_lines":[{"line_number":599,"context_line":"        if (not isinstance(resp_body, collections.Mapping) or"},{"line_number":600,"context_line":"                \u0027retry-after\u0027 not in resp):"},{"line_number":601,"context_line":"            return True"},{"line_number":602,"context_line":"        if self._get_type() is \"json\":"},{"line_number":603,"context_line":"            over_limit \u003d resp_body.get(\u0027overLimit\u0027, None)"},{"line_number":604,"context_line":"            if not over_limit:"},{"line_number":605,"context_line":"                return True"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAT3%2F%2F6T0%3D","line":602,"updated":"2013-12-27 10:32:57.000000000","message":"same as above","commit_id":"4863c2cef758f4ac7e68f54dfa5b1c69b2036972"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"2c5f592c993d8e0b58131840c7943282297c2742","unresolved":false,"context_lines":[{"line_number":599,"context_line":"        if (not isinstance(resp_body, collections.Mapping) or"},{"line_number":600,"context_line":"                \u0027retry-after\u0027 not in resp):"},{"line_number":601,"context_line":"            return True"},{"line_number":602,"context_line":"        if self._get_type() is \"json\":"},{"line_number":603,"context_line":"            over_limit \u003d resp_body.get(\u0027overLimit\u0027, None)"},{"line_number":604,"context_line":"            if not over_limit:"},{"line_number":605,"context_line":"                return True"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAT3%2F%2F6OE%3D","line":602,"in_reply_to":"AAAAT3%2F%2F6T0%3D","updated":"2013-12-27 10:54:54.000000000","message":"This methods contain parts of old xml-rest-client and json-rest-client, these parts haven\u0027t been changed to better understanding, that it is just combining.","commit_id":"4863c2cef758f4ac7e68f54dfa5b1c69b2036972"},{"author":{"_account_id":6683,"name":"Pavel Sedlák","email":"psedlak@redhat.com","username":"psedlak"},"change_message_id":"bbfa50665164cfc86f54b2d0e0d9cd1bae01811b","unresolved":false,"context_lines":[{"line_number":325,"context_line":"                raise exceptions.InvalidHttpSuccessCode(details)"},{"line_number":326,"context_line":""},{"line_number":327,"context_line":"    def post(self, url, body, headers\u003dNone):"},{"line_number":328,"context_line":"        # NOTE(vponomaryov): autosetting of headers"},{"line_number":329,"context_line":"        # needed only in requests with data/body"},{"line_number":330,"context_line":"        if headers is None:"},{"line_number":331,"context_line":"            headers \u003d self.get_headers()"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAUH%2F%2F7qM%3D","line":328,"updated":"2014-01-06 16:18:12.000000000","message":"I see something like this in self.request line 478, and it\u0027s done there only for xml.\nBut if done for xml/json, or kept empty for json - as atm there is collision between behaviour defined in get/delete/... and in the request(), it could be removed from those get/delete/patch/... methods.\n\nBut does this comment about \u0027only-with-data\u0027 applies just for POST?\nIf so maybe it could be written like \"headers is None: headers \u003d body ? get_headers() else {}\" here so it does not get default-set in request(). Other methods then may rely on request() itself to add headers when needed.\n\nOr if this comment applies to all, the \"if body\" logic could put in the request() too.","commit_id":"464a0db5a5ee7a683a1c86128925ec75b499935f"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"b699ee397f1d5ed1332cf1eb0d8e6d2190bedeb4","unresolved":false,"context_lines":[{"line_number":325,"context_line":"                raise exceptions.InvalidHttpSuccessCode(details)"},{"line_number":326,"context_line":""},{"line_number":327,"context_line":"    def post(self, url, body, headers\u003dNone):"},{"line_number":328,"context_line":"        # NOTE(vponomaryov): autosetting of headers"},{"line_number":329,"context_line":"        # needed only in requests with data/body"},{"line_number":330,"context_line":"        if headers is None:"},{"line_number":331,"context_line":"            headers \u003d self.get_headers()"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAUH%2F%2F7TY%3D","line":328,"in_reply_to":"AAAAUH%2F%2F7qM%3D","updated":"2014-01-06 17:38:02.000000000","message":"line 478:\nAbsence of headers cause default container for data, and it can be also plain/text, as in swift\u0027s object client.\nSo, if we set up headers there for all types, we get errors in object tests, which handles plain/text.\n\nSecond, about \u0027only-with-data\u0027. \nExcept post, it is put and patch methods, it sends data, so we define container type with headers.\n\nIn other words:\n\nheaders like {} useful for plain/text and default value as json.\nOn line 478 we set xml, because we expect already defined headers to json.\nHere we add headers for json too, because we must set up container type.\nAfter all of this, we can exclude all headers, from all service client methods. We just define TYPE, and know, it is used in headers, where needed.","commit_id":"464a0db5a5ee7a683a1c86128925ec75b499935f"},{"author":{"_account_id":6683,"name":"Pavel Sedlák","email":"psedlak@redhat.com","username":"psedlak"},"change_message_id":"aee147bab6fe3f9027526822b4d451a625866d3d","unresolved":false,"context_lines":[{"line_number":119,"context_line":"                             self.base_url, self.region, self.endpoint_url,"},{"line_number":120,"context_line":"                             self.build_interval, self.build_timeout,"},{"line_number":121,"context_line":"                             str(self.token)[0:STRING_LIMIT],"},{"line_number":122,"context_line":"                             str(self._get_type())[0:STRING_LIMIT])"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    def _set_auth(self):"},{"line_number":125,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2BQ6E%3D","line":122,"updated":"2014-01-28 15:35:48.000000000","message":"If it\u0027s not mistake here (get_headers() instead), and you want to inform just about the type, could you please also modify the \u0027\\nheaders:%s\u0027 part above, to state \u0027type:\u0027 instead?","commit_id":"2dd318a7a962e927b62f14e361df87d40698da70"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"5ae1c0d18279688e86ea5a632a00866c079b48d5","unresolved":false,"context_lines":[{"line_number":119,"context_line":"                             self.base_url, self.region, self.endpoint_url,"},{"line_number":120,"context_line":"                             self.build_interval, self.build_timeout,"},{"line_number":121,"context_line":"                             str(self.token)[0:STRING_LIMIT],"},{"line_number":122,"context_line":"                             str(self._get_type())[0:STRING_LIMIT])"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    def _set_auth(self):"},{"line_number":125,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2BQfs%3D","line":122,"in_reply_to":"AAAAUH%2F%2BQ6E%3D","updated":"2014-01-28 16:25:29.000000000","message":"Thank you, you are right.\n\nIt should be get_headers() instead of self.headers","commit_id":"2dd318a7a962e927b62f14e361df87d40698da70"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"5463a789a5d8dd0b5525991e9b963f6bba33695a","unresolved":false,"context_lines":[{"line_number":119,"context_line":"                             self.base_url, self.region, self.endpoint_url,"},{"line_number":120,"context_line":"                             self.build_interval, self.build_timeout,"},{"line_number":121,"context_line":"                             str(self.token)[0:STRING_LIMIT],"},{"line_number":122,"context_line":"                             str(self._get_type())[0:STRING_LIMIT])"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    def _set_auth(self):"},{"line_number":125,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2BQLY%3D","line":122,"in_reply_to":"AAAAUH%2F%2BQfs%3D","updated":"2014-01-28 17:11:48.000000000","message":"Addition to previous comment:\nAnd, maybe, would be better to have both of them here, not only one.","commit_id":"2dd318a7a962e927b62f14e361df87d40698da70"},{"author":{"_account_id":5174,"name":"Mauro Sergio Martins Rodrigues","email":"maurosr@linux.vnet.ibm.com","username":"maurosr"},"change_message_id":"893472a7549f5f037c12d5d8bc011db5bc96c911","unresolved":false,"context_lines":[{"line_number":344,"context_line":""},{"line_number":345,"context_line":"    def put(self, url, body, headers\u003dNone):"},{"line_number":346,"context_line":"        if headers is None:"},{"line_number":347,"context_line":"            headers \u003d self.get_headers()"},{"line_number":348,"context_line":"        return self.request(\u0027PUT\u0027, url, headers, body)"},{"line_number":349,"context_line":""},{"line_number":350,"context_line":"    def head(self, url, headers\u003dNone):"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2BOEo%3D","line":347,"updated":"2014-01-28 23:43:06.000000000","message":"can we move the headers check and get to the request method? so we do it once for all?","commit_id":"2dd318a7a962e927b62f14e361df87d40698da70"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"585ef73b65d12c11c95d6c04533af7e8ffadece2","unresolved":false,"context_lines":[{"line_number":344,"context_line":""},{"line_number":345,"context_line":"    def put(self, url, body, headers\u003dNone):"},{"line_number":346,"context_line":"        if headers is None:"},{"line_number":347,"context_line":"            headers \u003d self.get_headers()"},{"line_number":348,"context_line":"        return self.request(\u0027PUT\u0027, url, headers, body)"},{"line_number":349,"context_line":""},{"line_number":350,"context_line":"    def head(self, url, headers\u003dNone):"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2BMC4%3D","line":347,"in_reply_to":"AAAAUH%2F%2BOEo%3D","updated":"2014-01-29 10:05:10.000000000","message":"It was done in that way, due to reasons, where swift\u0027s clients use empty headers to get \u0027plain/text\u0027 container of response data.\n\nAfter some thinking, I agree, that it should be done in way you mentioned, and need change that swift clients to set empty headers explicitly.","commit_id":"2dd318a7a962e927b62f14e361df87d40698da70"},{"author":{"_account_id":5174,"name":"Mauro Sergio Martins Rodrigues","email":"maurosr@linux.vnet.ibm.com","username":"maurosr"},"change_message_id":"893472a7549f5f037c12d5d8bc011db5bc96c911","unresolved":false,"context_lines":[{"line_number":347,"context_line":"            headers \u003d self.get_headers()"},{"line_number":348,"context_line":"        return self.request(\u0027PUT\u0027, url, headers, body)"},{"line_number":349,"context_line":""},{"line_number":350,"context_line":"    def head(self, url, headers\u003dNone):"},{"line_number":351,"context_line":"        return self.request(\u0027HEAD\u0027, url, headers)"},{"line_number":352,"context_line":""},{"line_number":353,"context_line":"    def copy(self, url, headers\u003dNone):"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2BOEw%3D","line":350,"updated":"2014-01-28 23:43:06.000000000","message":"why you don\u0027t use self.get_headers here, in get, delete and in copy methods?\nif you\u0027re going to do it for them all please mention on the commit message that this will fix https://bugs.launchpad.net/tempest/+bug/1269489","commit_id":"2dd318a7a962e927b62f14e361df87d40698da70"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"585ef73b65d12c11c95d6c04533af7e8ffadece2","unresolved":false,"context_lines":[{"line_number":347,"context_line":"            headers \u003d self.get_headers()"},{"line_number":348,"context_line":"        return self.request(\u0027PUT\u0027, url, headers, body)"},{"line_number":349,"context_line":""},{"line_number":350,"context_line":"    def head(self, url, headers\u003dNone):"},{"line_number":351,"context_line":"        return self.request(\u0027HEAD\u0027, url, headers)"},{"line_number":352,"context_line":""},{"line_number":353,"context_line":"    def copy(self, url, headers\u003dNone):"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2BMCo%3D","line":350,"in_reply_to":"AAAAUH%2F%2BOEw%3D","updated":"2014-01-29 10:05:10.000000000","message":"According to comment above, I agree. Will make it, and it will cover that bug.\n\nThanks.","commit_id":"2dd318a7a962e927b62f14e361df87d40698da70"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"dc6ef16161db8c505074ad003a07cc7d5ab35a0c","unresolved":false,"context_lines":[{"line_number":402,"context_line":"        if self._get_type() is \"json\":"},{"line_number":403,"context_line":"            body \u003d json.loads(body)"},{"line_number":404,"context_line":"            if isinstance(body.items()[0][1], (dict, list)):"},{"line_number":405,"context_line":"                return body.items()[0][1]"},{"line_number":406,"context_line":"            else:"},{"line_number":407,"context_line":"                return body"},{"line_number":408,"context_line":"        elif self._get_type() is \"xml\":"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2BOh4%3D","line":405,"updated":"2014-01-28 22:03:00.000000000","message":"Ahhhhh, now I see :)\n\nThe above is a bit too obscure for my taste...and it does not account for body returns that have two \"top-level\" elements in the dictionary, for example:\n\n {\n   \"servers\": [\n     ...\n   ],\n   \"links\": {\n     \"next\": \"\u003curi\u003e\",\n     \"self\": \"\u003curi\u003e\",\n     ...\n   }\n }\n   \n\nhow about this instead?\n\n try:\n     # Ensure there are not more than one top-level keys\n     if len(body.keys()) \u003e 1:\n         return body\n     # Just return the \"wrapped\" element\n     first_key, first_item \u003d body.items()[0]\n     if isinstance(first_item, (dict, list)):\n         return first_item\n except (ValueError, IndexError):\n     return body\n\nAlso please add a comment above this code that explains what you are doing (since it is not all that obvious). How about this?\n\n # We assume that if the first value of the deserialized body\u0027s\n # item set is a dict or a list, that we just return the first value,\n # essentially \"cutting out\" the first placeholder element in a body\n # that looks like this:\n #\n #  {\n #    \"servers\": [\n #      ...\n #    ]\n #  }\n # \n # and we will just return the list of servers and not the dictionary\n # \"wrapping\" it.","commit_id":"2dd318a7a962e927b62f14e361df87d40698da70"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"bd33ce2040ded8e10319ecc78c63cea3843aa5b4","unresolved":false,"context_lines":[{"line_number":402,"context_line":"        if self._get_type() is \"json\":"},{"line_number":403,"context_line":"            body \u003d json.loads(body)"},{"line_number":404,"context_line":"            if isinstance(body.items()[0][1], (dict, list)):"},{"line_number":405,"context_line":"                return body.items()[0][1]"},{"line_number":406,"context_line":"            else:"},{"line_number":407,"context_line":"                return body"},{"line_number":408,"context_line":"        elif self._get_type() is \"xml\":"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2BKm8%3D","line":405,"in_reply_to":"AAAAUH%2F%2BL%2FA%3D","updated":"2014-01-29 14:50:43.000000000","message":"Please do update the code to be more readable, yes. If you don\u0027t feel that the check on having multiple top-level keys is useful, then please add a comment into your code acknowledging this, and that it will be taken care of by some other code somewhere.","commit_id":"2dd318a7a962e927b62f14e361df87d40698da70"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"585ef73b65d12c11c95d6c04533af7e8ffadece2","unresolved":false,"context_lines":[{"line_number":402,"context_line":"        if self._get_type() is \"json\":"},{"line_number":403,"context_line":"            body \u003d json.loads(body)"},{"line_number":404,"context_line":"            if isinstance(body.items()[0][1], (dict, list)):"},{"line_number":405,"context_line":"                return body.items()[0][1]"},{"line_number":406,"context_line":"            else:"},{"line_number":407,"context_line":"                return body"},{"line_number":408,"context_line":"        elif self._get_type() is \"xml\":"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2BL%2FA%3D","line":405,"in_reply_to":"AAAAUH%2F%2BOh4%3D","updated":"2014-01-29 10:05:10.000000000","message":"Agree, comment here will be useful. \n\nPoint about code change isn\u0027t blocker. In that case, in json-client should be set one of the dict keys explicitly, and in xml-client it will be done in another way (xml removes top keys), so xml method with several top-items in response dict will be redefined, it is guaranteed. So code change will not make more profit instead as it is now, IMO.\n\nSo, should code be changed anyway?","commit_id":"2dd318a7a962e927b62f14e361df87d40698da70"},{"author":{"_account_id":5174,"name":"Mauro Sergio Martins Rodrigues","email":"maurosr@linux.vnet.ibm.com","username":"maurosr"},"change_message_id":"893472a7549f5f037c12d5d8bc011db5bc96c911","unresolved":false,"context_lines":[{"line_number":477,"context_line":"            if self._get_type() is \"xml\":"},{"line_number":478,"context_line":"                headers \u003d self.get_headers()"},{"line_number":479,"context_line":"            else:"},{"line_number":480,"context_line":"                headers \u003d {}"},{"line_number":481,"context_line":"        headers[\u0027X-Auth-Token\u0027] \u003d self.token"},{"line_number":482,"context_line":""},{"line_number":483,"context_line":"        resp, resp_body \u003d self._request(method, url,"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2BOA4%3D","line":480,"updated":"2014-01-28 23:43:06.000000000","message":"maybe I\u0027m assuming wrong here, but it seems to me that the headers only matter in xml, or if our clients specify it. So why don\u0027t you use the self.get_headers only here and change the http methods only to default headers to None?","commit_id":"2dd318a7a962e927b62f14e361df87d40698da70"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"585ef73b65d12c11c95d6c04533af7e8ffadece2","unresolved":false,"context_lines":[{"line_number":477,"context_line":"            if self._get_type() is \"xml\":"},{"line_number":478,"context_line":"                headers \u003d self.get_headers()"},{"line_number":479,"context_line":"            else:"},{"line_number":480,"context_line":"                headers \u003d {}"},{"line_number":481,"context_line":"        headers[\u0027X-Auth-Token\u0027] \u003d self.token"},{"line_number":482,"context_line":""},{"line_number":483,"context_line":"        resp, resp_body \u003d self._request(method, url,"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2BMCU%3D","line":480,"in_reply_to":"AAAAUH%2F%2BOA4%3D","updated":"2014-01-29 10:05:10.000000000","message":"Will rework it due to intentioned changes, in previous comments.","commit_id":"2dd318a7a962e927b62f14e361df87d40698da70"},{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"36bc0d28744f3d0529887713474bd39aae8b1b43","unresolved":false,"context_lines":[{"line_number":381,"context_line":"                               hashlib.md5(str_body).hexdigest())"},{"line_number":382,"context_line":""},{"line_number":383,"context_line":"    def _parse_resp(self, body):"},{"line_number":384,"context_line":"        if self._get_type() is \"json\":"},{"line_number":385,"context_line":"            body \u003d json.loads(body)"},{"line_number":386,"context_line":""},{"line_number":387,"context_line":"            # We assume, that if the first value of the deserialized body\u0027s"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAAUH%2F9qSw%3D","line":384,"updated":"2014-02-05 09:07:24.000000000","message":"nit: it\u0027s ok for now, but better to delegate this logic to polymorphism, calling proper deserialization method of derived class","commit_id":"7958805271e0700e2034c2f6966316cdbc3d4661"},{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"a6533b50e85fd7922a12a64eb72cbf469e981b88","unresolved":false,"context_lines":[{"line_number":402,"context_line":"                # Just return the \"wrapped\" element"},{"line_number":403,"context_line":"                first_key, first_item \u003d body.items()[0]"},{"line_number":404,"context_line":"                if isinstance(first_item, (dict, list)):"},{"line_number":405,"context_line":"                    return first_item"},{"line_number":406,"context_line":"            except (ValueError, IndexError):"},{"line_number":407,"context_line":"                return body"},{"line_number":408,"context_line":"        elif self._get_type() is \"xml\":"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAAUH%2F9kcc%3D","line":405,"updated":"2014-02-05 23:55:56.000000000","message":"so what happens here if there is only one top level key but the item is not a dict or a list? It looks like it just falls straight through...","commit_id":"7958805271e0700e2034c2f6966316cdbc3d4661"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"12ad16f096c155a39070e2964bdcb09e344c88d8","unresolved":false,"context_lines":[{"line_number":402,"context_line":"                # Just return the \"wrapped\" element"},{"line_number":403,"context_line":"                first_key, first_item \u003d body.items()[0]"},{"line_number":404,"context_line":"                if isinstance(first_item, (dict, list)):"},{"line_number":405,"context_line":"                    return first_item"},{"line_number":406,"context_line":"            except (ValueError, IndexError):"},{"line_number":407,"context_line":"                return body"},{"line_number":408,"context_line":"        elif self._get_type() is \"xml\":"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAAUH%2F9h6A%3D","line":405,"in_reply_to":"AAAAUH%2F9iio%3D","updated":"2014-02-06 09:28:54.000000000","message":"Oh, you are right. There is nothing returns with current code, if no dict and list in body of single top-level item.\nThank you, will fix it with rebase patch.","commit_id":"7958805271e0700e2034c2f6966316cdbc3d4661"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"5b07ae58cdc3747e6336575e2e96f9da7c85109e","unresolved":false,"context_lines":[{"line_number":402,"context_line":"                # Just return the \"wrapped\" element"},{"line_number":403,"context_line":"                first_key, first_item \u003d body.items()[0]"},{"line_number":404,"context_line":"                if isinstance(first_item, (dict, list)):"},{"line_number":405,"context_line":"                    return first_item"},{"line_number":406,"context_line":"            except (ValueError, IndexError):"},{"line_number":407,"context_line":"                return body"},{"line_number":408,"context_line":"        elif self._get_type() is \"xml\":"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAAUH%2F9iio%3D","line":405,"in_reply_to":"AAAAUH%2F9kcc%3D","updated":"2014-02-06 07:15:50.000000000","message":"Look at Exception body, there response is returned as is.\n\nIn other words, top-level item will be removed only if it is the only and its body \u0027dict\u0027 or \u0027list\u0027, in other cases response will be returned as is.","commit_id":"7958805271e0700e2034c2f6966316cdbc3d4661"},{"author":{"_account_id":5689,"name":"Masayuki Igawa","email":"masayuki@igawa.io","username":"igawa"},"change_message_id":"22fbc29a21bf16ff36db3a953b5141bda7cafe0f","unresolved":false,"context_lines":[{"line_number":257,"context_line":"                #    \"users\": ["},{"line_number":258,"context_line":"                #      ..."},{"line_number":259,"context_line":"                #    ]"},{"line_number":260,"context_line":"                #  }"},{"line_number":261,"context_line":"            try:"},{"line_number":262,"context_line":"                # Ensure there are not more than one top-level keys"},{"line_number":263,"context_line":"                if len(body.keys()) \u003e 1:"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAUH%2F9aKw%3D","line":260,"updated":"2014-02-07 04:29:51.000000000","message":"Are these indents intentional? It\u0027s a little odd to me.","commit_id":"ef7710cf9fa4b94dbf305f383a4c1d05ecb74ad4"},{"author":{"_account_id":5689,"name":"Masayuki Igawa","email":"masayuki@igawa.io","username":"igawa"},"change_message_id":"beb76eb40b33f47bbdf86819fe1843df4b1f2ec5","unresolved":false,"context_lines":[{"line_number":257,"context_line":"                #    \"users\": ["},{"line_number":258,"context_line":"                #      ..."},{"line_number":259,"context_line":"                #    ]"},{"line_number":260,"context_line":"                #  }"},{"line_number":261,"context_line":"            try:"},{"line_number":262,"context_line":"                # Ensure there are not more than one top-level keys"},{"line_number":263,"context_line":"                if len(body.keys()) \u003e 1:"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAUX%2F%2Fwz0%3D","line":260,"in_reply_to":"AAAAUH%2F9ZbQ%3D","updated":"2014-02-10 23:21:25.000000000","message":"I\u0027d prefer to fix in this patch because no one without me reviewed for now and it\u0027s too nit to separate the patch.","commit_id":"ef7710cf9fa4b94dbf305f383a4c1d05ecb74ad4"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"c70178d8ce448fbd62c79edcef11a6151ff7eb74","unresolved":false,"context_lines":[{"line_number":257,"context_line":"                #    \"users\": ["},{"line_number":258,"context_line":"                #      ..."},{"line_number":259,"context_line":"                #    ]"},{"line_number":260,"context_line":"                #  }"},{"line_number":261,"context_line":"            try:"},{"line_number":262,"context_line":"                # Ensure there are not more than one top-level keys"},{"line_number":263,"context_line":"                if len(body.keys()) \u003e 1:"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAUH%2F9ZbQ%3D","line":260,"in_reply_to":"AAAAUH%2F9aKw%3D","updated":"2014-02-07 07:12:09.000000000","message":"No, not intentional.\n\nShould I fix it in this patch, or let it fix separately?","commit_id":"ef7710cf9fa4b94dbf305f383a4c1d05ecb74ad4"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"b8a49a9c1bc13876c517e04bb8099a3405acc48e","unresolved":false,"context_lines":[{"line_number":257,"context_line":"                #    \"users\": ["},{"line_number":258,"context_line":"                #      ..."},{"line_number":259,"context_line":"                #    ]"},{"line_number":260,"context_line":"                #  }"},{"line_number":261,"context_line":"            try:"},{"line_number":262,"context_line":"                # Ensure there are not more than one top-level keys"},{"line_number":263,"context_line":"                if len(body.keys()) \u003e 1:"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAUX%2F%2Ftfk%3D","line":260,"in_reply_to":"AAAAUX%2F%2Fwz0%3D","updated":"2014-02-11 09:54:06.000000000","message":"Done","commit_id":"ef7710cf9fa4b94dbf305f383a4c1d05ecb74ad4"}],"tempest/services/identity/json/identity_client.py":[{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"b9ee2e4fe6a9f49c38ce19d0bfbde7a6cfb39ed0","unresolved":false,"context_lines":[{"line_number":52,"context_line":"            \u0027name\u0027: name,"},{"line_number":53,"context_line":"        }"},{"line_number":54,"context_line":"        post_body \u003d json.dumps({\u0027role\u0027: post_body})"},{"line_number":55,"context_line":"        resp, body \u003d self.post(\u0027OS-KSADM/roles\u0027, post_body, self.get_headers())"},{"line_number":56,"context_line":"        return resp, self._parse_resp(body)"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def create_tenant(self, name, **kwargs):"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAT3%2F%2F%2FBA%3D","line":55,"updated":"2013-12-25 12:58:12.000000000","message":"headers are never changed by any of methods here.\nyou can modify get/post/put/etc methods to accept headers with default value of None and remove all references to get_headers from this file.","commit_id":"8f3cf9de33dfb00f8087461df65cf9d7eee9f68d"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"9d9a5f2607e1115b9a79c5030a7fdbf0a46b84c1","unresolved":false,"context_lines":[{"line_number":52,"context_line":"            \u0027name\u0027: name,"},{"line_number":53,"context_line":"        }"},{"line_number":54,"context_line":"        post_body \u003d json.dumps({\u0027role\u0027: post_body})"},{"line_number":55,"context_line":"        resp, body \u003d self.post(\u0027OS-KSADM/roles\u0027, post_body, self.get_headers())"},{"line_number":56,"context_line":"        return resp, self._parse_resp(body)"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def create_tenant(self, name, **kwargs):"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAT3%2F%2F%2B%2B4%3D","line":55,"in_reply_to":"AAAAT3%2F%2F%2FBA%3D","updated":"2013-12-25 17:00:17.000000000","message":"Good point, thanks.\n\nDone.","commit_id":"8f3cf9de33dfb00f8087461df65cf9d7eee9f68d"},{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"b9ee2e4fe6a9f49c38ce19d0bfbde7a6cfb39ed0","unresolved":false,"context_lines":[{"line_number":53,"context_line":"        }"},{"line_number":54,"context_line":"        post_body \u003d json.dumps({\u0027role\u0027: post_body})"},{"line_number":55,"context_line":"        resp, body \u003d self.post(\u0027OS-KSADM/roles\u0027, post_body, self.get_headers())"},{"line_number":56,"context_line":"        return resp, self._parse_resp(body)"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def create_tenant(self, name, **kwargs):"},{"line_number":59,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAT3%2F%2F%2FBI%3D","line":56,"updated":"2013-12-25 12:58:12.000000000","message":"it makes sense to move _parse_resp into self.port/get/put/delete.\nIt will save you a bunch of calls in json and xml client methods","commit_id":"8f3cf9de33dfb00f8087461df65cf9d7eee9f68d"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"9d9a5f2607e1115b9a79c5030a7fdbf0a46b84c1","unresolved":false,"context_lines":[{"line_number":53,"context_line":"        }"},{"line_number":54,"context_line":"        post_body \u003d json.dumps({\u0027role\u0027: post_body})"},{"line_number":55,"context_line":"        resp, body \u003d self.post(\u0027OS-KSADM/roles\u0027, post_body, self.get_headers())"},{"line_number":56,"context_line":"        return resp, self._parse_resp(body)"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def create_tenant(self, name, **kwargs):"},{"line_number":59,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAT3%2F%2F%2BkA%3D","line":56,"in_reply_to":"AAAAT3%2F%2F%2FBI%3D","updated":"2013-12-25 17:00:17.000000000","message":"Done, but with one remark:\n\nFor xml clients there is need to define top tags of responses, that should be parsed as list/array instead as one item.","commit_id":"8f3cf9de33dfb00f8087461df65cf9d7eee9f68d"}],"tempest/services/identity/xml/identity_client.py":[{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"b9ee2e4fe6a9f49c38ce19d0bfbde7a6cfb39ed0","unresolved":false,"context_lines":[{"line_number":145,"context_line":"        auth \u003d Element(\"auth\", tenantName\u003dtenant)"},{"line_number":146,"context_line":"        auth.append(passwordCreds)"},{"line_number":147,"context_line":"        headers \u003d {\u0027Content-Type\u0027: \u0027application/%s\u0027 % self._get_type()}"},{"line_number":148,"context_line":"        return self.post(self.auth_url, headers\u003dheaders,"},{"line_number":149,"context_line":"                         body\u003dstr(Document(auth)))"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAT3%2F%2F%2FAs%3D","line":148,"updated":"2013-12-25 12:58:12.000000000","message":"as i mentioned in previous comments, it\u0027s better to get rid of passing headers to these methods.\nAlso I see the usage is inconsistent between this call and the call on line 112, 119.\nThis is abother reason to get rid of passing headers as a parameter","commit_id":"8f3cf9de33dfb00f8087461df65cf9d7eee9f68d"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"9d9a5f2607e1115b9a79c5030a7fdbf0a46b84c1","unresolved":false,"context_lines":[{"line_number":145,"context_line":"        auth \u003d Element(\"auth\", tenantName\u003dtenant)"},{"line_number":146,"context_line":"        auth.append(passwordCreds)"},{"line_number":147,"context_line":"        headers \u003d {\u0027Content-Type\u0027: \u0027application/%s\u0027 % self._get_type()}"},{"line_number":148,"context_line":"        return self.post(self.auth_url, headers\u003dheaders,"},{"line_number":149,"context_line":"                         body\u003dstr(Document(auth)))"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAT3%2F%2F%2BkE%3D","line":148,"in_reply_to":"AAAAT3%2F%2F%2FAs%3D","updated":"2013-12-25 17:00:17.000000000","message":"Done","commit_id":"8f3cf9de33dfb00f8087461df65cf9d7eee9f68d"}],"tempest/tests/fake_http.py":[{"author":{"_account_id":5689,"name":"Masayuki Igawa","email":"masayuki@igawa.io","username":"igawa"},"change_message_id":"e613f93bf0e15e73348e4935527547a4d55d8367","unresolved":false,"context_lines":[{"line_number":33,"context_line":"                \u0027headers\u0027: headers"},{"line_number":34,"context_line":"            }"},{"line_number":35,"context_line":"            return (fake_headers, return_obj)"},{"line_number":36,"context_line":"            # return (headers, return_obj)"},{"line_number":37,"context_line":"        elif isinstance(self.return_type, int):"},{"line_number":38,"context_line":"            body \u003d \"fake_body\""},{"line_number":39,"context_line":"            header_info \u003d {"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2B4A0%3D","line":36,"updated":"2014-01-21 07:45:35.000000000","message":"Do we need this commented out code? I think this should be removed in another patch.","commit_id":"2dd318a7a962e927b62f14e361df87d40698da70"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"585ef73b65d12c11c95d6c04533af7e8ffadece2","unresolved":false,"context_lines":[{"line_number":33,"context_line":"                \u0027headers\u0027: headers"},{"line_number":34,"context_line":"            }"},{"line_number":35,"context_line":"            return (fake_headers, return_obj)"},{"line_number":36,"context_line":"            # return (headers, return_obj)"},{"line_number":37,"context_line":"        elif isinstance(self.return_type, int):"},{"line_number":38,"context_line":"            body \u003d \"fake_body\""},{"line_number":39,"context_line":"            header_info \u003d {"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2BMDs%3D","line":36,"in_reply_to":"AAAAUH%2F%2B4A0%3D","updated":"2014-01-29 10:05:10.000000000","message":"Agree, it is redundant, and it is out of scope for this topic too.\nMaybe it should be done in another commit.","commit_id":"2dd318a7a962e927b62f14e361df87d40698da70"}],"tempest/tests/test_rest_client.py":[{"author":{"_account_id":5174,"name":"Mauro Sergio Martins Rodrigues","email":"maurosr@linux.vnet.ibm.com","username":"maurosr"},"change_message_id":"893472a7549f5f037c12d5d8bc011db5bc96c911","unresolved":false,"context_lines":[{"line_number":74,"context_line":"    def test_head(self):"},{"line_number":75,"context_line":"        self.useFixture(mockpatch.PatchObject(self.rest_client,"},{"line_number":76,"context_line":"                                              \u0027response_checker\u0027))"},{"line_number":77,"context_line":"        resp, return_dict \u003d self.rest_client.head(self.url)"},{"line_number":78,"context_line":"        self.assertEqual(\u0027HEAD\u0027, return_dict[\u0027method\u0027])"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def test_copy(self):"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2BN%2FU%3D","line":77,"updated":"2014-01-28 23:43:06.000000000","message":"why resp here? I don\u0027t think this change matters here","commit_id":"2dd318a7a962e927b62f14e361df87d40698da70"},{"author":{"_account_id":8851,"name":"Valeriy Ponomaryov","email":"kiparis.kh@gmail.com","username":"vponomaryov"},"change_message_id":"585ef73b65d12c11c95d6c04533af7e8ffadece2","unresolved":false,"context_lines":[{"line_number":74,"context_line":"    def test_head(self):"},{"line_number":75,"context_line":"        self.useFixture(mockpatch.PatchObject(self.rest_client,"},{"line_number":76,"context_line":"                                              \u0027response_checker\u0027))"},{"line_number":77,"context_line":"        resp, return_dict \u003d self.rest_client.head(self.url)"},{"line_number":78,"context_line":"        self.assertEqual(\u0027HEAD\u0027, return_dict[\u0027method\u0027])"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def test_copy(self):"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2BMEk%3D","line":77,"in_reply_to":"AAAAUH%2F%2BN%2FU%3D","updated":"2014-01-29 10:05:10.000000000","message":"You are right, setting here \u0027resp\u0027 is mistake. Forgot to set it back after testing stuff.","commit_id":"2dd318a7a962e927b62f14e361df87d40698da70"}]}
