version request url move to the dir of module

Change-Id: If6819e3131144c5630539d76bafd42b101e06a91
This commit is contained in:
jiasirui 2020-12-23 18:34:02 +08:00
parent 8453642b1e
commit a5e1284138
5 changed files with 247 additions and 250 deletions

View File

@ -37,7 +37,7 @@ paste.app_factory = venus.api.v1.router:APIRouter.factory
pipeline = faultwrap osvenusversionapp pipeline = faultwrap osvenusversionapp
[app:osvenusversionapp] [app:osvenusversionapp]
paste.app_factory = venus.api.versions:Versions.factory paste.app_factory = venus.modules.version.versions:Versions.factory
########## ##########
# Shared # # Shared #

View File

@ -81,10 +81,10 @@ class APIRouter(base_wsgi.Router):
mapper = ProjectMapper() mapper = ProjectMapper()
self.resources = {} self.resources = {}
self._setup_routes(mapper, ext_mgr) self._setup_routes(mapper, ext_mgr)
self._setup_ext_routes(mapper, ext_mgr) # self._setup_ext_routes(mapper, ext_mgr)
self._setup_extensions(ext_mgr) # self._setup_extensions(ext_mgr)
for url in mapper.matchlist: for url in mapper.matchlist:
LOG.debug('URL methid: s% register: %s ', LOG.debug('URL method: %s register: %s ',
url.conditions, url.routepath) url.conditions, url.routepath)
super(APIRouter, self).__init__(mapper) super(APIRouter, self).__init__(mapper)

View File

@ -20,9 +20,9 @@ from oslo_log import log as logging
from venus.api import extensions from venus.api import extensions
import venus.api.openstack import venus.api.openstack
from venus.api import versions
from venus.modules.custom_config import controller as custom_config from venus.modules.custom_config import controller as custom_config
from venus.modules.search import controller as search from venus.modules.search import controller as search
from venus.modules.version import versions
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)

View File

View File

