[fix] Updates to use cached jsonpath
Layering code was not using a parse cache for jsonpath This change adds use of the cache around all calls to jsonpath_ng.parse Change-Id: I800eb397badf19ed2ea47b88fa7c91e4a09225ef
This commit is contained in:
parent
5c9efa9d74
commit
c50501cc89
|
@ -26,7 +26,9 @@ from deckhand import errors
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
path_cache = dict()
|
# Cache for JSON paths computed from path strings because jsonpath_ng
|
||||||
|
# is computationally expensive.
|
||||||
|
_PATH_CACHE = dict()
|
||||||
|
|
||||||
|
|
||||||
def to_camel_case(s):
|
def to_camel_case(s):
|
||||||
|
@ -41,6 +43,28 @@ def to_snake_case(name):
|
||||||
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
|
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_jsonpath(jsonpath):
|
||||||
|
"""Changes jsonpath starting with a `.` character with a `$`"""
|
||||||
|
if jsonpath == '.':
|
||||||
|
jsonpath = '$'
|
||||||
|
elif jsonpath.startswith('.'):
|
||||||
|
jsonpath = '$' + jsonpath
|
||||||
|
return jsonpath
|
||||||
|
|
||||||
|
|
||||||
|
def _jsonpath_parse_cache(jsonpath):
|
||||||
|
"""Retrieve the parsed jsonpath path
|
||||||
|
|
||||||
|
Utilizes a cache of parsed values to eliminate re-parsing
|
||||||
|
"""
|
||||||
|
if jsonpath not in _PATH_CACHE:
|
||||||
|
p = jsonpath_ng.parse(jsonpath)
|
||||||
|
_PATH_CACHE[jsonpath] = p
|
||||||
|
else:
|
||||||
|
p = _PATH_CACHE[jsonpath]
|
||||||
|
return p
|
||||||
|
|
||||||
|
|
||||||
def jsonpath_parse(data, jsonpath, match_all=False):
|
def jsonpath_parse(data, jsonpath, match_all=False):
|
||||||
"""Parse value in the data for the given ``jsonpath``.
|
"""Parse value in the data for the given ``jsonpath``.
|
||||||
|
|
||||||
|
@ -69,16 +93,8 @@ def jsonpath_parse(data, jsonpath, match_all=False):
|
||||||
src_secret = utils.jsonpath_parse(src_doc['data'], src_path)
|
src_secret = utils.jsonpath_parse(src_doc['data'], src_path)
|
||||||
# Do something with the extracted secret from the source document.
|
# Do something with the extracted secret from the source document.
|
||||||
"""
|
"""
|
||||||
if jsonpath == '.':
|
jsonpath = _normalize_jsonpath(jsonpath)
|
||||||
jsonpath = '$'
|
p = _jsonpath_parse_cache(jsonpath)
|
||||||
elif jsonpath.startswith('.'):
|
|
||||||
jsonpath = '$' + jsonpath
|
|
||||||
|
|
||||||
if jsonpath not in path_cache:
|
|
||||||
p = jsonpath_ng.parse(jsonpath)
|
|
||||||
path_cache[jsonpath] = p
|
|
||||||
else:
|
|
||||||
p = path_cache[jsonpath]
|
|
||||||
|
|
||||||
matches = p.find(data)
|
matches = p.find(data)
|
||||||
if matches:
|
if matches:
|
||||||
|
@ -152,10 +168,7 @@ def jsonpath_replace(data, value, jsonpath, pattern=None):
|
||||||
data = copy.copy(data)
|
data = copy.copy(data)
|
||||||
value = copy.copy(value)
|
value = copy.copy(value)
|
||||||
|
|
||||||
if jsonpath == '.':
|
jsonpath = _normalize_jsonpath(jsonpath)
|
||||||
jsonpath = '$'
|
|
||||||
elif jsonpath.startswith('.'):
|
|
||||||
jsonpath = '$' + jsonpath
|
|
||||||
|
|
||||||
if not jsonpath == '$' and not jsonpath.startswith('$.'):
|
if not jsonpath == '$' and not jsonpath.startswith('$.'):
|
||||||
LOG.error('The provided jsonpath %s does not begin with "." or "$"',
|
LOG.error('The provided jsonpath %s does not begin with "." or "$"',
|
||||||
|
@ -164,7 +177,7 @@ def jsonpath_replace(data, value, jsonpath, pattern=None):
|
||||||
'or "$"' % jsonpath)
|
'or "$"' % jsonpath)
|
||||||
|
|
||||||
def _do_replace():
|
def _do_replace():
|
||||||
p = jsonpath_ng.parse(jsonpath)
|
p = _jsonpath_parse_cache(jsonpath)
|
||||||
p_to_change = p.find(data)
|
p_to_change = p.find(data)
|
||||||
|
|
||||||
if p_to_change:
|
if p_to_change:
|
||||||
|
|
Loading…
Reference in New Issue