Store JSON Home Resources off the composing router

JSON Home Resources must be stored in a location other
than the router for Flask as we are not composing routers
in the same way as we used to with the home-grown webob
based WSGI setup.

Partial-Bug: #1776504
Closes-Bug: #1776506
Change-Id: I292ea9e923ff2f49041dfd417994bcdd797d0520
This commit is contained in:
Morgan Fainberg 2018-06-12 06:59:38 -07:00
parent 0e24f91075
commit f18d54fe16
5 changed files with 41 additions and 16 deletions

View File

@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo_serialization import jsonutils
from keystone import exception
from keystone.i18n import _
@ -80,6 +81,36 @@ class Status(object):
'Unexpected status requested for JSON Home response, %s') % status)
class JsonHomeResources(object):
"""JSON Home resource data."""
__resources = {}
__serialized_resource_data = None
@classmethod
def _reset(cls):
# NOTE(morgan): this will reset all json home resource definitions.
# This is only used for testing.
cls.__resources.clear()
cls.__serialized_resource_data = None
@classmethod
def append_resource(cls, rel, data):
cls.__resources[rel] = data
cls.__serialized_resource_data = None
@classmethod
def resources(cls):
# NOTE(morgan): We use a serialized form of the resource data to
# ensure that the raw data is not changed by processing, this method
# simply populates the serialized store if it is not already populated.
# Any changes to this class storage object will result in clearing
# the serialized data value.
if cls.__serialized_resource_data is None:
cls.__serialized_resource_data = jsonutils.dumps(cls.__resources)
return {'resources': jsonutils.loads(cls.__serialized_resource_data)}
def translate_urls(json_home, new_prefix):
"""Given a JSON Home document, sticks new_prefix on each of the urls."""
for dummy_rel, resource in json_home['resources'].items():

View File

@ -68,6 +68,7 @@ class Router(wsgi.ComposableRouter):
self.collection_key)
rel_data = {'href': collection_path, }
self._resource_descriptions.append((collection_rel, rel_data))
json_home.JsonHomeResources.append_resource(collection_rel, rel_data)
if self._is_entity_implemented:
entity_rel = json_home.build_v3_resource_relation(self.key)
@ -80,3 +81,5 @@ class Router(wsgi.ComposableRouter):
},
}
self._resource_descriptions.append((entity_rel, entity_rel_data))
json_home.JsonHomeResources.append_resource(
entity_rel, entity_rel_data)

View File

@ -623,6 +623,7 @@ class RoutersBase(object):
json_home.Status.update_resource_data(resource_data, status)
self.v3_resources.append((rel, resource_data))
json_home.JsonHomeResources.append_resource(rel, resource_data)
class V3ExtensionRouter(ExtensionRouter, RoutersBase):

View File

@ -40,6 +40,7 @@ import testtools
from testtools import testcase
from keystone.common import context
from keystone.common import json_home
from keystone.common import provider_api
from keystone.common import request
from keystone.common import sql
@ -685,6 +686,9 @@ class TestCase(BaseTestCase):
# tests aren't used.
self.addCleanup(provider_api.ProviderAPIs._clear_registry_instances)
# Clear the registry of JSON Home Resources
self.addCleanup(json_home.JsonHomeResources._reset)
# Ensure Notification subscriptions and resource types are empty
self.addCleanup(notifications.clear_subscribers)
self.addCleanup(notifications.reset_notifier)

View File

@ -12,9 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo_serialization import jsonutils
from six.moves import http_client
import webob
from keystone.common import extension
from keystone.common import json_home
@ -39,11 +37,7 @@ def request_v3_json_home(new_prefix):
if 'v3' not in _VERSIONS:
# No V3 support, so return an empty JSON Home document.
return {'resources': {}}
req = webob.Request.blank(
'/v3', headers={'Accept': 'application/json-home'})
v3_json_home_str = req.get_response(latest_app).body
v3_json_home = jsonutils.loads(v3_json_home_str)
v3_json_home = json_home.JsonHomeResources.resources()
json_home.translate_urls(v3_json_home, new_prefix)
return v3_json_home
@ -180,15 +174,7 @@ class Version(wsgi.Application):
})
def _get_json_home_v3(self):
def all_resources():
for router in self._routers:
for resource in router.v3_resources:
yield resource
return {
'resources': dict(all_resources())
}
return json_home.JsonHomeResources.resources()
def get_version_v3(self, request):
versions = self._get_versions_list(request.context_dict)