Skip to content

Commit

Permalink
add links to return values from API methods
Browse files Browse the repository at this point in the history
add meter links to resource return values.
add resource self link.

Change-Id: I0c9802b57ebbb9aa852acd7fdec1c49df8883a64
Fixes: bug1048728
  • Loading branch information
Gordon Chung committed May 2, 2013
1 parent 88afcdd commit 89ab2f8
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 2 deletions.
59 changes: 57 additions & 2 deletions ceilometer/api/controllers/v2.py
Expand Up @@ -55,6 +55,10 @@ class _Base(wtypes.Base):
def from_db_model(cls, m):
return cls(**(m.as_dict()))

@classmethod
def from_db_and_links(cls, m, links):
return cls(links=links, **(m.as_dict()))

def as_dict(self, db_model):
valid_keys = inspect.getargspec(db_model.__init__)[0]
if 'self' in valid_keys:
Expand All @@ -66,6 +70,25 @@ def as_dict(self, db_model):
getattr(self, k) != wsme.Unset)


class Link(_Base):
"""A link representation
"""

href = wtypes.text
"The url of a link"

rel = wtypes.text
"The name of a link"

@classmethod
def sample(cls):
return cls(href=('http://localhost:8777/v2/meters/volume?'
'q.field=resource_id&'
'q.value=bd9431c1-8d69-4ad3-803a-8d4a6b89fd36'),
rel='volume'
)


class Query(_Base):
"""Sample query filter.
"""
Expand Down Expand Up @@ -218,6 +241,15 @@ def _flatten_metadata(metadata):
return {}


def _make_link(rel_name, url, type, type_arg, query=None):
query_str = ''
if query:
query_str = '?q.field=%s&q.value=%s' % (query['field'],
query['value'])
return Link(href=('%s/v2/%s/%s%s') % (url, type, type_arg, query_str),
rel=rel_name)


class Sample(_Base):
"""A single measurement for a given meter and resource.
"""
Expand Down Expand Up @@ -496,6 +528,9 @@ class Resource(_Base):
metadata = {wtypes.text: wtypes.text}
"Arbitrary metadata associated with the resource"

links = [Link]
"A list containing a self link and associated meter links"

def __init__(self, metadata={}, **kwds):
metadata = _flatten_metadata(metadata)
super(Resource, self).__init__(metadata=metadata, **kwds)
Expand All @@ -508,12 +543,30 @@ def sample(cls):
timestamp=datetime.datetime.utcnow(),
metadata={'name1': 'value1',
'name2': 'value2'},
links=[Link(href=('http://localhost:8777/v2/resources/'
'bd9431c1-8d69-4ad3-803a-8d4a6b89fd36'),
rel='self'),
Link(href=('http://localhost:8777/v2/meters/volume?'
'q.field=resource_id&'
'q.value=bd9431c1-8d69-4ad3-803a-'
'8d4a6b89fd36'),
rel='volume')],
)


class ResourcesController(rest.RestController):
"""Works on resources."""

def _resource_links(self, resource_id):
links = [_make_link('self', pecan.request.host_url, 'resources',
resource_id)]
for meter in pecan.request.storage_conn.get_meters(resource=
resource_id):
query = {'field': 'resource_id', 'value': resource_id}
links.append(_make_link(meter.name, pecan.request.host_url,
'meters', meter.name, query=query))
return links

@wsme_pecan.wsexpose(Resource, unicode)
def get_one(self, resource_id):
"""Retrieve details about one resource.
Expand All @@ -522,7 +575,8 @@ def get_one(self, resource_id):
"""
r = list(pecan.request.storage_conn.get_resources(
resource=resource_id))[0]
return Resource.from_db_model(r)
return Resource.from_db_and_links(r,
self._resource_links(resource_id))

@wsme_pecan.wsexpose([Resource], [Query])
def get_all(self, q=[]):
Expand All @@ -532,7 +586,8 @@ def get_all(self, q=[]):
"""
kwargs = _query_to_kwargs(q, pecan.request.storage_conn.get_resources)
resources = [
Resource.from_db_model(r)
Resource.from_db_and_links(r,
self._resource_links(r.resource_id))
for r in pecan.request.storage_conn.get_resources(**kwargs)]
return resources

Expand Down
7 changes: 7 additions & 0 deletions doc/source/webapi/v2.rst
Expand Up @@ -93,3 +93,10 @@ or::
and finally, a JSON-based example::

$ curl -X GET -H 'X-Auth-Token:<inserttokenhere>' -H 'Content-Type:application/json' -d '{"q":[{"field": "timestamp","op": "ge","value":"2013-04-01T13:34:17"}]}' http://localhost:8777/v2/meters


Links
=====

.. autotype:: ceilometer.api.controllers.v2.Link
:members:
31 changes: 31 additions & 0 deletions tests/api/v2/test_list_resources.py
Expand Up @@ -308,3 +308,34 @@ def test_metadata(self):
[('display_name', 'test-server'),
('tag', 'self.counter'),
])

def test_resource_meter_links(self):
counter1 = counter.Counter(
'instance',
'cumulative',
'',
1,
'user-id',
'project-id',
'resource-id',
timestamp=datetime.datetime(2012, 7, 2, 10, 40),
resource_metadata={'display_name': 'test-server',
'tag': 'self.counter',
}
)
msg = meter.meter_message_from_counter(counter1,
cfg.CONF.metering_secret,
'test_list_resources',
)
self.conn.record_metering_data(msg)

data = self.get_json('/resources')
links = data[0]['links']
self.assertEqual(len(links), 2)
self.assertEqual(links[0]['rel'], 'self')
self.assertTrue((self.PATH_PREFIX + '/resources/resource-id')
in links[0]['href'])
self.assertEqual(links[1]['rel'], 'instance')
self.assertTrue((self.PATH_PREFIX + '/meters/instance?'
'q.field=resource_id&q.value=resource-id')
in links[1]['href'])

0 comments on commit 89ab2f8

Please sign in to comment.