Versions endpoint is working
Fix Versions endpoint - was conflicting with other endpoints starting from v2.0 and v3.0 which for versions was {version_id} - template dict VERSIONS was mutated every request Additionally this commit provides moving /version outside of keystone authentication Change-Id: I184a0fbc2dcaca21aa5f1256d9a1c41597f9d184
This commit is contained in:
parent
81413d4d52
commit
0405d59701
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2015 FUJITSU LIMITED
|
||||
# Copyright 2016 FUJITSU LIMITED
|
||||
#
|
||||
# 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
|
||||
|
@ -17,6 +17,9 @@ from oslo_log import log
|
|||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
_SKIP_PATH = '/version', '/healthcheck'
|
||||
"""Tuple of non-application endpoints"""
|
||||
|
||||
|
||||
class SkippingAuthProtocol(auth_token.AuthProtocol):
|
||||
"""SkippingAuthProtocol to reach healthcheck endpoint
|
||||
|
@ -35,10 +38,12 @@ class SkippingAuthProtocol(auth_token.AuthProtocol):
|
|||
|
||||
def process_request(self, request):
|
||||
path = request.path
|
||||
if path == '/healthcheck':
|
||||
LOG.debug(('Request path is %s and it does not require keystone '
|
||||
'communication'), path)
|
||||
return None # return NONE to reach actual logic
|
||||
for p in _SKIP_PATH:
|
||||
if path.startswith(p):
|
||||
LOG.debug(
|
||||
('Request path is %s and it does not require keystone '
|
||||
'communication'), path)
|
||||
return None # return NONE to reach actual logic
|
||||
|
||||
return super(SkippingAuthProtocol, self).process_request(request)
|
||||
|
||||
|
|
|
@ -20,68 +20,104 @@ from oslo_log import log
|
|||
from monasca_log_api.api import versions_api
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
VERSIONS = {
|
||||
|
||||
_VERSIONS_TPL_DICT = {
|
||||
'v2.0': {
|
||||
'id': 'v2.0',
|
||||
'links': [
|
||||
{
|
||||
'rel': 'self',
|
||||
'href': ''
|
||||
},
|
||||
'rel': 'logs',
|
||||
'href': '/log/single'
|
||||
}
|
||||
],
|
||||
'status': 'DEPRECATED',
|
||||
'updated': "2015-09-01T00:00:00Z"
|
||||
},
|
||||
'v3.0': {
|
||||
'id': 'v3.0',
|
||||
'links': [
|
||||
{
|
||||
'rel': 'links',
|
||||
'href': '/log'
|
||||
'rel': 'logs',
|
||||
'href': '/logs'
|
||||
}
|
||||
],
|
||||
'status': 'CURRENT',
|
||||
'updated': "2013-03-06T00:00:00Z"
|
||||
'updated': "2016-03-01T00:00:00Z"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Versions(versions_api.VersionsAPI):
|
||||
"""Versions Api V2."""
|
||||
def __init__(self):
|
||||
super(Versions, self).__init__()
|
||||
"""Versions Api"""
|
||||
|
||||
@staticmethod
|
||||
def handle_none_version_id(req, res, result):
|
||||
for version in VERSIONS:
|
||||
VERSIONS[version]['links'][0]['href'] = (
|
||||
req.uri.decode('utf8') + version)
|
||||
result['elements'].append(VERSIONS[version])
|
||||
res.body = rest_utils.as_json(result)
|
||||
for version in _VERSIONS_TPL_DICT:
|
||||
selected_version = _parse_version(version, req)
|
||||
result['elements'].append(selected_version)
|
||||
res.body = rest_utils.as_json(result, sort_keys=True)
|
||||
res.status = falcon.HTTP_200
|
||||
|
||||
@staticmethod
|
||||
def handle_version_id(req, res, version_id):
|
||||
if version_id in VERSIONS:
|
||||
VERSIONS[version_id]['links'][0]['href'] = (
|
||||
req.uri.decode(rest_utils.ENCODING)
|
||||
)
|
||||
for version in VERSIONS:
|
||||
VERSIONS[version]['links'][0]['href'] = (
|
||||
req.uri.decode('utf8')
|
||||
)
|
||||
VERSIONS[version_id]['links'][1]['href'] = (
|
||||
req.uri.decode('utf8') +
|
||||
VERSIONS[version_id]['links'][1]['href']
|
||||
)
|
||||
res.body = rest_utils.as_json(VERSIONS[version_id])
|
||||
def handle_version_id(req, res, result, version_id):
|
||||
if version_id in _VERSIONS_TPL_DICT:
|
||||
result['elements'].append(_parse_version(version_id, req))
|
||||
res.body = rest_utils.as_json(result, sort_keys=True)
|
||||
res.status = falcon.HTTP_200
|
||||
else:
|
||||
res.body = 'Invalid Version ID'
|
||||
error_body = {'message': '%s is not valid version' % version_id}
|
||||
res.body = rest_utils.as_json(error_body)
|
||||
res.status = falcon.HTTP_400
|
||||
|
||||
def on_get(self, req, res, version_id=None):
|
||||
result = {
|
||||
'links': [{
|
||||
'rel': 'self',
|
||||
'href': req.uri.decode(rest_utils.ENCODING)
|
||||
}],
|
||||
'links': _get_common_links(req),
|
||||
'elements': []
|
||||
}
|
||||
if version_id is None:
|
||||
self.handle_none_version_id(req, res, result)
|
||||
else:
|
||||
self.handle_version_id(req, res, version_id)
|
||||
self.handle_version_id(req, res, result, version_id)
|
||||
|
||||
|
||||
def _get_common_links(req):
|
||||
self_uri = req.uri.decode(rest_utils.ENCODING)
|
||||
base_uri = self_uri.replace(req.path, '')
|
||||
return [
|
||||
{
|
||||
'rel': 'self',
|
||||
'href': self_uri
|
||||
},
|
||||
{
|
||||
'rel': 'version',
|
||||
'href': '%s/version' % base_uri
|
||||
},
|
||||
{
|
||||
'rel': 'healthcheck',
|
||||
'href': '%s/healthcheck' % base_uri
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
def _parse_version(version_id, req):
|
||||
self_uri = req.uri.decode('utf-8')
|
||||
base_uri = self_uri.replace(req.path, '')
|
||||
|
||||
# need to get template dict, consecutive calls
|
||||
# needs to operate on unmodified instance
|
||||
|
||||
selected_version = _VERSIONS_TPL_DICT[version_id].copy()
|
||||
raw_links = selected_version['links']
|
||||
links = []
|
||||
|
||||
for link in raw_links:
|
||||
raw_link_href = link.get('href')
|
||||
raw_link_rel = link.get('rel')
|
||||
link_href = base_uri + '/' + version_id + raw_link_href
|
||||
links.append({
|
||||
'href': link_href,
|
||||
'rel': raw_link_rel
|
||||
})
|
||||
selected_version['links'] = links
|
||||
|
||||
return selected_version
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Copyright 2015 kornicameister@gmail.com
|
||||
# Copyright 2015 FUJITSU LIMITED
|
||||
# Copyright 2016 FUJITSU LIMITED
|
||||
#
|
||||
# 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
|
||||
|
@ -84,8 +84,8 @@ def load_logs_resource(app):
|
|||
|
||||
def load_versions_resource(app):
|
||||
versions = simport.load(CONF.dispatcher.versions)()
|
||||
app.add_route("/", versions)
|
||||
app.add_route("/{version_id}", versions)
|
||||
app.add_route("/version", versions)
|
||||
app.add_route("/version/{version_id}", versions)
|
||||
|
||||
|
||||
def get_wsgi_app(config_base_path=None):
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
# Copyright 2016 FUJITSU LIMITED
|
||||
#
|
||||
# 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.
|
||||
|
||||
import falcon
|
||||
from falcon import testing
|
||||
import ujson as json
|
||||
|
||||
from monasca_log_api.reference import versions
|
||||
|
||||
|
||||
def _get_versioned_url(version_id):
|
||||
return '/version/%s' % version_id
|
||||
|
||||
|
||||
class TestVersions(testing.TestBase):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.versions = None
|
||||
super(TestVersions, self).__init__(*args, **kwargs)
|
||||
|
||||
def before(self):
|
||||
self.versions = versions.Versions()
|
||||
self.api.add_route("/version/", self.versions)
|
||||
self.api.add_route("/version/{version_id}", self.versions)
|
||||
|
||||
def test_should_fail_for_unsupported_version(self):
|
||||
unsupported_version = 'v5.0'
|
||||
uri = _get_versioned_url(unsupported_version)
|
||||
|
||||
self.simulate_request(
|
||||
uri,
|
||||
method='GET',
|
||||
headers={
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
)
|
||||
|
||||
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
||||
|
||||
def test_should_return_all_supported_versions(self):
|
||||
|
||||
def _check_elements():
|
||||
self.assertIn('elements', response)
|
||||
elements = response.get('elements')
|
||||
self.assertIsInstance(elements, list)
|
||||
|
||||
for el in elements:
|
||||
# do checkup by expected keys
|
||||
self.assertIn('id', el)
|
||||
self.assertItemsEqual([
|
||||
u'id',
|
||||
u'links',
|
||||
u'status',
|
||||
u'updated'
|
||||
], el.keys())
|
||||
|
||||
ver = el.get('id')
|
||||
self.assertIn(ver, expected_versions)
|
||||
|
||||
def _check_global_links():
|
||||
self.assertIn('links', response)
|
||||
links = response.get('links')
|
||||
self.assertIsInstance(links, list)
|
||||
|
||||
for link in links:
|
||||
self.assertIn('rel', link)
|
||||
key = link.get('rel')
|
||||
self.assertIn(key, expected_links_keys)
|
||||
|
||||
expected_versions = 'v2.0', 'v3.0'
|
||||
expected_links_keys = 'self', 'version', 'healthcheck'
|
||||
|
||||
res = self.simulate_request(
|
||||
'/version',
|
||||
method='GET',
|
||||
headers={
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
decode='utf-8'
|
||||
)
|
||||
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
||||
|
||||
response = json.loads(res)
|
||||
|
||||
_check_elements()
|
||||
_check_global_links()
|
||||
|
||||
def test_should_return_expected_version_id(self):
|
||||
expected_versions = 'v2.0', 'v3.0'
|
||||
for expected_version in expected_versions:
|
||||
uri = _get_versioned_url(expected_version)
|
||||
res = self.simulate_request(
|
||||
uri,
|
||||
method='GET',
|
||||
headers={
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
decode='utf-8'
|
||||
)
|
||||
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
||||
|
||||
response = json.loads(res)
|
||||
self.assertIn('elements', response)
|
||||
self.assertIn('links', response)
|
||||
|
||||
elements = response.get('elements')
|
||||
self.assertIsInstance(elements, list)
|
||||
self.assertEqual(1, len(elements))
|
||||
|
||||
el = elements[0]
|
||||
ver = el.get('id')
|
||||
self.assertEqual(expected_version, ver)
|
Loading…
Reference in New Issue