@ -1,245 +1,242 @@
# Copyright 2020 Inspur # Copyright 2020 Inspur
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # not use this file except in compliance with the License. You may obtain
# a copy of the License at # a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import datetime import datetime
from lxml import etree from lxml import etree
from oslo_config import cfg
from venus.api.openstack import wsgi
from venus.api.openstack import wsgi from venus.api.v1.views import versions as views_versions
from venus.api.v1.views import versions as views_versions from venus.api import xmlutil
from venus.api import xmlutil from venus.conf import CONF
CONF = cfg.CONF _KNOWN_VERSIONS = {
"v1.0": {
"id": "v1.0",
_KNOWN_VERSIONS = { "status": "SUPPORTED",
"v1.0": { "updated": "2014-06-28T12:20:21Z",
"id": "v1.0", "links": [
"status": "SUPPORTED", {
"updated": "2014-06-28T12:20:21Z", "rel": "describedby",
"links": [ "type": "text/html",
{ "href": "http://docs.openstack.org/",
"rel": "describedby", },
"type": "text/html", ],
"href": "http://docs.openstack.org/", "media-types": [
}, {
], "base": "application/xml",
"media-types": [ "type": "application/vnd.openstack.venus+xml;version=1",
{ },
"base": "application/xml", {
"type": "application/vnd.openstack.venus+xml;version=1", "base": "application/json",
}, "type": "application/vnd.openstack.venus+json;version=1",
{ }
"base": "application/json", ],
"type": "application/vnd.openstack.venus+json;version=1", }
} }
],
}
} def get_supported_versions():
versions = {}
def get_supported_versions(): if CONF.enable_v1_api:
versions = {} versions['v1.0'] = _KNOWN_VERSIONS['v1.0']
if CONF.enable_v1_api: return versions
versions['v1.0'] = _KNOWN_VERSIONS['v1.0']
return versions class MediaTypesTemplateElement(xmlutil.TemplateElement):
def will_render(self, datum):
return 'media-types' in datum
class MediaTypesTemplateElement(xmlutil.TemplateElement):
def will_render(self, datum):
return 'media-types' in datum def make_version(elem):
elem.set('id')
elem.set('status')
def make_version(elem): elem.set('updated')
elem.set('id')
elem.set('status') mts = MediaTypesTemplateElement('media-types')
elem.set('updated') elem.append(mts)
mts = MediaTypesTemplateElement('media-types') mt = xmlutil.sub_template_element(mts, 'media-type',
elem.append(mts) selector='media-types')
mt.set('base')
mt = xmlutil.sub_template_element(mts, 'media-type', mt.set('type')
selector='media-types')
mt.set('base') xmlutil.make_links(elem, 'links')
mt.set('type')
xmlutil.make_links(elem, 'links') version_nsmap = {None: xmlutil.XMLNS_COMMON_V10, 'atom': xmlutil.XMLNS_ATOM}
version_nsmap = {None: xmlutil.XMLNS_COMMON_V10, 'atom': xmlutil.XMLNS_ATOM} class VersionTemplate(xmlutil.TemplateBuilder):
def construct(self):
root = xmlutil.TemplateElement('version', selector='version')
class VersionTemplate(xmlutil.TemplateBuilder): make_version(root)
def construct(self): return xmlutil.MasterTemplate(root, 1, nsmap=version_nsmap)
root = xmlutil.TemplateElement('version', selector='version')
make_version(root)
return xmlutil.MasterTemplate(root, 1, nsmap=version_nsmap) class VersionsTemplate(xmlutil.TemplateBuilder):
def construct(self):
root = xmlutil.TemplateElement('versions')
class VersionsTemplate(xmlutil.TemplateBuilder): elem = xmlutil.sub_template_element(root, 'version',
def construct(self): selector='versions')
root = xmlutil.TemplateElement('versions') make_version(elem)
elem = xmlutil.sub_template_element(root, 'version', return xmlutil.MasterTemplate(root, 1, nsmap=version_nsmap)
selector='versions')
make_version(elem)
return xmlutil.MasterTemplate(root, 1, nsmap=version_nsmap) class ChoicesTemplate(xmlutil.TemplateBuilder):
def construct(self):
root = xmlutil.TemplateElement('choices')
class ChoicesTemplate(xmlutil.TemplateBuilder): elem = xmlutil.sub_template_element(root, 'version',
def construct(self): selector='choices')
root = xmlutil.TemplateElement('choices') make_version(elem)
elem = xmlutil.sub_template_element(root, 'version', return xmlutil.MasterTemplate(root, 1, nsmap=version_nsmap)
selector='choices')
make_version(elem)
return xmlutil.MasterTemplate(root, 1, nsmap=version_nsmap) class AtomSerializer(wsgi.XMLDictSerializer):
NSMAP = {None: xmlutil.XMLNS_ATOM}
class AtomSerializer(wsgi.XMLDictSerializer):
def __init__(self, metadata=None, xmlns=None):
NSMAP = {None: xmlutil.XMLNS_ATOM} super(AtomSerializer, self).__init__(metadata, xmlns)
self.metadata = metadata or {}
def __init__(self, metadata=None, xmlns=None): if not xmlns:
super(AtomSerializer, self).__init__(metadata, xmlns) self.xmlns = wsgi.XML_NS_ATOM
self.metadata = metadata or {} else:
if not xmlns: self.xmlns = xmlns
self.xmlns = wsgi.XML_NS_ATOM
else: def _get_most_recent_update(self, versions):
self.xmlns = xmlns recent = None
for version in versions:
def _get_most_recent_update(self, versions): updated = datetime.datetime.strptime(version['updated'],
recent = None '%Y-%m-%dT%H:%M:%SZ')
for version in versions: if not recent:
updated = datetime.datetime.strptime(version['updated'], recent = updated
'%Y-%m-%dT%H:%M:%SZ') elif updated > recent:
if not recent: recent = updated
recent = updated
elif updated > recent: return recent.strftime('%Y-%m-%dT%H:%M:%SZ')
recent = updated
def _get_base_url(self, link_href):
return recent.strftime('%Y-%m-%dT%H:%M:%SZ') # Make sure no trailing /
link_href = link_href.rstrip('/')
def _get_base_url(self, link_href): return link_href.rsplit('/', 1)[0] + '/'
# Make sure no trailing /
link_href = link_href.rstrip('/') def _create_feed(self, versions, feed_title, feed_id):
return link_href.rsplit('/', 1)[0] + '/' feed = etree.Element('feed', nsmap=self.NSMAP)
title = etree.SubElement(feed, 'title')
def _create_feed(self, versions, feed_title, feed_id): title.set('type', 'text')
feed = etree.Element('feed', nsmap=self.NSMAP) title.text = feed_title
title = etree.SubElement(feed, 'title')
title.set('type', 'text') # Set this updated to the most recently updated version
title.text = feed_title recent = self._get_most_recent_update(versions)
etree.SubElement(feed, 'updated').text = recent
# Set this updated to the most recently updated version
recent = self._get_most_recent_update(versions) etree.SubElement(feed, 'id').text = feed_id
etree.SubElement(feed, 'updated').text = recent
link = etree.SubElement(feed, 'link')
etree.SubElement(feed, 'id').text = feed_id link.set('rel', 'self')
link.set('href', feed_id)
link = etree.SubElement(feed, 'link')
link.set('rel', 'self') author = etree.SubElement(feed, 'author')
link.set('href', feed_id) etree.SubElement(author, 'name').text = 'Rackspace'
etree.SubElement(author, 'uri').text = 'http://www.rackspace.com/'
author = etree.SubElement(feed, 'author')
etree.SubElement(author, 'name').text = 'Rackspace' for version in versions:
etree.SubElement(author, 'uri').text = 'http://www.rackspace.com/' feed.append(self._create_version_entry(version))
for version in versions: return feed
feed.append(self._create_version_entry(version))
def _create_version_entry(self, version):
return feed entry = etree.Element('entry')
etree.SubElement(entry, 'id').text = version['links'][0]['href']
def _create_version_entry(self, version): title = etree.SubElement(entry, 'title')
entry = etree.Element('entry') title.set('type', 'text')
etree.SubElement(entry, 'id').text = version['links'][0]['href'] title.text = 'Version %s' % version['id']
title = etree.SubElement(entry, 'title') etree.SubElement(entry, 'updated').text = version['updated']
title.set('type', 'text')
title.text = 'Version %s' % version['id'] for link in version['links']:
etree.SubElement(entry, 'updated').text = version['updated'] link_elem = etree.SubElement(entry, 'link')
link_elem.set('rel', link['rel'])
for link in version['links']: link_elem.set('href', link['href'])
link_elem = etree.SubElement(entry, 'link') if 'type' in link:
link_elem.set('rel', link['rel']) link_elem.set('type', link['type'])
link_elem.set('href', link['href'])
if 'type' in link: content = etree.SubElement(entry, 'content')
link_elem.set('type', link['type']) content.set('type', 'text')
content.text = 'Version %s %s (%s)' % (version['id'],
content = etree.SubElement(entry, 'content') version['status'],
content.set('type', 'text') version['updated'])
content.text = 'Version %s %s (%s)' % (version['id'], return entry
version['status'],
version['updated'])
return entry class VersionsAtomSerializer(AtomSerializer):
def default(self, data):
versions = data['versions']
class VersionsAtomSerializer(AtomSerializer): feed_id = self._get_base_url(versions[0]['links'][0]['href'])
def default(self, data): feed = self._create_feed(versions, 'Available API Versions', feed_id)
versions = data['versions'] return self._to_xml(feed)
feed_id = self._get_base_url(versions[0]['links'][0]['href'])
feed = self._create_feed(versions, 'Available API Versions', feed_id)
return self._to_xml(feed) class VersionAtomSerializer(AtomSerializer):
def default(self, data):
version = data['version']
class VersionAtomSerializer(AtomSerializer): feed_id = version['links'][0]['href']
def default(self, data): feed = self._create_feed([version], 'About This Version', feed_id)
version = data['version'] return self._to_xml(feed)
feed_id = version['links'][0]['href']
feed = self._create_feed([version], 'About This Version', feed_id)
return self._to_xml(feed) class Versions(wsgi.Resource):
def __init__(self):
class Versions(wsgi.Resource): super(Versions, self).__init__(None)
def __init__(self): @wsgi.serializers(xml=VersionsTemplate,
super(Versions, self).__init__(None) atom=VersionsAtomSerializer)
def index(self, req):
@wsgi.serializers(xml=VersionsTemplate, """Return all versions."""
atom=VersionsAtomSerializer) builder = views_versions.get_view_builder(req)
def index(self, req): return builder.build_versions(get_supported_versions())
"""Return all versions."""
builder = views_versions.get_view_builder(req) @wsgi.serializers(xml=ChoicesTemplate)
return builder.build_versions(get_supported_versions()) @wsgi.response(300)
def multi(self, req):
@wsgi.serializers(xml=ChoicesTemplate) """Return multiple choices."""
@wsgi.response(300) builder = views_versions.get_view_builder(req)
def multi(self, req): return builder.build_choices(get_supported_versions(), req)
"""Return multiple choices."""
builder = views_versions.get_view_builder(req) def get_action_args(self, request_environment):
return builder.build_choices(get_supported_versions(), req) """Parse dictionary created by routes library."""
args = {}
def get_action_args(self, request_environment): if request_environment['PATH_INFO'] == '/':
"""Parse dictionary created by routes library.""" args['action'] = 'index'
args = {} else:
if request_environment['PATH_INFO'] == '/': args['action'] = 'multi'
args['action'] = 'index'
else: return args
args['action'] = 'multi'
return args class VenusVersion(object):
@wsgi.serializers(xml=VersionTemplate,
atom=VersionAtomSerializer)
class VenusVersion(object): def show(self, req):
@wsgi.serializers(xml=VersionTemplate, builder = views_versions.get_view_builder(req)
atom=VersionAtomSerializer) if 'v1' in builder.base_url:
def show(self, req): return builder.build_version(_KNOWN_VERSIONS['v1.0'])
builder = views_versions.get_view_builder(req)
if 'v1' in builder.base_url:
return builder.build_version(_KNOWN_VERSIONS['v1.0']) def create_resource():
return wsgi.Resource(VenusVersion())
def create_resource():
return wsgi.Resource(VenusVersion())