)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"c5c5724d5dfde83321330138ac5eb4efaa2211b7","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Add granularity in searching for values in metrics"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Add paramter granularity in \u0027search_value()\u0027 method to allow"},{"line_number":10,"context_line":"search values by granularities."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"The http reqeust is like this:"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"5a8bc5a2_7f34e2dd","line":9,"range":{"start_line":9,"start_character":4,"end_line":9,"end_character":12},"updated":"2016-09-22 09:18:33.000000000","message":"parameter","commit_id":"cafac29b775673cc095171676a109f2066c1856d"}],"doc/source/rest.j2":[{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"7878c56205ef51d03869623f62cb6364c4902b80","unresolved":false,"context_lines":[{"line_number":457,"context_line":"{{ scenarios[\u0027search-value-in-metric\u0027][\u0027doc\u0027] }}"},{"line_number":458,"context_line":""},{"line_number":459,"context_line":"And it is possible to search for values in metrics by using one or multiple"},{"line_number":460,"context_line":"granularities"},{"line_number":461,"context_line":""},{"line_number":462,"context_line":"{{ scenarios[\u0027search-value-in-metrics-by-granularity\u0027][\u0027doc\u0027] }}"},{"line_number":463,"context_line":""}],"source_content_type":"text/x-jinja2","patch_set":5,"id":"5a8bc5a2_6ce31006","line":460,"updated":"2016-09-23 12:30:15.000000000","message":"missing dot or :","commit_id":"72e612cdcf7cfaf336846d7d12d5570a7a125cda"}],"gnocchi/rest/__init__.py":[{"author":{"_account_id":18414,"name":"Shengping Zhang","email":"zhangshengping@unitedstack.com","username":"PeterZhang"},"change_message_id":"d03dd00de255ffd338bf606dbaa11c6ce3d86e7d","unresolved":false,"context_lines":[{"line_number":1249,"context_line":"             granularity\u003d[]):"},{"line_number":1250,"context_line":"        granularity \u003d [Timespan(g) for g in arg_to_list(granularity)]"},{"line_number":1251,"context_line":""},{"line_number":1252,"context_line":"        metrics \u003d pecan.request.indexer.list_metrics("},{"line_number":1253,"context_line":"            ids\u003darg_to_list(metric_id))"},{"line_number":1254,"context_line":"        for metric in metrics:"},{"line_number":1255,"context_line":"            enforce(\"search metric\", metric)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5a8bc5a2_d017a552","line":1252,"range":{"start_line":1252,"start_character":8,"end_line":1252,"end_character":15},"updated":"2016-09-22 10:21:18.000000000","message":"should we abort here, if we get nothing in metrics?","commit_id":"cafac29b775673cc095171676a109f2066c1856d"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"d9ee090decf118d138c252b8eba3691b9e8ae1c0","unresolved":false,"context_lines":[{"line_number":1249,"context_line":"             granularity\u003d[]):"},{"line_number":1250,"context_line":"        granularity \u003d [Timespan(g) for g in arg_to_list(granularity)]"},{"line_number":1251,"context_line":""},{"line_number":1252,"context_line":"        metrics \u003d pecan.request.indexer.list_metrics("},{"line_number":1253,"context_line":"            ids\u003darg_to_list(metric_id))"},{"line_number":1254,"context_line":"        for metric in metrics:"},{"line_number":1255,"context_line":"            enforce(\"search metric\", metric)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5a8bc5a2_67bb62c5","line":1252,"range":{"start_line":1252,"start_character":8,"end_line":1252,"end_character":15},"in_reply_to":"5a8bc5a2_d017a552","updated":"2016-09-22 15:15:32.000000000","message":"No abort() is for error, this is not really an error.\n\nPerhaps, we can add an \"optimisation\" that returns an empty dict. But this is unrelated with the goal of this review. I would suggest to make this kind of change into other review.","commit_id":"cafac29b775673cc095171676a109f2066c1856d"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"3ba53f469b1b297a130376a776c319d907cd9ac6","unresolved":false,"context_lines":[{"line_number":1255,"context_line":"            enforce(\"search metric\", metric)"},{"line_number":1256,"context_line":""},{"line_number":1257,"context_line":"        try:"},{"line_number":1258,"context_line":"            body \u003d json.loads(pecan.request.body)"},{"line_number":1259,"context_line":"            if not body:"},{"line_number":1260,"context_line":"                abort(400, \"No query specified in body\")"},{"line_number":1261,"context_line":"        except Exception as e:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5a8bc5a2_06b47bf0","line":1258,"range":{"start_line":1258,"start_character":19,"end_line":1258,"end_character":30},"updated":"2016-09-22 08:35:30.000000000","message":"We shouldn\u0027t use json.loads here. All deserialization must be done in deserialize_and_validate.","commit_id":"cafac29b775673cc095171676a109f2066c1856d"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"3ba53f469b1b297a130376a776c319d907cd9ac6","unresolved":false,"context_lines":[{"line_number":1256,"context_line":""},{"line_number":1257,"context_line":"        try:"},{"line_number":1258,"context_line":"            body \u003d json.loads(pecan.request.body)"},{"line_number":1259,"context_line":"            if not body:"},{"line_number":1260,"context_line":"                abort(400, \"No query specified in body\")"},{"line_number":1261,"context_line":"        except Exception as e:"},{"line_number":1262,"context_line":"            abort(400, \"Unable to decode body: \" + six.text_type(e))"}],"source_content_type":"text/x-python","patch_set":1,"id":"5a8bc5a2_e6ba2fc0","line":1259,"updated":"2016-09-22 08:35:30.000000000","message":"I prefer keeping the previous code. that\njust uses pecan.request.body. Because you can query with \u0027{}\u0027 and this is valid (even that looks useless).\n\nAnd also this additional control is not related to you change.","commit_id":"cafac29b775673cc095171676a109f2066c1856d"},{"author":{"_account_id":18414,"name":"Shengping Zhang","email":"zhangshengping@unitedstack.com","username":"PeterZhang"},"change_message_id":"4cde7c0b647ae5e5beb6bfd7007e3abf64a3a757","unresolved":false,"context_lines":[{"line_number":1256,"context_line":""},{"line_number":1257,"context_line":"        try:"},{"line_number":1258,"context_line":"            body \u003d json.loads(pecan.request.body)"},{"line_number":1259,"context_line":"            if not body:"},{"line_number":1260,"context_line":"                abort(400, \"No query specified in body\")"},{"line_number":1261,"context_line":"        except Exception as e:"},{"line_number":1262,"context_line":"            abort(400, \"Unable to decode body: \" + six.text_type(e))"}],"source_content_type":"text/x-python","patch_set":1,"id":"5a8bc5a2_9aaa9c18","line":1259,"in_reply_to":"5a8bc5a2_e6ba2fc0","updated":"2016-09-22 10:04:11.000000000","message":"hahaha, you are right, I thought this code is attempted to catch something like a empty body. \n\nNo, problem, I will restore it :)","commit_id":"cafac29b775673cc095171676a109f2066c1856d"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"49f8318b50a49f8316386fa94d3f5659f9f32b9d","unresolved":false,"context_lines":[{"line_number":1250,"context_line":"             granularity\u003d[]):"},{"line_number":1251,"context_line":""},{"line_number":1252,"context_line":"        # used this to assimilate data structure to metric object"},{"line_number":1253,"context_line":"        Granularity \u003d namedtuple(\"Granularity\", \"granularity\")"},{"line_number":1254,"context_line":"        granularity \u003d [Granularity(Timespan(g))"},{"line_number":1255,"context_line":"                       for g in arg_to_list(granularity)]"},{"line_number":1256,"context_line":"        metrics \u003d pecan.request.indexer.list_metrics("}],"source_content_type":"text/x-python","patch_set":2,"id":"5a8bc5a2_55dd3013","line":1253,"range":{"start_line":1253,"start_character":8,"end_line":1253,"end_character":62},"updated":"2016-09-22 15:35:56.000000000","message":"Why do you create this intermediate object ? Can we not use the Timespam directly.","commit_id":"01f9c07ff4a80b5ce46ec114ef6bcd6cb4ac66d9"},{"author":{"_account_id":18414,"name":"Shengping Zhang","email":"zhangshengping@unitedstack.com","username":"PeterZhang"},"change_message_id":"a5c12850f8687fb9753b16813b8e240e7f6fb7cd","unresolved":false,"context_lines":[{"line_number":1250,"context_line":"             granularity\u003d[]):"},{"line_number":1251,"context_line":""},{"line_number":1252,"context_line":"        # used this to assimilate data structure to metric object"},{"line_number":1253,"context_line":"        Granularity \u003d namedtuple(\"Granularity\", \"granularity\")"},{"line_number":1254,"context_line":"        granularity \u003d [Granularity(Timespan(g))"},{"line_number":1255,"context_line":"                       for g in arg_to_list(granularity)]"},{"line_number":1256,"context_line":"        metrics \u003d pecan.request.indexer.list_metrics("}],"source_content_type":"text/x-python","patch_set":2,"id":"5a8bc5a2_d0ca2e4f","line":1253,"range":{"start_line":1253,"start_character":8,"end_line":1253,"end_character":62},"in_reply_to":"5a8bc5a2_55dd3013","updated":"2016-09-22 15:46:27.000000000","message":"I use namedtuple to try to ensures that rest layer always sends the same format,\nso that, I deleted the previous method and add this.\n\nIf we do not use Timespan, when user pass values like 1s, 1hour, or 1day, we need figure out how many seconds with bare-hand.","commit_id":"01f9c07ff4a80b5ce46ec114ef6bcd6cb4ac66d9"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"436a3af78bacb66ae3e8bf3e825f416add3538f7","unresolved":false,"context_lines":[{"line_number":1250,"context_line":"             granularity\u003d[]):"},{"line_number":1251,"context_line":""},{"line_number":1252,"context_line":"        # used this to assimilate data structure to metric object"},{"line_number":1253,"context_line":"        Granularity \u003d namedtuple(\"Granularity\", \"granularity\")"},{"line_number":1254,"context_line":"        granularity \u003d [Granularity(Timespan(g))"},{"line_number":1255,"context_line":"                       for g in arg_to_list(granularity)]"},{"line_number":1256,"context_line":"        metrics \u003d pecan.request.indexer.list_metrics("}],"source_content_type":"text/x-python","patch_set":2,"id":"5a8bc5a2_445c80ed","line":1253,"range":{"start_line":1253,"start_character":8,"end_line":1253,"end_character":62},"in_reply_to":"5a8bc5a2_905a6682","updated":"2016-09-23 05:47:37.000000000","message":"I mean you should just use Timespan() and not creating the Granularity()","commit_id":"01f9c07ff4a80b5ce46ec114ef6bcd6cb4ac66d9"},{"author":{"_account_id":18414,"name":"Shengping Zhang","email":"zhangshengping@unitedstack.com","username":"PeterZhang"},"change_message_id":"6a5af4fb77b66d0ba9605e6693bb3e0bf865576f","unresolved":false,"context_lines":[{"line_number":1250,"context_line":"             granularity\u003d[]):"},{"line_number":1251,"context_line":""},{"line_number":1252,"context_line":"        # used this to assimilate data structure to metric object"},{"line_number":1253,"context_line":"        Granularity \u003d namedtuple(\"Granularity\", \"granularity\")"},{"line_number":1254,"context_line":"        granularity \u003d [Granularity(Timespan(g))"},{"line_number":1255,"context_line":"                       for g in arg_to_list(granularity)]"},{"line_number":1256,"context_line":"        metrics \u003d pecan.request.indexer.list_metrics("}],"source_content_type":"text/x-python","patch_set":2,"id":"5a8bc5a2_905a6682","line":1253,"range":{"start_line":1253,"start_character":8,"end_line":1253,"end_character":62},"in_reply_to":"5a8bc5a2_d0ca2e4f","updated":"2016-09-22 15:49:40.000000000","message":"do not use Timespan directly, does it means use utils.to_timespan(value).total_seconds() instead?","commit_id":"01f9c07ff4a80b5ce46ec114ef6bcd6cb4ac66d9"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"ab63ba5d910dc99869e6a595d110837dc33b8d2c","unresolved":false,"context_lines":[{"line_number":1249,"context_line":"             granularity\u003d[]):"},{"line_number":1250,"context_line":""},{"line_number":1251,"context_line":"        # used this to assimilate data structure to metric object"},{"line_number":1252,"context_line":"        granularity \u003d [{\"granularity\": Timespan(g)}"},{"line_number":1253,"context_line":"                       for g in arg_to_list(granularity)]"},{"line_number":1254,"context_line":"        metrics \u003d pecan.request.indexer.list_metrics("},{"line_number":1255,"context_line":"            ids\u003darg_to_list(metric_id))"},{"line_number":1256,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"5a8bc5a2_5e860c14","line":1253,"range":{"start_line":1252,"start_character":8,"end_line":1253,"end_character":57},"updated":"2016-09-23 07:33:11.000000000","message":"The dict look useless, why not just:\n\n    granularity \u003d [Timespan(g) for g in arg_to_list(granularity)]","commit_id":"2eea308c8820568c80616c94d27340e1eed2d86a"},{"author":{"_account_id":18414,"name":"Shengping Zhang","email":"zhangshengping@unitedstack.com","username":"PeterZhang"},"change_message_id":"eca757f550f5cf5f29132d5a4ae04d8bf967894a","unresolved":false,"context_lines":[{"line_number":1249,"context_line":"             granularity\u003d[]):"},{"line_number":1250,"context_line":""},{"line_number":1251,"context_line":"        # used this to assimilate data structure to metric object"},{"line_number":1252,"context_line":"        granularity \u003d [{\"granularity\": Timespan(g)}"},{"line_number":1253,"context_line":"                       for g in arg_to_list(granularity)]"},{"line_number":1254,"context_line":"        metrics \u003d pecan.request.indexer.list_metrics("},{"line_number":1255,"context_line":"            ids\u003darg_to_list(metric_id))"},{"line_number":1256,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"5a8bc5a2_f42b79e9","line":1253,"range":{"start_line":1252,"start_character":8,"end_line":1253,"end_character":57},"in_reply_to":"5a8bc5a2_5e860c14","updated":"2016-09-23 08:16:38.000000000","message":"I used this granularity \u003d [Timespan(g) for g in arg_to_list(granularity)] the totally same in the previous code.\n\n\nHowever there is one thing, I concerned here: the code in pecan.request.storage.search_value \n\n\nthere is a python list comprehensions, in search_value method,  to grab granularity by using code like this way below:\n\nap.granularity\n\n\nI need to keep it like this way, because the \u0027metric.archive_policy.definition\u0027 in \u0027search_value\u0027 method is a list of \u003cclass \u0027gnocchi.archive_policy.ArchivePolicyItem\u0027\u003e .\n\n\nwhich is looks like below\n\n\n[{\u0027points\u0027: 12, \u0027granularity\u0027: 300.0, \u0027timespan\u0027: 3600.0}, {\u0027points\u0027: 24, \u0027granularity\u0027: 3600.0, \u0027timespan\u0027: 86400.0}, {\u0027points\u0027: 30, \u0027granularity\u0027: 86400.0, \u0027timespan\u0027: 2592000.0}] \n\n\neach of the dict is a \u003cclass \u0027gnocchi.archive_policy.ArchivePolicyItem\u0027\u003e.\n\n\nthe granularity can be retrieved from the class by using way.\n     a_instance.graunlarity (I am thinking to keep it like this way)\n\n\n\notherwise, I need to sort all the metrics like \n{metric_idA:[granularityA, granularityB...\"], metric_idB:[granularityA,...]}, for list comprehension loop, \n\n\nit will be more complex  then add a namedtuple or dictionary.\n\n\n\nThat why I change the namedtuple to a dict, and use \u0027get\u0027 method in list comprehension loop.","commit_id":"2eea308c8820568c80616c94d27340e1eed2d86a"},{"author":{"_account_id":18414,"name":"Shengping Zhang","email":"zhangshengping@unitedstack.com","username":"PeterZhang"},"change_message_id":"f36a58f294b9807efc3d3cf52c0843dcfb40b16b","unresolved":false,"context_lines":[{"line_number":1249,"context_line":"             granularity\u003d[]):"},{"line_number":1250,"context_line":""},{"line_number":1251,"context_line":"        # used this to assimilate data structure to metric object"},{"line_number":1252,"context_line":"        granularity \u003d [{\"granularity\": Timespan(g)}"},{"line_number":1253,"context_line":"                       for g in arg_to_list(granularity)]"},{"line_number":1254,"context_line":"        metrics \u003d pecan.request.indexer.list_metrics("},{"line_number":1255,"context_line":"            ids\u003darg_to_list(metric_id))"},{"line_number":1256,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"5a8bc5a2_3445e16f","line":1253,"range":{"start_line":1252,"start_character":8,"end_line":1253,"end_character":57},"in_reply_to":"5a8bc5a2_5e860c14","updated":"2016-09-23 08:22:35.000000000","message":"if metric.archive_policy.definition\u0027 in \u0027search_value\u0027 method was a list of granularities.\n\n\nI will think use granularity \u003d [Timespan(g) for g in arg_to_list(granularity)] is a better way.","commit_id":"2eea308c8820568c80616c94d27340e1eed2d86a"}],"gnocchi/storage/_carbonara.py":[{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"3ba53f469b1b297a130376a776c319d907cd9ac6","unresolved":false,"context_lines":[{"line_number":645,"context_line":"                 for timestamp, g, value in values"},{"line_number":646,"context_line":"                 if predicate(value)]}"},{"line_number":647,"context_line":""},{"line_number":648,"context_line":"    # TODO(jd) Add granularity parameter here and in the REST API"},{"line_number":649,"context_line":"    # rather than fetching all granularities"},{"line_number":650,"context_line":"    def search_value(self, metrics, query, from_timestamp\u003dNone,"},{"line_number":651,"context_line":"                     to_timestamp\u003dNone, aggregation\u003d\u0027mean\u0027,"}],"source_content_type":"text/x-python","patch_set":1,"id":"5a8bc5a2_66d8dff0","line":648,"updated":"2016-09-22 08:35:30.000000000","message":"This can be removed :p","commit_id":"cafac29b775673cc095171676a109f2066c1856d"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"3ba53f469b1b297a130376a776c319d907cd9ac6","unresolved":false,"context_lines":[{"line_number":654,"context_line":""},{"line_number":655,"context_line":"        def grab_granularity(value):"},{"line_number":656,"context_line":"            if isinstance(value, dict):"},{"line_number":657,"context_line":"                return value.granularity"},{"line_number":658,"context_line":"            return value"},{"line_number":659,"context_line":""},{"line_number":660,"context_line":"        results \u003d self._map_in_thread("}],"source_content_type":"text/x-python","patch_set":1,"id":"5a8bc5a2_86208bf9","line":657,"updated":"2016-09-22 08:35:30.000000000","message":"This looks weird. If value is dict, then access it like an object...\n\nI think we should remove this method and just ensures that rest layer always sends the same format.","commit_id":"cafac29b775673cc095171676a109f2066c1856d"},{"author":{"_account_id":18414,"name":"Shengping Zhang","email":"zhangshengping@unitedstack.com","username":"PeterZhang"},"change_message_id":"4cde7c0b647ae5e5beb6bfd7007e3abf64a3a757","unresolved":false,"context_lines":[{"line_number":654,"context_line":""},{"line_number":655,"context_line":"        def grab_granularity(value):"},{"line_number":656,"context_line":"            if isinstance(value, dict):"},{"line_number":657,"context_line":"                return value.granularity"},{"line_number":658,"context_line":"            return value"},{"line_number":659,"context_line":""},{"line_number":660,"context_line":"        results \u003d self._map_in_thread("}],"source_content_type":"text/x-python","patch_set":1,"id":"5a8bc5a2_305c4925","line":657,"in_reply_to":"5a8bc5a2_86208bf9","updated":"2016-09-22 10:04:11.000000000","message":"OK, I got a idea. I will do it then.","commit_id":"cafac29b775673cc095171676a109f2066c1856d"}],"gnocchi/tests/gabbi/gabbits/search-metric.yaml":[{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"c5c5724d5dfde83321330138ac5eb4efaa2211b7","unresolved":false,"context_lines":[{"line_number":160,"context_line":"      status: 400"},{"line_number":161,"context_line":"      response_strings:"},{"line_number":162,"context_line":"        - Invalid value for stop"},{"line_number":163,"context_line":""},{"line_number":164,"context_line":""}],"source_content_type":"text/x-yaml","patch_set":1,"id":"5a8bc5a2_1f5cbe24","line":163,"updated":"2016-09-22 09:18:33.000000000","message":"no need :)","commit_id":"cafac29b775673cc095171676a109f2066c1856d"}]}
