Add complex query support for samples
Change-Id: I88c4eb6fa32514100187dbbca9777c7a5974fac6
This commit is contained in:
		 Balazs Gibizer
					Balazs Gibizer
				
			
				
					committed by
					
						 Ildiko Vancsa
						Ildiko Vancsa
					
				
			
			
				
	
			
			
			 Ildiko Vancsa
						Ildiko Vancsa
					
				
			
						parent
						
							3e8045c9ca
						
					
				
				
					commit
					08e644110a
				
			
							
								
								
									
										65
									
								
								ceilometerclient/tests/v2/test_query_samples.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								ceilometerclient/tests/v2/test_query_samples.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| # Copyright Ericsson AB 2014. All rights reserved | ||||
| # | ||||
| # Author: Balazs Gibizer <balazs.gibizer@ericsson.com> | ||||
| # | ||||
| #    Licensed under the Apache License, Version 2.0 (the "License"); you may | ||||
| #    not use this file except in compliance with the License. You may obtain | ||||
| #    a copy of the License at | ||||
| # | ||||
| #         http://www.apache.org/licenses/LICENSE-2.0 | ||||
| # | ||||
| #    Unless required by applicable law or agreed to in writing, software | ||||
| #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
| #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
| #    License for the specific language governing permissions and limitations | ||||
| #    under the License. | ||||
|  | ||||
| from ceilometerclient.tests import utils | ||||
| from ceilometerclient.v2 import query_samples | ||||
|  | ||||
|  | ||||
| SAMPLE = {u'id': u'b55d1526-9929-11e3-a3f6-02163e5df1e6', | ||||
|           u'metadata': { | ||||
|               u'name1': u'value1', | ||||
|               u'name2': u'value2'}, | ||||
|           u'meter': 'instance', | ||||
|           u'project_id': u'35b17138-b364-4e6a-a131-8f3099c5be68', | ||||
|           u'resource_id': u'bd9431c1-8d69-4ad3-803a-8d4a6b89fd36', | ||||
|           u'source': u'openstack', | ||||
|           u'timestamp': u'2014-02-19T05:50:16.673604', | ||||
|           u'type': u'gauge', | ||||
|           u'unit': u'instance', | ||||
|           u'volume': 1, | ||||
|           u'user_id': 'efd87807-12d2-4b38-9c70-5f5c2ac427ff'} | ||||
|  | ||||
| QUERY = {"filter": {"and": [{"=": {"source": "openstack"}}, | ||||
|                             {">": {"timestamp": "2014-02-19T05:50:16"}}]}, | ||||
|          "orderby": [{"timestamp": "desc"}, {"volume": "asc"}], | ||||
|          "limit": 10} | ||||
|  | ||||
| base_url = '/v2/query/samples' | ||||
| fixtures = { | ||||
|     base_url: | ||||
|     { | ||||
|         'POST': ( | ||||
|             {}, | ||||
|             [SAMPLE], | ||||
|         ), | ||||
|     }, | ||||
| } | ||||
|  | ||||
|  | ||||
| class QuerySamplesManagerTest(utils.BaseTestCase): | ||||
|  | ||||
|     def setUp(self): | ||||
|         super(QuerySamplesManagerTest, self).setUp() | ||||
|         self.api = utils.FakeAPI(fixtures) | ||||
|         self.mgr = query_samples.QuerySamplesManager(self.api) | ||||
|  | ||||
|     def test_query(self): | ||||
|         samples = self.mgr.query(**QUERY) | ||||
|         expect = [ | ||||
|             ('POST', '/v2/query/samples', {}, QUERY), | ||||
|         ] | ||||
|         self.assertEqual(expect, self.api.calls) | ||||
|         self.assertEqual(1, len(samples)) | ||||
| @@ -1,3 +1,7 @@ | ||||
| # Copyright Ericsson AB 2014. All rights reserved | ||||
| # | ||||
| # Author: Balazs Gibizer <balazs.gibizer@ericsson.com> | ||||
| # | ||||
| #   Licensed under the Apache License, Version 2.0 (the "License"); you may | ||||
| #   not use this file except in compliance with the License. You may obtain | ||||
| #   a copy of the License at | ||||
| @@ -410,3 +414,58 @@ class ShellSampleCreateCommandTest(utils.BaseTestCase): | ||||
| | volume            | 1.0                                         | | ||||
| +-------------------+---------------------------------------------+ | ||||
| ''') | ||||
|  | ||||
|  | ||||
| class ShellQuerySamplesCommandTest(utils.BaseTestCase): | ||||
|  | ||||
|     SAMPLE = [{u'id': u'b55d1526-9929-11e3-a3f6-02163e5df1e6', | ||||
|                u'metadata': { | ||||
|                    u'name1': u'value1', | ||||
|                    u'name2': u'value2'}, | ||||
|                u'meter': 'instance', | ||||
|                u'project_id': u'35b17138-b364-4e6a-a131-8f3099c5be68', | ||||
|                u'resource_id': u'bd9431c1-8d69-4ad3-803a-8d4a6b89fd36', | ||||
|                u'source': u'openstack', | ||||
|                u'timestamp': u'2014-02-19T05:50:16.673604', | ||||
|                u'type': u'gauge', | ||||
|                u'unit': u'instance', | ||||
|                u'volume': 1, | ||||
|                u'user_id': 'efd87807-12d2-4b38-9c70-5f5c2ac427ff'}] | ||||
|  | ||||
|     QUERY = {"filter": {"and": [{"=": {"source": "openstack"}}, | ||||
|                                 {">": {"timestamp": "2014-02-19T05:50:16"}}]}, | ||||
|              "orderby": [{"timestamp": "desc"}, {"volume": "asc"}], | ||||
|              "limit": 10} | ||||
|  | ||||
|     def setUp(self): | ||||
|         super(ShellQuerySamplesCommandTest, self).setUp() | ||||
|         self.cc = mock.Mock() | ||||
|         self.args = mock.Mock() | ||||
|         self.args.filter = self.QUERY["filter"] | ||||
|         self.args.orderby = self.QUERY["orderby"] | ||||
|         self.args.limit = self.QUERY["limit"] | ||||
|  | ||||
|     def test_query(self): | ||||
|  | ||||
|         ret_sample = [samples.Sample(mock.Mock(), sample) | ||||
|                       for sample in self.SAMPLE] | ||||
|         self.cc.query_samples.query.return_value = ret_sample | ||||
|         org_stdout = sys.stdout | ||||
|         try: | ||||
|             sys.stdout = output = six.StringIO() | ||||
|             ceilometer_shell.do_query_samples(self.cc, self.args) | ||||
|         finally: | ||||
|             sys.stdout = org_stdout | ||||
|  | ||||
|         self.assertEqual('''\ | ||||
| +--------------------------------------+----------+-------+--------+---------\ | ||||
| -+----------------------------+ | ||||
| | Resource ID                          | Meter    | Type  | Volume | Unit    \ | ||||
|  | Timestamp                  | | ||||
| +--------------------------------------+----------+-------+--------+---------\ | ||||
| -+----------------------------+ | ||||
| | bd9431c1-8d69-4ad3-803a-8d4a6b89fd36 | instance | gauge | 1      | instance\ | ||||
|  | 2014-02-19T05:50:16.673604 | | ||||
| +--------------------------------------+----------+-------+--------+---------\ | ||||
| -+----------------------------+ | ||||
| ''', output.getvalue()) | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| # Copyright 2012 OpenStack Foundation | ||||
| # All Rights Reserved. | ||||
| # Copyright Ericsson AB 2014. All rights reserved | ||||
| # | ||||
| # Author: Balazs Gibizer <balazs.gibizer@ericsson.com> | ||||
| # | ||||
| #    Licensed under the Apache License, Version 2.0 (the "License"); you may | ||||
| #    not use this file except in compliance with the License. You may obtain | ||||
| @@ -18,6 +19,7 @@ from ceilometerclient.v2 import alarms | ||||
| from ceilometerclient.v2 import event_types | ||||
| from ceilometerclient.v2 import events | ||||
| from ceilometerclient.v2 import meters | ||||
| from ceilometerclient.v2 import query_samples | ||||
| from ceilometerclient.v2 import resources | ||||
| from ceilometerclient.v2 import samples | ||||
| from ceilometerclient.v2 import statistics | ||||
| @@ -48,3 +50,5 @@ class Client(object): | ||||
|         self.traits = traits.TraitManager(self.http_client) | ||||
|         self.trait_info = trait_descriptions.\ | ||||
|             TraitDescriptionManager(self.http_client) | ||||
|         self.query_samples = query_samples.QuerySamplesManager( | ||||
|             self.http_client) | ||||
|   | ||||
							
								
								
									
										44
									
								
								ceilometerclient/v2/query_samples.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								ceilometerclient/v2/query_samples.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| # Copyright Ericsson AB 2014. All rights reserved | ||||
| # | ||||
| # Author: Balazs Gibizer <balazs.gibizer@ericsson.com> | ||||
| # | ||||
| #    Licensed under the Apache License, Version 2.0 (the "License"); you may | ||||
| #    not use this file except in compliance with the License. You may obtain | ||||
| #    a copy of the License at | ||||
| # | ||||
| #         http://www.apache.org/licenses/LICENSE-2.0 | ||||
| # | ||||
| #    Unless required by applicable law or agreed to in writing, software | ||||
| #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
| #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
| #    License for the specific language governing permissions and limitations | ||||
| #    under the License. | ||||
|  | ||||
| from ceilometerclient.common import base | ||||
| from ceilometerclient.v2 import samples | ||||
|  | ||||
|  | ||||
| class QuerySamplesManager(base.Manager): | ||||
|     resource_class = samples.Sample | ||||
|  | ||||
|     @staticmethod | ||||
|     def _path(): | ||||
|         return '/v2/query/samples' | ||||
|  | ||||
|     def query(self, filter, orderby, limit): | ||||
|         query = {} | ||||
|         if filter: | ||||
|             query["filter"] = filter | ||||
|         if orderby: | ||||
|             query["orderby"] = orderby | ||||
|         if limit: | ||||
|             query["limit"] = limit | ||||
|  | ||||
|         url = self._path() | ||||
|         resp, body = self.api.json_request('POST', | ||||
|                                            url, | ||||
|                                            body=query) | ||||
|         if body: | ||||
|             return [self.resource_class(self, b) for b in body] | ||||
|         else: | ||||
|             return [] | ||||
| @@ -1,8 +1,10 @@ | ||||
| # -*- encoding: utf-8 -*- | ||||
| # | ||||
| # Copyright © 2013 Red Hat, Inc | ||||
| # Copyright Ericsson AB 2014. All rights reserved | ||||
| # | ||||
| # Author:  Angus Salkeld <asalkeld@redhat.com> | ||||
| # Authors: Angus Salkeld <asalkeld@redhat.com> | ||||
| #          Balazs Gibizer <balazs.gibizer@ericsson.com> | ||||
| # | ||||
| #    Licensed under the Apache License, Version 2.0 (the "License"); you may | ||||
| #    not use this file except in compliance with the License. You may obtain | ||||
| @@ -33,6 +35,9 @@ STATISTICS = ['max', 'min', 'avg', 'sum', 'count'] | ||||
| OPERATORS_STRING = dict(gt='>', ge='>=', | ||||
|                         lt='<', le="<=", | ||||
|                         eq='==', ne='!=') | ||||
| ORDER_DIRECTIONS = ['asc', 'desc'] | ||||
| COMPLEX_OPERATORS = ['and', 'or'] | ||||
| SIMPLE_OPERATORS = ["=", "!=", "<", "<=", '>', '>='] | ||||
|  | ||||
|  | ||||
| @utils.arg('-q', '--query', metavar='<QUERY>', | ||||
| @@ -639,3 +644,30 @@ def do_trait_list(cc, args={}): | ||||
|     field_labels = ['Trait Name', 'Value', 'Data Type'] | ||||
|     fields = ['name', 'value', 'type'] | ||||
|     utils.print_list(traits, fields, field_labels) | ||||
|  | ||||
|  | ||||
| @utils.arg('-f', '--filter', metavar='<FILTER>', | ||||
|            help=('{complex_op: [{simple_op: {field_name: value}}]} ' | ||||
|                  'The complex_op is one of: ' + str(COMPLEX_OPERATORS) + ', ' | ||||
|                  'simple_op is one of: ' + str(SIMPLE_OPERATORS) + '.')) | ||||
| @utils.arg('-o', '--orderby', metavar='<ORDERBY>', | ||||
|            help=('[{field_name: direction}, {field_name: direction}] ' | ||||
|                  'The direction is one of: ' + str(ORDER_DIRECTIONS) + '.')) | ||||
| @utils.arg('-l', '--limit', metavar='<LIMIT>', | ||||
|            help='Maximum number of samples to return.') | ||||
| def do_query_samples(cc, args): | ||||
|     '''Query samples.''' | ||||
|     fields = {'filter': args.filter, | ||||
|               'orderby': args.orderby, | ||||
|               'limit': args.limit} | ||||
|     try: | ||||
|         samples = cc.query_samples.query(**fields) | ||||
|     except exc.HTTPNotFound: | ||||
|         raise exc.CommandError('Samples not found') | ||||
|     else: | ||||
|         field_labels = ['Resource ID', 'Meter', 'Type', 'Volume', 'Unit', | ||||
|                         'Timestamp'] | ||||
|         fields = ['resource_id', 'meter', 'type', | ||||
|                   'volume', 'unit', 'timestamp'] | ||||
|         utils.print_list(samples, fields, field_labels, | ||||
|                          sortby=None) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user