Merge "Fix the error about the translation of KarborException message"
This commit is contained in:
commit
0898ad5c40
|
@ -9,12 +9,15 @@ use = egg:Paste#urlmap
|
|||
|
||||
[composite:openstack_karbor_api_v1]
|
||||
use = call:karbor.api.middleware.auth:pipeline_factory
|
||||
noauth = request_id catch_errors noauth apiv1
|
||||
keystone = request_id catch_errors authtoken keystonecontext apiv1
|
||||
noauth = request_id faultwrap noauth apiv1
|
||||
keystone = request_id faultwrap authtoken keystonecontext apiv1
|
||||
|
||||
[filter:request_id]
|
||||
paste.filter_factory = oslo_middleware:RequestId.factory
|
||||
|
||||
[filter:faultwrap]
|
||||
paste.filter_factory = karbor.api.middleware.fault:FaultWrapper.factory
|
||||
|
||||
[filter:catch_errors]
|
||||
paste.filter_factory = oslo_middleware:CatchErrors.factory
|
||||
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
# 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 oslo_log import log as logging
|
||||
import six
|
||||
from six.moves import http_client
|
||||
import webob.dec
|
||||
import webob.exc
|
||||
|
||||
from karbor.api.openstack import wsgi
|
||||
from karbor import exception
|
||||
from karbor import utils
|
||||
from karbor.wsgi import common as base_wsgi
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class FaultWrapper(base_wsgi.Middleware):
|
||||
"""Calls down the middleware stack, making exceptions into faults."""
|
||||
|
||||
_status_to_type = {}
|
||||
|
||||
@staticmethod
|
||||
def status_to_type(status):
|
||||
if not FaultWrapper._status_to_type:
|
||||
for clazz in utils.walk_class_hierarchy(webob.exc.HTTPError):
|
||||
FaultWrapper._status_to_type[clazz.code] = clazz
|
||||
return FaultWrapper._status_to_type.get(
|
||||
status, webob.exc.HTTPInternalServerError)()
|
||||
|
||||
def _error(self, inner, req):
|
||||
safe = getattr(inner, 'safe', False)
|
||||
headers = getattr(inner, 'headers', None)
|
||||
status = getattr(inner, 'code', http_client.INTERNAL_SERVER_ERROR)
|
||||
if status is None:
|
||||
status = http_client.INTERNAL_SERVER_ERROR
|
||||
|
||||
msg_dict = dict(url=req.url, status=status)
|
||||
LOG.info("%(url)s returned with HTTP %(status)d", msg_dict)
|
||||
outer = self.status_to_type(status)
|
||||
if headers:
|
||||
outer.headers = headers
|
||||
|
||||
if safe:
|
||||
msg = (inner.msg if isinstance(inner, exception.KarborException)
|
||||
else six.text_type(inner))
|
||||
outer.explanation = msg
|
||||
return wsgi.Fault(outer)
|
||||
|
||||
@webob.dec.wsgify(RequestClass=wsgi.Request)
|
||||
def __call__(self, req):
|
||||
try:
|
||||
return req.get_response(self.application)
|
||||
except Exception as ex:
|
||||
return self._error(ex, req)
|
|
@ -83,7 +83,7 @@ class KarborException(Exception):
|
|||
message = _("An unknown exception occurred.")
|
||||
code = http_client.INTERNAL_SERVER_ERROR
|
||||
headers = {}
|
||||
safe = False
|
||||
safe = True
|
||||
|
||||
def __init__(self, message=None, **kwargs):
|
||||
"""Initiate the instance of KarborException
|
||||
|
@ -132,7 +132,7 @@ class KarborException(Exception):
|
|||
super(KarborException, self).__init__(message)
|
||||
|
||||
def __unicode__(self):
|
||||
return six.text_type(self.msg)
|
||||
return self.msg
|
||||
|
||||
|
||||
class NotAuthorized(KarborException):
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
# 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 karbor.tests import base
|
||||
|
||||
from karbor import utils
|
||||
|
||||
|
||||
class WalkClassHierarchyTestCase(base.TestCase):
|
||||
def test_walk_class_hierarchy(self):
|
||||
class A(object):
|
||||
pass
|
||||
|
||||
class B(A):
|
||||
pass
|
||||
|
||||
class C(A):
|
||||
pass
|
||||
|
||||
class D(B):
|
||||
pass
|
||||
|
||||
class E(A):
|
||||
pass
|
||||
|
||||
class_pairs = zip((D, B, E),
|
||||
utils.walk_class_hierarchy(A, encountered=[C]))
|
||||
for actual, expected in class_pairs:
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
class_pairs = zip((D, B, C, E), utils.walk_class_hierarchy(A))
|
||||
for actual, expected in class_pairs:
|
||||
self.assertEqual(expected, actual)
|
|
@ -162,3 +162,16 @@ def validate_integer(value, name, min_value=None, max_value=None):
|
|||
{'value_name': name, 'max_value': max_value}))
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def walk_class_hierarchy(clazz, encountered=None):
|
||||
"""Walk class hierarchy, yielding most derived classes first."""
|
||||
if not encountered:
|
||||
encountered = []
|
||||
for subclass in clazz.__subclasses__():
|
||||
if subclass not in encountered:
|
||||
encountered.append(subclass)
|
||||
# drill down to leaves first
|
||||
for subsubclass in walk_class_hierarchy(subclass, encountered):
|
||||
yield subsubclass
|
||||
yield subclass
|
||||
|
|
Loading…
Reference in New Issue