Skip to content

Commit

Permalink
Merge pull request #17 from BenjamenMeyer/enhancement_stack_tracing
Browse files Browse the repository at this point in the history
Enhancement stack tracing
  • Loading branch information
BenjamenMeyer committed Mar 6, 2015
2 parents d8ce967 + 01661fa commit dccdcdb
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 4 deletions.
2 changes: 1 addition & 1 deletion stackinabox/services/keystone/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,6 @@ def validate_token_admin(self, token):
return user_data

except Exception as ex:
logger.debug('Error: {0}'.format(ex))
logger.exception('Error: {0}'.format(ex))

raise KeystoneInvalidTokenError('Invalid Token')
1 change: 1 addition & 0 deletions stackinabox/services/keystone/v2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ def user_data_filter(user):
return (200, headers, json.dumps({'users': []}))

except Exception as ex:
logger.exception('User List Failure')
return (401, headers, 'Not Authorized')
else:
return (403, headers, 'Forbidden')
3 changes: 3 additions & 0 deletions stackinabox/stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ def call(self, method, request, uri, headers):
service_caller_uri,
headers)
except Exception as ex:
logger.exception('StackInABox({0}): Service {1} - '
'Internal Failure'
.format(self.__id, service.name))
return (500,
headers,
'Service Handler had an error: {0}'.format(ex))
Expand Down
8 changes: 7 additions & 1 deletion stackinabox/util_httpretty.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,23 @@
from httpretty.http import HttpBaseClass

from stackinabox.stack import StackInABox
from stackinabox.utils import CaseInsensitiveDict


logger = logging.getLogger(__name__)


def httpretty_callback(request, uri, headers):
method = request.method
response_headers = CaseInsensitiveDict()
response_headers.update(headers)
request_headers = CaseInsensitiveDict()
request_headers.update(request.headers)
request.headers = request_headers
return StackInABox.call_into(method,
request,
uri,
headers)
response_headers)


def httpretty_registration(uri):
Expand Down
6 changes: 5 additions & 1 deletion stackinabox/util_requests_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import six

from stackinabox.stack import StackInABox
from stackinabox.utils import CaseInsensitiveDict


logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -65,7 +66,10 @@ def split_status(status):

def handle(self, request, uri):
method = request.method
headers = request.headers
headers = CaseInsensitiveDict()
request_headers = CaseInsensitiveDict()
request_headers.update(request.headers)
request.headers = request_headers
stackinabox_result = StackInABox.call_into(method,
request,
uri,
Expand Down
6 changes: 5 additions & 1 deletion stackinabox/util_responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@
import responses

from stackinabox.stack import StackInABox
from stackinabox.utils import CaseInsensitiveDict


logger = logging.getLogger(__name__)


def responses_callback(request):
method = request.method
headers = request.headers
headers = CaseInsensitiveDict()
request_headers = CaseInsensitiveDict()
request_headers.update(request.headers)
request.headers = request_headers
uri = request.url
return StackInABox.call_into(method,
request,
Expand Down
1 change: 1 addition & 0 deletions stackinabox/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from stackinabox.utils.caseinsensitivedict import CaseInsensitiveDict
93 changes: 93 additions & 0 deletions stackinabox/utils/caseinsensitivedict.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Copied from the Requests library by Kenneth Reitz et al.

# Copyright 2013 Kenneth Reitz

# 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 collections


# Compliments of Requests
class CaseInsensitiveDict(collections.MutableMapping): # pragma: no cover
"""
A case-insensitive ``dict``-like object.
Implements all methods and operations of
``collections.MutableMapping`` as well as dict's `copy`. Also
provides `lower_items`.
All keys are expected to be strings. The structure remembers the
case of the last key to be set, and ``iter(instance)``,
``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()``
will contain case-sensitive keys. However, querying and contains
testing is case insensitive:
cid = CaseInsensitiveDict()
cid['Accept'] = 'application/json'
cid['aCCEPT'] == 'application/json' # True
list(cid) == ['Accept'] # True
For example, ``headers['content-encoding']`` will return the
value of a ``'Content-Encoding'`` response header, regardless
of how the header name was originally stored.
If the constructor, ``.update``, or equality comparison
operations are given keys that have equal ``.lower()``s, the
behavior is undefined.
"""
def __init__(self, data=None, **kwargs):
self._store = dict()
if data is None:
data = {}
self.update(data, **kwargs)

def __setitem__(self, key, value):
# Use the lowercased key for lookups, but store the actual
# key alongside the value.
self._store[key.lower()] = (key, value)

def __getitem__(self, key):
return self._store[key.lower()][1]

def __delitem__(self, key):
del self._store[key.lower()]

def __iter__(self):
return (casedkey for casedkey, mappedvalue in self._store.values())

def __len__(self):
return len(self._store)

def lower_items(self):
"""Like iteritems(), but with all lowercase keys."""
return (
(lowerkey, keyval[1])
for (lowerkey, keyval)
in self._store.items()
)

def __eq__(self, other):
if isinstance(other, collections.Mapping):
other = CaseInsensitiveDict(other)
else:
return NotImplemented
# Compare insensitively
return dict(self.lower_items()) == dict(other.lower_items())

# Copy is required
def copy(self):
return CaseInsensitiveDict(self._store.values())

def __repr__(self):
return '%s(%r)' % (self.__class__.__name__, dict(self.items()))

0 comments on commit dccdcdb

Please sign in to comment.