)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"43d9adc42c7afb30331b0bc0954daafadad08f6b","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Add a Ceilometer collector dispatcher"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This introduces a new dispatcher for Ceilometer that is able to"},{"line_number":10,"context_line":"transform and publisher the Ceilometer samples to Gnocchi."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: I424b991075ddc6ca7ef6bd7c6d17db247bf90c83"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"1ae5cdf2_8d28ed86","line":10,"updated":"2014-06-17 12:43:58.000000000","message":"s/publisher/publish/","commit_id":"78988ca1dd1bfa5bc52bbd0a065a04a62dbe28be"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"3176a3606e5d314e156a37be4f8190bf934383e4","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Add a Ceilometer collector dispatcher"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This introduces a new dispatcher for Ceilometer that is able to"},{"line_number":10,"context_line":"transform and publisher the Ceilometer samples to Gnocchi."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: I424b991075ddc6ca7ef6bd7c6d17db247bf90c83"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"1ae5cdf2_db215d9f","line":10,"in_reply_to":"1ae5cdf2_8d28ed86","updated":"2014-06-19 13:22:26.000000000","message":"Done","commit_id":"78988ca1dd1bfa5bc52bbd0a065a04a62dbe28be"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"aa157b5861531772baf4b9ab1b88e51e88511293","unresolved":false,"context_lines":[{"line_number":9,"context_line":"This introduces a new dispatcher for Gnocchi that is able to"},{"line_number":10,"context_line":"transform and publish the Ceilometer samples to Gnocchi."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Co-Authored-by: Julien Danjou\u003cjulien@danjou.info\u003e"},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Change-Id: I424b991075ddc6ca7ef6bd7c6d17db247bf90c83"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":57,"id":"9aa7fdbe_7e0158ae","line":12,"updated":"2014-10-23 14:47:31.000000000","message":"Missing space","commit_id":"fdb74e7826afe46ce21e9cb7c75d8fef3d7e3daa"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"a4dcabb577f35775a64712d8f60207ce7485efd3","unresolved":false,"context_lines":[{"line_number":9,"context_line":"This introduces a new dispatcher for Gnocchi that is able to"},{"line_number":10,"context_line":"transform and publish the Ceilometer samples to Gnocchi."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Co-Authored-by: Julien Danjou\u003cjulien@danjou.info\u003e"},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Change-Id: I424b991075ddc6ca7ef6bd7c6d17db247bf90c83"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":57,"id":"9aa7fdbe_e18f6d28","line":12,"in_reply_to":"9aa7fdbe_7e0158ae","updated":"2014-10-23 15:11:20.000000000","message":"Done","commit_id":"fdb74e7826afe46ce21e9cb7c75d8fef3d7e3daa"}],"gnocchi/ceilometer.py":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"43d9adc42c7afb30331b0bc0954daafadad08f6b","unresolved":false,"context_lines":[{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    def record_metering_data(self, data):"},{"line_number":47,"context_line":"        for sample in data:"},{"line_number":48,"context_line":"            if sample[\u0027counter_name\u0027] in (\u0027instance\u0027,"},{"line_number":49,"context_line":"                                          \u0027disk.root.size\u0027,"},{"line_number":50,"context_line":"                                          \u0027disk.ephemeral.size\u0027,"},{"line_number":51,"context_line":"                                          \u0027memory\u0027,"}],"source_content_type":"text/x-python","patch_set":17,"id":"1ae5cdf2_48f6d35e","line":48,"updated":"2014-06-17 12:43:58.000000000","message":"With this chunk here we now have at least three places where the description of an instance is being maintained:\n\n* the place/code that sent the notification\n* here\n* at the storage level\n\nNot DRY.\n\nI recognize that this is a prototype so we want to get it working and then get it right, but I\u0027m not feeling entirely confident that getting DRY-ness of this kind of info is a shared goal.\n\nIt\u0027s not just a question of not duplicating stuff, but also ensuring that the center of authority is designed such that we maximize opportunity for various things to use the service without the service needing to be upgraded to take notice of it.","commit_id":"78988ca1dd1bfa5bc52bbd0a065a04a62dbe28be"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"3176a3606e5d314e156a37be4f8190bf934383e4","unresolved":false,"context_lines":[{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    def record_metering_data(self, data):"},{"line_number":47,"context_line":"        for sample in data:"},{"line_number":48,"context_line":"            if sample[\u0027counter_name\u0027] in (\u0027instance\u0027,"},{"line_number":49,"context_line":"                                          \u0027disk.root.size\u0027,"},{"line_number":50,"context_line":"                                          \u0027disk.ephemeral.size\u0027,"},{"line_number":51,"context_line":"                                          \u0027memory\u0027,"}],"source_content_type":"text/x-python","patch_set":17,"id":"1ae5cdf2_5b5b8d21","line":48,"in_reply_to":"1ae5cdf2_48f6d35e","updated":"2014-06-19 13:22:26.000000000","message":"Oh I agree. The ultimate goal is to entirely remove the notion of samples anyway, so this is clearly just code toward that goal.\n\nThere\u0027s also plan to schematize (and therefore share the schema) the oslo notifications Ceilometer handles FWIW.","commit_id":"78988ca1dd1bfa5bc52bbd0a065a04a62dbe28be"},{"author":{"_account_id":3012,"name":"Dina Belova","email":"dbelova@mirantis.com","username":"dbelova"},"change_message_id":"b94885bd6e4107c43c11714777212e7fbe582419","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# -*- encoding: utf-8 -*-"},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"# Copyright © 2014 eNovance"},{"line_number":4,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":18,"id":"baada198_12144ee7","line":1,"updated":"2014-07-08 02:45:40.000000000","message":"btw, we have removed all encoding lines in the ceilometer, so, probably, we need not to introduce them here?","commit_id":"b6012636e4224d036600153eac1414052ec5ff6b"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"13c510126f726312858654d82ac40698ded57cfc","unresolved":false,"context_lines":[{"line_number":67,"context_line":"                continue"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"            resource_id \u003d sample[\u0027resource_id\u0027]"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"            r \u003d requests.patch("},{"line_number":72,"context_line":"                \"%s/v1/resource/%s/%s\""},{"line_number":73,"context_line":"                % (self.gnocchi_url, resource_type, resource_id),"}],"source_content_type":"text/x-python","patch_set":18,"id":"1ae5cdf2_3b8fa1ce","line":70,"updated":"2014-06-19 13:53:20.000000000","message":"I\u0027m somewhat confused about the semantics of the api, especially in the area of mapping names used in old skool ceilometer to the names used in gnocchi and how those things correspond to the http methods.\n\nFor example I\u0027m surprised to see `patch` here, not `put`. It appears that a resource with a type and id is being replaced. That is, that the representation that is in params is the entire resource, not some part of it.\n\nAlso is there an optimization here:\n\n    if HEAD \u003cresource\u003e \u003d\u003d 404: create or update resource\n\nOr depending on the form of `data` do the resource checking in a loop before/separate from the sample writes.\n\nI\u0027m not making these comments to say \"ew ick\" but rather \"help me to understand the goals and processes here\".\n\nI suppose much of this will be more clear when the metric posting code exists.","commit_id":"b6012636e4224d036600153eac1414052ec5ff6b"},{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"c1e7fd1e4d479c9577574988c8c18855d142a425","unresolved":false,"context_lines":[{"line_number":67,"context_line":"                continue"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"            resource_id \u003d sample[\u0027resource_id\u0027]"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"            r \u003d requests.patch("},{"line_number":72,"context_line":"                \"%s/v1/resource/%s/%s\""},{"line_number":73,"context_line":"                % (self.gnocchi_url, resource_type, resource_id),"}],"source_content_type":"text/x-python","patch_set":18,"id":"1ae5cdf2_b936544f","line":70,"in_reply_to":"1ae5cdf2_2dee86b5","updated":"2014-06-19 16:51:39.000000000","message":"@chdent\n\nI suspect the point here is that the resource indexer driver get_resource() signature requires a resource type to be specified up front, for example in the sqlalchemy implementation:\n\n  https://github.com/stackforge/gnocchi/blob/master/gnocchi/indexer/sqlalchemy.py#L257\n\nShort of knowing the resource type a priori, I guess the calling code would have to call get_resource once with resource_type\u003d\u0027generic\u0027 to retrieve the type and other generic attributes, then call it a second time with resource_type\u003d\u003cthe actual type\u003e in order to recover the type-specific attributes shorn off in the first call.\n\nBut I guess all of that is just an artifact of how the indexer driver internal API is expressed, and not necessarily something that needs necessarily to be exposed in the RESTful API.","commit_id":"b6012636e4224d036600153eac1414052ec5ff6b"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"e4a0678b5ea68acc8a5be7e2dd8778fb41ce725f","unresolved":false,"context_lines":[{"line_number":67,"context_line":"                continue"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"            resource_id \u003d sample[\u0027resource_id\u0027]"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"            r \u003d requests.patch("},{"line_number":72,"context_line":"                \"%s/v1/resource/%s/%s\""},{"line_number":73,"context_line":"                % (self.gnocchi_url, resource_type, resource_id),"}],"source_content_type":"text/x-python","patch_set":18,"id":"1ae5cdf2_f625500a","line":70,"in_reply_to":"1ae5cdf2_368c1880","updated":"2014-06-19 14:13:11.000000000","message":"Okay, sorry if I\u0027m being thick about the difference between resources and samples, but a few more questions:\n\n* If I were to GET /resource/$type/$id what would I get? a) a description of the reslource b) a description of the resource and all its samples c) something else?\n* Why should I have to care about $type when doing a PATCH or POST?  If the URI structure is to facilitate retrieving all the resources of a particular type, a query string would allow that while making /resource/$id a valid route.\n* I don\u0027t think you addressed my query about optimizing resource existence checking and creation outside the sample writes. If `data` includes 550 samples from the same resource, we\u0027re going to do at least 549 redundant writes and maybe 550.","commit_id":"b6012636e4224d036600153eac1414052ec5ff6b"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"4219a36c300b1fcfd911901710a1e8fcd8c40daa","unresolved":false,"context_lines":[{"line_number":67,"context_line":"                continue"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"            resource_id \u003d sample[\u0027resource_id\u0027]"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"            r \u003d requests.patch("},{"line_number":72,"context_line":"                \"%s/v1/resource/%s/%s\""},{"line_number":73,"context_line":"                % (self.gnocchi_url, resource_type, resource_id),"}],"source_content_type":"text/x-python","patch_set":18,"id":"1ae5cdf2_368c1880","line":70,"in_reply_to":"1ae5cdf2_3b8fa1ce","updated":"2014-06-19 13:57:42.000000000","message":"The entire resource is NOT being replaced, because to replace it you would have to GET it, make changes, and then PUT it back, which needs 2 requests. Using PATCH avoids doing 2 requests.\n\n\nSo what the code does is that it tries to PATCH, and if that fails (which is the case the first time we encounter a resource), we receive a 404 and therefore we start a POST to create the request.\n\nThat makes sure that 99% of the time, we just use PATCH and do one request per sample, no more.","commit_id":"b6012636e4224d036600153eac1414052ec5ff6b"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"f4db1df15d611a018e612cbeabc9e7c7341f5fbc","unresolved":false,"context_lines":[{"line_number":67,"context_line":"                continue"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"            resource_id \u003d sample[\u0027resource_id\u0027]"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"            r \u003d requests.patch("},{"line_number":72,"context_line":"                \"%s/v1/resource/%s/%s\""},{"line_number":73,"context_line":"                % (self.gnocchi_url, resource_type, resource_id),"}],"source_content_type":"text/x-python","patch_set":18,"id":"1ae5cdf2_2dee86b5","line":70,"in_reply_to":"1ae5cdf2_4a4738a3","updated":"2014-06-19 15:11:40.000000000","message":"I\u0027m sorry, but I don\u0027t understand this comment at all. Can you point me to a bit more information? Thanks.","commit_id":"b6012636e4224d036600153eac1414052ec5ff6b"},{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"75d07bd15a331ff8830ebceb66c262b7e70371d8","unresolved":false,"context_lines":[{"line_number":67,"context_line":"                continue"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"            resource_id \u003d sample[\u0027resource_id\u0027]"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"            r \u003d requests.patch("},{"line_number":72,"context_line":"                \"%s/v1/resource/%s/%s\""},{"line_number":73,"context_line":"                % (self.gnocchi_url, resource_type, resource_id),"}],"source_content_type":"text/x-python","patch_set":18,"id":"1ae5cdf2_c335cff7","line":70,"in_reply_to":"1ae5cdf2_6da78a50","updated":"2014-06-20 14:41:50.000000000","message":"@cdent\n\n\u003e Can someone _please_ explain to me why 2 queries are needed when you have an $id? Or to put it another way, why is an $id not an ID?\n\nCan we separate out the as-is from the ought-to-be?\n\nFirst, how I understand the as-is currently (open to correction as always) ...\n\nResources are strongly typed, with one table for generic resource attributes and also separate tables for the instance-specific, image-specific, volume-specific metadata, with resource ID as a foreign key in each case.\n\nSo if you know the resource in question is an instance for example, you can query over an inner join of the generic and instance tables.\n\nWhereas I guess if you don\u0027t know the resource type upfront *and* you still want all the detailed resource-specific attributes, you have to query the generic table first to find the resource type, which then tells you which resource-type-specific table to also look in.\n\nOnce we\u0027ve that piece tied down, we can move on to the separate ought-to-be debate.","commit_id":"b6012636e4224d036600153eac1414052ec5ff6b"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"678ddba9ff9bb3a101f23b6ca21a68646ac49393","unresolved":false,"context_lines":[{"line_number":67,"context_line":"                continue"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"            resource_id \u003d sample[\u0027resource_id\u0027]"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"            r \u003d requests.patch("},{"line_number":72,"context_line":"                \"%s/v1/resource/%s/%s\""},{"line_number":73,"context_line":"                % (self.gnocchi_url, resource_type, resource_id),"}],"source_content_type":"text/x-python","patch_set":18,"id":"1ae5cdf2_6da78a50","line":70,"in_reply_to":"1ae5cdf2_74bbd70e","updated":"2014-06-20 13:45:49.000000000","message":"Can someone _please_ explain to me why 2 queries are needed when you have an $id? Or to put it another way, why is an $id not an ID? See my comments elsewhere in the review (not inline, but on the gerrit comment flow).","commit_id":"b6012636e4224d036600153eac1414052ec5ff6b"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"b5fa71c97dc606086828be990815fb54f4362ff9","unresolved":false,"context_lines":[{"line_number":67,"context_line":"                continue"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"            resource_id \u003d sample[\u0027resource_id\u0027]"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"            r \u003d requests.patch("},{"line_number":72,"context_line":"                \"%s/v1/resource/%s/%s\""},{"line_number":73,"context_line":"                % (self.gnocchi_url, resource_type, resource_id),"}],"source_content_type":"text/x-python","patch_set":18,"id":"1ae5cdf2_74bbd70e","line":70,"in_reply_to":"1ae5cdf2_b936544f","updated":"2014-06-20 12:17:34.000000000","message":"Eoghan: so my plan is to add a ?detail\u003dtrue in the API if you try to retrieve the resource with /v1/resource/generic/$id and don\u0027t know the exact type. That will in that case do 2 SQL queries behind.\n\nI think it\u0027s stupid to *always* do 2 SQL queries if the client know the type of the resource is looking advance already (which is the case in many cases like here).","commit_id":"b6012636e4224d036600153eac1414052ec5ff6b"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"c5b48dcd014edff1218a23d68b531b937bfeadb8","unresolved":false,"context_lines":[{"line_number":67,"context_line":"                continue"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"            resource_id \u003d sample[\u0027resource_id\u0027]"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"            r \u003d requests.patch("},{"line_number":72,"context_line":"                \"%s/v1/resource/%s/%s\""},{"line_number":73,"context_line":"                % (self.gnocchi_url, resource_type, resource_id),"}],"source_content_type":"text/x-python","patch_set":18,"id":"1ae5cdf2_4a4738a3","line":70,"in_reply_to":"1ae5cdf2_d613f462","updated":"2014-06-19 14:46:26.000000000","message":"To reply on point 2, actually it is more expensive to have /resource/$id because you have to find the type on the API with at least 2 SQL requests.\n\nOr if you already know what type it is, it\u0027s better to tell the API right away so it\u0027s faster.","commit_id":"b6012636e4224d036600153eac1414052ec5ff6b"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"164688a3b620404067be714efe9f845a7e593ae2","unresolved":false,"context_lines":[{"line_number":67,"context_line":"                continue"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"            resource_id \u003d sample[\u0027resource_id\u0027]"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"            r \u003d requests.patch("},{"line_number":72,"context_line":"                \"%s/v1/resource/%s/%s\""},{"line_number":73,"context_line":"                % (self.gnocchi_url, resource_type, resource_id),"}],"source_content_type":"text/x-python","patch_set":18,"id":"1ae5cdf2_d613f462","line":70,"in_reply_to":"1ae5cdf2_f625500a","updated":"2014-06-19 14:20:12.000000000","message":"So to clear things out, \"samples\" are what Ceilometer currently generates, and \"resources\" and \"entities\" are objects that are specific to Gnocchi. So the point of all this code is to \"convert\" samples to resources+entities.\n\n- a)\n- The question is rather why is the URIs scheme /resource/$type. I don\u0027t recall exactly why I made this choice, but we can still change it, I\u0027ll look into that.\n- You are right, there is no optimization for now for this case. Best thing we can is to do a reduce() on data to handle the resource creation/update first I guess.","commit_id":"b6012636e4224d036600153eac1414052ec5ff6b"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"13c510126f726312858654d82ac40698ded57cfc","unresolved":false,"context_lines":[{"line_number":81,"context_line":"                params[\"user_id\"] \u003d sample[\u0027user_id\u0027]"},{"line_number":82,"context_line":"                params[\"project_id\"] \u003d sample[\u0027project_id\u0027]"},{"line_number":83,"context_line":"                # TODO(jd) Create entities"},{"line_number":84,"context_line":"                r \u003d requests.post(\"%s/v1/resource/%s\""},{"line_number":85,"context_line":"                                  % (self.gnocchi_url, resource_type),"},{"line_number":86,"context_line":"                                  headers\u003d{\u0027Content-Type\u0027: \"application/json\"},"},{"line_number":87,"context_line":"                                  data\u003djson.dumps(params))"}],"source_content_type":"text/x-python","patch_set":18,"id":"1ae5cdf2_3bffa1ac","line":84,"updated":"2014-06-19 13:53:20.000000000","message":"Is it worth making this URI string a constant (kept at the module level)?","commit_id":"b6012636e4224d036600153eac1414052ec5ff6b"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"e4a0678b5ea68acc8a5be7e2dd8778fb41ce725f","unresolved":false,"context_lines":[{"line_number":81,"context_line":"                params[\"user_id\"] \u003d sample[\u0027user_id\u0027]"},{"line_number":82,"context_line":"                params[\"project_id\"] \u003d sample[\u0027project_id\u0027]"},{"line_number":83,"context_line":"                # TODO(jd) Create entities"},{"line_number":84,"context_line":"                r \u003d requests.post(\"%s/v1/resource/%s\""},{"line_number":85,"context_line":"                                  % (self.gnocchi_url, resource_type),"},{"line_number":86,"context_line":"                                  headers\u003d{\u0027Content-Type\u0027: \"application/json\"},"},{"line_number":87,"context_line":"                                  data\u003djson.dumps(params))"}],"source_content_type":"text/x-python","patch_set":18,"id":"1ae5cdf2_36733817","line":84,"in_reply_to":"1ae5cdf2_16dabc77","updated":"2014-06-19 14:13:11.000000000","message":"?","commit_id":"b6012636e4224d036600153eac1414052ec5ff6b"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"f4db1df15d611a018e612cbeabc9e7c7341f5fbc","unresolved":false,"context_lines":[{"line_number":81,"context_line":"                params[\"user_id\"] \u003d sample[\u0027user_id\u0027]"},{"line_number":82,"context_line":"                params[\"project_id\"] \u003d sample[\u0027project_id\u0027]"},{"line_number":83,"context_line":"                # TODO(jd) Create entities"},{"line_number":84,"context_line":"                r \u003d requests.post(\"%s/v1/resource/%s\""},{"line_number":85,"context_line":"                                  % (self.gnocchi_url, resource_type),"},{"line_number":86,"context_line":"                                  headers\u003d{\u0027Content-Type\u0027: \"application/json\"},"},{"line_number":87,"context_line":"                                  data\u003djson.dumps(params))"}],"source_content_type":"text/x-python","patch_set":18,"id":"1ae5cdf2_6d05eec0","line":84,"in_reply_to":"1ae5cdf2_3602580c","updated":"2014-06-19 15:11:40.000000000","message":"Feh. Why gerrit no unicode? That was a tickmark U+2713.","commit_id":"b6012636e4224d036600153eac1414052ec5ff6b"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"164688a3b620404067be714efe9f845a7e593ae2","unresolved":false,"context_lines":[{"line_number":81,"context_line":"                params[\"user_id\"] \u003d sample[\u0027user_id\u0027]"},{"line_number":82,"context_line":"                params[\"project_id\"] \u003d sample[\u0027project_id\u0027]"},{"line_number":83,"context_line":"                # TODO(jd) Create entities"},{"line_number":84,"context_line":"                r \u003d requests.post(\"%s/v1/resource/%s\""},{"line_number":85,"context_line":"                                  % (self.gnocchi_url, resource_type),"},{"line_number":86,"context_line":"                                  headers\u003d{\u0027Content-Type\u0027: \"application/json\"},"},{"line_number":87,"context_line":"                                  data\u003djson.dumps(params))"}],"source_content_type":"text/x-python","patch_set":18,"id":"1ae5cdf2_3602580c","line":84,"in_reply_to":"1ae5cdf2_36733817","updated":"2014-06-19 14:20:12.000000000","message":"!","commit_id":"b6012636e4224d036600153eac1414052ec5ff6b"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"4219a36c300b1fcfd911901710a1e8fcd8c40daa","unresolved":false,"context_lines":[{"line_number":81,"context_line":"                params[\"user_id\"] \u003d sample[\u0027user_id\u0027]"},{"line_number":82,"context_line":"                params[\"project_id\"] \u003d sample[\u0027project_id\u0027]"},{"line_number":83,"context_line":"                # TODO(jd) Create entities"},{"line_number":84,"context_line":"                r \u003d requests.post(\"%s/v1/resource/%s\""},{"line_number":85,"context_line":"                                  % (self.gnocchi_url, resource_type),"},{"line_number":86,"context_line":"                                  headers\u003d{\u0027Content-Type\u0027: \"application/json\"},"},{"line_number":87,"context_line":"                                  data\u003djson.dumps(params))"}],"source_content_type":"text/x-python","patch_set":18,"id":"1ae5cdf2_16dabc77","line":84,"in_reply_to":"1ae5cdf2_3bffa1ac","updated":"2014-06-19 13:57:42.000000000","message":"Probably – the plan would be to have a gnocchiclient, but as this is more a PoC than anything else, I\u0027m not worried yet.","commit_id":"b6012636e4224d036600153eac1414052ec5ff6b"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"b5fa71c97dc606086828be990815fb54f4362ff9","unresolved":false,"context_lines":[{"line_number":81,"context_line":"                params[\"user_id\"] \u003d sample[\u0027user_id\u0027]"},{"line_number":82,"context_line":"                params[\"project_id\"] \u003d sample[\u0027project_id\u0027]"},{"line_number":83,"context_line":"                # TODO(jd) Create entities"},{"line_number":84,"context_line":"                r \u003d requests.post(\"%s/v1/resource/%s\""},{"line_number":85,"context_line":"                                  % (self.gnocchi_url, resource_type),"},{"line_number":86,"context_line":"                                  headers\u003d{\u0027Content-Type\u0027: \"application/json\"},"},{"line_number":87,"context_line":"                                  data\u003djson.dumps(params))"}],"source_content_type":"text/x-python","patch_set":18,"id":"1ae5cdf2_b438ffa0","line":84,"in_reply_to":"1ae5cdf2_6d05eec0","updated":"2014-06-20 12:17:34.000000000","message":"I feel your pain.","commit_id":"b6012636e4224d036600153eac1414052ec5ff6b"}],"gnocchi/ceilometer/dispatcher.py":[{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"2cf831d38b56ecf0dc0a455c05493bb3b040699c","unresolved":false,"context_lines":[{"line_number":85,"context_line":"            \"%s/v1/resource/%s/%s\""},{"line_number":86,"context_line":"            % (self.gnocchi_url, resource_type, resource_id),"},{"line_number":87,"context_line":"            headers\u003d{\u0027Content-Type\u0027: \"application/json\"},"},{"line_number":88,"context_line":"            data\u003djson.dumps(params))"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"        # If we get a 404, that\u0027s because the resource has not been"},{"line_number":91,"context_line":"        # created yet, let\u0027s do it"}],"source_content_type":"text/x-python","patch_set":35,"id":"da9df570_3c0ca142","line":88,"updated":"2014-09-22 17:24:45.000000000","message":"Seems sub-optimal to try to patch the resource *upfront* for every single sample.\n\nWould it be more efficient to avoid always hitting the resource API in this way and instead optimistically assume that the resource already exists, by jumping straight to the:\n\n  POST /v1/resource/resource-type/resource-id/entity/meter-name/measures\n\nrequest that\u0027s currently on line 136, and only then fall back to checking if we need to create the resource and/or entity if the optimistic post fails with 404?\n\nSo we\u0027d effectively invert the current ordering and always eagerly post the measure to the entity first, only checking if the entity and possibly even the resource need to be created if the initial attempt to submit the datapoint fails.","commit_id":"4f95c93c24a3a489c2e0b9a177ce718629e1a026"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"d56bdc2976e4c76c4236051c785997d274e47c62","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    cfg.StrOpt(\u0027archive_policy\u0027,"},{"line_number":36,"context_line":"               default\u003d\"low\","},{"line_number":37,"context_line":"               help\u003d\u0027The archive policy to use when the dispatcher \u0027"},{"line_number":38,"context_line":"               \u0027create a new resource\u0027)"},{"line_number":39,"context_line":"]"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"cfg.CONF.register_opts(dispatcher_opts, group\u003d\"dispatcher_gnocchi\")"}],"source_content_type":"text/x-python","patch_set":40,"id":"baa201ad_c2f70ef4","line":38,"updated":"2014-10-01 12:22:39.000000000","message":"Minor grammar nit: \"creates\"","commit_id":"76d310b5d7537a0f655ea848e028ebe200cca8b8"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"d56bdc2976e4c76c4236051c785997d274e47c62","unresolved":false,"context_lines":[{"line_number":95,"context_line":""},{"line_number":96,"context_line":"        # If we get a 404, that\u0027s because the resource has not been"},{"line_number":97,"context_line":"        # created yet, let\u0027s do it"},{"line_number":98,"context_line":"        if r.status_code \u003d\u003d 404:"},{"line_number":99,"context_line":"            params[\"id\"] \u003d resource_id"},{"line_number":100,"context_line":"            params[\"user_id\"] \u003d sample[\u0027user_id\u0027]"},{"line_number":101,"context_line":"            params[\"project_id\"] \u003d sample[\u0027project_id\u0027]"}],"source_content_type":"text/x-python","patch_set":40,"id":"baa201ad_42687e87","line":98,"updated":"2014-10-01 12:22:39.000000000","message":"I\u0027d be somewhat inclined to extract the body of this conditional to its own method, just for the sake of readability. Not really critical but I think it would be nice.","commit_id":"76d310b5d7537a0f655ea848e028ebe200cca8b8"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"d56bdc2976e4c76c4236051c785997d274e47c62","unresolved":false,"context_lines":[{"line_number":146,"context_line":"                          data\u003djson.dumps(params))"},{"line_number":147,"context_line":""},{"line_number":148,"context_line":"        if r.status_code \u003d\u003d 404:"},{"line_number":149,"context_line":"            LOG.debug(_(\"The entity %(entity_name)s of \""},{"line_number":150,"context_line":"                        \"resource %(resource_id)s doesn\u0027t exists\""},{"line_number":151,"context_line":"                        \"%(status_code)d\"),"},{"line_number":152,"context_line":"                      {\u0027entity_name\u0027: entity_name,"}],"source_content_type":"text/x-python","patch_set":40,"id":"baa201ad_820986df","line":149,"updated":"2014-10-01 12:22:39.000000000","message":"same as above, might be worth extracting method here","commit_id":"76d310b5d7537a0f655ea848e028ebe200cca8b8"},{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"2f01240e81da1595cd06f79aac847ceab5027ba9","unresolved":false,"context_lines":[{"line_number":91,"context_line":"            \"%s/v1/resource/%s/%s\""},{"line_number":92,"context_line":"            % (self.gnocchi_url, resource_type, resource_id),"},{"line_number":93,"context_line":"            headers\u003d{\u0027Content-Type\u0027: \"application/json\"},"},{"line_number":94,"context_line":"            data\u003djson.dumps(params))"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"        # If we get a 404, that\u0027s because the resource has not been"},{"line_number":97,"context_line":"        # created yet, let\u0027s do it"}],"source_content_type":"text/x-python","patch_set":42,"id":"baa201ad_87c09c7d","line":94,"updated":"2014-10-02 10:46:15.000000000","message":"Just repeating a comment I made on patchset 35:\n\n  https://review.openstack.org/#/c/98798/35/gnocchi/ceilometer/dispatcher.py\n\nthat may have gotten overlooked in the rapid sequence of updates:\n\nSeems sub-optimal to try to patch the resource *upfront* for every single sample.\n\nWould it be more efficient to avoid always hitting the resource API in this way and instead optimistically assume that the resource already exists, by jumping straight to the:\n\nPOST /v1/resource/resource-type/resource-id/entity/meter-name/measures\n\nrequest that\u0027s currently on line 136, and only then fall back to checking if we need to create the resource and/or entity if the optimistic post fails with 404?\n\nSo we\u0027d effectively invert the current ordering and always eagerly post the measure to the entity first, only checking if the entity and possibly even the resource need to be created if the initial attempt to submit the datapoint fails.","commit_id":"44a1467e3946238d38746a007a0bf5695ccde13c"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"65a93c834304feb188963a55cd86d86838ddbd50","unresolved":false,"context_lines":[{"line_number":91,"context_line":"            \"%s/v1/resource/%s/%s\""},{"line_number":92,"context_line":"            % (self.gnocchi_url, resource_type, resource_id),"},{"line_number":93,"context_line":"            headers\u003d{\u0027Content-Type\u0027: \"application/json\"},"},{"line_number":94,"context_line":"            data\u003djson.dumps(params))"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"        # If we get a 404, that\u0027s because the resource has not been"},{"line_number":97,"context_line":"        # created yet, let\u0027s do it"}],"source_content_type":"text/x-python","patch_set":42,"id":"baa201ad_63b70c3b","line":94,"in_reply_to":"baa201ad_2b8896e6","updated":"2014-10-03 12:54:00.000000000","message":"Done","commit_id":"44a1467e3946238d38746a007a0bf5695ccde13c"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"38e509bc18ed54deb965f03c584d9ffec11f3e64","unresolved":false,"context_lines":[{"line_number":91,"context_line":"            \"%s/v1/resource/%s/%s\""},{"line_number":92,"context_line":"            % (self.gnocchi_url, resource_type, resource_id),"},{"line_number":93,"context_line":"            headers\u003d{\u0027Content-Type\u0027: \"application/json\"},"},{"line_number":94,"context_line":"            data\u003djson.dumps(params))"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"        # If we get a 404, that\u0027s because the resource has not been"},{"line_number":97,"context_line":"        # created yet, let\u0027s do it"}],"source_content_type":"text/x-python","patch_set":42,"id":"baa201ad_2b8896e6","line":94,"in_reply_to":"baa201ad_87c09c7d","updated":"2014-10-02 15:26:33.000000000","message":"I don\u0027t see any difference, in term of number of requests.\n\n  resource don\u0027t exists: PATCH resource, POST resource, POST measures\n  resource exists:         PATCH resource, POST measures\n\nvs\n\n  resource don\u0027t exists: POST measures, POST resource, POST measures\n  resource exists:         POST measures, PATCH resource\n\nOh ok, finally I see a difference, the question is, does it better to get the 404 from swift or from the database ? And I guess swift is better, so I will invert the logic.","commit_id":"44a1467e3946238d38746a007a0bf5695ccde13c"},{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"bb20285c7ae50e9bbf775d4b46dc2976680484d6","unresolved":false,"context_lines":[{"line_number":104,"context_line":""},{"line_number":105,"context_line":"            entity_grouped_samples \u003d itertools.groupby("},{"line_number":106,"context_line":"                list(samples_of_resource),"},{"line_number":107,"context_line":"                key\u003doperator.itemgetter(\u0027counter_name\u0027))"},{"line_number":108,"context_line":"            for entity_name, samples in entity_grouped_samples:"},{"line_number":109,"context_line":"                for ext in self.mgmr:"},{"line_number":110,"context_line":"                    if entity_name in ext.obj.get_entities_names():"}],"source_content_type":"text/x-python","patch_set":48,"id":"baa201ad_99ccdf8c","line":107,"updated":"2014-10-09 12:42:57.000000000","message":"Since we\u0027ve already grouped by resource-id, are you explicitly dealing with the case here where the compute notification handlers emit a sequence of samples for the same meter in quick succession as a result of the tight sequence of \"compute.instance.{create.start|update|create.end}\" emitted by nova?\n\nWould that actually ever map onto multiple samples for the same meter batched up in a single call to record_metering_data()?\n\ni.e. would there in practice be enough of a delay between the tight sequence of nova notifications, that multiple samples for the same resource and meter are unlikely to ever occur in the same batch?","commit_id":"863fa6c9004ada10a754038f1a06190757dc854d"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"75ddd4687a52f946e96cfc8d5c1a66699499ee1c","unresolved":false,"context_lines":[{"line_number":104,"context_line":""},{"line_number":105,"context_line":"            entity_grouped_samples \u003d itertools.groupby("},{"line_number":106,"context_line":"                list(samples_of_resource),"},{"line_number":107,"context_line":"                key\u003doperator.itemgetter(\u0027counter_name\u0027))"},{"line_number":108,"context_line":"            for entity_name, samples in entity_grouped_samples:"},{"line_number":109,"context_line":"                for ext in self.mgmr:"},{"line_number":110,"context_line":"                    if entity_name in ext.obj.get_entities_names():"}],"source_content_type":"text/x-python","patch_set":48,"id":"baa201ad_df2d67aa","line":107,"in_reply_to":"baa201ad_99ccdf8c","updated":"2014-10-09 15:17:25.000000000","message":"Currently grouping samples is not really useful.\n\nBecause each time record_metering_data is called, the received samples are:\n  - 1 resource with different counter_name (usually a sample that come from notification)\nor\n  - 1 counter of many resources (usually a sample that come from polling)\n\nThe current issue it\u0027s that on each record_metering_data call, we call gnocchi, and we we do some http calls, and eventlet schedule an other task on each http call (it read a other message on amqp and it call record_metering_data again), so you have at least one HTTP gnocchi per message on the notification bus.\n\nThis opens a ton of HTTP request to gnocchi, and a message is ack on rabbit only when the last gnocchi call for this message is done (the resource metadata update, the slower one).\n\nSo if you receive 10000 samples, this open at least 10000 HTTP requests to gnocchi, and gnocchi have to deal with all those requests.\n\nIf we take a look in how ceilometer handles that, it easy it can only handled a limited among of samples at once, because of the mongo/sql connection pool.\n\nBut now, the db connection pool is no more handled by the dispatcher, but by gnocchi.\n\nWe don\u0027t have this kind of pool in this dispatcher, so my plan is to add one.\nAnd then this \"grouping\" code will become useful specially in case of samples generated by instance.exists, *.exists notifications or the swift rx/tx samples.","commit_id":"863fa6c9004ada10a754038f1a06190757dc854d"},{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"bb20285c7ae50e9bbf775d4b46dc2976680484d6","unresolved":false,"context_lines":[{"line_number":134,"context_line":"        except NoSuchEntity:"},{"line_number":135,"context_line":"            # NOTE(sileht): we try first to create the resource, because"},{"line_number":136,"context_line":"            # they more chance that the resource doesn\u0027t exists than the entity"},{"line_number":137,"context_line":"            # is missing, the should be reduce the number of resource API call"},{"line_number":138,"context_line":"            resource_attributes \u003d self._get_resource_attributes("},{"line_number":139,"context_line":"                ext, resource_id, entity_name, samples)"},{"line_number":140,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":48,"id":"baa201ad_f99a4b6d","line":137,"updated":"2014-10-09 12:42:57.000000000","message":"I don\u0027t fully understand the logic here that leads to the conclusion that the resource not existing is more likely than the entity not existing.\n\nIn the context of my previous comment, I had thought we\u0027d be more likely to see multiple samples together for the same resource but different meters, than multiple samples together for the same resource and same meter.\n\nIf that\u0027s true, then the gnocchi resource will only not exist for the first of the batch of samples for the new resource, whereas the entity won\u0027t exist for each of the samples in that first batch.","commit_id":"863fa6c9004ada10a754038f1a06190757dc854d"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"75ddd4687a52f946e96cfc8d5c1a66699499ee1c","unresolved":false,"context_lines":[{"line_number":134,"context_line":"        except NoSuchEntity:"},{"line_number":135,"context_line":"            # NOTE(sileht): we try first to create the resource, because"},{"line_number":136,"context_line":"            # they more chance that the resource doesn\u0027t exists than the entity"},{"line_number":137,"context_line":"            # is missing, the should be reduce the number of resource API call"},{"line_number":138,"context_line":"            resource_attributes \u003d self._get_resource_attributes("},{"line_number":139,"context_line":"                ext, resource_id, entity_name, samples)"},{"line_number":140,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":48,"id":"baa201ad_9f667fed","line":137,"in_reply_to":"baa201ad_f99a4b6d","updated":"2014-10-09 15:17:25.000000000","message":"It just because when we create the resource, gnocchi creates the entities posted with the resource for us, so the only case we need to create a entity manually, is when you do a gnocchi upgrade and new supported entity come with the new version, but the database doesn\u0027t known yet about that one (in this case the resource exists but not yet the entity).","commit_id":"863fa6c9004ada10a754038f1a06190757dc854d"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"a94bbf92ecb941a5a6abdfbd4c71a02faf44a585","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    cfg.StrOpt(\u0027archive_policy\u0027,"},{"line_number":39,"context_line":"               default\u003d\"low\","},{"line_number":40,"context_line":"               help\u003d\u0027The archive policy to use when the dispatcher \u0027"},{"line_number":41,"context_line":"               \u0027create a new resource\u0027)"},{"line_number":42,"context_line":"]"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"cfg.CONF.register_opts(dispatcher_opts, group\u003d\"dispatcher_gnocchi\")"}],"source_content_type":"text/x-python","patch_set":49,"id":"9aa7fdbe_0db0968a","line":41,"updated":"2014-10-20 13:29:28.000000000","message":"s/resource/entity/","commit_id":"d9f2781d777133acf2d7f3d4b713f51580d2f5fd"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"9308485d8eef2cd55b01d78e5d8b3f1972a9a495","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    cfg.StrOpt(\u0027archive_policy\u0027,"},{"line_number":39,"context_line":"               default\u003d\"low\","},{"line_number":40,"context_line":"               help\u003d\u0027The archive policy to use when the dispatcher \u0027"},{"line_number":41,"context_line":"               \u0027create a new resource\u0027)"},{"line_number":42,"context_line":"]"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"cfg.CONF.register_opts(dispatcher_opts, group\u003d\"dispatcher_gnocchi\")"}],"source_content_type":"text/x-python","patch_set":49,"id":"9aa7fdbe_7e8f0624","line":41,"in_reply_to":"9aa7fdbe_0db0968a","updated":"2014-10-20 14:16:55.000000000","message":"Done","commit_id":"d9f2781d777133acf2d7f3d4b713f51580d2f5fd"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"a94bbf92ecb941a5a6abdfbd4c71a02faf44a585","unresolved":false,"context_lines":[{"line_number":100,"context_line":"            data, key\u003doperator.itemgetter(\u0027resource_id\u0027))"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"        for resource_id, samples_of_resource in resource_grouped_samples:"},{"line_number":103,"context_line":"            resource_need_to_be_updated \u003d True"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"            entity_grouped_samples \u003d itertools.groupby("},{"line_number":106,"context_line":"                list(samples_of_resource),"}],"source_content_type":"text/x-python","patch_set":49,"id":"9aa7fdbe_a06311b0","line":103,"updated":"2014-10-20 13:29:28.000000000","message":"Looks like this is not really useful?","commit_id":"d9f2781d777133acf2d7f3d4b713f51580d2f5fd"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"9308485d8eef2cd55b01d78e5d8b3f1972a9a495","unresolved":false,"context_lines":[{"line_number":100,"context_line":"            data, key\u003doperator.itemgetter(\u0027resource_id\u0027))"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"        for resource_id, samples_of_resource in resource_grouped_samples:"},{"line_number":103,"context_line":"            resource_need_to_be_updated \u003d True"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"            entity_grouped_samples \u003d itertools.groupby("},{"line_number":106,"context_line":"                list(samples_of_resource),"}],"source_content_type":"text/x-python","patch_set":49,"id":"9aa7fdbe_beb08ede","line":103,"in_reply_to":"9aa7fdbe_a06311b0","updated":"2014-10-20 14:16:55.000000000","message":"It depends of what we decide about the comment L115","commit_id":"d9f2781d777133acf2d7f3d4b713f51580d2f5fd"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"a94bbf92ecb941a5a6abdfbd4c71a02faf44a585","unresolved":false,"context_lines":[{"line_number":282,"context_line":""},{"line_number":283,"context_line":"    @staticmethod"},{"line_number":284,"context_line":"    def record_events(events):"},{"line_number":285,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":49,"id":"9aa7fdbe_4077c502","line":285,"updated":"2014-10-20 13:29:28.000000000","message":"Should we have something like \"NotImplemented\" rather?","commit_id":"d9f2781d777133acf2d7f3d4b713f51580d2f5fd"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"9308485d8eef2cd55b01d78e5d8b3f1972a9a495","unresolved":false,"context_lines":[{"line_number":282,"context_line":""},{"line_number":283,"context_line":"    @staticmethod"},{"line_number":284,"context_line":"    def record_events(events):"},{"line_number":285,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":49,"id":"9aa7fdbe_9ee2ead3","line":285,"in_reply_to":"9aa7fdbe_4077c502","updated":"2014-10-20 14:16:55.000000000","message":"Sure, done","commit_id":"d9f2781d777133acf2d7f3d4b713f51580d2f5fd"},{"author":{"_account_id":7729,"name":"Ilya Tyaptin","email":"ityaptin@mirantis.com","username":"ityaptin"},"change_message_id":"5a48878be519febd1467ea7de9de9af6f237346b","unresolved":false,"context_lines":[{"line_number":124,"context_line":"    def _process_samples(self, ext, resource_id, entity_name, samples,"},{"line_number":125,"context_line":"                         resource_need_to_be_updated):"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"        if not samples[-1][\u0027project_id\u0027] or not samples[-1][\u0027project_id\u0027]:"},{"line_number":128,"context_line":"            LOG.debug(\"Get resource without project_id/user_id: %s\" %"},{"line_number":129,"context_line":"                      samples)"},{"line_number":130,"context_line":"            # NOTE(sileht): project_id/user_id are mandatory for gnocchi"}],"source_content_type":"text/x-python","patch_set":64,"id":"9aa7fdbe_61d21836","line":127,"updated":"2014-10-29 13:00:27.000000000","message":"I think in this line you are going to check samples[-1][\u0027project_id\u0027] and samples[-1][\u0027user_id\u0027].","commit_id":"92cdfddb7ba146697994f6ca3dedab51eb8d810c"},{"author":{"_account_id":7729,"name":"Ilya Tyaptin","email":"ityaptin@mirantis.com","username":"ityaptin"},"change_message_id":"f57c7b36e5a24983342c5b54ad0ff039e9bd1aa3","unresolved":false,"context_lines":[{"line_number":124,"context_line":"    def _process_samples(self, ext, resource_id, entity_name, samples,"},{"line_number":125,"context_line":"                         resource_need_to_be_updated):"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"        if not samples[-1][\u0027project_id\u0027] or not samples[-1][\u0027project_id\u0027]:"},{"line_number":128,"context_line":"            LOG.debug(\"Get resource without project_id/user_id: %s\" %"},{"line_number":129,"context_line":"                      samples)"},{"line_number":130,"context_line":"            # NOTE(sileht): project_id/user_id are mandatory for gnocchi"}],"source_content_type":"text/x-python","patch_set":64,"id":"9aa7fdbe_95e652e7","line":127,"in_reply_to":"9aa7fdbe_155422c9","updated":"2014-10-29 14:55:43.000000000","message":"I told about project_id and project_id in one condition, but project_id and user_id should be here. It looks like \"if x or x\".","commit_id":"92cdfddb7ba146697994f6ca3dedab51eb8d810c"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"5ec13813decd9eb73b9bd93179b5044b07a474d8","unresolved":false,"context_lines":[{"line_number":124,"context_line":"    def _process_samples(self, ext, resource_id, entity_name, samples,"},{"line_number":125,"context_line":"                         resource_need_to_be_updated):"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"        if not samples[-1][\u0027project_id\u0027] or not samples[-1][\u0027project_id\u0027]:"},{"line_number":128,"context_line":"            LOG.debug(\"Get resource without project_id/user_id: %s\" %"},{"line_number":129,"context_line":"                      samples)"},{"line_number":130,"context_line":"            # NOTE(sileht): project_id/user_id are mandatory for gnocchi"}],"source_content_type":"text/x-python","patch_set":64,"id":"9aa7fdbe_155422c9","line":127,"in_reply_to":"9aa7fdbe_61d21836","updated":"2014-10-29 14:47:16.000000000","message":"No, the condition looks good. I want to skip the sample if one of them is None or \"\"","commit_id":"92cdfddb7ba146697994f6ca3dedab51eb8d810c"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"db68076cc0e024f114d4755b9e78cadc55288489","unresolved":false,"context_lines":[{"line_number":124,"context_line":"    def _process_samples(self, ext, resource_id, entity_name, samples,"},{"line_number":125,"context_line":"                         resource_need_to_be_updated):"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"        if not samples[-1][\u0027project_id\u0027] or not samples[-1][\u0027project_id\u0027]:"},{"line_number":128,"context_line":"            LOG.debug(\"Get resource without project_id/user_id: %s\" %"},{"line_number":129,"context_line":"                      samples)"},{"line_number":130,"context_line":"            # NOTE(sileht): project_id/user_id are mandatory for gnocchi"}],"source_content_type":"text/x-python","patch_set":64,"id":"9aa7fdbe_555f8a75","line":127,"in_reply_to":"9aa7fdbe_95e652e7","updated":"2014-10-29 15:20:09.000000000","message":"Oh sorry, thanks a lot Ilya !","commit_id":"92cdfddb7ba146697994f6ca3dedab51eb8d810c"},{"author":{"_account_id":10987,"name":"Igor Degtiarov","username":"tovstun","inactive":true},"change_message_id":"0e793a8808ab533b02e9b15f33115ca610843e28","unresolved":false,"context_lines":[{"line_number":201,"context_line":"                       \u0027resource_id\u0027: resource_id,"},{"line_number":202,"context_line":"                       \u0027status_code\u0027: r.status_code})"},{"line_number":203,"context_line":"            raise NoSuchEntity"},{"line_number":204,"context_line":"        elif int(r.status_code / 100) !\u003d 2:"},{"line_number":205,"context_line":"            raise UnexpectedWorkflowError("},{"line_number":206,"context_line":"                _(\"Fail to post measure on entity %(entity_name)s of \""},{"line_number":207,"context_line":"                  \"resource %(resource_id)s with status: \""}],"source_content_type":"text/x-python","patch_set":65,"id":"7a8c0949_2ef5eaca","line":204,"updated":"2014-11-07 12:03:17.000000000","message":"I think that it would be better if line 204 will be:\nelif r.status_code // 100 !\u003d 2:","commit_id":"bf3d297ade596c81f586fb456542bdc9f6a3195b"},{"author":{"_account_id":10987,"name":"Igor Degtiarov","username":"tovstun","inactive":true},"change_message_id":"0e793a8808ab533b02e9b15f33115ca610843e28","unresolved":false,"context_lines":[{"line_number":224,"context_line":"            LOG.debug(\"Resource %s already exists\", resource_id)"},{"line_number":225,"context_line":"            raise ResourceAlreadyExists"},{"line_number":226,"context_line":""},{"line_number":227,"context_line":"        elif int(r.status_code / 100) !\u003d 2:"},{"line_number":228,"context_line":"            raise UnexpectedWorkflowError("},{"line_number":229,"context_line":"                _(\"Resource %(resource_id)s creation failed with \""},{"line_number":230,"context_line":"                  \"status: %(status_code)d: %(msg)s\") %"}],"source_content_type":"text/x-python","patch_set":65,"id":"7a8c0949_aea55ab6","line":227,"updated":"2014-11-07 12:03:17.000000000","message":"ditto as at line 204","commit_id":"bf3d297ade596c81f586fb456542bdc9f6a3195b"},{"author":{"_account_id":10987,"name":"Igor Degtiarov","username":"tovstun","inactive":true},"change_message_id":"0e793a8808ab533b02e9b15f33115ca610843e28","unresolved":false,"context_lines":[{"line_number":242,"context_line":"            headers\u003d{\u0027Content-Type\u0027: \"application/json\"},"},{"line_number":243,"context_line":"            data\u003djson.dumps(resource_attributes))"},{"line_number":244,"context_line":""},{"line_number":245,"context_line":"        if int(r.status_code / 100) !\u003d 2:"},{"line_number":246,"context_line":"            raise UnexpectedWorkflowError("},{"line_number":247,"context_line":"                _(\"Resource %(resource_id)s update failed with \""},{"line_number":248,"context_line":"                  \"status: %(status_code)d: %(msg)s\") %"}],"source_content_type":"text/x-python","patch_set":65,"id":"7a8c0949_ee868212","line":245,"updated":"2014-11-07 12:03:17.000000000","message":"ditto","commit_id":"bf3d297ade596c81f586fb456542bdc9f6a3195b"},{"author":{"_account_id":10987,"name":"Igor Degtiarov","username":"tovstun","inactive":true},"change_message_id":"0e793a8808ab533b02e9b15f33115ca610843e28","unresolved":false,"context_lines":[{"line_number":264,"context_line":"                      entity_name, resource_id)"},{"line_number":265,"context_line":"            raise EntityAlreadyExists"},{"line_number":266,"context_line":""},{"line_number":267,"context_line":"        elif int(r.status_code / 100) !\u003d 2:"},{"line_number":268,"context_line":"            raise UnexpectedWorkflowError("},{"line_number":269,"context_line":"                _(\"Fail to create entity %(entity_name)s of \""},{"line_number":270,"context_line":"                  \"resource %(resource_id)s with status: \""}],"source_content_type":"text/x-python","patch_set":65,"id":"7a8c0949_6e1612f3","line":267,"updated":"2014-11-07 12:03:17.000000000","message":"ditto as at line 204","commit_id":"bf3d297ade596c81f586fb456542bdc9f6a3195b"}],"gnocchi/ceilometer/resources/base.py":[{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"2cf831d38b56ecf0dc0a455c05493bb3b040699c","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        \"\"\""},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    @abc.abstractmethod"},{"line_number":36,"context_line":"    def get_entities_names(self):"},{"line_number":37,"context_line":"        \"\"\"Return the entity handled by this resource"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"        :returns: list of entity names"}],"source_content_type":"text/x-python","patch_set":35,"id":"da9df570_27748a98","line":36,"updated":"2014-09-22 17:24:45.000000000","message":"Nitpick:\n\n  s/et_entities_names/et_entity_names/","commit_id":"4f95c93c24a3a489c2e0b9a177ce718629e1a026"},{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"2cf831d38b56ecf0dc0a455c05493bb3b040699c","unresolved":false,"context_lines":[{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    @abc.abstractmethod"},{"line_number":36,"context_line":"    def get_entities_names(self):"},{"line_number":37,"context_line":"        \"\"\"Return the entity handled by this resource"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"        :returns: list of entity names"},{"line_number":40,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":35,"id":"da9df570_27abaad9","line":37,"updated":"2014-09-22 17:24:45.000000000","message":"Nitpick:\n\n  s/the entity/the list of entity names/","commit_id":"4f95c93c24a3a489c2e0b9a177ce718629e1a026"},{"author":{"_account_id":10987,"name":"Igor Degtiarov","username":"tovstun","inactive":true},"change_message_id":"0e793a8808ab533b02e9b15f33115ca610843e28","unresolved":false,"context_lines":[{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    @abc.abstractmethod"},{"line_number":28,"context_line":"    def get_resource_extra_attributes(self, sample):"},{"line_number":29,"context_line":"        \"\"\"Extract the metadata from a ceilometer sample"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"        :param sample: The ceilometer sample"},{"line_number":32,"context_line":"        :returns: the resource attributes"}],"source_content_type":"text/x-python","patch_set":65,"id":"7a8c0949_2e9faa51","line":29,"updated":"2014-11-07 12:03:17.000000000","message":"Would be better to have a dot at the end of the summary line in multi line docsrtings.","commit_id":"bf3d297ade596c81f586fb456542bdc9f6a3195b"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"2258f47c6914565cdbcaf9132609a59ce8160a35","unresolved":false,"context_lines":[{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    @abc.abstractmethod"},{"line_number":28,"context_line":"    def get_resource_extra_attributes(self, sample):"},{"line_number":29,"context_line":"        \"\"\"Extract the metadata from a ceilometer sample"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"        :param sample: The ceilometer sample"},{"line_number":32,"context_line":"        :returns: the resource attributes"}],"source_content_type":"text/x-python","patch_set":65,"id":"5a890539_7583c102","line":29,"in_reply_to":"7a8c0949_2e9faa51","updated":"2014-11-26 15:29:57.000000000","message":"Done","commit_id":"bf3d297ade596c81f586fb456542bdc9f6a3195b"},{"author":{"_account_id":10987,"name":"Igor Degtiarov","username":"tovstun","inactive":true},"change_message_id":"0e793a8808ab533b02e9b15f33115ca610843e28","unresolved":false,"context_lines":[{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    @abc.abstractmethod"},{"line_number":36,"context_line":"    def get_entities_names(self):"},{"line_number":37,"context_line":"        \"\"\"Return the entity handled by this resource"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"        :returns: list of entity names"},{"line_number":40,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":65,"id":"7a8c0949_4eaeb686","line":37,"updated":"2014-11-07 12:03:17.000000000","message":"ditto","commit_id":"bf3d297ade596c81f586fb456542bdc9f6a3195b"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"2258f47c6914565cdbcaf9132609a59ce8160a35","unresolved":false,"context_lines":[{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    @abc.abstractmethod"},{"line_number":36,"context_line":"    def get_entities_names(self):"},{"line_number":37,"context_line":"        \"\"\"Return the entity handled by this resource"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"        :returns: list of entity names"},{"line_number":40,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":65,"id":"5a890539_b578c92b","line":37,"in_reply_to":"7a8c0949_4eaeb686","updated":"2014-11-26 15:29:57.000000000","message":"Done","commit_id":"bf3d297ade596c81f586fb456542bdc9f6a3195b"}],"gnocchi/ceilometer/resources/instance.py":[{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"6115c4414ec94687d6248ee8ee2a1e4f1618cd0f","unresolved":false,"context_lines":[{"line_number":32,"context_line":"                \"image_ref\":"},{"line_number":33,"context_line":"                sample[\u0027resource_metadata\u0027][\u0027image_ref_url\u0027],"},{"line_number":34,"context_line":"                \"display_name\":"},{"line_number":35,"context_line":"                sample[\u0027resource_metadata\u0027][\u0027display_name\u0027],"},{"line_number":36,"context_line":"            }"},{"line_number":37,"context_line":"            if \"instance_flavor_id\" in sample[\u0027resource_metadata\u0027]:"},{"line_number":38,"context_line":"                params[\"flavor_id\"] \u003d int("}],"source_content_type":"text/x-python","patch_set":31,"id":"fa98f980_20d35260","line":35,"updated":"2014-09-19 12:40:47.000000000","message":"I\u0027m wondering about mapping the instance user_metadata here also.\n\nAt the Paris mid-cycle[1] we discussed a way of ensuring that sufficient information would be included in the instance resource representation so that the alarms dimensioned across an autoscaling group could continue to be evaluated via a single query.\n\n(as opposed to explicitly keeping track of all instances in the group and querying timeseries data for each instance separately before doing the cross-series aggregation in the alarm evaluator)\n\nThe idea would be to selectively map certain fields of user_metadata, i.e. \"metering.server_group\" and map that onto a strongly-typed attribute (e.g. \"server_group\") on the resource representation. This would avoid the worst aspects of the free-form loosely-typed resource metadata capture that we currently do in ceilometer.\n\nThis would also require a change to the instance model used by the indexer, in addition to the dispatcher capturing the relevant item of user_metadata from the first sample seen for the instance.\n\n[1] https://etherpad.openstack.org/p/paris-July2014-ceilometer-sprint\n     ctrl+f: \"proposal discussed with jd__\"","commit_id":"630176318db3d389a0f6d74c338a253ab1e6ec46"},{"author":{"_account_id":7478,"name":"Nadya Shakhat","email":"nadmi4@gmail.com","username":"nprivalova"},"change_message_id":"a05210c690806dd037eb1cc6e59827fb02341ec2","unresolved":false,"context_lines":[{"line_number":24,"context_line":""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"class Instance(base.ResourceBase):"},{"line_number":27,"context_line":"    @staticmethod"},{"line_number":28,"context_line":"    def get_resource_extra_attributes(sample):"},{"line_number":29,"context_line":"        metadata \u003d sample[\u0027resource_metadata\u0027]"},{"line_number":30,"context_line":"        params \u003d {"}],"source_content_type":"text/x-python","patch_set":65,"id":"5a890539_230bf18e","line":27,"updated":"2014-11-17 14:09:29.000000000","message":"If we want to have a link to Heat stack (or Sahara cluster, or Trove cluster) we will manually add corresponding params here? Or the solution is still is being discussed?","commit_id":"bf3d297ade596c81f586fb456542bdc9f6a3195b"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"2258f47c6914565cdbcaf9132609a59ce8160a35","unresolved":false,"context_lines":[{"line_number":24,"context_line":""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"class Instance(base.ResourceBase):"},{"line_number":27,"context_line":"    @staticmethod"},{"line_number":28,"context_line":"    def get_resource_extra_attributes(sample):"},{"line_number":29,"context_line":"        metadata \u003d sample[\u0027resource_metadata\u0027]"},{"line_number":30,"context_line":"        params \u003d {"}],"source_content_type":"text/x-python","patch_set":65,"id":"5a890539_d54635bf","line":27,"in_reply_to":"5a890539_230bf18e","updated":"2014-11-26 15:29:57.000000000","message":"We need to update the gnocchi schema to add the new property and here to extract this new property from the emitted samples","commit_id":"bf3d297ade596c81f586fb456542bdc9f6a3195b"}],"gnocchi/tests/test_ceilometer_dispatcher.py":[{"author":{"_account_id":10987,"name":"Igor Degtiarov","username":"tovstun","inactive":true},"change_message_id":"0e793a8808ab533b02e9b15f33115ca610843e28","unresolved":false,"context_lines":[{"line_number":77,"context_line":"                    \u0027instance_flavor_id\u0027: 1234,"},{"line_number":78,"context_line":"                    \u0027display_name\u0027: \u0027myinstance\u0027,"},{"line_number":79,"context_line":"                }"},{"line_number":80,"context_line":"        }]"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    def test_extensions_load(self):"},{"line_number":83,"context_line":"        d \u003d dispatcher.GnocchiDispatcher(self.conf.conf)"}],"source_content_type":"text/x-python","patch_set":65,"id":"7a8c0949_0e558e4f","line":80,"updated":"2014-11-07 12:03:17.000000000","message":"It is seems that here not suitable indent is used. (line 80)","commit_id":"bf3d297ade596c81f586fb456542bdc9f6a3195b"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"2258f47c6914565cdbcaf9132609a59ce8160a35","unresolved":false,"context_lines":[{"line_number":77,"context_line":"                    \u0027instance_flavor_id\u0027: 1234,"},{"line_number":78,"context_line":"                    \u0027display_name\u0027: \u0027myinstance\u0027,"},{"line_number":79,"context_line":"                }"},{"line_number":80,"context_line":"        }]"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    def test_extensions_load(self):"},{"line_number":83,"context_line":"        d \u003d dispatcher.GnocchiDispatcher(self.conf.conf)"}],"source_content_type":"text/x-python","patch_set":65,"id":"5a890539_f597b142","line":80,"in_reply_to":"7a8c0949_0e558e4f","updated":"2014-11-26 15:29:57.000000000","message":"Done","commit_id":"bf3d297ade596c81f586fb456542bdc9f6a3195b"}],"requirements.txt":[{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"aa157b5861531772baf4b9ab1b88e51e88511293","unresolved":false,"context_lines":[{"line_number":1,"context_line":"babel"},{"line_number":2,"context_line":"http://tarballs.openstack.org/ceilometer/ceilometer-master.tar.gz#egg\u003dceilometer"},{"line_number":3,"context_line":"iso8601"},{"line_number":4,"context_line":"lockfile\u003e\u003d0.9.1"},{"line_number":5,"context_line":"netaddr"}],"source_content_type":"text/plain","patch_set":57,"id":"9aa7fdbe_5e1f3408","line":2,"updated":"2014-10-23 14:47:31.000000000","message":"test-requirements only would be better I think","commit_id":"fdb74e7826afe46ce21e9cb7c75d8fef3d7e3daa"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"a4dcabb577f35775a64712d8f60207ce7485efd3","unresolved":false,"context_lines":[{"line_number":1,"context_line":"babel"},{"line_number":2,"context_line":"http://tarballs.openstack.org/ceilometer/ceilometer-master.tar.gz#egg\u003dceilometer"},{"line_number":3,"context_line":"iso8601"},{"line_number":4,"context_line":"lockfile\u003e\u003d0.9.1"},{"line_number":5,"context_line":"netaddr"}],"source_content_type":"text/plain","patch_set":57,"id":"9aa7fdbe_e1a84d8f","line":2,"in_reply_to":"9aa7fdbe_5e1f3408","updated":"2014-10-23 15:11:20.000000000","message":"Done","commit_id":"fdb74e7826afe46ce21e9cb7c75d8fef3d7e3daa"}],"tools/init_testr_if_needed.sh":[{"author":{"_account_id":2284,"name":"Eoghan Glynn","email":"eglynn@redhat.com","username":"eglynn"},"change_message_id":"6115c4414ec94687d6248ee8ee2a1e4f1618cd0f","unresolved":false,"context_lines":[{"line_number":1,"context_line":"#!/bin/sh"},{"line_number":2,"context_line":"# this is rather stupid script is needed as testr init"},{"line_number":3,"context_line":"# complains if there is already a repo."},{"line_number":4,"context_line":"if [ -d ceilometer_tests/.testrepository ]"},{"line_number":5,"context_line":"then"}],"source_content_type":"text/x-sh","patch_set":31,"id":"fa98f980_f5ed8e8f","line":2,"updated":"2014-09-19 12:40:47.000000000","message":"s/this is rather/this rather/","commit_id":"630176318db3d389a0f6d74c338a253ab1e6ec46"}],"tox.ini":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"d56bdc2976e4c76c4236051c785997d274e47c62","unresolved":false,"context_lines":[{"line_number":16,"context_line":"deps \u003d -r{toxinidir}/requirements.txt"},{"line_number":17,"context_line":"       -r{toxinidir}/test-requirements.txt"},{"line_number":18,"context_line":"       hacking\u003e\u003d0.9.2,\u003c0.10"},{"line_number":19,"context_line":"commands \u003d flake8 "},{"line_number":20,"context_line":"           flake8 --exclude .tox,doc ceilometer_tests gnocchi/ceilometer"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"[testenv:py33]"}],"source_content_type":"text/x-properties","patch_set":40,"id":"baa201ad_c2b8eee7","line":19,"updated":"2014-10-01 12:22:39.000000000","message":"trailing whitespace","commit_id":"76d310b5d7537a0f655ea848e028ebe200cca8b8"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"ac81fcc9711d9c32af23e1ccc7fca2f1b5f03b68","unresolved":false,"context_lines":[{"line_number":16,"context_line":"deps \u003d -r{toxinidir}/requirements.txt"},{"line_number":17,"context_line":"       -r{toxinidir}/test-requirements.txt"},{"line_number":18,"context_line":"       hacking\u003e\u003d0.9.2,\u003c0.10"},{"line_number":19,"context_line":"commands \u003d flake8 "},{"line_number":20,"context_line":"           flake8 --exclude .tox,doc ceilometer_tests gnocchi/ceilometer"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"[testenv:py33]"}],"source_content_type":"text/x-properties","patch_set":42,"id":"baa201ad_ee35bcf7","line":19,"updated":"2014-10-02 16:05:45.000000000","message":"white space!!1!1","commit_id":"44a1467e3946238d38746a007a0bf5695ccde13c"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"65a93c834304feb188963a55cd86d86838ddbd50","unresolved":false,"context_lines":[{"line_number":16,"context_line":"deps \u003d -r{toxinidir}/requirements.txt"},{"line_number":17,"context_line":"       -r{toxinidir}/test-requirements.txt"},{"line_number":18,"context_line":"       hacking\u003e\u003d0.9.2,\u003c0.10"},{"line_number":19,"context_line":"commands \u003d flake8 "},{"line_number":20,"context_line":"           flake8 --exclude .tox,doc ceilometer_tests gnocchi/ceilometer"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"[testenv:py33]"}],"source_content_type":"text/x-properties","patch_set":42,"id":"baa201ad_51301501","line":19,"in_reply_to":"baa201ad_ee35bcf7","updated":"2014-10-03 12:54:00.000000000","message":"Done","commit_id":"44a1467e3946238d38746a007a0bf5695ccde13c"}]}
