Add complex query support for samples
Change-Id: I88c4eb6fa32514100187dbbca9777c7a5974fac6
This commit is contained in:
committed by
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