wip
Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/dffcb988 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/dffcb988 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/dffcb988 Branch: refs/heads/ARIA-262-Inconsistent-node-attributes-behavior Commit: dffcb9883a4c045430b853581a14f1a4d370e882 Parents: 9174f94 Author: max-orlov <[email protected]> Authored: Wed May 31 21:07:49 2017 +0300 Committer: max-orlov <[email protected]> Committed: Thu Jun 1 11:26:08 2017 +0300 ---------------------------------------------------------------------- .../context/collection_instrumentation.py | 92 +++++++++++++------- aria/orchestrator/context/common.py | 5 ++ aria/orchestrator/context/operation.py | 22 ++--- 3 files changed, 74 insertions(+), 45 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/dffcb988/aria/orchestrator/context/collection_instrumentation.py ---------------------------------------------------------------------- diff --git a/aria/orchestrator/context/collection_instrumentation.py b/aria/orchestrator/context/collection_instrumentation.py index 91cfd35..00a9227 100644 --- a/aria/orchestrator/context/collection_instrumentation.py +++ b/aria/orchestrator/context/collection_instrumentation.py @@ -18,6 +18,30 @@ from functools import partial from aria.modeling import models +class _Wrapper(object): + + def __init__(self, instrumented_cls, instrumentation_cls, wrapped, **kwargs): + self._instrumented_cls = instrumented_cls + self._instrumentation_cls = instrumentation_cls + self._wrapped = wrapped + self._kwargs = kwargs + + def _wrap(self, value): + from aria.modeling.models import aria_declarative_base + if isinstance(value, self._instrumented_cls): + return Instrument(**self._kwargs) + elif isinstance(value, aria_declarative_base): + return _Wrapper( + self._instrumented_cls, self._instrumentation_cls, value, **self._kwargs) + return value + + def __getattr__(self, item): + return self._wrap(getattr(self._wrapped, item)) + + def __getitem__(self, item): + return self._wrap(self._wrapped[item]) + + class _InstrumentedCollection(object): def __init__(self, @@ -202,41 +226,47 @@ class _InstrumentedList(_InstrumentedCollection, list): return list(self) -class _InstrumentedModel(object): +class Instrument(object): - def __init__(self, field_name, original_model, model_storage): - super(_InstrumentedModel, self).__init__() - self._field_name = field_name + def __init__(self, original_model, model_storage, field_names): + super(Instrument, self).__init__() + self._field_names = field_names self._model_storage = model_storage self._original_model = original_model - self._apply_instrumentation() + self._instrumentation_cls = self._apply_instrumentation() def __getattr__(self, item): - return getattr(self._original_model, item) + return_value = getattr(self._original_model, item) + if isinstance(return_value, (list, dict)): + return _Wrapper(self._original_model.__class__, + self._instrumentation_cls, + return_value, + field_name=self._field_names, + original_model=self._original_model, + model_storage=self._model_storage, + ) + return return_value def _apply_instrumentation(self): - - field = getattr(self._original_model, self._field_name) - - # Preserve the original value. e.g. original attributes would be located under - # _attributes - setattr(self, '_{0}'.format(self._field_name), field) - - # set instrumented value - setattr(self, self._field_name, _InstrumentedDict(self._model_storage, - self._original_model, - self._field_name, - field)) - - -def instrument_collection(field_name, func=None): - if func is None: - return partial(instrument_collection, field_name) - - def _wrapper(*args, **kwargs): - original_model = func(*args, **kwargs) - return type('Instrumented{0}'.format(original_model.__class__.__name__), - (_InstrumentedModel, ), - {})(field_name, original_model, args[0].model) - - return _wrapper + for field_name in self._field_names: + field = getattr(self._original_model, field_name) + + # Preserve the original value. e.g. original attributes would be located under + # _attributes + setattr(self, '_{0}'.format(field_name), field) + + # set instrumented value + if isinstance(field, dict): + instrumentation_cls = _InstrumentedDict + elif isinstance(field, list): + instrumentation_cls = _InstrumentedList + else: + # TODO: raise proper error + raise + + instrumented_class = instrumentation_cls(seq=field, + parent=self._original_model, + model=self._model_storage, + field_name=field_name) + setattr(self, field_name, instrumented_class) + return instrumentation_cls http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/dffcb988/aria/orchestrator/context/common.py ---------------------------------------------------------------------- diff --git a/aria/orchestrator/context/common.py b/aria/orchestrator/context/common.py index c98e026..22a673e 100644 --- a/aria/orchestrator/context/common.py +++ b/aria/orchestrator/context/common.py @@ -29,6 +29,7 @@ from aria import ( from aria.storage import exceptions from ...utils.uuid import generate_uuid +from . import collection_instrumentation class BaseContext(object): @@ -194,3 +195,7 @@ class BaseContext(object): variables.setdefault('ctx', self) resource_template = jinja2.Template(resource_content) return resource_template.render(variables) + + def instrument(self, original_model, field, *fields): + return collection_instrumentation.Instrument( + original_model, self.model, [field] + list(fields)) \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/dffcb988/aria/orchestrator/context/operation.py ---------------------------------------------------------------------- diff --git a/aria/orchestrator/context/operation.py b/aria/orchestrator/context/operation.py index f0ba337..07ff3cb 100644 --- a/aria/orchestrator/context/operation.py +++ b/aria/orchestrator/context/operation.py @@ -21,6 +21,7 @@ import threading import aria from aria.utils import file +from aria.modeling import models from . import ( common, collection_instrumentation @@ -76,7 +77,6 @@ class BaseOperationContext(common.BaseContext): @property def serialization_dict(self): - context_cls = self.__class__ context_dict = { 'name': self.name, 'service_id': self._service_id, @@ -89,7 +89,7 @@ class BaseOperationContext(common.BaseContext): 'logger_level': self.logger.level } return { - 'context_cls': context_cls, + 'context_cls': self.__class__, 'context': context_dict } @@ -117,22 +117,20 @@ class NodeOperationContext(BaseOperationContext): """ @property - @collection_instrumentation.instrument_collection('attributes') def node_template(self): """ the node of the current operation :return: """ - return self.node.node_template + return self.instrument(self.node.node_template, 'attributes', 'properties') @property - @collection_instrumentation.instrument_collection('attributes') def node(self): """ The node instance of the current operation :return: """ - return self.model.node.get(self._actor_id) + return self.instrument(self.model.node.get(self._actor_id), 'attributes', 'properties') class RelationshipOperationContext(BaseOperationContext): @@ -141,40 +139,36 @@ class RelationshipOperationContext(BaseOperationContext): """ @property - @collection_instrumentation.instrument_collection('attributes') def source_node_template(self): """ The source node :return: """ - return self.source_node.node_template + return self.instrument(self.source_node.node_template, 'attributes') @property - @collection_instrumentation.instrument_collection('attributes') def source_node(self): """ The source node instance :return: """ - return self.relationship.source_node + return self.instrument(self.relationship.source_node, 'attributes') @property - @collection_instrumentation.instrument_collection('attributes') def target_node_template(self): """ The target node :return: """ - return self.target_node.node_template + return self.instrument(self.target_node.node_template, 'attributes') @property - @collection_instrumentation.instrument_collection('attributes') def target_node(self): """ The target node instance :return: """ - return self.relationship.target_node + return self.instrument(self.relationship.target_node, 'attributes') @property def relationship(self):
