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):

Reply via email to