You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ariatosca.apache.org by da...@apache.org on 2016/11/16 17:47:02 UTC
[1/3] incubator-ariatosca git commit: ARIA-21 Move general code from
parser.utils to top level utils
Repository: incubator-ariatosca
Updated Branches:
refs/heads/ARIA-21-extract-some-parser-code [created] 3e7f1e15a
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/utils/caching.py
----------------------------------------------------------------------
diff --git a/aria/utils/caching.py b/aria/utils/caching.py
new file mode 100644
index 0000000..613ade6
--- /dev/null
+++ b/aria/utils/caching.py
@@ -0,0 +1,133 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 __future__ import absolute_import # so we can import standard 'collections' and 'threading'
+
+from threading import Lock
+from functools import partial
+
+from .collections import OrderedDict
+
+
+class cachedmethod(object): # pylint: disable=invalid-name
+ """
+ Decorator for caching method return values.
+
+ The implementation is thread-safe.
+
+ Supports :code:`cache_info` to be compatible with Python 3's :code:`functools.lru_cache`.
+ Note that the statistics are combined for all instances of the class.
+
+ Won't use the cache if not called when bound to an object, allowing you to override the cache.
+
+ Adapted from `this solution
+ <http://code.activestate.com/recipes/577452-a-memoize-decorator-for-instance-methods/>`__.
+ """
+
+ ENABLED = True
+
+ def __init__(self, func):
+ self.func = func
+ self.hits = 0
+ self.misses = 0
+ self.lock = Lock()
+
+ def cache_info(self):
+ with self.lock:
+ return (self.hits, self.misses, None, self.misses)
+
+ def reset_cache_info(self):
+ with self.lock:
+ self.hits = 0
+ self.misses = 0
+
+ def __get__(self, instance, owner):
+ if instance is None:
+ # Don't use cache if not bound to an object
+ # Note: This is also a way for callers to override the cache
+ return self.func
+ return partial(self, instance)
+
+ def __call__(self, *args, **kwargs):
+ if not self.ENABLED:
+ return self.func(*args, **kwargs)
+
+ instance = args[0]
+ cache = instance.get_method_cache()
+
+ key = (self.func, args[1:], frozenset(kwargs.items()))
+
+ try:
+ with self.lock:
+ return_value = cache[key]
+ self.hits += 1
+ except KeyError:
+ return_value = self.func(*args, **kwargs)
+ with self.lock:
+ cache[key] = return_value
+ self.misses += 1
+ # Another thread may override our cache entry here, so we need to read
+ # it again to make sure all threads use the same return value
+ return_value = cache.get(key, return_value)
+
+ return return_value
+
+
+class HasCachedMethods(object):
+ """
+ Provides convenience methods for working with :class:`cachedmethod`.
+ """
+
+ def __init__(self, method_cache=None):
+ self._method_cache = method_cache or {}
+
+ def get_method_cache(self):
+ return self._method_cache
+
+ @property
+ def _method_cache_info(self):
+ """
+ The cache infos of all cached methods.
+
+ :rtype: dict of str, 4-tuple
+ """
+
+ cached_info = OrderedDict()
+ for k, v in self.__class__.__dict__.iteritems():
+ if isinstance(v, property):
+ # The property getter might be cached
+ v = v.fget
+ if hasattr(v, 'cache_info'):
+ cached_info[k] = v.cache_info()
+ return cached_info
+
+ def _reset_method_cache(self):
+ """
+ Resets the caches of all cached methods.
+ """
+
+ if hasattr(self, '_method_cache'):
+ self._method_cache = {}
+
+ # Note: Another thread may already be storing entries in the cache here.
+ # But it's not a big deal! It only means that our cache_info isn't
+ # guaranteed to be accurate.
+
+ for entry in self.__class__.__dict__.itervalues():
+ if isinstance(entry, property):
+ # The property getter might be cached
+ entry = entry.fget
+ if hasattr(entry, 'reset_cache_info'):
+ entry.reset_cache_info()
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/utils/collections.py
----------------------------------------------------------------------
diff --git a/aria/utils/collections.py b/aria/utils/collections.py
new file mode 100644
index 0000000..03feabd
--- /dev/null
+++ b/aria/utils/collections.py
@@ -0,0 +1,291 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 __future__ import absolute_import # so we can import standard 'collections'
+
+from copy import deepcopy
+try:
+ from collections import OrderedDict
+except ImportError:
+ from ordereddict import OrderedDict
+
+
+def cls_name(cls):
+ module = str(cls.__module__)
+ name = str(cls.__name__)
+ return name if module == '__builtin__' else '%s.%s' % (module, name)
+
+
+class FrozenList(list):
+ """
+ An immutable list.
+
+ After initialization it will raise :class:`TypeError` exceptions if modification
+ is attempted.
+
+ Note that objects stored in the list may not be immutable.
+ """
+ def __init__(self, *args, **kwargs):
+ self.locked = False
+ super(FrozenList, self).__init__(*args, **kwargs)
+ self.locked = True
+
+ def __setitem__(self, index, value):
+ if self.locked:
+ raise TypeError('frozen list')
+ return super(FrozenList, self).__setitem__(index, value)
+
+ def __delitem__(self, index):
+ if self.locked:
+ raise TypeError('frozen list')
+ return super(FrozenList, self).__delitem__(index)
+
+ def __iadd__(self, values):
+ if self.locked:
+ raise TypeError('frozen list')
+ return super(FrozenList, self).__iadd__(values)
+
+ def __deepcopy__(self, memo):
+ res = [deepcopy(v, memo) for v in self]
+ return FrozenList(res)
+
+ def append(self, value):
+ if self.locked:
+ raise TypeError('frozen list')
+ return super(FrozenList, self).append(value)
+
+ def extend(self, values):
+ if self.locked:
+ raise TypeError('frozen list')
+ return super(FrozenList, self).append(values)
+
+ def insert(self, index, value):
+ if self.locked:
+ raise TypeError('frozen list')
+ return super(FrozenList, self).insert(index, value)
+
+EMPTY_READ_ONLY_LIST = FrozenList()
+
+class FrozenDict(OrderedDict):
+ """
+ An immutable ordered dict.
+
+ After initialization it will raise :class:`TypeError` exceptions if modification
+ is attempted.
+
+ Note that objects stored in the dict may not be immutable.
+ """
+
+ def __init__(self, *args, **kwargs):
+ self.locked = False
+ super(FrozenDict, self).__init__(*args, **kwargs)
+ self.locked = True
+
+ def __setitem__(self, key, value, **_):
+ if self.locked:
+ raise TypeError('frozen dict')
+ return super(FrozenDict, self).__setitem__(key, value)
+
+ def __delitem__(self, key, **_):
+ if self.locked:
+ raise TypeError('frozen dict')
+ return super(FrozenDict, self).__delitem__(key)
+
+ def __deepcopy__(self, memo):
+ res = [(deepcopy(k, memo), deepcopy(v, memo)) for k, v in self.iteritems()]
+ return FrozenDict(res)
+
+EMPTY_READ_ONLY_DICT = FrozenDict()
+
+class StrictList(list):
+ """
+ A list that raises :class:`TypeError` exceptions when objects of the wrong type are inserted.
+ """
+
+ def __init__(self,
+ items=None,
+ value_class=None,
+ wrapper_function=None,
+ unwrapper_function=None):
+ super(StrictList, self).__init__()
+ if isinstance(items, StrictList):
+ self.value_class = items.value_class
+ self.wrapper_function = items.wrapper_function
+ self.unwrapper_function = items.unwrapper_function
+ self.value_class = value_class
+ self.wrapper_function = wrapper_function
+ self.unwrapper_function = unwrapper_function
+ if items:
+ for item in items:
+ self.append(item)
+
+ def _wrap(self, value):
+ if (self.value_class is not None) and (not isinstance(value, self.value_class)):
+ raise TypeError('value must be a "%s": %s' % (cls_name(self.value_class), repr(value)))
+ if self.wrapper_function is not None:
+ value = self.wrapper_function(value)
+ return value
+
+ def _unwrap(self, value):
+ if self.unwrapper_function is not None:
+ value = self.unwrapper_function(value)
+ return value
+
+ def __getitem__(self, index):
+ value = super(StrictList, self).__getitem__(index)
+ value = self._unwrap(value)
+ return value
+
+ def __setitem__(self, index, value):
+ value = self._wrap(value)
+ return super(StrictList, self).__setitem__(index, value)
+
+ def __iadd__(self, values):
+ values = [self._wrap(v) for v in values]
+ return super(StrictList, self).__iadd__(values)
+
+ def append(self, value):
+ value = self._wrap(value)
+ return super(StrictList, self).append(value)
+
+ def extend(self, values):
+ values = [self._wrap(v) for v in values]
+ return super(StrictList, self).extend(values)
+
+ def insert(self, index, value):
+ value = self._wrap(value)
+ return super(StrictList, self).insert(index, value)
+
+class StrictDict(OrderedDict):
+ """
+ An ordered dict that raises :class:`TypeError` exceptions
+ when keys or values of the wrong type are used.
+ """
+
+ def __init__(self,
+ items=None,
+ key_class=None,
+ value_class=None,
+ wrapper_function=None,
+ unwrapper_function=None):
+ super(StrictDict, self).__init__()
+ if isinstance(items, StrictDict):
+ self.key_class = items.key_class
+ self.value_class = items.value_class
+ self.wrapper_function = items.wrapper_function
+ self.unwrapper_function = items.unwrapper_function
+ self.key_class = key_class
+ self.value_class = value_class
+ self.wrapper_function = wrapper_function
+ self.unwrapper_function = unwrapper_function
+ if items:
+ for k, v in items:
+ self[k] = v
+
+ def __getitem__(self, key):
+ if (self.key_class is not None) and (not isinstance(key, self.key_class)):
+ raise TypeError('key must be a "%s": %s' % (cls_name(self.key_class), repr(key)))
+ value = super(StrictDict, self).__getitem__(key)
+ if self.unwrapper_function is not None:
+ value = self.unwrapper_function(value)
+ return value
+
+ def __setitem__(self, key, value, **_):
+ if (self.key_class is not None) and (not isinstance(key, self.key_class)):
+ raise TypeError('key must be a "%s": %s' % (cls_name(self.key_class), repr(key)))
+ if (self.value_class is not None) and (not isinstance(value, self.value_class)):
+ raise TypeError('value must be a "%s": %s' % (cls_name(self.value_class), repr(value)))
+ if self.wrapper_function is not None:
+ value = self.wrapper_function(value)
+ return super(StrictDict, self).__setitem__(key, value)
+
+def merge(dict_a, dict_b, path=None, strict=False):
+ """
+ Merges dicts, recursively.
+ """
+
+ # TODO: a.add_yaml_merge(b), see https://bitbucket.org/ruamel/yaml/src/
+ # TODO: 86622a1408e0f171a12e140d53c4ffac4b6caaa3/comments.py?fileviewer=file-view-default
+
+ path = path or []
+ for key, value_b in dict_b.iteritems():
+ if key in dict_a:
+ value_a = dict_a[key]
+ if isinstance(value_a, dict) and isinstance(value_b, dict):
+ merge(value_a, value_b, path + [str(key)], strict)
+ elif value_a != value_b:
+ if strict:
+ raise ValueError('dict merge conflict at %s' % '.'.join(path + [str(key)]))
+ else:
+ dict_a[key] = value_b
+ else:
+ dict_a[key] = value_b
+ return dict_a
+
+def is_removable(_container, _key, v):
+ return (v is None) or ((isinstance(v, dict) or isinstance(v, list)) and (len(v) == 0))
+
+def prune(value, is_removable_function=is_removable):
+ """
+ Deletes :code:`None` and empty lists and dicts, recursively.
+ """
+
+ if isinstance(value, list):
+ for i, v in enumerate(value):
+ if is_removable_function(value, i, v):
+ del value[i]
+ else:
+ prune(v, is_removable_function)
+ elif isinstance(value, dict):
+ for k, v in value.iteritems():
+ if is_removable_function(value, k, v):
+ del value[k]
+ else:
+ prune(v, is_removable_function)
+
+ return value
+
+
+# TODO (left for tal): Move following two methods to some place parser specific
+def deepcopy_with_locators(value):
+ """
+ Like :code:`deepcopy`, but also copies over locators.
+ """
+
+ res = deepcopy(value)
+ copy_locators(res, value)
+ return res
+
+
+def copy_locators(target, source):
+ """
+ Copies over :code:`_locator` for all elements, recursively.
+
+ Assumes that target and source have exactly the same list/dict structure.
+ """
+
+ locator = getattr(source, '_locator', None)
+ if locator is not None:
+ try:
+ setattr(target, '_locator', locator)
+ except AttributeError:
+ pass
+
+ if isinstance(target, list) and isinstance(source, list):
+ for i, _ in enumerate(target):
+ copy_locators(target[i], source[i])
+ elif isinstance(target, dict) and isinstance(source, dict):
+ for k, v in target.iteritems():
+ copy_locators(v, source[k])
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/utils/console.py
----------------------------------------------------------------------
diff --git a/aria/utils/console.py b/aria/utils/console.py
new file mode 100644
index 0000000..55d2529
--- /dev/null
+++ b/aria/utils/console.py
@@ -0,0 +1,64 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 clint.textui.core import STDOUT
+from clint.textui import puts as _puts
+from clint.textui.colored import ColoredString as _ColoredString
+from clint.textui import indent # pylint: disable=unused-import
+
+from .formatting import safe_str
+
+
+class ColoredString(_ColoredString):
+ def __init__(self, color, str_, always_color=False, bold=False):
+ super(ColoredString, self).__init__(color, safe_str(str_), always_color, bold)
+
+
+def puts(string='', newline=True, stream=STDOUT):
+ _puts(safe_str(string), newline, stream)
+
+
+class Colored(object):
+ @staticmethod
+ def black(string, always=False, bold=False):
+ return ColoredString('BLACK', string, always_color=always, bold=bold)
+
+ @staticmethod
+ def red(string, always=False, bold=False):
+ return ColoredString('RED', string, always_color=always, bold=bold)
+
+ @staticmethod
+ def green(string, always=False, bold=False):
+ return ColoredString('GREEN', string, always_color=always, bold=bold)
+
+ @staticmethod
+ def yellow(string, always=False, bold=False):
+ return ColoredString('YELLOW', string, always_color=always, bold=bold)
+
+ @staticmethod
+ def blue(string, always=False, bold=False):
+ return ColoredString('BLUE', string, always_color=always, bold=bold)
+
+ @staticmethod
+ def magenta(string, always=False, bold=False):
+ return ColoredString('MAGENTA', string, always_color=always, bold=bold)
+
+ @staticmethod
+ def cyan(string, always=False, bold=False):
+ return ColoredString('CYAN', string, always_color=always, bold=bold)
+
+ @staticmethod
+ def white(string, always=False, bold=False):
+ return ColoredString('WHITE', string, always_color=always, bold=bold)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/utils/exceptions.py
----------------------------------------------------------------------
diff --git a/aria/utils/exceptions.py b/aria/utils/exceptions.py
new file mode 100644
index 0000000..0370bb3
--- /dev/null
+++ b/aria/utils/exceptions.py
@@ -0,0 +1,64 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 sys
+import linecache
+
+from clint.textui import indent
+from .console import (puts, Colored)
+
+
+def print_exception(e, full=True, cause=False, traceback=None):
+ """
+ Prints the exception with nice colors and such.
+ """
+ def format_heading(e):
+ return '%s%s: %s' % (Colored.red('Caused by ') if cause else '', Colored.red(
+ e.__class__.__name__, bold=True), Colored.red(e))
+
+ puts(format_heading(e))
+ if full:
+ if cause:
+ if traceback:
+ print_traceback(traceback)
+ else:
+ print_traceback()
+ if hasattr(e, 'cause') and e.cause:
+ traceback = e.cause_traceback if hasattr(e, 'cause_traceback') else None
+ print_exception(e.cause, full=full, cause=True, traceback=traceback)
+
+def print_traceback(traceback=None):
+ """
+ Prints the traceback with nice colors and such.
+ """
+
+ if traceback is None:
+ _, _, traceback = sys.exc_info()
+ while traceback is not None:
+ frame = traceback.tb_frame
+ lineno = traceback.tb_lineno
+ code = frame.f_code
+ filename = code.co_filename
+ name = code.co_name
+ with indent(2):
+ puts('File "%s", line %s, in %s' % (Colored.blue(filename),
+ Colored.cyan(lineno),
+ Colored.cyan(name)))
+ linecache.checkcache(filename)
+ line = linecache.getline(filename, lineno, frame.f_globals)
+ if line:
+ with indent(2):
+ puts(Colored.black(line.strip()))
+ traceback = traceback.tb_next
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/utils/formatting.py
----------------------------------------------------------------------
diff --git a/aria/utils/formatting.py b/aria/utils/formatting.py
new file mode 100644
index 0000000..3725bc7
--- /dev/null
+++ b/aria/utils/formatting.py
@@ -0,0 +1,203 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 __future__ import absolute_import # so we can import standard 'collections'
+
+import json
+from types import MethodType
+from ruamel import yaml # @UnresolvedImport
+
+from .collections import FrozenList, FrozenDict, StrictList, StrictDict, OrderedDict
+
+# Add our types to ruamel.yaml (for round trips)
+yaml.representer.RoundTripRepresenter.add_representer(
+ FrozenList, yaml.representer.RoundTripRepresenter.represent_list)
+yaml.representer.RoundTripRepresenter.add_representer(
+ FrozenDict, yaml.representer.RoundTripRepresenter.represent_dict)
+yaml.representer.RoundTripRepresenter.add_representer(
+ StrictList, yaml.representer.RoundTripRepresenter.represent_list)
+yaml.representer.RoundTripRepresenter.add_representer(
+ StrictDict, yaml.representer.RoundTripRepresenter.represent_dict)
+
+# Without this, ruamel.yaml will output "!!omap" types, which is
+# technically correct but unnecessarily verbose for our uses
+yaml.representer.RoundTripRepresenter.add_representer(
+ OrderedDict, yaml.representer.RoundTripRepresenter.represent_dict)
+
+
+class JsonAsRawEncoder(json.JSONEncoder):
+ """
+ A :class:`JSONEncoder` that will use the :code:`as_raw` property of objects
+ if available.
+ """
+ def raw_encoder_default(self, obj):
+ try:
+ return iter(obj)
+ except TypeError:
+ if hasattr(obj, 'as_raw'):
+ return as_raw(obj)
+ return str(obj)
+ return super(JsonAsRawEncoder, self).default(obj)
+
+ def __init__(self, *args, **kwargs):
+ kwargs['default'] = self.raw_encoder_default
+ super(JsonAsRawEncoder, self).__init__(*args, **kwargs)
+
+
+class YamlAsRawDumper(yaml.dumper.RoundTripDumper): # pylint: disable=too-many-ancestors
+ """
+ A :class:`RoundTripDumper` that will use the :code:`as_raw` property of objects
+ if available.
+ """
+
+ def represent_data(self, data):
+ if hasattr(data, 'as_raw'):
+ data = as_raw(data)
+ return super(YamlAsRawDumper, self).represent_data(data)
+
+
+def full_type_name(value):
+ """
+ The full class name of a type or object.
+ """
+
+ if not isinstance(value, type):
+ value = value.__class__
+ module = str(value.__module__)
+ name = str(value.__name__)
+ return name if module == '__builtin__' else '%s.%s' % (module, name)
+
+
+def safe_str(value):
+ """
+ Like :code:`str` coercion, but makes sure that Unicode strings are properly
+ encoded, and will never return None.
+ """
+
+ try:
+ return str(value)
+ except UnicodeEncodeError:
+ return unicode(value).encode('utf8')
+
+
+def safe_repr(value):
+ """
+ Like :code:`repr`, but calls :code:`as_raw` and :code:`as_agnostic` first.
+ """
+
+ return repr(as_agnostic(as_raw(value)))
+
+
+def string_list_as_string(strings):
+ """
+ Nice representation of a list of strings.
+ """
+
+ return ', '.join('"%s"' % safe_str(v) for v in strings)
+
+
+def as_raw(value):
+ """
+ Converts values using their :code:`as_raw` property, if it exists, recursively.
+ """
+
+ if hasattr(value, 'as_raw'):
+ value = value.as_raw
+ if isinstance(value, MethodType):
+ # Old-style Python classes don't support properties
+ value = value()
+ elif isinstance(value, list):
+ value = list(value)
+ for i, _ in enumerate(value):
+ value[i] = as_raw(value[i])
+ elif isinstance(value, dict):
+ value = dict(value)
+ for k, v in value.iteritems():
+ value[k] = as_raw(v)
+ return value
+
+
+def as_raw_list(value):
+ """
+ Assuming value is a list, converts its values using :code:`as_raw`.
+ """
+
+ if value is None:
+ return []
+ if isinstance(value, dict):
+ value = value.itervalues()
+ return [as_raw(v) for v in value]
+
+
+def as_raw_dict(value):
+ """
+ Assuming value is a dict, converts its values using :code:`as_raw`.
+ The keys are left as is.
+ """
+
+ if value is None:
+ return OrderedDict()
+ return OrderedDict((
+ (k, as_raw(v)) for k, v in value.iteritems()))
+
+
+def as_agnostic(value):
+ """
+ Converts subclasses of list and dict to standard lists and dicts, and Unicode strings
+ to non-Unicode if possible, recursively.
+
+ Useful for creating human-readable output of structures.
+ """
+
+ if isinstance(value, unicode):
+ try:
+ value = str(value)
+ except UnicodeEncodeError:
+ pass
+ elif isinstance(value, list):
+ value = list(value)
+ elif isinstance(value, dict):
+ value = dict(value)
+
+ if isinstance(value, list):
+ for i, _ in enumerate(value):
+ value[i] = as_agnostic(value[i])
+ elif isinstance(value, dict):
+ for k, v in value.iteritems():
+ value[k] = as_agnostic(v)
+
+ return value
+
+
+def json_dumps(value, indent=2):
+ """
+ JSON dumps that supports Unicode and the :code:`as_raw` property of objects
+ if available.
+ """
+
+ return json.dumps(value, indent=indent, ensure_ascii=False, cls=JsonAsRawEncoder)
+
+
+def yaml_dumps(value, indent=2):
+ """
+ YAML dumps that supports Unicode and the :code:`as_raw` property of objects
+ if available.
+ """
+
+ return yaml.dump(value, indent=indent, allow_unicode=True, Dumper=YamlAsRawDumper)
+
+
+def yaml_loads(value):
+ return yaml.load(value, Loader=yaml.SafeLoader)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/utils/imports.py
----------------------------------------------------------------------
diff --git a/aria/utils/imports.py b/aria/utils/imports.py
new file mode 100644
index 0000000..e9c164e
--- /dev/null
+++ b/aria/utils/imports.py
@@ -0,0 +1,78 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+"""
+Utility methods for dynamically loading python code
+"""
+
+import importlib
+
+
+def import_fullname(name, paths=None):
+ """
+ Imports a variable or class based on a full name, optionally searching for it in the paths.
+ """
+ paths = paths or []
+ if name is None:
+ return None
+
+ def do_import(name):
+ if name and ('.' in name):
+ module_name, name = name.rsplit('.', 1)
+ return getattr(__import__(module_name, fromlist=[name], level=0), name)
+ else:
+ raise ImportError('import not found: %s' % name)
+
+ try:
+ return do_import(name)
+ except ImportError:
+ for path in paths:
+ try:
+ return do_import('%s.%s' % (path, name))
+ except Exception as e:
+ raise ImportError('cannot import %s, because %s' % (name, e))
+
+ raise ImportError('import not found: %s' % name)
+
+
+def import_modules(name):
+ """
+ Imports a module and all its sub-modules, recursively.
+ Relies on modules defining a 'MODULES' attribute listing their sub-module names.
+ """
+
+ module = __import__(name, fromlist=['MODULES'], level=0)
+ if hasattr(module, 'MODULES'):
+ for module_ in module.MODULES:
+ import_modules('%s.%s' % (name, module_))
+
+
+# TODO merge with import_fullname
+def load_attribute(attribute_path):
+ """
+ Dynamically load an attribute based on the path to it.
+ e.g. some_package.some_module.some_attribute, will load the some_attribute from the
+ some_package.some_module module
+ """
+ module_name, attribute_name = attribute_path.rsplit('.', 1)
+ try:
+ module = importlib.import_module(module_name)
+ return getattr(module, attribute_name)
+ except ImportError:
+ # TODO: handle
+ raise
+ except AttributeError:
+ # TODO: handle
+ raise
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/utils/openclose.py
----------------------------------------------------------------------
diff --git a/aria/utils/openclose.py b/aria/utils/openclose.py
new file mode 100644
index 0000000..19740eb
--- /dev/null
+++ b/aria/utils/openclose.py
@@ -0,0 +1,32 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+class OpenClose(object):
+ """
+ Wraps an object that has open() and close() methods to support the "with" keyword.
+ """
+
+ def __init__(self, wrapped):
+ self.wrapped = wrapped
+
+ def __enter__(self):
+ if hasattr(self.wrapped, 'open'):
+ self.wrapped.open()
+ return self.wrapped
+
+ def __exit__(self, the_type, value, traceback):
+ if hasattr(self.wrapped, 'close'):
+ self.wrapped.close()
+ return False
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/utils/plugin.py
----------------------------------------------------------------------
diff --git a/aria/utils/plugin.py b/aria/utils/plugin.py
new file mode 100644
index 0000000..bb2b974
--- /dev/null
+++ b/aria/utils/plugin.py
@@ -0,0 +1,39 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+"""
+Contains utility methods that enable dynamic python code loading
+# TODO: merge with tools.module
+"""
+
+import os
+from importlib import import_module
+
+
+def plugin_installer(path, plugin_suffix, package=None, callback=None):
+ """
+ Load each module under ``path`` that ends with ``plugin_suffix``. If ``callback`` is supplied,
+ call it with each loaded module.
+ """
+ assert callback is None or callable(callback)
+ plugin_suffix = '{0}.py'.format(plugin_suffix)
+
+ for file_name in os.listdir(path):
+ if not file_name.endswith(plugin_suffix):
+ continue
+ module_name = '{0}.{1}'.format(package, file_name[:-3]) if package else file_name[:-3]
+ module = import_module(module_name)
+ if callback:
+ callback(module)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/utils/threading.py
----------------------------------------------------------------------
diff --git a/aria/utils/threading.py b/aria/utils/threading.py
new file mode 100644
index 0000000..575d011
--- /dev/null
+++ b/aria/utils/threading.py
@@ -0,0 +1,252 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 __future__ import absolute_import # so we can import standard 'threading'
+
+import itertools
+import multiprocessing
+from threading import (Thread, Lock)
+from Queue import (Queue, Full, Empty)
+
+from .exceptions import print_exception
+
+class ExecutorException(Exception):
+ pass
+
+class DaemonThread(Thread):
+ def __init__(self, *args, **kwargs):
+ super(DaemonThread, self).__init__(*args, **kwargs)
+ self.daemon = True
+
+ def run(self):
+ """
+ We're overriding `Thread.run` in order to avoid annoying (but harmless) error
+ messages during shutdown. The problem is that CPython nullifies the
+ global state _before_ shutting down daemon threads, so that exceptions
+ might happen, and then `Thread.__bootstrap_inner` prints them out.
+
+ Our solution is to swallow these exceptions here.
+
+ The side effect is that uncaught exceptions in our own thread code will _not_
+ be printed out as usual, so it's our responsibility to catch them in our
+ code.
+ """
+
+ try:
+ super(DaemonThread, self).run()
+ except SystemExit as e:
+ # This exception should be bubbled up
+ raise e
+ except BaseException:
+ # Exceptions might occur in daemon threads during interpreter shutdown
+ pass
+
+# https://gist.github.com/tliron/81dd915166b0bfc64be08b4f8e22c835
+class FixedThreadPoolExecutor(object):
+ """
+ Executes tasks in a fixed thread pool.
+
+ Makes sure to gather all returned results and thrown exceptions in one place, in order of task
+ submission.
+
+ Example::
+
+ def sum(arg1, arg2):
+ return arg1 + arg2
+
+ executor = FixedThreadPoolExecutor(10)
+ try:
+ for value in range(100):
+ executor.submit(sum, value, value)
+ executor.drain()
+ except:
+ executor.close()
+ executor.raise_first()
+ print executor.returns
+
+ You can also use it with the Python "with" keyword, in which case you don't need to call "close"
+ explicitly::
+
+ with FixedThreadPoolExecutor(10) as executor:
+ for value in range(100):
+ executor.submit(sum, value, value)
+ executor.drain()
+ executor.raise_first()
+ print executor.returns
+ """
+
+ _CYANIDE = object() # Special task marker used to kill worker threads.
+
+ def __init__(self,
+ size=multiprocessing.cpu_count() * 2 + 1,
+ timeout=None,
+ print_exceptions=False):
+ """
+ :param size: Number of threads in the pool (fixed).
+ :param timeout: Timeout in seconds for all
+ blocking operations. (Defaults to none, meaning no timeout)
+ :param print_exceptions: Set to true in order to
+ print exceptions from tasks. (Defaults to false)
+ """
+
+ self.size = size
+ self.timeout = timeout
+ self.print_exceptions = print_exceptions
+
+ self._tasks = Queue()
+ self._returns = {}
+ self._exceptions = {}
+ self._id_creator = itertools.count()
+ self._lock = Lock() # for console output
+
+ self._workers = []
+ for index in range(size):
+ worker = DaemonThread(
+ name='%s%d' % (self.__class__.__name__, index),
+ target=self._thread_worker)
+ worker.start()
+ self._workers.append(worker)
+
+ def submit(self, func, *args, **kwargs):
+ """
+ Submit a task for execution.
+
+ The task will be called ASAP on the next available worker thread in the pool.
+
+ Will raise an :class:`ExecutorException` exception if cannot be submitted.
+ """
+
+ try:
+ self._tasks.put((self._id_creator.next(), func, args, kwargs), timeout=self.timeout)
+ except Full:
+ raise ExecutorException('cannot submit task: queue is full')
+
+ def close(self):
+ """
+ Blocks until all current tasks finish execution and all worker threads are dead.
+
+ You cannot submit tasks anymore after calling this.
+
+ This is called automatically upon exit if you are using the "with" keyword.
+ """
+
+ self.drain()
+ while self.is_alive:
+ try:
+ self._tasks.put(self._CYANIDE, timeout=self.timeout)
+ except Full:
+ raise ExecutorException('cannot close executor: a thread seems to be hanging')
+ self._workers = None
+
+ def drain(self):
+ """
+ Blocks until all current tasks finish execution, but leaves the worker threads alive.
+ """
+
+ self._tasks.join() # oddly, the API does not support a timeout parameter
+
+ @property
+ def is_alive(self):
+ """
+ True if any of the worker threads are alive.
+ """
+
+ for worker in self._workers:
+ if worker.is_alive():
+ return True
+ return False
+
+ @property
+ def returns(self):
+ """
+ The returned values from all tasks, in order of submission.
+ """
+
+ return [self._returns[k] for k in sorted(self._returns)]
+
+ @property
+ def exceptions(self):
+ """
+ The raised exceptions from all tasks, in order of submission.
+ """
+
+ return [self._exceptions[k] for k in sorted(self._exceptions)]
+
+ def raise_first(self):
+ """
+ If exceptions were thrown by any task, then the first one will be raised.
+
+ This is rather arbitrary: proper handling would involve iterating all the
+ exceptions. However, if you want to use the "raise" mechanism, you are
+ limited to raising only one of them.
+ """
+
+ exceptions = self.exceptions
+ if exceptions:
+ raise exceptions[0]
+
+ def _thread_worker(self):
+ while True:
+ if not self._execute_next_task():
+ break
+
+ def _execute_next_task(self):
+ try:
+ task = self._tasks.get(timeout=self.timeout)
+ except Empty:
+ # Happens if timeout is reached
+ return True
+ if task == self._CYANIDE:
+ # Time to die :(
+ return False
+ self._execute_task(*task)
+ return True
+
+ def _execute_task(self, task_id, func, args, kwargs):
+ try:
+ result = func(*args, **kwargs)
+ self._returns[task_id] = result
+ except Exception as e:
+ self._exceptions[task_id] = e
+ if self.print_exceptions:
+ with self._lock:
+ print_exception(e)
+ self._tasks.task_done()
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, the_type, value, traceback):
+ self.close()
+ return False
+
+class LockedList(list):
+ """
+ A list that supports the "with" keyword with a built-in lock.
+
+ Though Python lists are thread-safe in that they will not raise exceptions
+ during concurrent access, they do not guarantee atomicity. This class will
+ let you gain atomicity when needed.
+ """
+
+ def __init__(self, *args, **kwargs):
+ super(LockedList, self).__init__(*args, **kwargs)
+ self.lock = Lock()
+
+ def __enter__(self):
+ return self.lock.__enter__()
+
+ def __exit__(self, the_type, value, traceback):
+ return self.lock.__exit__(the_type, value, traceback)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/utils/uris.py
----------------------------------------------------------------------
diff --git a/aria/utils/uris.py b/aria/utils/uris.py
new file mode 100644
index 0000000..1686517
--- /dev/null
+++ b/aria/utils/uris.py
@@ -0,0 +1,28 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 os
+import urlparse
+
+def as_file(uri):
+ """
+ If the URI is a file (either the :code:`file` scheme or no scheme), then returns the absolute
+ path. Otherwise, returns None.
+ """
+
+ url = urlparse.urlparse(uri)
+ if (not url.scheme) or (url.scheme == 'file'):
+ return os.path.abspath(url.path)
+ return None
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/utils/validation.py
----------------------------------------------------------------------
diff --git a/aria/utils/validation.py b/aria/utils/validation.py
new file mode 100644
index 0000000..a33f7a2
--- /dev/null
+++ b/aria/utils/validation.py
@@ -0,0 +1,95 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+"""
+Contains validation related utilities
+"""
+
+
+class ValidatorMixin(object):
+ """
+ A mixin that should be added to classes that require validating user input
+ """
+
+ _ARGUMENT_TYPE_MESSAGE = '{name} argument must be {type} based, got {arg!r}'
+ _ARGUMENT_CHOICE_MESSAGE = '{name} argument must be in {choices}, got {arg!r}'
+
+ @classmethod
+ def validate_in_choice(cls, name, argument, choices):
+ """
+ Validate ``argument`` is in ``choices``
+ """
+ if argument not in choices:
+ raise TypeError(cls._ARGUMENT_CHOICE_MESSAGE.format(
+ name=name, choices=choices, arg=argument))
+
+ @classmethod
+ def validate_type(cls, argument_name, argument, expected_type):
+ """
+ Validate ``argument`` is a subclass of ``expected_type``
+ """
+ if not issubclass(argument, expected_type):
+ raise TypeError(cls._ARGUMENT_TYPE_MESSAGE.format(
+ name=argument_name, type=expected_type, arg=argument))
+
+ @classmethod
+ def validate_instance(cls, argument_name, argument, expected_type):
+ """
+ Validate ``argument`` is a instance of ``expected_type``
+ """
+ if not isinstance(argument, expected_type):
+ raise TypeError(cls._ARGUMENT_TYPE_MESSAGE.format(
+ name=argument_name, type=expected_type, arg=argument))
+
+ @classmethod
+ def validate_callable(cls, argument_name, argument):
+ """
+ Validate ``argument`` is callable
+ """
+ if not callable(argument):
+ raise TypeError(cls._ARGUMENT_TYPE_MESSAGE.format(
+ name=argument_name, type='callable', arg=argument))
+
+
+def validate_function_arguments(func, func_kwargs):
+ """
+ Validates all required arguments are supplied to ``func`` and that no additional arguments are
+ supplied
+ """
+
+ _kwargs_flags = 8
+
+ has_kwargs = func.func_code.co_flags & _kwargs_flags != 0
+ args_count = func.func_code.co_argcount
+
+ # all args without the ones with default values
+ args = func.func_code.co_varnames[:args_count]
+ non_default_args = args[:len(func.func_defaults)] if func.func_defaults else args
+
+ # Check if any args without default values is missing in the func_kwargs
+ for arg in non_default_args:
+ if arg not in func_kwargs:
+ raise ValueError(
+ "The argument '{arg}' doest not have a default value, and it "
+ "isn't passed to {func.__name__}".format(arg=arg, func=func))
+
+ # check if there are any extra kwargs
+ extra_kwargs = [arg for arg in func_kwargs.keys() if arg not in args]
+
+ # assert that the function has kwargs
+ if extra_kwargs and not has_kwargs:
+ raise ValueError("The following extra kwargs were supplied: {extra_kwargs}".format(
+ extra_kwargs=extra_kwargs
+ ))
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/extensions/aria_extension_tosca/simple_nfv_v1_0/presenter.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_nfv_v1_0/presenter.py b/extensions/aria_extension_tosca/simple_nfv_v1_0/presenter.py
index e26ca7b..8098ccf 100644
--- a/extensions/aria_extension_tosca/simple_nfv_v1_0/presenter.py
+++ b/extensions/aria_extension_tosca/simple_nfv_v1_0/presenter.py
@@ -13,10 +13,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from aria.parser.utils import (FrozenList, EMPTY_READ_ONLY_LIST, cachedmethod)
+from aria.utils.collections import FrozenList, EMPTY_READ_ONLY_LIST
+from aria.utils.caching import cachedmethod
from ..simple_v1_0 import ToscaSimplePresenter1_0
+
class ToscaSimpleNfvPresenter1_0(ToscaSimplePresenter1_0): # pylint: disable=invalid-name
"""
ARIA presenter for the `TOSCA Simple Profile for NFV v1.0 csd03 <http://docs.oasis-open.org
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/extensions/aria_extension_tosca/simple_v1_0/assignments.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/assignments.py b/extensions/aria_extension_tosca/simple_v1_0/assignments.py
index 6f42d79..14fee96 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/assignments.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/assignments.py
@@ -13,12 +13,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from aria.utils.collections import FrozenDict
+from aria.utils.caching import cachedmethod
from aria.parser import dsl_specification
from aria.parser.presentation import (AsIsPresentation, has_fields, allow_unknown_fields,
short_form_field, primitive_field, object_field,
object_dict_field, object_dict_unknown_fields,
field_validator, type_validator)
-from aria.parser.utils import FrozenDict, cachedmethod
from .filters import NodeFilter
from .misc import Description, OperationImplementation
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/extensions/aria_extension_tosca/simple_v1_0/data_types.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/data_types.py b/extensions/aria_extension_tosca/simple_v1_0/data_types.py
index e9cd97c..1fdbe6e 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/data_types.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/data_types.py
@@ -14,19 +14,17 @@
# limitations under the License.
import re
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
from functools import total_ordering
from datetime import datetime, tzinfo, timedelta
from aria.parser import dsl_specification
-from aria.parser.utils import StrictDict, safe_repr
+from aria.utils.collections import StrictDict, OrderedDict
+from aria.utils.formatting import safe_repr
from .modeling.data_types import (coerce_to_data_type_class, report_issue_for_bad_format,
coerce_value)
+
class Timezone(tzinfo):
"""
Timezone as fixed offset in hours and minutes east of UTC.
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/extensions/aria_extension_tosca/simple_v1_0/definitions.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/definitions.py b/extensions/aria_extension_tosca/simple_v1_0/definitions.py
index e595e07..b60a797 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/definitions.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/definitions.py
@@ -13,8 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from aria.utils.collections import FrozenDict
+from aria.utils.caching import cachedmethod
from aria.parser import dsl_specification
-from aria.parser.utils import (FrozenDict, cachedmethod)
from aria.parser.presentation import (has_fields, short_form_field, allow_unknown_fields,
primitive_field, primitive_list_field, object_field,
object_list_field, object_dict_field,
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/extensions/aria_extension_tosca/simple_v1_0/filters.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/filters.py b/extensions/aria_extension_tosca/simple_v1_0/filters.py
index 7ead633..617ce7a 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/filters.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/filters.py
@@ -13,8 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from aria.utils.caching import cachedmethod
from aria.parser import dsl_specification
-from aria.parser.utils import cachedmethod
from aria.parser.presentation import (has_fields, object_sequenced_list_field, field_validator)
from .misc import ConstraintClause
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/extensions/aria_extension_tosca/simple_v1_0/functions.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/functions.py b/extensions/aria_extension_tosca/simple_v1_0/functions.py
index bf2f69d..79079df 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/functions.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/functions.py
@@ -15,9 +15,10 @@
from cStringIO import StringIO
+from aria.utils.collections import FrozenList
+from aria.utils.formatting import as_raw, safe_repr
from aria.parser import (dsl_specification, InvalidValueError)
from aria.parser.modeling import (Function, CannotEvaluateFunctionException)
-from aria.parser.utils import (FrozenList, as_raw, safe_repr)
from aria.parser.validation import Issue
#
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/extensions/aria_extension_tosca/simple_v1_0/misc.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/misc.py b/extensions/aria_extension_tosca/simple_v1_0/misc.py
index 5e41378..4453c7a 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/misc.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/misc.py
@@ -13,13 +13,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from aria.utils.caching import cachedmethod
+from aria.utils.console import puts
+from aria.utils.formatting import as_raw
from aria.parser import dsl_specification
from aria.parser.presentation import (AsIsPresentation, has_fields, allow_unknown_fields,
short_form_field, primitive_field, primitive_list_field,
primitive_dict_unknown_fields, object_field,
object_list_field, object_dict_field, field_validator,
type_validator)
-from aria.parser.utils import (cachedmethod, puts, as_raw)
from .modeling.data_types import (get_data_type, get_data_type_value, get_property_constraints,
apply_constraint_to_value)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/extensions/aria_extension_tosca/simple_v1_0/modeling/artifacts.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/artifacts.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/artifacts.py
index f5667a6..4f61ef5 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/artifacts.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/artifacts.py
@@ -13,15 +13,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
+from aria.utils.collections import OrderedDict
#
# NodeType, NodeTemplate
#
+
def get_inherited_artifact_definitions(context, presentation, for_presentation=None):
if hasattr(presentation, '_get_type'):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
index 4a96b04..d9b9f6b 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
@@ -13,12 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
-
-from aria.parser.utils import deepcopy_with_locators
+from aria.utils.collections import deepcopy_with_locators, OrderedDict
from aria.parser.validation import Issue
from .properties import (convert_property_definitions_to_values, merge_raw_property_definitions,
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
index d98bc54..99dcfea 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
@@ -14,14 +14,12 @@
# limitations under the License.
import re
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
+from aria.utils.collections import OrderedDict
+from aria.utils.formatting import full_type_name, safe_repr
+from aria.utils.imports import import_fullname
from aria.parser import dsl_specification
from aria.parser.presentation import (get_locator, validate_primitive)
-from aria.parser.utils import (import_fullname, full_type_name, safe_repr)
from aria.parser.validation import Issue
from ..functions import get_function
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
index bffb5dc..3e6aa6f 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
@@ -13,13 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
-
+from aria.utils.collections import merge, deepcopy_with_locators, OrderedDict
from aria.parser.presentation import get_locator
-from aria.parser.utils import (merge, deepcopy_with_locators)
from aria.parser.validation import Issue
from .properties import (coerce_property_value, convert_property_definitions_to_values)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/extensions/aria_extension_tosca/simple_v1_0/modeling/properties.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/properties.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/properties.py
index 439f44c..f61cb99 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/properties.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/properties.py
@@ -13,13 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
-
+from aria.utils.collections import merge, deepcopy_with_locators, OrderedDict
from aria.parser.presentation import Value
-from aria.parser.utils import (merge, deepcopy_with_locators)
from aria.parser.validation import Issue
from .data_types import coerce_value
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/extensions/aria_extension_tosca/simple_v1_0/modeling/requirements.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/requirements.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/requirements.py
index 068dde0..9dea874 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/requirements.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/requirements.py
@@ -13,12 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
from aria.parser.validation import Issue
-from aria.parser.utils import deepcopy_with_locators
+from aria.utils.collections import deepcopy_with_locators, OrderedDict
from .properties import (convert_property_definitions_to_values, validate_required_values,
coerce_property_value)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/extensions/aria_extension_tosca/simple_v1_0/modeling/substitution_mappings.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/substitution_mappings.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/substitution_mappings.py
index e0252b1..c1e21de 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/substitution_mappings.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/substitution_mappings.py
@@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from aria.parser.utils import safe_repr
+from aria.utils.formatting import safe_repr
from aria.parser.validation import Issue
def validate_subtitution_mappings_requirement(context, presentation):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py b/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py
index 22e9606..a2fd6ee 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py
@@ -13,8 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from aria.utils.caching import cachedmethod
from aria.parser.presentation import (Presentation, has_fields, primitive_dict_field)
-from aria.parser.utils import cachedmethod
@has_fields
class ExtensiblePresentation(Presentation):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/extensions/aria_extension_tosca/simple_v1_0/presentation/field_getters.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/presentation/field_getters.py b/extensions/aria_extension_tosca/simple_v1_0/presentation/field_getters.py
index 291e349..a2adb1e 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/presentation/field_getters.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/presentation/field_getters.py
@@ -13,8 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from aria.utils.formatting import safe_repr
from aria.parser import InvalidValueError
-from aria.parser.utils import safe_repr
+
def data_type_class_getter(cls):
"""
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py b/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py
index 662faab..f1b0a20 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py
@@ -15,9 +15,9 @@
import re
+from aria.utils.formatting import safe_repr
from aria.parser import dsl_specification
from aria.parser.presentation import (report_issue_for_unknown_type, derived_from_validator)
-from aria.parser.utils import safe_repr
from aria.parser.validation import Issue
from ..modeling.data_types import (get_primitive_data_type, get_data_type_name, coerce_value,
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/extensions/aria_extension_tosca/simple_v1_0/presenter.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/presenter.py b/extensions/aria_extension_tosca/simple_v1_0/presenter.py
index c21c326..0809014 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/presenter.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/presenter.py
@@ -13,8 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from aria.utils.collections import FrozenList, EMPTY_READ_ONLY_LIST
+from aria.utils.caching import cachedmethod
from aria.parser.presentation import Presenter
-from aria.parser.utils import (FrozenList, EMPTY_READ_ONLY_LIST, cachedmethod)
from .functions import (Concat, Token, GetInput, GetProperty, GetAttribute, GetOperationOutput,
GetNodesOfType, GetArtifact)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/extensions/aria_extension_tosca/simple_v1_0/templates.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/templates.py b/extensions/aria_extension_tosca/simple_v1_0/templates.py
index fda95a4..6860b72 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/templates.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/templates.py
@@ -13,12 +13,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from aria.utils.collections import FrozenDict, FrozenList
+from aria.utils.caching import cachedmethod
from aria.parser import dsl_specification
from aria.parser.presentation import (has_fields, primitive_field, primitive_list_field,
object_field, object_list_field, object_dict_field,
object_sequenced_list_field, field_validator,
type_validator, list_type_validator)
-from aria.parser.utils import (FrozenDict, FrozenList, cachedmethod)
from .assignments import (PropertyAssignment, AttributeAssignment, RequirementAssignment,
CapabilityAssignment, InterfaceAssignment, ArtifactAssignment)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/extensions/aria_extension_tosca/simple_v1_0/types.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/types.py b/extensions/aria_extension_tosca/simple_v1_0/types.py
index 37608a2..39843ac 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/types.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/types.py
@@ -13,6 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from aria.utils.collections import FrozenDict, FrozenList
+from aria.utils.caching import cachedmethod
from aria.parser import dsl_specification
from aria.parser.presentation import (has_fields, allow_unknown_fields, primitive_field,
primitive_list_field, object_field, object_dict_field,
@@ -20,7 +22,6 @@ from aria.parser.presentation import (has_fields, allow_unknown_fields, primitiv
object_dict_unknown_fields, field_getter, field_validator,
list_type_validator, derived_from_validator,
get_parent_presentation)
-from aria.parser.utils import (FrozenDict, FrozenList, cachedmethod)
from .assignments import ArtifactAssignment
from .data_types import Version
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/requirements.txt
----------------------------------------------------------------------
diff --git a/requirements.txt b/requirements.txt
index a9a7963..e6d5393 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -23,4 +23,3 @@ Jinja2==2.8
shortuuid==0.4.3
CacheControl[filecache]==0.11.6
clint==0.5.1
-python-daemon==2.1.2
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/setup.py
----------------------------------------------------------------------
diff --git a/setup.py b/setup.py
index 14c5873..171946d 100644
--- a/setup.py
+++ b/setup.py
@@ -16,6 +16,7 @@
import os
import sys
+
from setuptools import setup, find_packages
_PACKAGE_NAME = 'aria'
@@ -26,12 +27,14 @@ if (sys.version_info[0], sys.version_info[1]) not in _PYTHON_SUPPORTED_VERSIONS:
'{0} Package support Python version 2.6 & 2.7 Only'.format(
_PACKAGE_NAME))
+root_dir = os.path.dirname(__file__)
+
version = '0.1.0'
-execfile(os.path.join('.', _PACKAGE_NAME, 'VERSION.py'))
+execfile(os.path.join(root_dir, _PACKAGE_NAME, 'VERSION.py'))
try:
- with open('./requirements.txt') as requirements:
+ with open(os.path.join(root_dir, 'requirements.txt')) as requirements:
install_requires = [requirement.strip() for requirement in requirements.readlines()]
except IOError:
install_requires = []
@@ -45,7 +48,6 @@ setup(
author='aria',
author_email='dev@ariatosca.incubator.apache.org',
url='http://ariatosca.org',
-
classifiers=[
'Development Status :: 4 - Beta',
'Environment :: Console',
@@ -58,17 +60,12 @@ setup(
'Topic :: Software Development :: Libraries :: Python Modules',
'Topic :: System :: Networking',
'Topic :: System :: Systems Administration'],
-
packages=find_packages(exclude=('*tests*',)),
package_data={
- 'aria.tools': [
- 'web/**'],
'aria_extension_tosca': [
'profiles/tosca-simple-1.0/**',
- 'profiles/tosca-simple-nfv-1.0/**'],
- 'aria_extension_open_o': [
- 'web/**']},
-
+ 'profiles/tosca-simple-nfv-1.0/**']
+ },
zip_safe=False,
install_requires=install_requires,
entry_points={
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/tests/orchestrator/context/test_workflow.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/context/test_workflow.py b/tests/orchestrator/context/test_workflow.py
index 19eb57c..258f0c5 100644
--- a/tests/orchestrator/context/test_workflow.py
+++ b/tests/orchestrator/context/test_workflow.py
@@ -59,5 +59,6 @@ class TestWorkflowContext(object):
def storage():
result = application_model_storage(InMemoryModelDriver())
result.setup()
+ result.blueprint.store(models.get_blueprint())
result.deployment.store(models.get_deployment())
return result
[2/3] incubator-ariatosca git commit: ARIA-21 Move general code from
parser.utils to top level utils
Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/utils/daemon.py
----------------------------------------------------------------------
diff --git a/aria/parser/utils/daemon.py b/aria/parser/utils/daemon.py
deleted file mode 100644
index b47eea1..0000000
--- a/aria/parser/utils/daemon.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 __future__ import absolute_import # so we can import standard 'daemon'
-
-try:
- import os
- import signal
- from time import sleep
- from .console import puts, Colored
- from daemon import DaemonContext
- from daemon.pidfile import TimeoutPIDLockFile
- from daemon.runner import is_pidfile_stale
-
- def start_daemon(pidfile_path, log_path, acquire_timeout=5):
- pidfile = TimeoutPIDLockFile(pidfile_path, acquire_timeout=acquire_timeout)
- if is_pidfile_stale(pidfile):
- pidfile.break_lock()
- if pidfile.is_locked():
- pid = pidfile.read_pid()
- if pid is not None:
- puts(Colored.red('Already running at pid: %d' % pid))
- else:
- puts(Colored.red('Already running'))
- return None
- logfile = open(log_path, 'w+t')
- puts(Colored.blue('Starting'))
- return DaemonContext(pidfile=pidfile, stdout=logfile, stderr=logfile)
-
- def stop_daemon(pidfile_path, acquire_timeout=5):
- pidfile = TimeoutPIDLockFile(pidfile_path, acquire_timeout=acquire_timeout)
- pid = pidfile.read_pid()
- if pid is not None:
- puts(Colored.blue('Stopping pid: %d' % pid))
- os.kill(pid, signal.SIGTERM)
- while pidfile.is_locked():
- puts(Colored.cyan('Waiting...'))
- sleep(0.1)
- puts(Colored.blue('Stopped'))
- else:
- puts(Colored.red('Not running'))
-
- def status_daemon(pidfile_path, acquire_timeout=5):
- pid = TimeoutPIDLockFile(pidfile_path, acquire_timeout=acquire_timeout).read_pid()
- if pid is not None:
- puts(Colored.blue('Running at pid: %d' % pid))
- else:
- puts(Colored.blue('Not running'))
-
-except ImportError:
- def start_daemon(*args, **kwargs):
- puts(Colored.red('Cannot start daemon in this environment'))
-
- def stop_daemon(*args, **kwargs):
- puts(Colored.red('Not running'))
-
- def status_daemon(*args, **kwargs):
- puts(Colored.blue('Not running'))
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/utils/exceptions.py
----------------------------------------------------------------------
diff --git a/aria/parser/utils/exceptions.py b/aria/parser/utils/exceptions.py
deleted file mode 100644
index 0370bb3..0000000
--- a/aria/parser/utils/exceptions.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 sys
-import linecache
-
-from clint.textui import indent
-from .console import (puts, Colored)
-
-
-def print_exception(e, full=True, cause=False, traceback=None):
- """
- Prints the exception with nice colors and such.
- """
- def format_heading(e):
- return '%s%s: %s' % (Colored.red('Caused by ') if cause else '', Colored.red(
- e.__class__.__name__, bold=True), Colored.red(e))
-
- puts(format_heading(e))
- if full:
- if cause:
- if traceback:
- print_traceback(traceback)
- else:
- print_traceback()
- if hasattr(e, 'cause') and e.cause:
- traceback = e.cause_traceback if hasattr(e, 'cause_traceback') else None
- print_exception(e.cause, full=full, cause=True, traceback=traceback)
-
-def print_traceback(traceback=None):
- """
- Prints the traceback with nice colors and such.
- """
-
- if traceback is None:
- _, _, traceback = sys.exc_info()
- while traceback is not None:
- frame = traceback.tb_frame
- lineno = traceback.tb_lineno
- code = frame.f_code
- filename = code.co_filename
- name = code.co_name
- with indent(2):
- puts('File "%s", line %s, in %s' % (Colored.blue(filename),
- Colored.cyan(lineno),
- Colored.cyan(name)))
- linecache.checkcache(filename)
- line = linecache.getline(filename, lineno, frame.f_globals)
- if line:
- with indent(2):
- puts(Colored.black(line.strip()))
- traceback = traceback.tb_next
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/utils/formatting.py
----------------------------------------------------------------------
diff --git a/aria/parser/utils/formatting.py b/aria/parser/utils/formatting.py
deleted file mode 100644
index 0a7b34d..0000000
--- a/aria/parser/utils/formatting.py
+++ /dev/null
@@ -1,207 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 __future__ import absolute_import # so we can import standard 'collections'
-
-import json
-from types import MethodType
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
-from ruamel import yaml # @UnresolvedImport
-
-from aria.parser.utils.collections import (FrozenList, FrozenDict, StrictList, StrictDict)
-
-# Add our types to ruamel.yaml (for round trips)
-yaml.representer.RoundTripRepresenter.add_representer(
- FrozenList, yaml.representer.RoundTripRepresenter.represent_list)
-yaml.representer.RoundTripRepresenter.add_representer(
- FrozenDict, yaml.representer.RoundTripRepresenter.represent_dict)
-yaml.representer.RoundTripRepresenter.add_representer(
- StrictList, yaml.representer.RoundTripRepresenter.represent_list)
-yaml.representer.RoundTripRepresenter.add_representer(
- StrictDict, yaml.representer.RoundTripRepresenter.represent_dict)
-
-# Without this, ruamel.yaml will output "!!omap" types, which is
-# technically correct but unnecessarily verbose for our uses
-yaml.representer.RoundTripRepresenter.add_representer(
- OrderedDict, yaml.representer.RoundTripRepresenter.represent_dict)
-
-
-class JsonAsRawEncoder(json.JSONEncoder):
- """
- A :class:`JSONEncoder` that will use the :code:`as_raw` property of objects
- if available.
- """
- def raw_encoder_default(self, obj):
- try:
- return iter(obj)
- except TypeError:
- if hasattr(obj, 'as_raw'):
- return as_raw(obj)
- return str(obj)
- return super(JsonAsRawEncoder, self).default(obj)
-
- def __init__(self, *args, **kwargs):
- kwargs['default'] = self.raw_encoder_default
- super(JsonAsRawEncoder, self).__init__(*args, **kwargs)
-
-
-class YamlAsRawDumper(yaml.dumper.RoundTripDumper): # pylint: disable=too-many-ancestors
- """
- A :class:`RoundTripDumper` that will use the :code:`as_raw` property of objects
- if available.
- """
-
- def represent_data(self, data):
- if hasattr(data, 'as_raw'):
- data = as_raw(data)
- return super(YamlAsRawDumper, self).represent_data(data)
-
-
-def full_type_name(value):
- """
- The full class name of a type or object.
- """
-
- if not isinstance(value, type):
- value = value.__class__
- module = str(value.__module__)
- name = str(value.__name__)
- return name if module == '__builtin__' else '%s.%s' % (module, name)
-
-
-def safe_str(value):
- """
- Like :code:`str` coercion, but makes sure that Unicode strings are properly
- encoded, and will never return None.
- """
-
- try:
- return str(value)
- except UnicodeEncodeError:
- return unicode(value).encode('utf8')
-
-
-def safe_repr(value):
- """
- Like :code:`repr`, but calls :code:`as_raw` and :code:`as_agnostic` first.
- """
-
- return repr(as_agnostic(as_raw(value)))
-
-
-def string_list_as_string(strings):
- """
- Nice representation of a list of strings.
- """
-
- return ', '.join('"%s"' % safe_str(v) for v in strings)
-
-
-def as_raw(value):
- """
- Converts values using their :code:`as_raw` property, if it exists, recursively.
- """
-
- if hasattr(value, 'as_raw'):
- value = value.as_raw
- if isinstance(value, MethodType):
- # Old-style Python classes don't support properties
- value = value()
- elif isinstance(value, list):
- value = list(value)
- for i, _ in enumerate(value):
- value[i] = as_raw(value[i])
- elif isinstance(value, dict):
- value = dict(value)
- for k, v in value.iteritems():
- value[k] = as_raw(v)
- return value
-
-
-def as_raw_list(value):
- """
- Assuming value is a list, converts its values using :code:`as_raw`.
- """
-
- if value is None:
- return []
- if isinstance(value, dict):
- value = value.itervalues()
- return [as_raw(v) for v in value]
-
-
-def as_raw_dict(value):
- """
- Assuming value is a dict, converts its values using :code:`as_raw`.
- The keys are left as is.
- """
-
- if value is None:
- return OrderedDict()
- return OrderedDict((
- (k, as_raw(v)) for k, v in value.iteritems()))
-
-
-def as_agnostic(value):
- """
- Converts subclasses of list and dict to standard lists and dicts, and Unicode strings
- to non-Unicode if possible, recursively.
-
- Useful for creating human-readable output of structures.
- """
-
- if isinstance(value, unicode):
- try:
- value = str(value)
- except UnicodeEncodeError:
- pass
- elif isinstance(value, list):
- value = list(value)
- elif isinstance(value, dict):
- value = dict(value)
-
- if isinstance(value, list):
- for i, _ in enumerate(value):
- value[i] = as_agnostic(value[i])
- elif isinstance(value, dict):
- for k, v in value.iteritems():
- value[k] = as_agnostic(v)
-
- return value
-
-
-def json_dumps(value, indent=2):
- """
- JSON dumps that supports Unicode and the :code:`as_raw` property of objects
- if available.
- """
-
- return json.dumps(value, indent=indent, ensure_ascii=False, cls=JsonAsRawEncoder)
-
-
-def yaml_dumps(value, indent=2):
- """
- YAML dumps that supports Unicode and the :code:`as_raw` property of objects
- if available.
- """
-
- return yaml.dump(value, indent=indent, allow_unicode=True, Dumper=YamlAsRawDumper)
-
-
-def yaml_loads(value):
- return yaml.load(value, Loader=yaml.SafeLoader)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/utils/imports.py
----------------------------------------------------------------------
diff --git a/aria/parser/utils/imports.py b/aria/parser/utils/imports.py
deleted file mode 100644
index 8f97156..0000000
--- a/aria/parser/utils/imports.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-def import_fullname(name, paths=None):
- """
- Imports a variable or class based on a full name, optionally searching for it in the paths.
- """
- paths = paths or []
- if name is None:
- return None
-
- def do_import(name):
- if name and ('.' in name):
- module_name, name = name.rsplit('.', 1)
- return getattr(__import__(module_name, fromlist=[name], level=0), name)
- else:
- raise ImportError('import not found: %s' % name)
-
- try:
- return do_import(name)
- except ImportError:
- for path in paths:
- try:
- return do_import('%s.%s' % (path, name))
- except Exception as e:
- raise ImportError('cannot import %s, because %s' % (name, e))
-
- raise ImportError('import not found: %s' % name)
-
-def import_modules(name):
- """
- Imports a module and all its sub-modules, recursively.
- Relies on modules defining a 'MODULES' attribute listing their sub-module names.
- """
-
- module = __import__(name, fromlist=['MODULES'], level=0)
- if hasattr(module, 'MODULES'):
- for module_ in module.MODULES:
- import_modules('%s.%s' % (name, module_))
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/utils/openclose.py
----------------------------------------------------------------------
diff --git a/aria/parser/utils/openclose.py b/aria/parser/utils/openclose.py
deleted file mode 100644
index 19740eb..0000000
--- a/aria/parser/utils/openclose.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-class OpenClose(object):
- """
- Wraps an object that has open() and close() methods to support the "with" keyword.
- """
-
- def __init__(self, wrapped):
- self.wrapped = wrapped
-
- def __enter__(self):
- if hasattr(self.wrapped, 'open'):
- self.wrapped.open()
- return self.wrapped
-
- def __exit__(self, the_type, value, traceback):
- if hasattr(self.wrapped, 'close'):
- self.wrapped.close()
- return False
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/utils/rest_client.py
----------------------------------------------------------------------
diff --git a/aria/parser/utils/rest_client.py b/aria/parser/utils/rest_client.py
deleted file mode 100644
index 905e372..0000000
--- a/aria/parser/utils/rest_client.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 json
-import urllib2
-
-def call_rest(url, payload=None, with_payload_method='PUT'):
- """
- REST call with JSON decoding of the response and JSON payloads.
- """
-
- if payload:
- if not isinstance(payload, basestring):
- payload = json.dumps(payload)
- # PUT or POST
- response = urllib2.urlopen(MethodRequest(
- url,
- payload,
- {'Content-Type': 'application/json'}, method=with_payload_method))
- else:
- # GET
- response = urllib2.urlopen(url)
- response = response.read().decode()
- return json.loads(response)
-
-#
-# Utils
-#
-
-class MethodRequest(urllib2.Request):
- """
- Workaround to support all HTTP methods.
-
- From `here <https://gist.github.com/logic/2715756>`__.
- """
-
- def __init__(self, *args, **kwargs):
- if 'method' in kwargs:
- self._method = kwargs['method']
- del kwargs['method']
- else:
- self._method = None
- urllib2.Request.__init__(self, *args, **kwargs)
-
- def get_method(self, *args, **kwargs):
- return self._method if self._method is not None else urllib2.Request.get_method(
- self, *args, **kwargs)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/utils/rest_server.py
----------------------------------------------------------------------
diff --git a/aria/parser/utils/rest_server.py b/aria/parser/utils/rest_server.py
deleted file mode 100644
index 17823f1..0000000
--- a/aria/parser/utils/rest_server.py
+++ /dev/null
@@ -1,252 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 __future__ import absolute_import # so we can import standard 'collections'
-
-import os
-import re
-import shutil
-import json
-import sys
-import BaseHTTPServer
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
-from ..utils import (puts, Colored)
-
-class RestServer(object):
- """
- Straightforward REST server.
-
- Supports custom handling of all HTTP verbs, with special (optional) support for JSON, as well
- as serving straightforward static files via GET.
-
- Properties:
-
- * :code:`configuration`: An optional configuration object
- * :code:`port`: HTTP server port
- * :code:`routes`: :class:`OrderedDict` of routes (see below)
- * :code:`static_root`: Root directory for static files
- * :code:`json_encoder`: :class:`JSONEncoder` for responses
- * :code:`json_decoder`: :class:`JSONDecoder` for requests
- * :code:`unicode`: True to support Unicode
-
- The route keys are regular expressions for matching the path. They are checked in order, which
- is why it's important to use :class:`OrderedDict`.
-
- The route values are dicts with the following optional fields:
-
- * :code:`GET`: Function to handle GET for this route
- * :code:`PUT`: Function to handle PUT for this route
- * :code:`POST`: Function to handle POST for this route
- * :code:`DELETE`: Function to handle DELETE for this route
- * :code:`file`: Attach a static file to this route; it is the path to
- the file to return relative to :code:`static_root` (if :code:`file` is
- set then :code:`GET`/:code:`PUT`/:code:`POST`/:code:`DELETE` are ignored)
- * :code:`media_type`: Media type to set for responses to this
- route (except error message, which will be in "text/plan")
-
- The :code:`GET`/:code:`PUT`/:code:`POST`/:code:`DELETE` handler functions all receive a single
- argument: an instance of :class:`RestRequestHandler`.
-
- If you return None, then a 404 error will be generated. Otherwise, it will be a 200 response
- with the return value will be written to it. If the :code:`media_type` for the route was set to
- "application/json", then the return value will first be encoded into JSON using the configured
- :code:`json_encoder`.
-
- If you want to write the response yourself, set :code:`handled=True` on the
- :class:`RestRequestHandler`, which will cause the return value to be ignored (you won't have to
- return anything). If all you want to do is send an error message, then use
- :code:`send_plain_text_response`.
-
- If you raise an (uncaught) exception, then a 500 error will be generated with the exception
- message.
-
- To get the payload (for :code:`PUT`/:code:`POST`) use :code:`payload` on the
- :class:`RestRequestHandler` for plain text, or :code:`json_payload` to use the configured
- :code:`json_decoder`. Note that it's up to you to check for JSON decoding exceptions and return
- an appropriate 400 error message.
- """
-
- def __init__(self):
- self.configuration = None
- self.port = 8080
- self.routes = OrderedDict()
- self.static_root = '.'
- self.json_encoder = json.JSONEncoder(ensure_ascii=False, separators=(',', ':'))
- self.json_decoder = json.JSONDecoder(object_pairs_hook=OrderedDict)
- self.unicode = True
-
- def start(self, daemon=False):
- """
- Starts the REST server.
- """
-
- if self.unicode:
- # Fixes issues with decoding HTTP responses
- # (Not such a great solution! But there doesn't seem to be a better way)
- reload(sys)
- sys.setdefaultencoding('utf8') # @UndefinedVariable
-
- http_server = BaseHTTPServer.HTTPServer(('', self.port), rest_request_handler(self))
- if daemon:
- print 'Running HTTP server daemon at port %d' % self.port
- else:
- puts(Colored.red('Running HTTP server at port %d, use CTRL-C to exit' % self.port))
- try:
- http_server.serve_forever()
- except KeyboardInterrupt:
- pass
- puts(Colored.red('Stopping HTTP server'))
- http_server.server_close()
-
-class RestRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
- """
- Handler for :class:`RestServer`.
- """
-
- def __init__(self, rest_server, *args, **kwargs):
- self.rest_server = rest_server
- self.handled = False
- self.matched_re = None
- self.matched_route = None
- # Old-style Python classes don't support super
- BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, *args, **kwargs)
-
- @property
- def content_length(self):
- return int(self.headers.getheader('content-length', 0))
-
- @property
- def payload(self):
- return self.rfile.read(self.content_length)
-
- @property
- def json_payload(self):
- return self.rest_server.json_decoder.decode(self.payload)
-
- def match_route(self):
- for path_re, route in self.rest_server.routes.iteritems():
- if re.match(path_re, self.path):
- return path_re, route
- return None, None
-
- def send_plain_text_response(self, status, content):
- self.send_response(status)
- self.send_header('Content-type', 'text/plain')
- self.end_headers()
- self.wfile.write(content)
- self.handled = True
-
- def send_content_type(self, route=None):
- if route is None:
- _, route = self.match_route()
- media_type = route.get('media_type')
- if media_type is not None:
- self.send_header('Content-type', media_type)
- return media_type
-
- def _handle_file(self, method):
- if method != 'GET':
- self.send_plain_text_response(405, '%s is not supported\n' % method)
- return
-
- try:
- matched_route_file = open(os.path.join(
- self.rest_server.static_root,
- self.matched_route['file']))
- try:
- self.send_response(200)
- self.send_content_type(self.matched_route)
- self.end_headers()
- shutil.copyfileobj(matched_route_file, self.wfile)
- finally:
- matched_route_file.close()
- except IOError:
- self.send_plain_text_response(404, 'Not found\n')
- return
-
- def handle_method(self, method):
- # pylint: disable=too-many-return-statements
- self.matched_re, self.matched_route = self.match_route()
-
- if self.matched_route is None:
- self.send_plain_text_response(404, 'Not found\n')
- return
-
- if method == 'HEAD':
- self.send_response(200)
- self.send_content_type(self.matched_route)
- self.end_headers()
- return
-
- if 'file' in self.matched_route:
- self._handle_file(method)
- return
-
- if method not in self.matched_route:
- self.send_plain_text_response(405, '%s is not supported\n' % method)
- return
-
- try:
- content = self.matched_route[method](self)
- except Exception as e:
- self.send_plain_text_response(500, 'Internal error: %s\n' % e)
- return
-
- if self.handled:
- return
-
- if content is None:
- self.send_plain_text_response(404, 'Not found\n')
- return
-
- self.send_response(200)
- media_type = self.send_content_type(self.matched_route)
- self.end_headers()
-
- if method == 'DELETE':
- # No content for DELETE
- return
-
- if media_type == 'application/json':
- self.wfile.write(self.rest_server.json_encoder.encode(content))
- else:
- self.wfile.write(content)
-
- # BaseHTTPRequestHandler
- # pylint: disable=invalid-name
- def do_HEAD(self):
- self.handle_method('HEAD')
-
- def do_GET(self):
- self.handle_method('GET')
-
- def do_POST(self):
- self.handle_method('POST')
-
- def do_PUT(self):
- self.handle_method('PUT')
-
- def do_DELETE(self):
- self.handle_method('DELETE')
-
-#
-# Utils
-#
-
-def rest_request_handler(rest_server):
- return lambda *args, **kwargs: RestRequestHandler(rest_server, *args, **kwargs)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/utils/threading.py
----------------------------------------------------------------------
diff --git a/aria/parser/utils/threading.py b/aria/parser/utils/threading.py
deleted file mode 100644
index 575d011..0000000
--- a/aria/parser/utils/threading.py
+++ /dev/null
@@ -1,252 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 __future__ import absolute_import # so we can import standard 'threading'
-
-import itertools
-import multiprocessing
-from threading import (Thread, Lock)
-from Queue import (Queue, Full, Empty)
-
-from .exceptions import print_exception
-
-class ExecutorException(Exception):
- pass
-
-class DaemonThread(Thread):
- def __init__(self, *args, **kwargs):
- super(DaemonThread, self).__init__(*args, **kwargs)
- self.daemon = True
-
- def run(self):
- """
- We're overriding `Thread.run` in order to avoid annoying (but harmless) error
- messages during shutdown. The problem is that CPython nullifies the
- global state _before_ shutting down daemon threads, so that exceptions
- might happen, and then `Thread.__bootstrap_inner` prints them out.
-
- Our solution is to swallow these exceptions here.
-
- The side effect is that uncaught exceptions in our own thread code will _not_
- be printed out as usual, so it's our responsibility to catch them in our
- code.
- """
-
- try:
- super(DaemonThread, self).run()
- except SystemExit as e:
- # This exception should be bubbled up
- raise e
- except BaseException:
- # Exceptions might occur in daemon threads during interpreter shutdown
- pass
-
-# https://gist.github.com/tliron/81dd915166b0bfc64be08b4f8e22c835
-class FixedThreadPoolExecutor(object):
- """
- Executes tasks in a fixed thread pool.
-
- Makes sure to gather all returned results and thrown exceptions in one place, in order of task
- submission.
-
- Example::
-
- def sum(arg1, arg2):
- return arg1 + arg2
-
- executor = FixedThreadPoolExecutor(10)
- try:
- for value in range(100):
- executor.submit(sum, value, value)
- executor.drain()
- except:
- executor.close()
- executor.raise_first()
- print executor.returns
-
- You can also use it with the Python "with" keyword, in which case you don't need to call "close"
- explicitly::
-
- with FixedThreadPoolExecutor(10) as executor:
- for value in range(100):
- executor.submit(sum, value, value)
- executor.drain()
- executor.raise_first()
- print executor.returns
- """
-
- _CYANIDE = object() # Special task marker used to kill worker threads.
-
- def __init__(self,
- size=multiprocessing.cpu_count() * 2 + 1,
- timeout=None,
- print_exceptions=False):
- """
- :param size: Number of threads in the pool (fixed).
- :param timeout: Timeout in seconds for all
- blocking operations. (Defaults to none, meaning no timeout)
- :param print_exceptions: Set to true in order to
- print exceptions from tasks. (Defaults to false)
- """
-
- self.size = size
- self.timeout = timeout
- self.print_exceptions = print_exceptions
-
- self._tasks = Queue()
- self._returns = {}
- self._exceptions = {}
- self._id_creator = itertools.count()
- self._lock = Lock() # for console output
-
- self._workers = []
- for index in range(size):
- worker = DaemonThread(
- name='%s%d' % (self.__class__.__name__, index),
- target=self._thread_worker)
- worker.start()
- self._workers.append(worker)
-
- def submit(self, func, *args, **kwargs):
- """
- Submit a task for execution.
-
- The task will be called ASAP on the next available worker thread in the pool.
-
- Will raise an :class:`ExecutorException` exception if cannot be submitted.
- """
-
- try:
- self._tasks.put((self._id_creator.next(), func, args, kwargs), timeout=self.timeout)
- except Full:
- raise ExecutorException('cannot submit task: queue is full')
-
- def close(self):
- """
- Blocks until all current tasks finish execution and all worker threads are dead.
-
- You cannot submit tasks anymore after calling this.
-
- This is called automatically upon exit if you are using the "with" keyword.
- """
-
- self.drain()
- while self.is_alive:
- try:
- self._tasks.put(self._CYANIDE, timeout=self.timeout)
- except Full:
- raise ExecutorException('cannot close executor: a thread seems to be hanging')
- self._workers = None
-
- def drain(self):
- """
- Blocks until all current tasks finish execution, but leaves the worker threads alive.
- """
-
- self._tasks.join() # oddly, the API does not support a timeout parameter
-
- @property
- def is_alive(self):
- """
- True if any of the worker threads are alive.
- """
-
- for worker in self._workers:
- if worker.is_alive():
- return True
- return False
-
- @property
- def returns(self):
- """
- The returned values from all tasks, in order of submission.
- """
-
- return [self._returns[k] for k in sorted(self._returns)]
-
- @property
- def exceptions(self):
- """
- The raised exceptions from all tasks, in order of submission.
- """
-
- return [self._exceptions[k] for k in sorted(self._exceptions)]
-
- def raise_first(self):
- """
- If exceptions were thrown by any task, then the first one will be raised.
-
- This is rather arbitrary: proper handling would involve iterating all the
- exceptions. However, if you want to use the "raise" mechanism, you are
- limited to raising only one of them.
- """
-
- exceptions = self.exceptions
- if exceptions:
- raise exceptions[0]
-
- def _thread_worker(self):
- while True:
- if not self._execute_next_task():
- break
-
- def _execute_next_task(self):
- try:
- task = self._tasks.get(timeout=self.timeout)
- except Empty:
- # Happens if timeout is reached
- return True
- if task == self._CYANIDE:
- # Time to die :(
- return False
- self._execute_task(*task)
- return True
-
- def _execute_task(self, task_id, func, args, kwargs):
- try:
- result = func(*args, **kwargs)
- self._returns[task_id] = result
- except Exception as e:
- self._exceptions[task_id] = e
- if self.print_exceptions:
- with self._lock:
- print_exception(e)
- self._tasks.task_done()
-
- def __enter__(self):
- return self
-
- def __exit__(self, the_type, value, traceback):
- self.close()
- return False
-
-class LockedList(list):
- """
- A list that supports the "with" keyword with a built-in lock.
-
- Though Python lists are thread-safe in that they will not raise exceptions
- during concurrent access, they do not guarantee atomicity. This class will
- let you gain atomicity when needed.
- """
-
- def __init__(self, *args, **kwargs):
- super(LockedList, self).__init__(*args, **kwargs)
- self.lock = Lock()
-
- def __enter__(self):
- return self.lock.__enter__()
-
- def __exit__(self, the_type, value, traceback):
- return self.lock.__exit__(the_type, value, traceback)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/utils/uris.py
----------------------------------------------------------------------
diff --git a/aria/parser/utils/uris.py b/aria/parser/utils/uris.py
deleted file mode 100644
index 1686517..0000000
--- a/aria/parser/utils/uris.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 os
-import urlparse
-
-def as_file(uri):
- """
- If the URI is a file (either the :code:`file` scheme or no scheme), then returns the absolute
- path. Otherwise, returns None.
- """
-
- url = urlparse.urlparse(uri)
- if (not url.scheme) or (url.scheme == 'file'):
- return os.path.abspath(url.path)
- return None
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/validation/context.py
----------------------------------------------------------------------
diff --git a/aria/parser/validation/context.py b/aria/parser/validation/context.py
index e0355e3..d81f1cd 100644
--- a/aria/parser/validation/context.py
+++ b/aria/parser/validation/context.py
@@ -14,7 +14,12 @@
# limitations under the License.
from .issue import Issue
-from ..utils import (LockedList, FrozenList, print_exception, puts, Colored, indent, as_raw)
+from ...utils.threading import LockedList
+from ...utils.collections import FrozenList
+from ...utils.exceptions import print_exception
+from ...utils.console import puts, Colored, indent
+from ...utils.formatting import as_raw
+
class ValidationContext(object):
"""
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/validation/issue.py
----------------------------------------------------------------------
diff --git a/aria/parser/validation/issue.py b/aria/parser/validation/issue.py
index 7c73b1c..f001efc 100644
--- a/aria/parser/validation/issue.py
+++ b/aria/parser/validation/issue.py
@@ -15,11 +15,9 @@
from __future__ import absolute_import # so we can import standard 'collections'
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
-from ..utils import full_type_name
+from ...utils.collections import OrderedDict
+from ...utils.formatting import full_type_name
+
class Issue(object):
PLATFORM = 0
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/storage/structures.py
----------------------------------------------------------------------
diff --git a/aria/storage/structures.py b/aria/storage/structures.py
index a833d99..b02366e 100644
--- a/aria/storage/structures.py
+++ b/aria/storage/structures.py
@@ -32,7 +32,7 @@ from uuid import uuid4
from .exceptions import StorageError
from ..logger import LoggerMixin
-from ..tools.validation import ValidatorMixin
+from ..utils.validation import ValidatorMixin
__all__ = (
'uuid_generator',
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/tools/__init__.py
----------------------------------------------------------------------
diff --git a/aria/tools/__init__.py b/aria/tools/__init__.py
deleted file mode 100644
index 320b445..0000000
--- a/aria/tools/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 .lru_cache import lru_cache
-from .module import load_attribute
-from .plugin import plugin_installer
-from .process import Process
-from .validation import validate_function_arguments, ValidatorMixin
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/tools/application.py
----------------------------------------------------------------------
diff --git a/aria/tools/application.py b/aria/tools/application.py
deleted file mode 100644
index b1a7fcc..0000000
--- a/aria/tools/application.py
+++ /dev/null
@@ -1,294 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Convenience storage related tools.
-# TODO rename module name
-"""
-
-import json
-import os
-import shutil
-import tarfile
-import tempfile
-from datetime import datetime
-
-from aria.storage.exceptions import StorageError
-from aria.logger import LoggerMixin
-
-
-class StorageManager(LoggerMixin):
- """
- Convenience wrapper to simplify work with the lower level storage mechanism
- """
-
- def __init__(
- self,
- model_storage,
- resource_storage,
- blueprint_path,
- blueprint_id,
- blueprint_plan,
- deployment_id,
- deployment_plan,
- **kwargs):
- super(StorageManager, self).__init__(**kwargs)
- self.model_storage = model_storage
- self.resource_storage = resource_storage
- self.blueprint_path = blueprint_path
- self.blueprint_id = blueprint_id
- self.blueprint_plan = blueprint_plan
- self.deployment_id = deployment_id
- self.deployment_plan = deployment_plan
-
- @classmethod
- def from_deployment(
- cls,
- model_storage,
- resource_storage,
- deployment_id,
- deployment_plan):
- """
- Create a StorageManager from a deployment
- """
- return cls(
- model_storage=model_storage,
- resource_storage=resource_storage,
- deployment_id=deployment_id,
- deployment_plan=deployment_plan,
- blueprint_path=None,
- blueprint_plan=None,
- blueprint_id=None
- )
-
- @classmethod
- def from_blueprint(
- cls,
- model_storage,
- resource_storage,
- blueprint_path,
- blueprint_id,
- blueprint_plan):
- """
- Create a StorageManager from a blueprint
- """
- return cls(
- model_storage=model_storage,
- resource_storage=resource_storage,
- blueprint_path=blueprint_path,
- blueprint_plan=blueprint_plan,
- blueprint_id=blueprint_id,
- deployment_id=None,
- deployment_plan=None)
-
- def create_blueprint_storage(self, source, main_file_name=None):
- """
- create blueprint model & resource
- """
- assert self.blueprint_path and self.blueprint_id
- assert hasattr(self.resource_storage, 'blueprint')
- assert hasattr(self.model_storage, 'blueprint')
-
- self.logger.debug('creating blueprint resource storage entry')
- self.resource_storage.blueprint.upload(
- entry_id=self.blueprint_id,
- source=os.path.dirname(source))
- self.logger.debug('created blueprint resource storage entry')
-
- self.logger.debug('creating blueprint model storage entry')
- now = datetime.utcnow()
- blueprint = self.model_storage.blueprint.model_cls(
- plan=self.blueprint_plan,
- id=self.blueprint_id,
- description=self.blueprint_plan.get('description'),
- created_at=now,
- updated_at=now,
- main_file_name=main_file_name,
- )
- self.model_storage.blueprint.store(blueprint)
- self.logger.debug('created blueprint model storage entry')
-
- def create_nodes_storage(self):
- """
- create nodes model
- """
- assert self.blueprint_path and self.blueprint_id
- assert hasattr(self.model_storage, 'node')
- assert hasattr(self.model_storage, 'relationship')
-
- for node in self.blueprint_plan['nodes']:
- node_copy = node.copy()
- for field in ('name',
- 'deployment_plugins_to_install',
- 'interfaces',
- 'instances'):
- node_copy.pop(field)
- scalable = node_copy.pop('capabilities')['scalable']['properties']
- for index, relationship in enumerate(node_copy['relationships']):
- relationship = self.model_storage.relationship.model_cls(**relationship)
- self.model_storage.relationship.store(relationship)
- node_copy['relationships'][index] = relationship
-
- node_copy = self.model_storage.node.model_cls(
- blueprint_id=self.blueprint_id,
- planned_number_of_instances=scalable['current_instances'],
- deploy_number_of_instances=scalable['default_instances'],
- min_number_of_instances=scalable['min_instances'],
- max_number_of_instances=scalable['max_instances'],
- number_of_instances=scalable['current_instances'],
- **node_copy)
- self.model_storage.node.store(node_copy)
-
- def create_deployment_storage(self):
- """
- create deployment model & resource
- """
- assert self.deployment_id and self.deployment_plan
-
- assert hasattr(self.resource_storage, 'blueprint')
- assert hasattr(self.resource_storage, 'deployment')
- assert hasattr(self.model_storage, 'deployment')
-
- self.logger.debug('creating deployment resource storage entry')
- temp_dir = tempfile.mkdtemp()
- try:
- self.resource_storage.blueprint.download(
- entry_id=self.blueprint_id,
- destination=temp_dir)
- self.resource_storage.deployment.upload(
- entry_id=self.deployment_id,
- source=temp_dir)
- finally:
- shutil.rmtree(temp_dir, ignore_errors=True)
- self.logger.debug('created deployment resource storage entry')
-
- self.logger.debug('creating deployment model storage entry')
- now = datetime.utcnow()
- deployment = self.model_storage.deployment.model_cls(
- id=self.deployment_id,
- blueprint_id=self.blueprint_id,
- description=self.deployment_plan['description'],
- workflows=self.deployment_plan['workflows'],
- inputs=self.deployment_plan['inputs'],
- policy_types=self.deployment_plan['policy_types'],
- policy_triggers=self.deployment_plan['policy_triggers'],
- groups=self.deployment_plan['groups'],
- scaling_groups=self.deployment_plan['scaling_groups'],
- outputs=self.deployment_plan['outputs'],
- created_at=now,
- updated_at=now
- )
- self.model_storage.deployment.store(deployment)
- self.logger.debug('created deployment model storage entry')
-
- def create_node_instances_storage(self):
- """
- create node_instances model
- """
- assert self.deployment_id and self.deployment_plan
- assert hasattr(self.model_storage, 'node_instance')
- assert hasattr(self.model_storage, 'relationship_instance')
-
- self.logger.debug('creating node-instances model storage entries')
- for node_instance in self.deployment_plan['node_instances']:
- node_model = self.model_storage.node.get(node_instance['node_id'])
- relationship_instances = []
-
- for index, relationship_instance in enumerate(node_instance['relationships']):
- relationship_instance_model = self.model_storage.relationship_instance.model_cls(
- relationship=node_model.relationships[index],
- target_name=relationship_instance['target_name'],
- type=relationship_instance['type'],
- target_id=relationship_instance['target_id'])
- relationship_instances.append(relationship_instance_model)
- self.model_storage.relationship_instance.store(relationship_instance_model)
-
- node_instance_model = self.model_storage.node_instance.model_cls(
- node=node_model,
- id=node_instance['id'],
- runtime_properties={},
- state=self.model_storage.node_instance.model_cls.UNINITIALIZED,
- deployment_id=self.deployment_id,
- version='1.0',
- relationship_instances=relationship_instances)
-
- self.model_storage.node_instance.store(node_instance_model)
- self.logger.debug('created node-instances model storage entries')
-
- def create_plugin_storage(self, plugin_id, source):
- """
- create plugin model & resource
- """
- assert hasattr(self.model_storage, 'plugin')
- assert hasattr(self.resource_storage, 'plugin')
-
- self.logger.debug('creating plugin resource storage entry')
- self.resource_storage.plugin.upload(entry_id=plugin_id, source=source)
- self.logger.debug('created plugin resource storage entry')
-
- self.logger.debug('creating plugin model storage entry')
- plugin = _load_plugin_from_archive(source)
- build_props = plugin.get('build_server_os_properties')
- now = datetime.utcnow()
-
- plugin = self.model_storage.plugin.model_cls(
- id=plugin_id,
- package_name=plugin.get('package_name'),
- package_version=plugin.get('package_version'),
- archive_name=plugin.get('archive_name'),
- package_source=plugin.get('package_source'),
- supported_platform=plugin.get('supported_platform'),
- distribution=build_props.get('distribution'),
- distribution_version=build_props.get('distribution_version'),
- distribution_release=build_props.get('distribution_release'),
- wheels=plugin.get('wheels'),
- excluded_wheels=plugin.get('excluded_wheels'),
- supported_py_versions=plugin.get('supported_python_versions'),
- uploaded_at=now
- )
- self.model_storage.plugin.store(plugin)
- self.logger.debug('created plugin model storage entry')
-
-
-def _load_plugin_from_archive(tar_source):
- if not tarfile.is_tarfile(tar_source):
- # TODO: go over the exceptions
- raise StorageError(
- 'the provided tar archive can not be read.')
-
- with tarfile.open(tar_source) as tar:
- tar_members = tar.getmembers()
- # a wheel plugin will contain exactly one sub directory
- if not tar_members:
- raise StorageError(
- 'archive file structure malformed. expecting exactly one '
- 'sub directory; got none.')
- package_json_path = os.path.join(tar_members[0].name,
- 'package.json')
- try:
- package_member = tar.getmember(package_json_path)
- except KeyError:
- raise StorageError("'package.json' was not found under {0}"
- .format(package_json_path))
- try:
- package_json = tar.extractfile(package_member)
- except tarfile.ExtractError as e:
- raise StorageError(str(e))
- try:
- return json.load(package_json)
- except ValueError as e:
- raise StorageError("'package.json' is not a valid json: "
- "{json_str}. error is {error}"
- .format(json_str=package_json.read(), error=str(e)))
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/tools/lru_cache.py
----------------------------------------------------------------------
diff --git a/aria/tools/lru_cache.py b/aria/tools/lru_cache.py
deleted file mode 100755
index bb39b90..0000000
--- a/aria/tools/lru_cache.py
+++ /dev/null
@@ -1,136 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Function lru_cache implementation for python 2.7
-(In Python 3 this decorator is in functools)
-"""
-
-from time import time
-from functools import partial, wraps
-from itertools import imap
-
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
-
-
-class _LRUCache(object):
-
- def __init__(self, input_func, max_size, timeout):
- self._input_func = input_func
- self._max_size = max_size
- self._timeout = timeout
-
- # This will store the cache for this function, format:
- # {caller1 : [OrderedDict1, last_refresh_time1],
- # caller2 : [OrderedDict2, last_refresh_time2]}.
- # In case of an instance method -
- # the caller is the instance,
- # in case called from a regular function - the caller is None.
- self._caches_dict = {}
-
- @staticmethod
- def _prepare_key(*args, **kwargs):
- kwargs_key = "".join(
- imap(lambda x: str(x) + str(type(kwargs[x])) + str(kwargs[x]),
- sorted(kwargs)))
- return "".join(imap(lambda x: str(type(x)) + str(x), args)) + kwargs_key
-
- def cache_clear(self, caller=None):
- """
- Clears the cache, optionally, only for a specific caller
- """
- # Remove the cache for the caller, only if exists:
- if caller in self._caches_dict:
- del self._caches_dict[caller]
- self._caches_dict[caller] = (OrderedDict(), time())
-
- def __get__(self, obj, _):
- """ Called for instance methods """
- return_func = partial(self._cache_wrapper, obj)
- return_func.cache_clear = partial(self.cache_clear, obj)
- # Return the wrapped function and wraps it to maintain the docstring
- # and the name of the original function:
- return wraps(self._input_func)(return_func)
-
- def __call__(self, *args, **kwargs):
- """ Called for regular functions """
- return self._cache_wrapper(None, *args, **kwargs)
- # Set the cache_clear function in the __call__ operator:
- __call__.cache_clear = cache_clear
-
- def _cache_wrapper(self, caller, *args, **kwargs):
- # Create a unique key including the types
- # (in order to differentiate between 1 and '1'):
- key = self._prepare_key(*args, **kwargs)
-
- # Check if caller exists, if not create one:
- if caller not in self._caches_dict:
- self._caches_dict[caller] = (OrderedDict(), time())
- else:
- # Validate in case the refresh time has passed:
- if self._timeout is not None and time() - self._caches_dict[caller][1] > self._timeout:
- self.cache_clear(caller)
-
- # Check if the key exists, if so - return it:
- cur_caller_cache_dict = self._caches_dict[caller][0]
- if key in cur_caller_cache_dict:
- return cur_caller_cache_dict[key]
-
- # Validate we didn't exceed the max_size:
- if len(cur_caller_cache_dict) >= self._max_size:
- # Delete the first item in the dict:
- cur_caller_cache_dict.popitem(False)
-
- # Call the function and store the data in the cache
- # (call it with the caller in case it's an instance function - Ternary condition):
- cur_caller_cache_dict[key] = self._input_func(caller, *args, **kwargs) \
- if caller is not None else self._input_func(*args, **kwargs)
- return cur_caller_cache_dict[key]
-
-
-def lru_cache(maxsize=255, timeout=None):
- """
- lru_cache(maxsize = 255, timeout = None)
- Returns a decorator which returns an instance (a descriptor).
-
- Purpose:
- This decorator factory will wrap a function / instance method,
- and will supply a caching mechanism to the function.
- For every given input params it will store the result in a queue of maxsize size,
- and will return a cached ret_val if the same parameters are passed.
-
- Notes:
- * If an instance method is wrapped,
- each instance will have it's own cache and it's own timeout.
- * The wrapped function will have a cache_clear variable inserted into it,
- and may be called to clear it's specific cache.
- * The wrapped function will maintain the original function's docstring and name (wraps)
- * The type of the wrapped function will no longer be that of a function,
- but either an instance of _LRU_Cache_class or a functool.partial type.
-
- :param maxsize: The cache size limit,
- Anything added above that will delete the first values enterred (FIFO).
- This size is per instance, thus 1000 instances with maxsize of 255,
- will contain at max 255K elements.
- :type maxsize: int
- :param timeout: Every n seconds the cache is deleted, regardless of usage.
- If None - cache will never be refreshed.
- :type: timeout: int, float, None
-
- """
- return lambda input_func: wraps(input_func)(_LRUCache(input_func, maxsize, timeout))
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/tools/module.py
----------------------------------------------------------------------
diff --git a/aria/tools/module.py b/aria/tools/module.py
deleted file mode 100644
index 3afc0ff..0000000
--- a/aria/tools/module.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Utility methods for dynamically loading python code
-"""
-
-import importlib
-
-
-def load_attribute(attribute_path):
- """
- Dynamically load an attribute based on the path to it.
- e.g. some_package.some_module.some_attribute, will load the some_attribute from the
- some_package.some_module module
- """
- module_name, attribute_name = attribute_path.rsplit('.', 1)
- try:
- module = importlib.import_module(module_name)
- return getattr(module, attribute_name)
- except ImportError:
- # TODO: handle
- raise
- except AttributeError:
- # TODO: handle
- raise
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/tools/plugin.py
----------------------------------------------------------------------
diff --git a/aria/tools/plugin.py b/aria/tools/plugin.py
deleted file mode 100644
index bb2b974..0000000
--- a/aria/tools/plugin.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Contains utility methods that enable dynamic python code loading
-# TODO: merge with tools.module
-"""
-
-import os
-from importlib import import_module
-
-
-def plugin_installer(path, plugin_suffix, package=None, callback=None):
- """
- Load each module under ``path`` that ends with ``plugin_suffix``. If ``callback`` is supplied,
- call it with each loaded module.
- """
- assert callback is None or callable(callback)
- plugin_suffix = '{0}.py'.format(plugin_suffix)
-
- for file_name in os.listdir(path):
- if not file_name.endswith(plugin_suffix):
- continue
- module_name = '{0}.{1}'.format(package, file_name[:-3]) if package else file_name[:-3]
- module = import_module(module_name)
- if callback:
- callback(module)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/tools/process.py
----------------------------------------------------------------------
diff --git a/aria/tools/process.py b/aria/tools/process.py
deleted file mode 100644
index b9586b6..0000000
--- a/aria/tools/process.py
+++ /dev/null
@@ -1,186 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Subprocess utility methods
-"""
-
-import os
-import subprocess
-from signal import SIGKILL
-from time import sleep
-
-from aria.logger import LoggerMixin
-from aria.orchestrator.workflows.exceptions import ExecutorException, ProcessException
-
-
-class Process(LoggerMixin):
- """
- Subprocess wrapper
- """
-
- def __init__(
- self,
- args,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- cwd=None,
- env=None,
- **kwargs):
- """
- Subprocess wrapper
- """
- super(Process, self).__init__(**kwargs)
- self.args = args
- self.cwd = cwd
- self.env = env
- self.process = None
- self._stdout = stdout
- self._stderr = stderr
-
- def __repr__(self):
- return '{cls.__name__}(args={self.args}, cwd={self.cwd})'.format(
- cls=self.__class__, self=self)
-
- def __getattr__(self, item):
- return getattr(self.process, item)
-
- @property
- def name(self):
- """
- The process name
- """
- return self.args[0]
-
- @property
- def pid(self):
- """
- The process pid (if running)
- """
- if self.is_running():
- return self.process.pid
-
- @property
- def stdout(self):
- """
- The process stdout
- """
- assert self.process, 'Need to run before calling this method'
- return self.process.stdout
-
- @property
- def stderr(self):
- """
- The process stderr
- """
- assert self.process, 'Need to run before calling this method'
- return self.process.stderr
-
- @property
- def return_code(self):
- """
- The process return code. Will wait for process to end if it hasn't already
- """
- if self.process is None:
- return None
- if self.is_running():
- raise ExecutorException(
- 'Can not get return code while process is still running')
- if self.process.returncode is None:
- self.wait()
- return self.process.returncode
-
- def terminate(self):
- """
- Terminates the process by sending a SIGTERM to it. If the process did not stop after that,
- sends a SIGKILL with 1 second interval for a maximum of 10 times.
- """
- if self.process is not None and self.process.poll() is None:
- self.logger.debug('terminating process {0:d} ({1})'.format(self.process.pid, self.name))
- self.process.terminate()
- sleep(1)
- kill_attempts = 0
- while self.process is not None and self.process.poll() is None and kill_attempts < 10:
- self.logger.debug('trying to kill process {0:d}'.format(self.process.pid))
- self.process.kill()
- sleep(1)
- kill_attempts += 1
-
- def kill(self):
- """
- Kill the process by sending a SIGKILL to it
- """
- if self.is_running():
- os.killpg(os.getpgid(self.pid), SIGKILL)
-
- def is_running(self):
- """
- Returns ``True`` if the process is currently running
- """
- return self.process.poll() is None if self.process else False
-
- def wait(self):
- """
- Block until process finishes
- """
- assert self.process, 'Need to run before calling thie method'
- self.process.wait()
-
- def run(self, nice=None, universal_newlines=True):
- """
- Run the child process. This call does not block.
- """
- self.logger.debug('Running child process: {0}'.format(' '.join(self.args)))
- self.process = subprocess.Popen(
- self.args,
- cwd=self.cwd,
- env=self.env,
- stdout=self._stdout,
- stderr=self._stderr,
- close_fds=os.name != 'nt',
- preexec_fn=lambda: os.nice(nice) if nice else None,
- universal_newlines=universal_newlines)
-
- def run_in_shell(self, nice=None, universal_newlines=True):
- """
- Run the child process in a shell. This call does not block.
- """
- command = ' '.join(self.args)
- self.logger.debug('Running child process in shell: {0}'.format(command))
- self.process = subprocess.Popen(
- command,
- shell=True,
- cwd=self.cwd,
- env=self.env,
- stdout=self._stdout,
- stderr=self._stderr,
- close_fds=os.name != 'nt',
- preexec_fn=lambda: os.nice(nice) if nice else None,
- universal_newlines=universal_newlines)
-
- def raise_failure(self):
- """
- Raise a ProcessException if the process terminated with a non zero return code. Will wait
- for the process to finish if it hasn't already
- """
- if self.is_running():
- self.wait()
- if self.return_code == 0:
- return
- raise ProcessException(
- command=self.args,
- stderr=self.stderr.read(),
- stdout=self.stdout.read(),
- return_code=self.return_code)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/tools/validation.py
----------------------------------------------------------------------
diff --git a/aria/tools/validation.py b/aria/tools/validation.py
deleted file mode 100644
index a33f7a2..0000000
--- a/aria/tools/validation.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-"""
-Contains validation related utilities
-"""
-
-
-class ValidatorMixin(object):
- """
- A mixin that should be added to classes that require validating user input
- """
-
- _ARGUMENT_TYPE_MESSAGE = '{name} argument must be {type} based, got {arg!r}'
- _ARGUMENT_CHOICE_MESSAGE = '{name} argument must be in {choices}, got {arg!r}'
-
- @classmethod
- def validate_in_choice(cls, name, argument, choices):
- """
- Validate ``argument`` is in ``choices``
- """
- if argument not in choices:
- raise TypeError(cls._ARGUMENT_CHOICE_MESSAGE.format(
- name=name, choices=choices, arg=argument))
-
- @classmethod
- def validate_type(cls, argument_name, argument, expected_type):
- """
- Validate ``argument`` is a subclass of ``expected_type``
- """
- if not issubclass(argument, expected_type):
- raise TypeError(cls._ARGUMENT_TYPE_MESSAGE.format(
- name=argument_name, type=expected_type, arg=argument))
-
- @classmethod
- def validate_instance(cls, argument_name, argument, expected_type):
- """
- Validate ``argument`` is a instance of ``expected_type``
- """
- if not isinstance(argument, expected_type):
- raise TypeError(cls._ARGUMENT_TYPE_MESSAGE.format(
- name=argument_name, type=expected_type, arg=argument))
-
- @classmethod
- def validate_callable(cls, argument_name, argument):
- """
- Validate ``argument`` is callable
- """
- if not callable(argument):
- raise TypeError(cls._ARGUMENT_TYPE_MESSAGE.format(
- name=argument_name, type='callable', arg=argument))
-
-
-def validate_function_arguments(func, func_kwargs):
- """
- Validates all required arguments are supplied to ``func`` and that no additional arguments are
- supplied
- """
-
- _kwargs_flags = 8
-
- has_kwargs = func.func_code.co_flags & _kwargs_flags != 0
- args_count = func.func_code.co_argcount
-
- # all args without the ones with default values
- args = func.func_code.co_varnames[:args_count]
- non_default_args = args[:len(func.func_defaults)] if func.func_defaults else args
-
- # Check if any args without default values is missing in the func_kwargs
- for arg in non_default_args:
- if arg not in func_kwargs:
- raise ValueError(
- "The argument '{arg}' doest not have a default value, and it "
- "isn't passed to {func.__name__}".format(arg=arg, func=func))
-
- # check if there are any extra kwargs
- extra_kwargs = [arg for arg in func_kwargs.keys() if arg not in args]
-
- # assert that the function has kwargs
- if extra_kwargs and not has_kwargs:
- raise ValueError("The following extra kwargs were supplied: {extra_kwargs}".format(
- extra_kwargs=extra_kwargs
- ))
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/utils/__init__.py
----------------------------------------------------------------------
diff --git a/aria/utils/__init__.py b/aria/utils/__init__.py
new file mode 100644
index 0000000..ae1e83e
--- /dev/null
+++ b/aria/utils/__init__.py
@@ -0,0 +1,14 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/utils/application.py
----------------------------------------------------------------------
diff --git a/aria/utils/application.py b/aria/utils/application.py
new file mode 100644
index 0000000..b1a7fcc
--- /dev/null
+++ b/aria/utils/application.py
@@ -0,0 +1,294 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+"""
+Convenience storage related tools.
+# TODO rename module name
+"""
+
+import json
+import os
+import shutil
+import tarfile
+import tempfile
+from datetime import datetime
+
+from aria.storage.exceptions import StorageError
+from aria.logger import LoggerMixin
+
+
+class StorageManager(LoggerMixin):
+ """
+ Convenience wrapper to simplify work with the lower level storage mechanism
+ """
+
+ def __init__(
+ self,
+ model_storage,
+ resource_storage,
+ blueprint_path,
+ blueprint_id,
+ blueprint_plan,
+ deployment_id,
+ deployment_plan,
+ **kwargs):
+ super(StorageManager, self).__init__(**kwargs)
+ self.model_storage = model_storage
+ self.resource_storage = resource_storage
+ self.blueprint_path = blueprint_path
+ self.blueprint_id = blueprint_id
+ self.blueprint_plan = blueprint_plan
+ self.deployment_id = deployment_id
+ self.deployment_plan = deployment_plan
+
+ @classmethod
+ def from_deployment(
+ cls,
+ model_storage,
+ resource_storage,
+ deployment_id,
+ deployment_plan):
+ """
+ Create a StorageManager from a deployment
+ """
+ return cls(
+ model_storage=model_storage,
+ resource_storage=resource_storage,
+ deployment_id=deployment_id,
+ deployment_plan=deployment_plan,
+ blueprint_path=None,
+ blueprint_plan=None,
+ blueprint_id=None
+ )
+
+ @classmethod
+ def from_blueprint(
+ cls,
+ model_storage,
+ resource_storage,
+ blueprint_path,
+ blueprint_id,
+ blueprint_plan):
+ """
+ Create a StorageManager from a blueprint
+ """
+ return cls(
+ model_storage=model_storage,
+ resource_storage=resource_storage,
+ blueprint_path=blueprint_path,
+ blueprint_plan=blueprint_plan,
+ blueprint_id=blueprint_id,
+ deployment_id=None,
+ deployment_plan=None)
+
+ def create_blueprint_storage(self, source, main_file_name=None):
+ """
+ create blueprint model & resource
+ """
+ assert self.blueprint_path and self.blueprint_id
+ assert hasattr(self.resource_storage, 'blueprint')
+ assert hasattr(self.model_storage, 'blueprint')
+
+ self.logger.debug('creating blueprint resource storage entry')
+ self.resource_storage.blueprint.upload(
+ entry_id=self.blueprint_id,
+ source=os.path.dirname(source))
+ self.logger.debug('created blueprint resource storage entry')
+
+ self.logger.debug('creating blueprint model storage entry')
+ now = datetime.utcnow()
+ blueprint = self.model_storage.blueprint.model_cls(
+ plan=self.blueprint_plan,
+ id=self.blueprint_id,
+ description=self.blueprint_plan.get('description'),
+ created_at=now,
+ updated_at=now,
+ main_file_name=main_file_name,
+ )
+ self.model_storage.blueprint.store(blueprint)
+ self.logger.debug('created blueprint model storage entry')
+
+ def create_nodes_storage(self):
+ """
+ create nodes model
+ """
+ assert self.blueprint_path and self.blueprint_id
+ assert hasattr(self.model_storage, 'node')
+ assert hasattr(self.model_storage, 'relationship')
+
+ for node in self.blueprint_plan['nodes']:
+ node_copy = node.copy()
+ for field in ('name',
+ 'deployment_plugins_to_install',
+ 'interfaces',
+ 'instances'):
+ node_copy.pop(field)
+ scalable = node_copy.pop('capabilities')['scalable']['properties']
+ for index, relationship in enumerate(node_copy['relationships']):
+ relationship = self.model_storage.relationship.model_cls(**relationship)
+ self.model_storage.relationship.store(relationship)
+ node_copy['relationships'][index] = relationship
+
+ node_copy = self.model_storage.node.model_cls(
+ blueprint_id=self.blueprint_id,
+ planned_number_of_instances=scalable['current_instances'],
+ deploy_number_of_instances=scalable['default_instances'],
+ min_number_of_instances=scalable['min_instances'],
+ max_number_of_instances=scalable['max_instances'],
+ number_of_instances=scalable['current_instances'],
+ **node_copy)
+ self.model_storage.node.store(node_copy)
+
+ def create_deployment_storage(self):
+ """
+ create deployment model & resource
+ """
+ assert self.deployment_id and self.deployment_plan
+
+ assert hasattr(self.resource_storage, 'blueprint')
+ assert hasattr(self.resource_storage, 'deployment')
+ assert hasattr(self.model_storage, 'deployment')
+
+ self.logger.debug('creating deployment resource storage entry')
+ temp_dir = tempfile.mkdtemp()
+ try:
+ self.resource_storage.blueprint.download(
+ entry_id=self.blueprint_id,
+ destination=temp_dir)
+ self.resource_storage.deployment.upload(
+ entry_id=self.deployment_id,
+ source=temp_dir)
+ finally:
+ shutil.rmtree(temp_dir, ignore_errors=True)
+ self.logger.debug('created deployment resource storage entry')
+
+ self.logger.debug('creating deployment model storage entry')
+ now = datetime.utcnow()
+ deployment = self.model_storage.deployment.model_cls(
+ id=self.deployment_id,
+ blueprint_id=self.blueprint_id,
+ description=self.deployment_plan['description'],
+ workflows=self.deployment_plan['workflows'],
+ inputs=self.deployment_plan['inputs'],
+ policy_types=self.deployment_plan['policy_types'],
+ policy_triggers=self.deployment_plan['policy_triggers'],
+ groups=self.deployment_plan['groups'],
+ scaling_groups=self.deployment_plan['scaling_groups'],
+ outputs=self.deployment_plan['outputs'],
+ created_at=now,
+ updated_at=now
+ )
+ self.model_storage.deployment.store(deployment)
+ self.logger.debug('created deployment model storage entry')
+
+ def create_node_instances_storage(self):
+ """
+ create node_instances model
+ """
+ assert self.deployment_id and self.deployment_plan
+ assert hasattr(self.model_storage, 'node_instance')
+ assert hasattr(self.model_storage, 'relationship_instance')
+
+ self.logger.debug('creating node-instances model storage entries')
+ for node_instance in self.deployment_plan['node_instances']:
+ node_model = self.model_storage.node.get(node_instance['node_id'])
+ relationship_instances = []
+
+ for index, relationship_instance in enumerate(node_instance['relationships']):
+ relationship_instance_model = self.model_storage.relationship_instance.model_cls(
+ relationship=node_model.relationships[index],
+ target_name=relationship_instance['target_name'],
+ type=relationship_instance['type'],
+ target_id=relationship_instance['target_id'])
+ relationship_instances.append(relationship_instance_model)
+ self.model_storage.relationship_instance.store(relationship_instance_model)
+
+ node_instance_model = self.model_storage.node_instance.model_cls(
+ node=node_model,
+ id=node_instance['id'],
+ runtime_properties={},
+ state=self.model_storage.node_instance.model_cls.UNINITIALIZED,
+ deployment_id=self.deployment_id,
+ version='1.0',
+ relationship_instances=relationship_instances)
+
+ self.model_storage.node_instance.store(node_instance_model)
+ self.logger.debug('created node-instances model storage entries')
+
+ def create_plugin_storage(self, plugin_id, source):
+ """
+ create plugin model & resource
+ """
+ assert hasattr(self.model_storage, 'plugin')
+ assert hasattr(self.resource_storage, 'plugin')
+
+ self.logger.debug('creating plugin resource storage entry')
+ self.resource_storage.plugin.upload(entry_id=plugin_id, source=source)
+ self.logger.debug('created plugin resource storage entry')
+
+ self.logger.debug('creating plugin model storage entry')
+ plugin = _load_plugin_from_archive(source)
+ build_props = plugin.get('build_server_os_properties')
+ now = datetime.utcnow()
+
+ plugin = self.model_storage.plugin.model_cls(
+ id=plugin_id,
+ package_name=plugin.get('package_name'),
+ package_version=plugin.get('package_version'),
+ archive_name=plugin.get('archive_name'),
+ package_source=plugin.get('package_source'),
+ supported_platform=plugin.get('supported_platform'),
+ distribution=build_props.get('distribution'),
+ distribution_version=build_props.get('distribution_version'),
+ distribution_release=build_props.get('distribution_release'),
+ wheels=plugin.get('wheels'),
+ excluded_wheels=plugin.get('excluded_wheels'),
+ supported_py_versions=plugin.get('supported_python_versions'),
+ uploaded_at=now
+ )
+ self.model_storage.plugin.store(plugin)
+ self.logger.debug('created plugin model storage entry')
+
+
+def _load_plugin_from_archive(tar_source):
+ if not tarfile.is_tarfile(tar_source):
+ # TODO: go over the exceptions
+ raise StorageError(
+ 'the provided tar archive can not be read.')
+
+ with tarfile.open(tar_source) as tar:
+ tar_members = tar.getmembers()
+ # a wheel plugin will contain exactly one sub directory
+ if not tar_members:
+ raise StorageError(
+ 'archive file structure malformed. expecting exactly one '
+ 'sub directory; got none.')
+ package_json_path = os.path.join(tar_members[0].name,
+ 'package.json')
+ try:
+ package_member = tar.getmember(package_json_path)
+ except KeyError:
+ raise StorageError("'package.json' was not found under {0}"
+ .format(package_json_path))
+ try:
+ package_json = tar.extractfile(package_member)
+ except tarfile.ExtractError as e:
+ raise StorageError(str(e))
+ try:
+ return json.load(package_json)
+ except ValueError as e:
+ raise StorageError("'package.json' is not a valid json: "
+ "{json_str}. error is {error}"
+ .format(json_str=package_json.read(), error=str(e)))
[3/3] incubator-ariatosca git commit: ARIA-21 Move general code from
parser.utils to top level utils
Posted by da...@apache.org.
ARIA-21 Move general code from parser.utils to top level utils
Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/3e7f1e15
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/3e7f1e15
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/3e7f1e15
Branch: refs/heads/ARIA-21-extract-some-parser-code
Commit: 3e7f1e15ac1a3a94b16b5197817ea0457ce4d705
Parents: 653365d
Author: Dan Kilman <da...@gigaspaces.com>
Authored: Wed Nov 16 17:16:12 2016 +0200
Committer: Dan Kilman <da...@gigaspaces.com>
Committed: Wed Nov 16 19:44:08 2016 +0200
----------------------------------------------------------------------
aria/__init__.py | 2 +-
aria/cli/commands.py | 2 +-
aria/exceptions.py | 21 +-
aria/orchestrator/context/common.py | 4 -
aria/orchestrator/decorators.py | 2 +-
aria/orchestrator/events/__init__.py | 2 +-
.../orchestrator/workflows/executor/blocking.py | 4 +-
.../workflows/executor/multiprocess.py | 4 +-
aria/orchestrator/workflows/executor/thread.py | 4 +-
aria/parser/__init__.py | 8 -
aria/parser/consumption/consumer.py | 4 +-
aria/parser/consumption/exceptions.py | 2 +-
aria/parser/consumption/inputs.py | 2 +-
aria/parser/consumption/modeling.py | 2 +-
aria/parser/consumption/presentation.py | 3 +-
aria/parser/consumption/style.py | 3 +-
aria/parser/exceptions.py | 20 +-
aria/parser/loading/context.py | 2 +-
aria/parser/loading/exceptions.py | 2 +-
aria/parser/loading/location.py | 2 +-
aria/parser/loading/uri.py | 4 +-
aria/parser/modeling/context.py | 8 +-
aria/parser/modeling/elements.py | 7 +-
aria/parser/modeling/exceptions.py | 2 +-
aria/parser/modeling/instance_elements.py | 9 +-
aria/parser/modeling/model_elements.py | 11 +-
aria/parser/modeling/types.py | 8 +-
aria/parser/modeling/utils.py | 9 +-
aria/parser/presentation/exceptions.py | 2 +-
aria/parser/presentation/fields.py | 17 +-
aria/parser/presentation/null.py | 2 +-
aria/parser/presentation/presentation.py | 5 +-
aria/parser/presentation/presenter.py | 3 +-
aria/parser/presentation/utils.py | 2 +-
aria/parser/reading/context.py | 4 +-
aria/parser/reading/exceptions.py | 2 +-
aria/parser/reading/jinja.py | 4 +-
aria/parser/reading/json.py | 5 +-
aria/parser/reading/locator.py | 2 +-
aria/parser/reading/reader.py | 2 +-
aria/parser/reading/yaml.py | 6 +-
aria/parser/specification.py | 7 +-
aria/parser/tools/__init__.py | 14 -
aria/parser/tools/cli.py | 69 -----
aria/parser/tools/rest.py | 266 -----------------
aria/parser/tools/spec.py | 60 ----
aria/parser/tools/utils.py | 73 -----
aria/parser/tools/web/index.html | 8 -
aria/parser/utils/__init__.py | 81 -----
aria/parser/utils/argparse.py | 113 -------
aria/parser/utils/caching.py | 134 ---------
aria/parser/utils/collections.py | 287 ------------------
aria/parser/utils/console.py | 60 ----
aria/parser/utils/daemon.py | 70 -----
aria/parser/utils/exceptions.py | 64 ----
aria/parser/utils/formatting.py | 207 -------------
aria/parser/utils/imports.py | 51 ----
aria/parser/utils/openclose.py | 32 --
aria/parser/utils/rest_client.py | 59 ----
aria/parser/utils/rest_server.py | 252 ----------------
aria/parser/utils/threading.py | 252 ----------------
aria/parser/utils/uris.py | 28 --
aria/parser/validation/context.py | 7 +-
aria/parser/validation/issue.py | 8 +-
aria/storage/structures.py | 2 +-
aria/tools/__init__.py | 20 --
aria/tools/application.py | 294 -------------------
aria/tools/lru_cache.py | 136 ---------
aria/tools/module.py | 38 ---
aria/tools/plugin.py | 39 ---
aria/tools/process.py | 186 ------------
aria/tools/validation.py | 95 ------
aria/utils/__init__.py | 14 +
aria/utils/application.py | 294 +++++++++++++++++++
aria/utils/caching.py | 133 +++++++++
aria/utils/collections.py | 291 ++++++++++++++++++
aria/utils/console.py | 64 ++++
aria/utils/exceptions.py | 64 ++++
aria/utils/formatting.py | 203 +++++++++++++
aria/utils/imports.py | 78 +++++
aria/utils/openclose.py | 32 ++
aria/utils/plugin.py | 39 +++
aria/utils/threading.py | 252 ++++++++++++++++
aria/utils/uris.py | 28 ++
aria/utils/validation.py | 95 ++++++
.../simple_nfv_v1_0/presenter.py | 4 +-
.../simple_v1_0/assignments.py | 3 +-
.../simple_v1_0/data_types.py | 8 +-
.../simple_v1_0/definitions.py | 3 +-
.../aria_extension_tosca/simple_v1_0/filters.py | 2 +-
.../simple_v1_0/functions.py | 3 +-
.../aria_extension_tosca/simple_v1_0/misc.py | 4 +-
.../simple_v1_0/modeling/artifacts.py | 6 +-
.../simple_v1_0/modeling/capabilities.py | 7 +-
.../simple_v1_0/modeling/data_types.py | 8 +-
.../simple_v1_0/modeling/interfaces.py | 7 +-
.../simple_v1_0/modeling/properties.py | 7 +-
.../simple_v1_0/modeling/requirements.py | 6 +-
.../modeling/substitution_mappings.py | 2 +-
.../simple_v1_0/presentation/extensible.py | 2 +-
.../simple_v1_0/presentation/field_getters.py | 3 +-
.../presentation/field_validators.py | 2 +-
.../simple_v1_0/presenter.py | 3 +-
.../simple_v1_0/templates.py | 3 +-
.../aria_extension_tosca/simple_v1_0/types.py | 3 +-
requirements.txt | 1 -
setup.py | 17 +-
tests/orchestrator/context/test_workflow.py | 1 +
108 files changed, 1735 insertions(+), 3178 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/__init__.py
----------------------------------------------------------------------
diff --git a/aria/__init__.py b/aria/__init__.py
index b2d1157..eb04e39 100644
--- a/aria/__init__.py
+++ b/aria/__init__.py
@@ -22,7 +22,7 @@ from .VERSION import version as __version__
from .orchestrator.decorators import workflow, operation
from .storage import ModelStorage, ResourceStorage, models, ModelDriver, ResourceDriver
from . import (
- tools,
+ utils,
parser,
storage,
orchestrator,
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/cli/commands.py
----------------------------------------------------------------------
diff --git a/aria/cli/commands.py b/aria/cli/commands.py
index 2fff4f0..341b13a 100644
--- a/aria/cli/commands.py
+++ b/aria/cli/commands.py
@@ -31,7 +31,7 @@ from aria import application_model_storage, application_resource_storage
from aria.orchestrator.context.workflow import WorkflowContext
from aria.logger import LoggerMixin
from aria.storage import FileSystemModelDriver, FileSystemResourceDriver
-from aria.tools.application import StorageManager
+from aria.utils.application import StorageManager
from aria.orchestrator.workflows.core.engine import Engine
from aria.orchestrator.workflows.executor.thread import ThreadExecutor
from .exceptions import (
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/exceptions.py
----------------------------------------------------------------------
diff --git a/aria/exceptions.py b/aria/exceptions.py
index 472b264..28f8be9 100644
--- a/aria/exceptions.py
+++ b/aria/exceptions.py
@@ -19,9 +19,28 @@ Every sub-package in Aria has a module with its exceptions.
aria.exceptions module conveniently collects all these exceptions for easier imports.
"""
+import sys
+
class AriaError(Exception):
"""
- General aria exception
+ Base class for ARIA errors.
"""
pass
+
+
+class AriaException(Exception):
+ """
+ Base class for ARIA exceptions.
+ """
+
+ def __init__(self, message=None, cause=None, cause_traceback=None):
+ super(AriaException, self).__init__(message)
+ self.cause = cause
+ self.issue = None
+ if cause_traceback is None:
+ _, e, traceback = sys.exc_info()
+ if cause == e:
+ # Make sure it's our traceback
+ cause_traceback = traceback
+ self.cause_tb = cause_traceback
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/orchestrator/context/common.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/context/common.py b/aria/orchestrator/context/common.py
index 48f4557..f2bf83b 100644
--- a/aria/orchestrator/context/common.py
+++ b/aria/orchestrator/context/common.py
@@ -19,7 +19,6 @@ from uuid import uuid4
from aria import logger
from aria.storage import exceptions
-from aria.tools.lru_cache import lru_cache
class BaseContext(logger.LoggerMixin):
@@ -76,7 +75,6 @@ class BaseContext(logger.LoggerMixin):
return self._resource
@property
- @lru_cache()
def blueprint(self):
"""
The blueprint model
@@ -84,7 +82,6 @@ class BaseContext(logger.LoggerMixin):
return self.model.blueprint.get(self.deployment.blueprint_id)
@property
- @lru_cache()
def deployment(self):
"""
The deployment model
@@ -134,7 +131,6 @@ class BaseContext(logger.LoggerMixin):
destination=destination,
path=path)
- @lru_cache()
def get_resource(self, path=None):
"""
Read a deployment resource as string from the resource storage
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/orchestrator/decorators.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/decorators.py b/aria/orchestrator/decorators.py
index 7f7685d..6e8ab39 100644
--- a/aria/orchestrator/decorators.py
+++ b/aria/orchestrator/decorators.py
@@ -20,7 +20,7 @@ Workflow and operation decorators
from uuid import uuid4
from functools import partial, wraps
-from aria.tools.validation import validate_function_arguments
+from aria.utils.validation import validate_function_arguments
from . import context
from .workflows.api import task_graph
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/orchestrator/events/__init__.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/events/__init__.py b/aria/orchestrator/events/__init__.py
index 40bdd24..fbc0f32 100644
--- a/aria/orchestrator/events/__init__.py
+++ b/aria/orchestrator/events/__init__.py
@@ -36,7 +36,7 @@ import os
from blinker import signal
-from aria.tools import plugin_installer
+from aria.utils.plugin import plugin_installer
# workflow engine task signals:
sent_task_signal = signal('sent_task_signal')
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/orchestrator/workflows/executor/blocking.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/executor/blocking.py b/aria/orchestrator/workflows/executor/blocking.py
index 30bebbe..9d3a9ba 100644
--- a/aria/orchestrator/workflows/executor/blocking.py
+++ b/aria/orchestrator/workflows/executor/blocking.py
@@ -17,7 +17,7 @@
Blocking executor
"""
-from aria.tools import module
+from aria.utils import imports
from .base import BaseExecutor
@@ -29,7 +29,7 @@ class CurrentThreadBlockingExecutor(BaseExecutor):
def execute(self, task):
self._task_started(task)
try:
- task_func = module.load_attribute(task.operation_mapping)
+ task_func = imports.load_attribute(task.operation_mapping)
task_func(ctx=task.context, **task.inputs)
self._task_succeeded(task)
except BaseException as e:
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/orchestrator/workflows/executor/multiprocess.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/executor/multiprocess.py b/aria/orchestrator/workflows/executor/multiprocess.py
index e73ab09..d770e07 100644
--- a/aria/orchestrator/workflows/executor/multiprocess.py
+++ b/aria/orchestrator/workflows/executor/multiprocess.py
@@ -22,7 +22,7 @@ import threading
import jsonpickle
-from aria.tools import module
+from aria.utils import imports
from .base import BaseExecutor
@@ -90,7 +90,7 @@ class _MultiprocessMessage(object):
def _multiprocess_handler(queue, ctx, task_id, operation_mapping, operation_inputs):
queue.put(_MultiprocessMessage(type='task_started', task_id=task_id))
try:
- task_func = module.load_attribute(operation_mapping)
+ task_func = imports.load_attribute(operation_mapping)
task_func(ctx=ctx, **operation_inputs)
queue.put(_MultiprocessMessage(type='task_succeeded', task_id=task_id))
except BaseException as e:
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/orchestrator/workflows/executor/thread.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/executor/thread.py b/aria/orchestrator/workflows/executor/thread.py
index fd7b302..76ceefd 100644
--- a/aria/orchestrator/workflows/executor/thread.py
+++ b/aria/orchestrator/workflows/executor/thread.py
@@ -20,7 +20,7 @@ Thread based executor
import Queue
import threading
-from aria.tools import module
+from aria.utils import imports
from .base import BaseExecutor
@@ -55,7 +55,7 @@ class ThreadExecutor(BaseExecutor):
task = self._queue.get(timeout=1)
self._task_started(task)
try:
- task_func = module.load_attribute(task.operation_mapping)
+ task_func = imports.load_attribute(task.operation_mapping)
task_func(ctx=task.context, **task.inputs)
self._task_succeeded(task)
except BaseException as e:
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/__init__.py
----------------------------------------------------------------------
diff --git a/aria/parser/__init__.py b/aria/parser/__init__.py
index d479082..c2e2fd6 100644
--- a/aria/parser/__init__.py
+++ b/aria/parser/__init__.py
@@ -16,12 +16,9 @@
import sys
import pkgutil
-from .exceptions import AriaException, InvalidValueError
from .specification import (DSL_SPECIFICATION, DSL_SPECIFICATION_PACKAGES, dsl_specification,
iter_spec)
-VERSION = '0.1'
-
def install_aria_extensions():
"""
@@ -45,16 +42,11 @@ MODULES = (
'modeling',
'presentation',
'reading',
- 'tools',
- 'utils',
'validation')
__all__ = (
'MODULES',
- 'VERSION',
'install_aria_extensions',
- 'AriaException',
- 'InvalidValueError',
'DSL_SPECIFICATION',
'DSL_SPECIFICATION_PACKAGES',
'dsl_specification',
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/consumption/consumer.py
----------------------------------------------------------------------
diff --git a/aria/parser/consumption/consumer.py b/aria/parser/consumption/consumer.py
index 847d015..f9c2f2e 100644
--- a/aria/parser/consumption/consumer.py
+++ b/aria/parser/consumption/consumer.py
@@ -14,9 +14,9 @@
# limitations under the License.
-from .. import AriaException
+from ...exceptions import AriaException
+from ...utils.exceptions import print_exception
from ..validation import Issue
-from ..utils import print_exception
class Consumer(object):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/consumption/exceptions.py
----------------------------------------------------------------------
diff --git a/aria/parser/consumption/exceptions.py b/aria/parser/consumption/exceptions.py
index 564e71f..78509cb 100644
--- a/aria/parser/consumption/exceptions.py
+++ b/aria/parser/consumption/exceptions.py
@@ -14,7 +14,7 @@
# limitations under the License.
-from .. import AriaException
+from ...exceptions import AriaException
class ConsumerException(AriaException):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/consumption/inputs.py
----------------------------------------------------------------------
diff --git a/aria/parser/consumption/inputs.py b/aria/parser/consumption/inputs.py
index 3711001..fe7e192 100644
--- a/aria/parser/consumption/inputs.py
+++ b/aria/parser/consumption/inputs.py
@@ -13,9 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from ...utils.formatting import safe_repr
from ..loading import UriLocation, LiteralLocation
from ..reading import JsonReader
-from ..utils import safe_repr
from .consumer import Consumer
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/consumption/modeling.py
----------------------------------------------------------------------
diff --git a/aria/parser/consumption/modeling.py b/aria/parser/consumption/modeling.py
index 8f8ee53..599c260 100644
--- a/aria/parser/consumption/modeling.py
+++ b/aria/parser/consumption/modeling.py
@@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from ..utils import json_dumps, yaml_dumps
+from ...utils.formatting import json_dumps, yaml_dumps
from .consumer import Consumer, ConsumerChain
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/consumption/presentation.py
----------------------------------------------------------------------
diff --git a/aria/parser/consumption/presentation.py b/aria/parser/consumption/presentation.py
index 9723b9f..4d0f282 100644
--- a/aria/parser/consumption/presentation.py
+++ b/aria/parser/consumption/presentation.py
@@ -14,7 +14,8 @@
# limitations under the License.
-from ..utils import FixedThreadPoolExecutor, json_dumps, yaml_dumps
+from ...utils.threading import FixedThreadPoolExecutor
+from ...utils.formatting import json_dumps, yaml_dumps
from ..loading import UriLocation
from ..reading import AlreadyReadException
from ..presentation import PresenterNotFoundError
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/consumption/style.py
----------------------------------------------------------------------
diff --git a/aria/parser/consumption/style.py b/aria/parser/consumption/style.py
index 8222f3e..88ad934 100644
--- a/aria/parser/consumption/style.py
+++ b/aria/parser/consumption/style.py
@@ -13,7 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from ..utils import safe_repr, Colored, indent
+from ...utils.console import Colored, indent
+from ...utils.formatting import safe_repr
class Style(object):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/exceptions.py
----------------------------------------------------------------------
diff --git a/aria/parser/exceptions.py b/aria/parser/exceptions.py
index ab1b4fd..5d1a55c 100644
--- a/aria/parser/exceptions.py
+++ b/aria/parser/exceptions.py
@@ -13,28 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import sys
-
+from ..exceptions import AriaException
from .validation import Issue
-class AriaException(Exception):
- """
- Base class for ARIA exceptions.
- """
-
- def __init__(self, message=None, cause=None, cause_traceback=None):
- super(AriaException, self).__init__(message)
- self.cause = cause
- self.issue = None
- if cause_traceback is None:
- _, e, traceback = sys.exc_info()
- if cause == e:
- # Make sure it's our traceback
- cause_traceback = traceback
- self.cause_tb = cause_traceback
-
-
class InvalidValueError(AriaException):
"""
ARIA error: value is invalid.
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/loading/context.py
----------------------------------------------------------------------
diff --git a/aria/parser/loading/context.py b/aria/parser/loading/context.py
index 2c52086..44e3fd1 100644
--- a/aria/parser/loading/context.py
+++ b/aria/parser/loading/context.py
@@ -14,7 +14,7 @@
# limitations under the License.
-from ..utils import StrictList
+from ...utils.collections import StrictList
from .source import DefaultLoaderSource
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/loading/exceptions.py
----------------------------------------------------------------------
diff --git a/aria/parser/loading/exceptions.py b/aria/parser/loading/exceptions.py
index 204ad28..6e8267a 100644
--- a/aria/parser/loading/exceptions.py
+++ b/aria/parser/loading/exceptions.py
@@ -14,7 +14,7 @@
# limitations under the License.
-from .. import AriaException
+from ...exceptions import AriaException
class LoaderException(AriaException):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/loading/location.py
----------------------------------------------------------------------
diff --git a/aria/parser/loading/location.py b/aria/parser/loading/location.py
index 0a3d428..5bc6fab 100644
--- a/aria/parser/loading/location.py
+++ b/aria/parser/loading/location.py
@@ -16,7 +16,7 @@
import os
-from ..utils import as_file
+from ...utils.uris import as_file
class Location(object):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/loading/uri.py
----------------------------------------------------------------------
diff --git a/aria/parser/loading/uri.py b/aria/parser/loading/uri.py
index 5e6ff39..f94a003 100644
--- a/aria/parser/loading/uri.py
+++ b/aria/parser/loading/uri.py
@@ -16,7 +16,8 @@
import os
from urlparse import urljoin
-from ..utils import StrictList, as_file
+from ...utils.collections import StrictList
+from ...utils.uris import as_file
from .loader import Loader
from .file import FileTextLoader
from .request import RequestTextLoader
@@ -24,6 +25,7 @@ from .exceptions import DocumentNotFoundException
URI_LOADER_PREFIXES = StrictList(value_class=basestring)
+
class UriTextLoader(Loader):
"""
Base class for ARIA URI loaders.
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/modeling/context.py
----------------------------------------------------------------------
diff --git a/aria/parser/modeling/context.py b/aria/parser/modeling/context.py
index 9e64ac5..d47c202 100644
--- a/aria/parser/modeling/context.py
+++ b/aria/parser/modeling/context.py
@@ -13,13 +13,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
import itertools
-from ..utils import StrictDict, prune, puts, as_raw
+from ...utils.collections import StrictDict, prune, OrderedDict
+from ...utils.formatting import as_raw
+from ...utils.console import puts
from .types import TypeHierarchy
from .utils import generate_id_string
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/modeling/elements.py
----------------------------------------------------------------------
diff --git a/aria/parser/modeling/elements.py b/aria/parser/modeling/elements.py
index ffde635..62bc7b8 100644
--- a/aria/parser/modeling/elements.py
+++ b/aria/parser/modeling/elements.py
@@ -13,11 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
-from ..utils import StrictDict, puts
+from ...utils.collections import StrictDict, OrderedDict
+from ...utils.console import puts
from .utils import coerce_value
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/modeling/exceptions.py
----------------------------------------------------------------------
diff --git a/aria/parser/modeling/exceptions.py b/aria/parser/modeling/exceptions.py
index 66fb7d2..c7f08df 100644
--- a/aria/parser/modeling/exceptions.py
+++ b/aria/parser/modeling/exceptions.py
@@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from .. import AriaException
+from ...exceptions import AriaException
class CannotEvaluateFunctionException(AriaException):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/modeling/instance_elements.py
----------------------------------------------------------------------
diff --git a/aria/parser/modeling/instance_elements.py b/aria/parser/modeling/instance_elements.py
index 5fbf4f4..523de0b 100644
--- a/aria/parser/modeling/instance_elements.py
+++ b/aria/parser/modeling/instance_elements.py
@@ -13,13 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
+from ...utils.collections import StrictList, StrictDict, FrozenList, OrderedDict
+from ...utils.formatting import as_raw, as_raw_list, as_raw_dict, as_agnostic, safe_repr
+from ...utils.console import puts, indent
from ..validation import Issue
-from ..utils import (StrictList, StrictDict, FrozenList, puts, indent, as_raw, as_raw_list,\
- as_raw_dict, as_agnostic, safe_repr)
from .elements import Element, Parameter
from .utils import (validate_dict_values, validate_list_values, coerce_dict_values,
coerce_list_values, dump_list_values, dump_dict_values, dump_parameters,
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/modeling/model_elements.py
----------------------------------------------------------------------
diff --git a/aria/parser/modeling/model_elements.py b/aria/parser/modeling/model_elements.py
index ec081e7..7346a54 100644
--- a/aria/parser/modeling/model_elements.py
+++ b/aria/parser/modeling/model_elements.py
@@ -14,16 +14,13 @@
# limitations under the License.
from __future__ import absolute_import # so we can import standard 'types'
-from types import FunctionType
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
+from types import FunctionType
+from ...utils.collections import StrictList, StrictDict, deepcopy_with_locators, OrderedDict
+from ...utils.formatting import as_raw, as_raw_list, as_raw_dict, as_agnostic, safe_repr
+from ...utils.console import puts
from ..validation import Issue
-from ..utils import (StrictList, StrictDict, puts, safe_repr, as_raw, as_raw_list, as_raw_dict,
- as_agnostic, deepcopy_with_locators)
from .elements import ModelElement, Parameter
from .instance_elements import (ServiceInstance, Node, Capability, Relationship, Artifact, Group,
Policy, GroupPolicy, GroupPolicyTrigger, Mapping, Substitution,
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/modeling/types.py
----------------------------------------------------------------------
diff --git a/aria/parser/modeling/types.py b/aria/parser/modeling/types.py
index 4795fe0..e6249ef 100644
--- a/aria/parser/modeling/types.py
+++ b/aria/parser/modeling/types.py
@@ -13,11 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
-from ..utils import StrictList, StrictDict, puts, as_raw
+from ...utils.collections import StrictList, StrictDict, OrderedDict
+from ...utils.formatting import as_raw
+from ...utils.console import puts
class Type(object):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/modeling/utils.py
----------------------------------------------------------------------
diff --git a/aria/parser/modeling/utils.py b/aria/parser/modeling/utils.py
index 5d99eb5..906106e 100644
--- a/aria/parser/modeling/utils.py
+++ b/aria/parser/modeling/utils.py
@@ -15,15 +15,12 @@
from random import randrange
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
from shortuuid import ShortUUID
-from .. import InvalidValueError
+from ...utils.collections import OrderedDict
+from ...utils.console import puts
+from ..exceptions import InvalidValueError
from ..presentation import Value
-from ..utils import puts
from .exceptions import CannotEvaluateFunctionException
# UUID = ShortUUID() # default alphabet is base57, which is alphanumeric without visually ambiguous
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/presentation/exceptions.py
----------------------------------------------------------------------
diff --git a/aria/parser/presentation/exceptions.py b/aria/parser/presentation/exceptions.py
index 7c0e1f8..cd7eb07 100644
--- a/aria/parser/presentation/exceptions.py
+++ b/aria/parser/presentation/exceptions.py
@@ -14,7 +14,7 @@
# limitations under the License.
-from .. import AriaException
+from ...exceptions import AriaException
class PresenterException(AriaException):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/presentation/fields.py
----------------------------------------------------------------------
diff --git a/aria/parser/presentation/fields.py b/aria/parser/presentation/fields.py
index a3a9f12..da3cb05 100644
--- a/aria/parser/presentation/fields.py
+++ b/aria/parser/presentation/fields.py
@@ -16,14 +16,15 @@
import threading
from functools import wraps
from types import MethodType
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
-
-from ..exceptions import InvalidValueError, AriaException
-from ..utils import (FrozenList, FrozenDict, print_exception, deepcopy_with_locators, merge,
- cachedmethod, puts, as_raw, full_type_name, safe_repr)
+
+from ...exceptions import AriaException
+from ...utils.collections import FrozenDict, FrozenList, deepcopy_with_locators, merge, OrderedDict
+from ...utils.caching import cachedmethod
+from ...utils.console import puts
+from ...utils.formatting import as_raw, safe_repr, full_type_name
+from ...utils.exceptions import print_exception
+from ..exceptions import InvalidValueError
+
from .null import NULL
from .utils import validate_primitive
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/presentation/null.py
----------------------------------------------------------------------
diff --git a/aria/parser/presentation/null.py b/aria/parser/presentation/null.py
index a69134e..a018df4 100644
--- a/aria/parser/presentation/null.py
+++ b/aria/parser/presentation/null.py
@@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from ..utils import deepcopy_with_locators
+from ...utils.collections import deepcopy_with_locators
class Null(object):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/presentation/presentation.py
----------------------------------------------------------------------
diff --git a/aria/parser/presentation/presentation.py b/aria/parser/presentation/presentation.py
index 15cb5ed..0f098b5 100644
--- a/aria/parser/presentation/presentation.py
+++ b/aria/parser/presentation/presentation.py
@@ -13,8 +13,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from ...utils.caching import HasCachedMethods
+from ...utils.collections import deepcopy_with_locators
+from ...utils.formatting import full_type_name, safe_repr
+from ...utils.console import puts
from ..validation import Issue
-from ..utils import HasCachedMethods, full_type_name, deepcopy_with_locators, puts, safe_repr
from .null import none_to_null
from .utils import (get_locator, validate_no_short_form, validate_no_unknown_fields,
validate_known_fields, validate_primitive)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/presentation/presenter.py
----------------------------------------------------------------------
diff --git a/aria/parser/presentation/presenter.py b/aria/parser/presentation/presenter.py
index 4cade3a..9fd296f 100644
--- a/aria/parser/presentation/presenter.py
+++ b/aria/parser/presentation/presenter.py
@@ -13,8 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from ...utils.collections import merge
+from ...utils.formatting import safe_repr
from ..validation import Issue
-from ..utils import merge, safe_repr
from .presentation import Presentation
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/presentation/utils.py
----------------------------------------------------------------------
diff --git a/aria/parser/presentation/utils.py b/aria/parser/presentation/utils.py
index 2e4d873..74adbd1 100644
--- a/aria/parser/presentation/utils.py
+++ b/aria/parser/presentation/utils.py
@@ -15,8 +15,8 @@
from types import FunctionType
+from ...utils.formatting import full_type_name, safe_repr
from ..validation import Issue
-from ..utils import full_type_name, safe_repr
from .null import NULL
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/reading/context.py
----------------------------------------------------------------------
diff --git a/aria/parser/reading/context.py b/aria/parser/reading/context.py
index 81135dc..02d4de9 100644
--- a/aria/parser/reading/context.py
+++ b/aria/parser/reading/context.py
@@ -10,8 +10,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from ...utils.threading import LockedList
from .source import DefaultReaderSource
-from ..utils import LockedList
class ReadingContext(object):
@@ -26,4 +26,4 @@ class ReadingContext(object):
self.reader_source = DefaultReaderSource()
self.reader = None
- self._locations = LockedList() # for keeping track of locations already read
+ self._locations = LockedList() # for keeping track of locations already read
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/reading/exceptions.py
----------------------------------------------------------------------
diff --git a/aria/parser/reading/exceptions.py b/aria/parser/reading/exceptions.py
index bc2d2d5..3699729 100644
--- a/aria/parser/reading/exceptions.py
+++ b/aria/parser/reading/exceptions.py
@@ -10,7 +10,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from .. import AriaException
+from ...exceptions import AriaException
from ..validation import Issue
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/reading/jinja.py
----------------------------------------------------------------------
diff --git a/aria/parser/reading/jinja.py b/aria/parser/reading/jinja.py
index e15e54e..17bf49e 100644
--- a/aria/parser/reading/jinja.py
+++ b/aria/parser/reading/jinja.py
@@ -14,7 +14,7 @@ import os
from jinja2 import Template
-from .. import VERSION
+from ...VERSION import version
from ..loading import LiteralLocation, LiteralLoader
from .reader import Reader
from .exceptions import ReaderSyntaxError
@@ -22,7 +22,7 @@ from .exceptions import ReaderSyntaxError
# TODO: we could put a lot of other useful stuff here.
CONTEXT = {
- 'ARIA_VERSION': VERSION,
+ 'ARIA_VERSION': version,
'ENV': os.environ}
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/reading/json.py
----------------------------------------------------------------------
diff --git a/aria/parser/reading/json.py b/aria/parser/reading/json.py
index 24c4df0..d144f80 100644
--- a/aria/parser/reading/json.py
+++ b/aria/parser/reading/json.py
@@ -13,11 +13,8 @@
from __future__ import absolute_import # so we can import standard 'json'
import json
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
+from ...utils.collections import OrderedDict
from .reader import Reader
from .exceptions import ReaderSyntaxError
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/reading/locator.py
----------------------------------------------------------------------
diff --git a/aria/parser/reading/locator.py b/aria/parser/reading/locator.py
index 90b9e73..a1cfa9c 100644
--- a/aria/parser/reading/locator.py
+++ b/aria/parser/reading/locator.py
@@ -10,7 +10,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from ..utils import puts, Colored, indent
+from ...utils.console import puts, Colored, indent
# We are inheriting the primitive types in order to add the ability to set
# an attribute (_locator) on them.
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/reading/reader.py
----------------------------------------------------------------------
diff --git a/aria/parser/reading/reader.py b/aria/parser/reading/reader.py
index 3a50739..fe64697 100644
--- a/aria/parser/reading/reader.py
+++ b/aria/parser/reading/reader.py
@@ -10,7 +10,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from ..utils import OpenClose
+from ...utils.openclose import OpenClose
from .exceptions import ReaderException, AlreadyReadException
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/reading/yaml.py
----------------------------------------------------------------------
diff --git a/aria/parser/reading/yaml.py b/aria/parser/reading/yaml.py
index 097816a..f5eac43 100644
--- a/aria/parser/reading/yaml.py
+++ b/aria/parser/reading/yaml.py
@@ -10,13 +10,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
-
from ruamel import yaml # @UnresolvedImport
+from ...utils.collections import OrderedDict
from .reader import Reader
from .locator import Locator
from .exceptions import ReaderSyntaxError
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/specification.py
----------------------------------------------------------------------
diff --git a/aria/parser/specification.py b/aria/parser/specification.py
index ec9959a..6e022bc 100644
--- a/aria/parser/specification.py
+++ b/aria/parser/specification.py
@@ -13,11 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
-from .utils import full_type_name
+from ..utils.collections import OrderedDict
+from ..utils.formatting import full_type_name
DSL_SPECIFICATION = {}
DSL_SPECIFICATION_PACKAGES = []
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/tools/__init__.py
----------------------------------------------------------------------
diff --git a/aria/parser/tools/__init__.py b/aria/parser/tools/__init__.py
deleted file mode 100644
index ae1e83e..0000000
--- a/aria/parser/tools/__init__.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/tools/cli.py
----------------------------------------------------------------------
diff --git a/aria/parser/tools/cli.py b/aria/parser/tools/cli.py
deleted file mode 100644
index a274e49..0000000
--- a/aria/parser/tools/cli.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 aria.parser import install_aria_extensions
-from aria.parser.utils import (print_exception, import_fullname)
-from aria.parser.tools.utils import (CommonArgumentParser, create_context_from_namespace)
-from aria.parser.consumption import (ConsumerChain, Read, Validate, Model, Types, Inputs, Instance)
-
-class ArgumentParser(CommonArgumentParser):
- def __init__(self):
- super(ArgumentParser, self).__init__(description='CLI', prog='aria')
- self.add_argument('uri', help='URI or file path to profile')
- self.add_argument('consumer',
- nargs='?',
- default='instance',
- help='consumer class name (full class path or short name)')
-
-def main():
- try:
-
- args, unknown_args = ArgumentParser().parse_known_args()
-
- install_aria_extensions()
-
- context = create_context_from_namespace(args)
- context.args = unknown_args
-
- consumer = ConsumerChain(context, (Read, Validate))
-
- consumer_class_name = args.consumer
- dumper = None
- if consumer_class_name == 'presentation':
- dumper = consumer.consumers[0]
- elif consumer_class_name == 'model':
- consumer.append(Model)
- elif consumer_class_name == 'types':
- consumer.append(Model, Types)
- elif consumer_class_name == 'instance':
- consumer.append(Model, Inputs, Instance)
- else:
- consumer.append(Model, Inputs, Instance)
- consumer.append(import_fullname(consumer_class_name))
-
- if dumper is None:
- # Default to last consumer
- dumper = consumer.consumers[-1]
-
- consumer.consume()
-
- if not context.validation.dump_issues():
- dumper.dump()
-
- except Exception as e:
- print_exception(e)
-
-if __name__ == '__main__':
- main()
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/tools/rest.py
----------------------------------------------------------------------
diff --git a/aria/parser/tools/rest.py b/aria/parser/tools/rest.py
deleted file mode 100644
index 5c3dd5e..0000000
--- a/aria/parser/tools/rest.py
+++ /dev/null
@@ -1,266 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 os
-import urllib
-from urlparse import (urlparse, parse_qs)
-
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
-
-from ..loading import LiteralLocation
-from .. import install_aria_extensions
-from .utils import (CommonArgumentParser,
- create_context_from_namespace)
-from ..consumption import (ConsumerChain, Read, Validate, Model, Inputs, Instance)
-from ..utils import (RestServer, JsonAsRawEncoder, print_exception, start_daemon, stop_daemon,
- status_daemon, puts, Colored)
-
-VALIDATE_PATH = 'validate'
-INDIRECT_VALIDATE_PATH = 'indirect/validate'
-MODEL_PATH = 'model'
-INDIRECT_MODEL_PATH = 'indirect/model'
-INSTANCE_PATH = 'instance'
-INDIRECT_INSTANCE_PATH = 'indirect/instance'
-
-DEFAULT_PORT = 8080
-
-#
-# Utils
-#
-
-class Configuration(object):
- def __init__(self, arguments):
- self.arguments = arguments
-
- def create_context(self, uri):
- return create_context_from_namespace(self.arguments, uri=uri)
-
-def parse_path(handler):
- parsed = urlparse(urllib.unquote(handler.path))
- uri = parsed.path[len(handler.matched_re):]
- query = parse_qs(parsed.query, keep_blank_values=True)
- return uri, query
-
-def parse_indirect_payload(handler):
- try:
- payload = handler.json_payload
- except BaseException:
- handler.send_plain_text_response(400, 'Payload is not JSON\n')
- return None, None
-
- for key in payload.iterkeys():
- if key not in ('uri', 'inputs'):
- handler.send_plain_text_response(400, 'Payload has unsupported field: %s\n' % key)
- return None, None
-
- try:
- uri = payload['uri']
- except BaseException:
- handler.send_plain_text_response(400, 'Payload does not have required "uri" field\n')
- return None, None
-
- inputs = payload.get('inputs')
-
- return uri, inputs
-
-def validate(handler, uri):
- context = handler.rest_server.configuration.create_context(uri)
- ConsumerChain(context, (Read, Validate)).consume()
- return context
-
-def model(handler, uri):
- context = handler.rest_server.configuration.create_context(uri)
- ConsumerChain(context, (Read, Validate, Model)).consume()
- return context
-
-def instance(handler, uri, inputs):
- context = handler.rest_server.configuration.create_context(uri)
- if inputs:
- if isinstance(inputs, dict):
- for name, value in inputs.iteritems():
- context.modeling.set_input(name, value)
- else:
- context.args.append('--inputs=%s' % inputs)
- ConsumerChain(context, (Read, Validate, Model, Inputs, Instance)).consume()
- return context
-
-def issues(context):
- return {'issues': context.validation.issues_as_raw}
-
-#
-# Handlers
-#
-
-# Validate
-
-def validate_get(handler):
- uri, _ = parse_path(handler)
- context = validate(handler, uri)
- return issues(context) if context.validation.has_issues else {}
-
-def validate_post(handler):
- payload = handler.payload
- context = validate(handler, LiteralLocation(payload))
- return issues(context) if context.validation.has_issues else {}
-
-def indirect_validate_post(handler):
- uri, _ = parse_indirect_payload(handler)
- if uri is None:
- return None
- context = validate(handler, uri)
- return issues(context) if context.validation.has_issues else {}
-
-# Model
-
-def model_get(handler):
- uri, _ = parse_path(handler)
- context = model(handler, uri)
- return issues(context) if context.validation.has_issues else {
- 'types': context.modeling.types_as_raw,
- 'model': context.modeling.model_as_raw
- }
-
-def model_post(handler):
- payload = handler.payload
- context = model(handler, LiteralLocation(payload))
- return issues(context) if context.validation.has_issues else {
- 'types': context.modeling.types_as_raw,
- 'model': context.modeling.model_as_raw
- }
-
-def indirect_model_post(handler):
- uri, _ = parse_indirect_payload(handler)
- if uri is None:
- return None
- context = model(handler, uri)
- return issues(context) if context.validation.has_issues else {
- 'types': context.modeling.types_as_raw,
- 'model': context.modeling.model_as_raw
- }
-
-# Instance
-
-def instance_get(handler):
- uri, query = parse_path(handler)
- inputs = query.get('inputs')
- if inputs:
- inputs = inputs[0]
- context = instance(handler, uri, inputs)
- return issues(context) if context.validation.has_issues else {
- 'types': context.modeling.types_as_raw,
- 'model': context.modeling.model_as_raw,
- 'instance': context.modeling.instance_as_raw
- }
-
-def instance_post(handler):
- _, query = parse_path(handler)
- inputs = query.get('inputs')
- if inputs:
- inputs = inputs[0]
- payload = handler.payload
- context = instance(handler, LiteralLocation(payload), inputs)
- return issues(context) if context.validation.has_issues else {
- 'types': context.modeling.types_as_raw,
- 'model': context.modeling.model_as_raw,
- 'instance': context.modeling.instance_as_raw
- }
-
-def indirect_instance_post(handler):
- uri, inputs = parse_indirect_payload(handler)
- if uri is None:
- return None
- context = instance(handler, uri, inputs)
- return issues(context) if context.validation.has_issues else {
- 'types': context.modeling.types_as_raw,
- 'model': context.modeling.model_as_raw,
- 'instance': context.modeling.instance_as_raw
- }
-
-#
-# Server
-#
-
-ROUTES = OrderedDict((
- ('^/$', {'file': 'index.html', 'media_type': 'text/html'}),
- ('^/' + VALIDATE_PATH, {'GET': validate_get,
- 'POST': validate_post,
- 'media_type': 'application/json'}),
- ('^/' + MODEL_PATH, {'GET': model_get, 'POST': model_post, 'media_type': 'application/json'}),
- ('^/' + INSTANCE_PATH, {'GET': instance_get,
- 'POST': instance_post,
- 'media_type': 'application/json'}),
- ('^/' + INDIRECT_VALIDATE_PATH, {'POST': indirect_validate_post,
- 'media_type': 'application/json'}),
- ('^/' + INDIRECT_MODEL_PATH, {'POST': indirect_model_post, 'media_type': 'application/json'}),
- ('^/' + INDIRECT_INSTANCE_PATH, {'POST': indirect_instance_post,
- 'media_type': 'application/json'})))
-
-class ArgumentParser(CommonArgumentParser):
- def __init__(self):
- super(ArgumentParser, self).__init__(description='REST Server', prog='aria-rest')
- self.add_argument('command',
- nargs='?',
- help='daemon command: start, stop, restart, or status')
- self.add_argument('--port', type=int, default=DEFAULT_PORT, help='HTTP port')
- self.add_argument('--root', help='web root directory')
- self.add_argument('--rundir',
- help='pid and log files directory for daemons (defaults to user home)')
-
-def main():
- try:
- install_aria_extensions()
-
- arguments, _ = ArgumentParser().parse_known_args()
-
- rest_server = RestServer()
- rest_server.configuration = Configuration(arguments)
- rest_server.port = arguments.port
- rest_server.routes = ROUTES
- rest_server.static_root = arguments.root or os.path.join(os.path.dirname(__file__), 'web')
- rest_server.json_encoder = JsonAsRawEncoder(ensure_ascii=False, separators=(',', ':'))
-
- if arguments.command:
- rundir = os.path.abspath(arguments.rundir or os.path.expanduser('~'))
- pidfile_path = os.path.join(rundir, 'aria-rest.pid')
-
- def start():
- log_path = os.path.join(rundir, 'aria-rest.log')
- context = start_daemon(pidfile_path, log_path)
- if context is not None:
- with context:
- rest_server.start(daemon=True)
-
- if arguments.command == 'start':
- start()
- elif arguments.command == 'stop':
- stop_daemon(pidfile_path)
- elif arguments.command == 'restart':
- stop_daemon(pidfile_path)
- start()
- elif arguments.command == 'status':
- status_daemon(pidfile_path)
- else:
- puts(Colored.red('Unknown command: %s' % arguments.command))
- else:
- rest_server.start()
-
- except Exception as e:
- print_exception(e)
-
-if __name__ == '__main__':
- main()
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/tools/spec.py
----------------------------------------------------------------------
diff --git a/aria/parser/tools/spec.py b/aria/parser/tools/spec.py
deleted file mode 100644
index ecb4010..0000000
--- a/aria/parser/tools/spec.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 csv
-import sys
-
-from .utils import BaseArgumentParser
-from ..utils import (print_exception, import_modules, puts, Colored, indent)
-from .. import (install_aria_extensions, DSL_SPECIFICATION_PACKAGES, DSL_SPECIFICATION,
- iter_spec)
-
-class ArgumentParser(BaseArgumentParser):
- def __init__(self):
- super(ArgumentParser, self).__init__(description='Specification Tool', prog='aria-spec')
- self.add_argument('--csv', action='store_true', help='output as CSV')
-
-def main():
- try:
- args, _ = ArgumentParser().parse_known_args()
-
- install_aria_extensions()
-
- # Make sure that all @dsl_specification decorators are processed
- for pkg in DSL_SPECIFICATION_PACKAGES:
- import_modules(pkg)
-
- if args.csv:
- writer = csv.writer(sys.stdout, quoting=csv.QUOTE_ALL)
- writer.writerow(('Specification', 'Section', 'Code', 'URL'))
- for spec in sorted(DSL_SPECIFICATION):
- for section, details in iter_spec(spec):
- writer.writerow((spec, section, details['code'], details['url']))
-
- else:
- for spec in sorted(DSL_SPECIFICATION):
- puts(Colored.cyan(spec))
- with indent(2):
- for section, details in iter_spec(spec):
- puts(Colored.blue(section))
- with indent(2):
- for k, v in details.iteritems():
- puts('%s: %s' % (Colored.magenta(k), v))
-
- except Exception as e:
- print_exception(e)
-
-if __name__ == '__main__':
- main()
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/tools/utils.py
----------------------------------------------------------------------
diff --git a/aria/parser/tools/utils.py b/aria/parser/tools/utils.py
deleted file mode 100644
index 9080e43..0000000
--- a/aria/parser/tools/utils.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 .. import VERSION
-from ..consumption import ConsumptionContext
-from ..loading import (UriLocation, URI_LOADER_PREFIXES)
-from ..utils import (ArgumentParser, import_fullname, cachedmethod)
-
-class BaseArgumentParser(ArgumentParser):
- def __init__(self, description, **kwargs):
- super(BaseArgumentParser, self).__init__(
- description='%s for ARIA version %s' % (description, VERSION), **kwargs)
-
-class CommonArgumentParser(BaseArgumentParser):
- def __init__(self, description, **kwargs):
- super(CommonArgumentParser, self).__init__(description, **kwargs)
-
- self.add_argument('--loader-source',
- default='aria.loading.DefaultLoaderSource',
- help='loader source class for the parser')
- self.add_argument('--reader-source',
- default='aria.reading.DefaultReaderSource',
- help='reader source class for the parser')
- self.add_argument('--presenter-source',
- default='aria.presentation.DefaultPresenterSource',
- help='presenter source class for the parser')
- self.add_argument('--presenter', help='force use of this presenter class in parser')
- self.add_argument('--prefix', nargs='*', help='prefixes for imports')
- self.add_flag_argument('debug',
- help_true='print debug info',
- help_false='don\'t print debug info')
- self.add_flag_argument('cached-methods',
- help_true='enable cached methods',
- help_false='disable cached methods',
- default=True)
-
- def parse_known_args(self, args=None, namespace=None):
- namespace, args = super(CommonArgumentParser, self).parse_known_args(args, namespace)
-
- if namespace.prefix:
- for prefix in namespace.prefix:
- URI_LOADER_PREFIXES.append(prefix)
-
- cachedmethod.ENABLED = namespace.cached_methods
-
- return namespace, args
-
-def create_context_from_namespace(namespace, **kwargs):
- args = vars(namespace).copy()
- args.update(kwargs)
- return create_context(**args)
-
-def create_context(uri, loader_source, reader_source, presenter_source, presenter, debug, **kwargs):
- context = ConsumptionContext()
- context.loading.loader_source = import_fullname(loader_source)()
- context.reading.reader_source = import_fullname(reader_source)()
- context.presentation.location = UriLocation(uri) if isinstance(uri, basestring) else uri
- context.presentation.presenter_source = import_fullname(presenter_source)()
- context.presentation.presenter_class = import_fullname(presenter)
- context.presentation.print_exceptions = debug
- return context
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/tools/web/index.html
----------------------------------------------------------------------
diff --git a/aria/parser/tools/web/index.html b/aria/parser/tools/web/index.html
deleted file mode 100644
index 31b459d..0000000
--- a/aria/parser/tools/web/index.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-<head>
- <title>ARIA REST Service</title>
-</head>
-<body>
- <h1>ARIA REST Service</h1>
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/utils/__init__.py
----------------------------------------------------------------------
diff --git a/aria/parser/utils/__init__.py b/aria/parser/utils/__init__.py
deleted file mode 100644
index ba42565..0000000
--- a/aria/parser/utils/__init__.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 clint.textui import indent
-
-from .uris import as_file
-from .openclose import OpenClose
-from .rest_client import call_rest
-from .argparse import ArgumentParser
-from .console import (puts, Colored)
-from .caching import (cachedmethod, HasCachedMethods)
-from .imports import (import_fullname, import_modules)
-from .rest_server import (RestServer, RestRequestHandler)
-from .exceptions import (print_exception, print_traceback)
-from .daemon import (start_daemon, stop_daemon, status_daemon)
-from .threading import (ExecutorException, FixedThreadPoolExecutor, LockedList)
-from .collections import (FrozenList, EMPTY_READ_ONLY_LIST, FrozenDict, EMPTY_READ_ONLY_DICT,
- StrictList, StrictDict, merge, prune, deepcopy_with_locators,
- copy_locators, is_removable)
-from .formatting import (JsonAsRawEncoder, YamlAsRawDumper, full_type_name, safe_str, safe_repr,
- string_list_as_string, as_raw, as_raw_list, as_raw_dict, as_agnostic,
- json_dumps, yaml_dumps, yaml_loads)
-
-__all__ = (
- 'OpenClose',
- 'cachedmethod',
- 'HasCachedMethods',
- 'JsonAsRawEncoder',
- 'YamlAsRawDumper',
- 'full_type_name',
- 'safe_str',
- 'safe_repr',
- 'string_list_as_string',
- 'as_raw',
- 'as_raw_list',
- 'as_raw_dict',
- 'as_agnostic',
- 'json_dumps',
- 'yaml_dumps',
- 'yaml_loads',
- 'FrozenList',
- 'EMPTY_READ_ONLY_LIST',
- 'FrozenDict',
- 'EMPTY_READ_ONLY_DICT',
- 'StrictList',
- 'StrictDict',
- 'merge',
- 'prune',
- 'deepcopy_with_locators',
- 'copy_locators',
- 'is_removable',
- 'print_exception',
- 'print_traceback',
- 'import_fullname',
- 'import_modules',
- 'ExecutorException',
- 'FixedThreadPoolExecutor',
- 'LockedList',
- 'as_file',
- 'ArgumentParser',
- 'puts',
- 'Colored',
- 'indent',
- 'RestServer',
- 'RestRequestHandler',
- 'call_rest',
- 'start_daemon',
- 'stop_daemon',
- 'status_daemon')
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/utils/argparse.py
----------------------------------------------------------------------
diff --git a/aria/parser/utils/argparse.py b/aria/parser/utils/argparse.py
deleted file mode 100644
index 071752d..0000000
--- a/aria/parser/utils/argparse.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 __future__ import absolute_import # so we can import standard 'argparse'
-
-from argparse import ArgumentParser as BaseArgumentParser
-
-class ArgumentParser(BaseArgumentParser):
- """
- Enhanced argument parser.
-
- Applied patch to fix `this issue <https://bugs.python.org/issue22433>`__.
- """
-
- def add_flag_argument(self, name, help_true=None, help_false=None, default=False):
- """
- Adds a flag argument as two arguments: :code:`--my-flag` and :code:`--no-my-flag`.
- """
-
- dest = name.replace('-', '_')
-
- if default:
- if help_true is not None:
- help_true += ' (default)'
- else:
- help_true = '(default)'
- else:
- if help_false is not None:
- help_false += ' (default)'
- else:
- help_false = '(default)'
-
- group = self.add_mutually_exclusive_group()
- group.add_argument('--%s' % name, action='store_true', help=help_true)
- group.add_argument('--no-%s' % name, dest=dest, action='store_false', help=help_false)
-
- self.set_defaults(**{dest: default})
-
- def _parse_optional(self, arg_string):
-
- if self._is_positional(arg_string):
- return None
-
- # if the option string is present in the parser, return the action
- if arg_string in self._option_string_actions:
- action = self._option_string_actions[arg_string]
- return action, arg_string, None
-
- # if the option string before the "=" is present, return the action
- if '=' in arg_string:
- option_string, explicit_arg = arg_string.split('=', 1)
- if option_string in self._option_string_actions:
- action = self._option_string_actions[option_string]
- return action, option_string, explicit_arg
-
- # search through all possible prefixes of the option string
- # and all actions in the parser for possible interpretations
- option_tuples = self._get_option_tuples(arg_string)
-
- # if multiple actions match, the option string was ambiguous
- if len(option_tuples) > 1:
- options = ', '.join(
- [option_string for action, option_string, explicit_arg in option_tuples])
- tup = arg_string, options
- self.error('ambiguous option: %s could match %s' % tup)
-
- # if exactly one action matched, this segmentation is good,
- # so return the parsed action
- elif len(option_tuples) == 1:
- option_tuple = option_tuples
- return option_tuple
-
- # if it was not found as an option, but it looks like a negative
- # number, it was meant to be positional
- # unless there are negative-number-like options
- if self._negative_number_matcher.match(arg_string):
- if not self._has_negative_number_optionals:
- return None
-
- # it was meant to be an optional but there is no such option
- # in this parser (though it might be a valid option in a subparser)
- return None, arg_string, None
-
- def _is_positional(self, arg_string):
- # if it's an empty string, it was meant to be a positional
- if not arg_string:
- return True
-
- # if it doesn't start with a prefix, it was meant to be positional
- if not arg_string[0] in self.prefix_chars:
- return True
-
- # if it's just a single character, it was meant to be positional
- if len(arg_string) == 1:
- return True
-
- # if it contains a space, it was meant to be a positional
- if ' ' in arg_string and arg_string[0] not in self.prefix_chars:
- return True
-
- return False
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/utils/caching.py
----------------------------------------------------------------------
diff --git a/aria/parser/utils/caching.py b/aria/parser/utils/caching.py
deleted file mode 100644
index 8ebeef7..0000000
--- a/aria/parser/utils/caching.py
+++ /dev/null
@@ -1,134 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 __future__ import absolute_import # so we can import standard 'collections' and 'threading'
-
-from threading import Lock
-from functools import partial
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
-
-
-class cachedmethod(object): # pylint: disable=invalid-name
- """
- Decorator for caching method return values.
-
- The implementation is thread-safe.
-
- Supports :code:`cache_info` to be compatible with Python 3's :code:`functools.lru_cache`.
- Note that the statistics are combined for all instances of the class.
-
- Won't use the cache if not called when bound to an object, allowing you to override the cache.
-
- Adapted from `this solution
- <http://code.activestate.com/recipes/577452-a-memoize-decorator-for-instance-methods/>`__.
- """
-
- ENABLED = True
-
- def __init__(self, func):
- self.func = func
- self.hits = 0
- self.misses = 0
- self.lock = Lock()
-
- def cache_info(self):
- with self.lock:
- return (self.hits, self.misses, None, self.misses)
-
- def reset_cache_info(self):
- with self.lock:
- self.hits = 0
- self.misses = 0
-
- def __get__(self, instance, owner):
- if instance is None:
- # Don't use cache if not bound to an object
- # Note: This is also a way for callers to override the cache
- return self.func
- return partial(self, instance)
-
- def __call__(self, *args, **kwargs):
- if not self.ENABLED:
- return self.func(*args, **kwargs)
-
- instance = args[0]
- cache = instance.get_method_cache()
-
- key = (self.func, args[1:], frozenset(kwargs.items()))
-
- try:
- with self.lock:
- return_value = cache[key]
- self.hits += 1
- except KeyError:
- return_value = self.func(*args, **kwargs)
- with self.lock:
- cache[key] = return_value
- self.misses += 1
- # Another thread may override our cache entry here, so we need to read
- # it again to make sure all threads use the same return value
- return_value = cache.get(key, return_value)
-
- return return_value
-
-class HasCachedMethods(object):
- """
- Provides convenience methods for working with :class:`cachedmethod`.
- """
-
- def __init__(self, method_cache=None):
- self._method_cache = method_cache or {}
-
- def get_method_cache(self):
- return self._method_cache
-
- @property
- def _method_cache_info(self):
- """
- The cache infos of all cached methods.
-
- :rtype: dict of str, 4-tuple
- """
-
- cached_info = OrderedDict()
- for k, v in self.__class__.__dict__.iteritems():
- if isinstance(v, property):
- # The property getter might be cached
- v = v.fget
- if hasattr(v, 'cache_info'):
- cached_info[k] = v.cache_info()
- return cached_info
-
- def _reset_method_cache(self):
- """
- Resets the caches of all cached methods.
- """
-
- if hasattr(self, '_method_cache'):
- self._method_cache = {}
-
- # Note: Another thread may already be storing entries in the cache here.
- # But it's not a big deal! It only means that our cache_info isn't
- # guaranteed to be accurate.
-
- for entry in self.__class__.__dict__.itervalues():
- if isinstance(entry, property):
- # The property getter might be cached
- entry = entry.fget
- if hasattr(entry, 'reset_cache_info'):
- entry.reset_cache_info()
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/utils/collections.py
----------------------------------------------------------------------
diff --git a/aria/parser/utils/collections.py b/aria/parser/utils/collections.py
deleted file mode 100644
index ae45b25..0000000
--- a/aria/parser/utils/collections.py
+++ /dev/null
@@ -1,287 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 __future__ import absolute_import # so we can import standard 'collections'
-
-from copy import deepcopy
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
-
-
-def cls_name(cls):
- module = str(cls.__module__)
- name = str(cls.__name__)
- return name if module == '__builtin__' else '%s.%s' % (module, name)
-
-class FrozenList(list):
- """
- An immutable list.
-
- After initialization it will raise :class:`TypeError` exceptions if modification
- is attempted.
-
- Note that objects stored in the list may not be immutable.
- """
- def __init__(self, *args, **kwargs):
- self.locked = False
- super(FrozenList, self).__init__(*args, **kwargs)
- self.locked = True
-
- def __setitem__(self, index, value):
- if self.locked:
- raise TypeError('frozen list')
- return super(FrozenList, self).__setitem__(index, value)
-
- def __delitem__(self, index):
- if self.locked:
- raise TypeError('frozen list')
- return super(FrozenList, self).__delitem__(index)
-
- def __iadd__(self, values):
- if self.locked:
- raise TypeError('frozen list')
- return super(FrozenList, self).__iadd__(values)
-
- def __deepcopy__(self, memo):
- res = [deepcopy(v, memo) for v in self]
- return FrozenList(res)
-
- def append(self, value):
- if self.locked:
- raise TypeError('frozen list')
- return super(FrozenList, self).append(value)
-
- def extend(self, values):
- if self.locked:
- raise TypeError('frozen list')
- return super(FrozenList, self).append(values)
-
- def insert(self, index, value):
- if self.locked:
- raise TypeError('frozen list')
- return super(FrozenList, self).insert(index, value)
-
-EMPTY_READ_ONLY_LIST = FrozenList()
-
-class FrozenDict(OrderedDict):
- """
- An immutable ordered dict.
-
- After initialization it will raise :class:`TypeError` exceptions if modification
- is attempted.
-
- Note that objects stored in the dict may not be immutable.
- """
-
- def __init__(self, *args, **kwargs):
- self.locked = False
- super(FrozenDict, self).__init__(*args, **kwargs)
- self.locked = True
-
- def __setitem__(self, key, value, **_):
- if self.locked:
- raise TypeError('frozen dict')
- return super(FrozenDict, self).__setitem__(key, value)
-
- def __delitem__(self, key, **_):
- if self.locked:
- raise TypeError('frozen dict')
- return super(FrozenDict, self).__delitem__(key)
-
- def __deepcopy__(self, memo):
- res = [(deepcopy(k, memo), deepcopy(v, memo)) for k, v in self.iteritems()]
- return FrozenDict(res)
-
-EMPTY_READ_ONLY_DICT = FrozenDict()
-
-class StrictList(list):
- """
- A list that raises :class:`TypeError` exceptions when objects of the wrong type are inserted.
- """
-
- def __init__(self,
- items=None,
- value_class=None,
- wrapper_function=None,
- unwrapper_function=None):
- super(StrictList, self).__init__()
- if isinstance(items, StrictList):
- self.value_class = items.value_class
- self.wrapper_function = items.wrapper_function
- self.unwrapper_function = items.unwrapper_function
- self.value_class = value_class
- self.wrapper_function = wrapper_function
- self.unwrapper_function = unwrapper_function
- if items:
- for item in items:
- self.append(item)
-
- def _wrap(self, value):
- if (self.value_class is not None) and (not isinstance(value, self.value_class)):
- raise TypeError('value must be a "%s": %s' % (cls_name(self.value_class), repr(value)))
- if self.wrapper_function is not None:
- value = self.wrapper_function(value)
- return value
-
- def _unwrap(self, value):
- if self.unwrapper_function is not None:
- value = self.unwrapper_function(value)
- return value
-
- def __getitem__(self, index):
- value = super(StrictList, self).__getitem__(index)
- value = self._unwrap(value)
- return value
-
- def __setitem__(self, index, value):
- value = self._wrap(value)
- return super(StrictList, self).__setitem__(index, value)
-
- def __iadd__(self, values):
- values = [self._wrap(v) for v in values]
- return super(StrictList, self).__iadd__(values)
-
- def append(self, value):
- value = self._wrap(value)
- return super(StrictList, self).append(value)
-
- def extend(self, values):
- values = [self._wrap(v) for v in values]
- return super(StrictList, self).extend(values)
-
- def insert(self, index, value):
- value = self._wrap(value)
- return super(StrictList, self).insert(index, value)
-
-class StrictDict(OrderedDict):
- """
- An ordered dict that raises :class:`TypeError` exceptions
- when keys or values of the wrong type are used.
- """
-
- def __init__(self,
- items=None,
- key_class=None,
- value_class=None,
- wrapper_function=None,
- unwrapper_function=None):
- super(StrictDict, self).__init__()
- if isinstance(items, StrictDict):
- self.key_class = items.key_class
- self.value_class = items.value_class
- self.wrapper_function = items.wrapper_function
- self.unwrapper_function = items.unwrapper_function
- self.key_class = key_class
- self.value_class = value_class
- self.wrapper_function = wrapper_function
- self.unwrapper_function = unwrapper_function
- if items:
- for k, v in items:
- self[k] = v
-
- def __getitem__(self, key):
- if (self.key_class is not None) and (not isinstance(key, self.key_class)):
- raise TypeError('key must be a "%s": %s' % (cls_name(self.key_class), repr(key)))
- value = super(StrictDict, self).__getitem__(key)
- if self.unwrapper_function is not None:
- value = self.unwrapper_function(value)
- return value
-
- def __setitem__(self, key, value, **_):
- if (self.key_class is not None) and (not isinstance(key, self.key_class)):
- raise TypeError('key must be a "%s": %s' % (cls_name(self.key_class), repr(key)))
- if (self.value_class is not None) and (not isinstance(value, self.value_class)):
- raise TypeError('value must be a "%s": %s' % (cls_name(self.value_class), repr(value)))
- if self.wrapper_function is not None:
- value = self.wrapper_function(value)
- return super(StrictDict, self).__setitem__(key, value)
-
-def merge(dict_a, dict_b, path=None, strict=False):
- """
- Merges dicts, recursively.
- """
-
- # TODO: a.add_yaml_merge(b), see https://bitbucket.org/ruamel/yaml/src/
- # TODO: 86622a1408e0f171a12e140d53c4ffac4b6caaa3/comments.py?fileviewer=file-view-default
-
- path = path or []
- for key, value_b in dict_b.iteritems():
- if key in dict_a:
- value_a = dict_a[key]
- if isinstance(value_a, dict) and isinstance(value_b, dict):
- merge(value_a, value_b, path + [str(key)], strict)
- elif value_a != value_b:
- if strict:
- raise ValueError('dict merge conflict at %s' % '.'.join(path + [str(key)]))
- else:
- dict_a[key] = value_b
- else:
- dict_a[key] = value_b
- return dict_a
-
-def is_removable(_container, _key, v):
- return (v is None) or ((isinstance(v, dict) or isinstance(v, list)) and (len(v) == 0))
-
-def prune(value, is_removable_function=is_removable):
- """
- Deletes :code:`None` and empty lists and dicts, recursively.
- """
-
- if isinstance(value, list):
- for i, v in enumerate(value):
- if is_removable_function(value, i, v):
- del value[i]
- else:
- prune(v, is_removable_function)
- elif isinstance(value, dict):
- for k, v in value.iteritems():
- if is_removable_function(value, k, v):
- del value[k]
- else:
- prune(v, is_removable_function)
-
- return value
-
-def deepcopy_with_locators(value):
- """
- Like :code:`deepcopy`, but also copies over locators.
- """
-
- res = deepcopy(value)
- copy_locators(res, value)
- return res
-
-def copy_locators(target, source):
- """
- Copies over :code:`_locator` for all elements, recursively.
-
- Assumes that target and source have exactly the same list/dict structure.
- """
-
- locator = getattr(source, '_locator', None)
- if locator is not None:
- try:
- setattr(target, '_locator', locator)
- except AttributeError:
- pass
-
- if isinstance(target, list) and isinstance(source, list):
- for i, _ in enumerate(target):
- copy_locators(target[i], source[i])
- elif isinstance(target, dict) and isinstance(source, dict):
- for k, v in target.iteritems():
- copy_locators(v, source[k])
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3e7f1e15/aria/parser/utils/console.py
----------------------------------------------------------------------
diff --git a/aria/parser/utils/console.py b/aria/parser/utils/console.py
deleted file mode 100644
index 15c01e2..0000000
--- a/aria/parser/utils/console.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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 clint.textui.core import STDOUT
-from clint.textui import puts as _puts
-from clint.textui.colored import ColoredString as _ColoredString
-
-from .formatting import safe_str
-
-class ColoredString(_ColoredString):
- def __init__(self, color, str_, always_color=False, bold=False):
- super(ColoredString, self).__init__(color, safe_str(str_), always_color, bold)
-
-def puts(string='', newline=True, stream=STDOUT):
- _puts(safe_str(string), newline, stream)
-
-class Colored(object):
- @staticmethod
- def black(string, always=False, bold=False):
- return ColoredString('BLACK', string, always_color=always, bold=bold)
-
- @staticmethod
- def red(string, always=False, bold=False):
- return ColoredString('RED', string, always_color=always, bold=bold)
-
- @staticmethod
- def green(string, always=False, bold=False):
- return ColoredString('GREEN', string, always_color=always, bold=bold)
-
- @staticmethod
- def yellow(string, always=False, bold=False):
- return ColoredString('YELLOW', string, always_color=always, bold=bold)
-
- @staticmethod
- def blue(string, always=False, bold=False):
- return ColoredString('BLUE', string, always_color=always, bold=bold)
-
- @staticmethod
- def magenta(string, always=False, bold=False):
- return ColoredString('MAGENTA', string, always_color=always, bold=bold)
-
- @staticmethod
- def cyan(string, always=False, bold=False):
- return ColoredString('CYAN', string, always_color=always, bold=bold)
-
- @staticmethod
- def white(string, always=False, bold=False):
- return ColoredString('WHITE', string, always_color=always, bold=bold)