Refactoring of the ObjectStore passing in DSL

ObjectStore is a container for all of the objects that are either
loaded from object model or created at runtime. Thus ObjectStore
instance is required in order to either use new() function or use
class() contract with object model snippet.

In current implementation each object had a object_store property
that was pointing to the ObjectStore instance used to create it (the
one that has the object). In order to create new object an ObjectStore
of the $this object was used for that purpose. This approach caused
several issues:
* There is no $this object in static methods and thus no way to obtain
   current ObjectStore
* Objects are bind to their stores so temporary ObjectStore instances
  cannot be used to load object graphs

 This refactoring moves ObjectStore instances to the thread-local attribute.
 Thus there is always a "current" ObjectStore.

 Also because ObjectStore has a reference to the MuranoDslExecutor instance
 it becomes possible to get current executor and everything else that it contains
 (current execution session, attribute store, package loader) from the local
 thread storage without passing it in the hidden context variables.

Change-Id: I19a08b391486c1ae1b98ca559c8d3fafaca6e1ef
This commit is contained in:
Stan Lagun 2016-07-24 14:32:04 -07:00
parent 6b66e9914d
commit 0a835b87f0
26 changed files with 203 additions and 259 deletions

View File

@ -162,7 +162,7 @@ class MuranoTestRunner(object):
method = obj.type.find_single_method(name)
method.scope = dsl_types.MethodScopes.Public
LOG.debug('Executing: {0}.{1}'.format(obj.type.name, name))
obj.type.invoke(name, exc, obj, (), {})
exc.run(obj.type, name, obj, (), {})
def _validate_keystone_opts(self, args):
ks_opts_to_config = {
@ -254,8 +254,10 @@ class MuranoTestRunner(object):
pkg_loader,
mock_context_manager.MockContextManager(),
test_session)
obj = package.find_class(pkg_class, False).new(
None, dsl_executor.object_store, dsl_executor)(None)
with helpers.with_object_store(dsl_executor.object_store):
obj = helpers.instantiate(
{}, None, None, None,
package.find_class(pkg_class, False))
test_name = "{0}.{1}".format(obj.type.name, m)
dots_number = max_length - len(test_name)
@ -267,7 +269,7 @@ class MuranoTestRunner(object):
test_session.start()
try:
run_count += 1
obj.type.invoke(m, dsl_executor, obj, (), {})
dsl_executor.run(obj.type, m, obj, (), {})
self._call_service_method(
'tearDown', dsl_executor, obj)
msg = '{0}{1}{2}\n'.format(OK_COLOR, 'OK', END_COLOR)

View File

@ -289,7 +289,7 @@ class TaskExecutor(object):
method_name, kwargs = self.action['method'], self.action['args']
if obj is not None:
return obj.type.invoke(method_name, mpl_executor, obj, (), kwargs)
return mpl_executor.run(obj.type, method_name, obj, (), kwargs)
def _create_trust(self):
if not CONF.engine.use_trusts:
@ -352,4 +352,4 @@ class StaticActionExecutor(object):
cls = package.find_class(class_name, search_requirements=False)
method_name, kwargs = self.action['method'], self.action['args']
return cls.invoke(method_name, mpl_executor, None, (), kwargs)
return mpl_executor.run(cls, method_name, None, (), kwargs)

View File

@ -20,16 +20,12 @@ ITERATORS_LIMIT = 2000
CTX_ACTIONS_ONLY = '?actionsOnly'
CTX_ALLOW_PROPERTY_WRITES = '$?allowPropertyWrites'
CTX_ARGUMENT_OWNER = '$?argumentOwner'
CTX_ATTRIBUTE_STORE = '$?attributeStore'
CTX_CALLER_CONTEXT = '$?callerContext'
CTX_CURRENT_INSTRUCTION = '$?currentInstruction'
CTX_CURRENT_EXCEPTION = '$?currentException'
CTX_CURRENT_METHOD = '$?currentMethod'
CTX_EXECUTOR = '$?executor'
CTX_EXECUTION_SESSION = '$?executionSession'
CTX_NAMES_SCOPE = '$?namesScope'
CTX_ORIGINAL_CONTEXT = '$?originalContext'
CTX_PACKAGE_LOADER = '$?packageLoader'
CTX_SKIP_FRAME = '$?skipFrame'
CTX_THIS = '$?this'
CTX_TYPE = '$?type'
@ -51,6 +47,7 @@ CORE_LIBRARY_OBJECT = 'io.murano.Object'
TL_CONTEXT = '__murano_context'
TL_ID = '__thread_id'
TL_OBJECT_STORE = '__murano_object_store'
TL_SESSION = '__murano_execution_session'
RUNTIME_VERSION_1_0 = semantic_version.Version('1.0.0')

View File

@ -91,8 +91,7 @@ class ThisParameter(yaqltypes.HiddenParameterType, yaqltypes.SmartType):
*args, **kwargs):
this = helpers.get_this(context)
if isinstance(this, dsl_types.MuranoObject):
executor = helpers.get_executor(context)
return MuranoObjectInterface(this, executor)
return MuranoObjectInterface(this)
return this
@ -161,18 +160,17 @@ class MuranoObjectInterface(dsl_types.MuranoObjectInterface):
oi[key] = value
class CallInterface(object):
def __init__(self, mpl_object, executor):
def __init__(self, mpl_object, object_store):
self.__object = mpl_object
self.__executor = executor
self.__object_store = object_store
def __getattr__(self, item):
executor = self.__executor or helpers.get_executor()
def func(*args, **kwargs):
self._insert_instruction()
return self.__object.type.invoke(
item, executor, self.__object, args, kwargs,
helpers.get_context())
with helpers.with_object_store(self.__object_store):
return self.__object.type.invoke(
item, self.__object, args, kwargs,
helpers.get_context())
return func
@staticmethod
@ -186,9 +184,9 @@ class MuranoObjectInterface(dsl_types.MuranoObjectInterface):
context[constants.CTX_CURRENT_INSTRUCTION] = NativeInstruction(
frame[4][0].strip(), location)
def __init__(self, mpl_object, executor=None):
def __init__(self, mpl_object, object_store=None):
self.__object = mpl_object
self.__executor = executor
self.__object_store = object_store or helpers.get_object_store()
@property
def object(self):
@ -203,7 +201,7 @@ class MuranoObjectInterface(dsl_types.MuranoObjectInterface):
owner = self.__object.owner
if owner is None:
return None
return MuranoObjectInterface(owner, self.__executor)
return MuranoObjectInterface(owner)
def find_owner(self, type, optional=False):
if isinstance(type, six.string_types):
@ -213,7 +211,7 @@ class MuranoObjectInterface(dsl_types.MuranoObjectInterface):
p = self.__object.owner
while p is not None:
if type.is_compatible(p):
return MuranoObjectInterface(p, self.__executor)
return MuranoObjectInterface(p)
p = p.owner
if not optional:
raise ValueError('Object is not owned by any instance of type '
@ -244,8 +242,7 @@ class MuranoObjectInterface(dsl_types.MuranoObjectInterface):
return MuranoObjectInterface(
helpers.cast(
self.__object, murano_class,
version_spec or helpers.get_type()),
self.__executor)
version_spec or helpers.get_type()))
def is_instance_of(self, murano_class, version_spec=None):
return helpers.is_instance_of(
@ -268,7 +265,7 @@ class MuranoObjectInterface(dsl_types.MuranoObjectInterface):
def __call__(self):
return MuranoObjectInterface.CallInterface(
self.object, self.__executor)
self.object, self.__object_store)
def __repr__(self):
return '<{0}>'.format(repr(self.object))

View File

@ -15,7 +15,6 @@
import collections
import contextlib
import itertools
import weakref
import eventlet
import eventlet.event
@ -53,6 +52,10 @@ class MuranoDslExecutor(object):
def object_store(self):
return self._object_store
@property
def execution_session(self):
return self._session
@property
def attribute_store(self):
return self._attribute_store
@ -67,12 +70,6 @@ class MuranoDslExecutor(object):
def invoke_method(self, method, this, context, args, kwargs,
skip_stub=False):
with helpers.execution_session(self._session):
return self._invoke_method(
method, this, context, args, kwargs, skip_stub=skip_stub)
def _invoke_method(self, method, this, context, args, kwargs,
skip_stub=False):
if isinstance(this, dsl.MuranoObjectInterface):
this = this.object
kwargs = utils.filter_parameters_dict(kwargs)
@ -127,7 +124,7 @@ class MuranoDslExecutor(object):
native_this = this.get_reference()
else:
native_this = dsl.MuranoObjectInterface(this.cast(
method.declaring_type), self)
method.declaring_type))
return method.body(
yaql_engine, context, native_this)(*args, **kwargs)
else:
@ -246,7 +243,7 @@ class MuranoDslExecutor(object):
return tuple(), parameter_values
def load(self, data):
with helpers.execution_session(self._session):
with helpers.with_object_store(self.object_store):
return self._load(data)
def _load(self, data):
@ -256,33 +253,29 @@ class MuranoDslExecutor(object):
result = self._object_store.load(data.get(constants.DM_OBJECTS), None)
if result is None:
return None
return dsl.MuranoObjectInterface(result, executor=self)
return dsl.MuranoObjectInterface(result)
def cleanup(self, data):
with helpers.execution_session(self._session):
return self._cleanup(data)
def _cleanup(self, data):
objects_copy = data.get(constants.DM_OBJECTS_COPY)
if not objects_copy:
return
gc_object_store = object_store.ObjectStore(self)
gc_object_store.load(objects_copy, None)
objects_to_clean = []
for object_id in self._list_potential_object_ids(objects_copy):
if (gc_object_store.has(object_id) and
not self._object_store.has(object_id)):
obj = gc_object_store.get(object_id)
objects_to_clean.append(obj)
if objects_to_clean:
for obj in objects_to_clean:
self._destroy_object(obj)
with helpers.with_object_store(gc_object_store):
gc_object_store.load(objects_copy, None)
objects_to_clean = []
for object_id in self._list_potential_object_ids(objects_copy):
if (gc_object_store.has(object_id) and
not self._object_store.has(object_id)):
obj = gc_object_store.get(object_id)
objects_to_clean.append(obj)
if objects_to_clean:
for obj in objects_to_clean:
self._destroy_object(obj)
def cleanup_orphans(self, alive_object_ids):
with helpers.execution_session(self._session):
orphan_ids = self._collect_orphans(alive_object_ids)
self._destroy_orphans(orphan_ids)
return len(orphan_ids)
orphan_ids = self._collect_orphans(alive_object_ids)
self._destroy_orphans(orphan_ids)
return len(orphan_ids)
def _collect_orphans(self, alive_object_ids):
orphan_ids = []
@ -292,15 +285,16 @@ class MuranoDslExecutor(object):
return orphan_ids
def _destroy_orphans(self, orphan_ids):
for obj_id in orphan_ids:
self._destroy_object(self._object_store.get(obj_id))
self._object_store.remove(obj_id)
with helpers.with_object_store(self.object_store):
for obj_id in orphan_ids:
self._destroy_object(self._object_store.get(obj_id))
self._object_store.remove(obj_id)
def _destroy_object(self, obj):
methods = obj.type.find_methods(lambda m: m.name == '.destroy')
for method in methods:
try:
method.invoke(self, obj, (), {}, None)
method.invoke(obj, (), {}, None)
except Exception as e:
LOG.warning(_LW(
'Muted exception during execution of .destroy '
@ -325,13 +319,6 @@ class MuranoDslExecutor(object):
context = self._root_context_cache.get(runtime_version)
if not context:
context = self.context_manager.create_root_context(runtime_version)
context = context.create_child_context()
context[constants.CTX_EXECUTOR] = weakref.ref(self)
context[constants.CTX_PACKAGE_LOADER] = weakref.ref(
self._package_loader)
context[constants.CTX_EXECUTION_SESSION] = self._session
context[constants.CTX_ATTRIBUTE_STORE] = weakref.ref(
self._attribute_store)
self._root_context_cache[runtime_version] = context
return context
@ -394,3 +381,7 @@ class MuranoDslExecutor(object):
context = object_context.create_child_context()
context[constants.CTX_CURRENT_METHOD] = method
return context
def run(self, cls, method_name, this, args, kwargs):
with helpers.with_object_store(self.object_store):
return cls.invoke(method_name, this, args, kwargs)

View File

@ -116,13 +116,12 @@ def parallel_select(collection, func, limit=1000):
# workaround for eventlet issue 232
# https://github.com/eventlet/eventlet/issues/232
context = get_context()
session = get_execution_session()
object_store = get_object_store()
def wrapper(element):
try:
with contextual(context):
with execution_session(session):
return func(element), False, None
with with_object_store(object_store), contextual(context):
return func(element), False, None
except Exception as e:
return e, True, sys.exc_info()[2]
@ -145,10 +144,9 @@ def get_context():
return getattr(current_thread, constants.TL_CONTEXT, None)
def get_executor(context=None):
context = context or get_context()
result = context[constants.CTX_EXECUTOR]
return None if not result else result()
def get_executor():
store = get_object_store()
return None if store is None else store.executor
def get_type(context=None):
@ -156,28 +154,19 @@ def get_type(context=None):
return context[constants.CTX_TYPE]
def get_execution_session(context=None):
context = context or get_context()
session = None
if context is not None:
session = context[constants.CTX_EXECUTION_SESSION]
if session is None:
current_thread = eventlet.greenthread.getcurrent()
session = getattr(current_thread, constants.TL_SESSION, None)
return session
def get_execution_session():
executor = get_executor()
return None if executor is None else executor.execution_session
def get_object_store(context=None):
context = context or get_context()
this = context[constants.CTX_THIS]
return this.object_store if isinstance(
this, dsl_types.MuranoObject) else None
def get_object_store():
current_thread = eventlet.greenthread.getcurrent()
return getattr(current_thread, constants.TL_OBJECT_STORE, None)
def get_package_loader(context=None):
context = context or get_context()
result = context[constants.CTX_PACKAGE_LOADER]
return None if not result else result()
def get_package_loader():
executor = get_executor()
return None if executor is None else executor.package_loader
def get_this(context=None):
@ -190,10 +179,9 @@ def get_caller_context(context=None):
return context[constants.CTX_CALLER_CONTEXT]
def get_attribute_store(context=None):
context = context or get_context()
store = context[constants.CTX_ATTRIBUTE_STORE]
return None if not store else store()
def get_attribute_store():
executor = get_executor()
return None if executor is None else executor.attribute_store
def get_current_instruction(context=None):
@ -266,8 +254,8 @@ def contextual(ctx):
return thread_local_attribute(constants.TL_CONTEXT, ctx)
def execution_session(session):
return thread_local_attribute(constants.TL_SESSION, session)
def with_object_store(object_store):
return thread_local_attribute(constants.TL_OBJECT_STORE, object_store)
def parse_version_spec(version_spec):
@ -513,8 +501,7 @@ def resolve_type(value, scope_type, return_reference=False):
return result
def instantiate(data, owner, object_store, context, scope_type,
default_type=None):
def instantiate(data, owner, context, scope_type, default_type=None):
if data is None:
data = {}
if not isinstance(data, yaqlutils.MappingType):
@ -528,9 +515,7 @@ def instantiate(data, owner, object_store, context, scope_type,
type_obj = resolve_type(key, scope_type)
props = yaqlutils.filter_parameters_dict(data[key] or {})
props = evaluate(props, context, freeze=False)
return type_obj.new(
owner, object_store, object_store.executor)(
context, **props)
return type_obj.new(owner)(context, **props)
data = evaluate(data, context, freeze=False)
if '?' not in data:
@ -543,7 +528,7 @@ def instantiate(data, owner, object_store, context, scope_type,
if 'id' not in data['?']:
data['?']['id'] = uuid.uuid4().hex
return object_store.load(data, owner, context)
return get_object_store().load(data, owner, context)
def function(c):

View File

@ -20,7 +20,6 @@ import six
from murano.dsl import dsl_types
from murano.dsl import helpers
from murano.dsl import object_store
class MetaProvider(object):
@ -58,8 +57,8 @@ class MetaData(MetaProvider):
used_types.add(type_obj)
factory_maker = lambda template: \
lambda context, store: helpers.instantiate(
template, owner=None, object_store=store,
lambda context: helpers.instantiate(
template, owner=None,
context=context, scope_type=scope_type())
factories.append(factory_maker({type_obj: props}))
@ -68,11 +67,7 @@ class MetaData(MetaProvider):
def get_meta(self, context):
if self._meta is None:
executor = helpers.get_executor(context)
store = object_store.ObjectStore(executor)
self._meta = list(map(
lambda x: x(context, store),
self._meta_factories))
self._meta = list(map(lambda x: x(context), self._meta_factories))
return self._meta

View File

@ -202,7 +202,7 @@ class MuranoMethod(dsl_types.MuranoMethod, meta.MetaProvider):
return method._meta
if self._meta_values is None:
executor = helpers.get_executor(context)
executor = helpers.get_executor()
context = executor.create_type_context(
self.declaring_type, caller_context=context)
self._meta_values = meta.merge_providers(
@ -213,8 +213,7 @@ class MuranoMethod(dsl_types.MuranoMethod, meta.MetaProvider):
return 'MuranoMethod({0}::{1})'.format(
self.declaring_type.name, self.name)
def invoke(self, executor, this, args, kwargs, context=None,
skip_stub=False):
def invoke(self, this, args, kwargs, context=None, skip_stub=False):
if isinstance(this, dsl.MuranoObjectInterface):
this = this.object
if this and not self.declaring_type.is_compatible(this):
@ -226,6 +225,7 @@ class MuranoMethod(dsl_types.MuranoMethod, meta.MetaProvider):
this = this.cast(self.declaring_type)
else:
this = self.declaring_type
executor = helpers.get_executor()
return executor.invoke_method(
self, this, context, args, kwargs, skip_stub)
@ -278,7 +278,7 @@ class MuranoMethodArgument(dsl_types.MuranoMethodArgument, typespec.Spec,
return self._usage
def get_meta(self, context):
executor = helpers.get_executor(context)
executor = helpers.get_executor()
context = executor.create_type_context(
self.murano_method.declaring_type, caller_context=context)

View File

@ -12,8 +12,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import weakref
import six
from murano.dsl import constants
@ -25,8 +23,8 @@ from murano.dsl import yaql_integration
class MuranoObject(dsl_types.MuranoObject):
def __init__(self, murano_class, owner, object_store, executor,
object_id=None, name=None, known_classes=None, this=None):
def __init__(self, murano_class, owner, object_id=None, name=None,
known_classes=None, this=None):
if known_classes is None:
known_classes = {}
self.__owner = owner.real_this if owner else None
@ -37,9 +35,6 @@ class MuranoObject(dsl_types.MuranoObject):
self.__this = this
self.__name = name
self.__extension = None
self.__object_store = \
None if object_store is None else weakref.ref(object_store)
self.__executor = weakref.ref(executor)
self.__config = murano_class.package.get_class_config(
murano_class.name)
if not isinstance(self.__config, dict):
@ -49,7 +44,7 @@ class MuranoObject(dsl_types.MuranoObject):
name = parent_class.name
if name not in known_classes:
obj = parent_class.new(
owner, object_store, executor, object_id=self.__object_id,
owner, object_id=self.__object_id,
known_classes=known_classes, this=self.real_this).object
self.__parents[name] = known_classes[name] = obj
@ -69,17 +64,10 @@ class MuranoObject(dsl_types.MuranoObject):
def extension(self, value):
self.__extension = value
@property
def object_store(self):
return None if self.__object_store is None else self.__object_store()
@property
def executor(self):
return self.__executor()
def initialize(self, context, object_store, params):
def initialize(self, context, params):
if self.__initialized:
return
object_store = helpers.get_object_store()
for property_name in self.__type.properties:
spec = self.__type.properties[property_name]
if spec.usage == dsl_types.PropertyUsages.Config:
@ -137,7 +125,6 @@ class MuranoObject(dsl_types.MuranoObject):
raise exceptions.CircularExpressionDependenciesError()
last_errors = errors
executor = helpers.get_executor(context)
if ((object_store is None or not object_store.initializing) and
self.__extension is None):
method = self.type.methods.get('__init__')
@ -146,15 +133,14 @@ class MuranoObject(dsl_types.MuranoObject):
method.body, **params)
self.__extension = method.invoke(
executor, self, filtered_params[0],
filtered_params[1], context)
self, filtered_params[0], filtered_params[1], context)
for parent in self.__parents.values():
parent.initialize(context, object_store, params)
parent.initialize(context, params)
if (object_store is None or not object_store.initializing) and init:
context[constants.CTX_ARGUMENT_OWNER] = self.real_this
init.invoke(executor, self.real_this, (), init_args, context)
init.invoke(self.real_this, (), init_args, context)
self.__initialized = True
if object_store is not None and not object_store.initializing:
@ -215,7 +201,7 @@ class MuranoObject(dsl_types.MuranoObject):
declared_properties = start_type.find_properties(
lambda p: p.name == name)
if context is None:
context = self.executor.create_object_context(self)
context = helpers.get_executor().create_object_context(self)
if len(declared_properties) > 0:
declared_properties = self.type.find_properties(
lambda p: p.name == name)

View File

@ -226,7 +226,7 @@ class MuranoPackage(dsl_types.MuranoPackage, dslmeta.MetaProvider):
def get_meta(self, context):
if six.callable(self._meta):
executor = helpers.get_executor(context)
executor = helpers.get_executor()
context = executor.create_package_context(self)
self._meta = self._meta().get_meta(context)
return self._meta

View File

@ -70,7 +70,7 @@ class MuranoProperty(dsl_types.MuranoProperty, typespec.Spec,
return prop._meta
if self._meta_values is None:
executor = helpers.get_executor(context)
executor = helpers.get_executor()
context = executor.create_type_context(
self.declaring_type, caller_context=context)

View File

@ -261,9 +261,9 @@ class MuranoClass(dsl_types.MuranoClass, MuranoType, dslmeta.MetaProvider):
raise exceptions.AmbiguousPropertyNameError(name)
return result[0]
def invoke(self, name, executor, this, args, kwargs, context=None):
def invoke(self, name, this, args, kwargs, context=None):
method = self.find_single_method(name)
return method.invoke(executor, this, args, kwargs, context)
return method.invoke(this, args, kwargs, context)
def is_compatible(self, obj):
if isinstance(obj, (murano_object.MuranoObject,
@ -274,16 +274,16 @@ class MuranoClass(dsl_types.MuranoClass, MuranoType, dslmeta.MetaProvider):
return True
return any(cls is self for cls in obj.ancestors())
def new(self, owner, object_store, executor, **kwargs):
def new(self, owner, **kwargs):
obj = murano_object.MuranoObject(
self, helpers.weak_proxy(owner), object_store, executor, **kwargs)
self, helpers.weak_proxy(owner), **kwargs)
def initializer(__context, **params):
if __context is None:
__context = executor.create_object_context(obj)
__context = helpers.get_executor().create_object_context(obj)
init_context = __context.create_child_context()
init_context[constants.CTX_ALLOW_PROPERTY_WRITES] = True
obj.initialize(init_context, object_store, params)
obj.initialize(init_context, params)
return obj
initializer.object = obj
@ -430,7 +430,7 @@ class MuranoClass(dsl_types.MuranoClass, MuranoType, dslmeta.MetaProvider):
def get_meta(self, context):
if self._meta_values is None:
executor = helpers.get_executor(context)
executor = helpers.get_executor()
context = executor.create_type_context(
self, caller_context=context)
self._meta_values = dslmeta.merge_providers(

View File

@ -87,9 +87,7 @@ class ObjectStore(object):
return factory
else:
factory = class_obj.new(
owner, self, self.executor,
name=system_key.get('name'),
object_id=object_id)
owner, name=system_key.get('name'), object_id=object_id)
self._store[object_id] = factory
system_value = ObjectStore._get_designer_attributes(system_key)
self._designer_attributes_store[object_id] = system_value

View File

@ -106,6 +106,4 @@ def create_stack_trace(context, include_native_frames=True):
stacktrace = yaql_integration.call_func(
context, 'new', 'io.murano.StackTrace',
includeNativeFrames=include_native_frames)
executor = helpers.get_executor(context)
return dsl.MuranoObjectInterface(
stacktrace, executor)
return dsl.MuranoObjectInterface(stacktrace)

View File

@ -25,7 +25,7 @@ class SysObject(object):
if owner is None:
owner = helpers.get_type(helpers.get_caller_context(context))
attribute_store = helpers.get_attribute_store(context)
attribute_store = helpers.get_attribute_store()
attribute_store.set(this.object, owner, name, value)
@specs.parameter('owner', dsl.MuranoTypeParameter(nullable=True))
@ -33,7 +33,7 @@ class SysObject(object):
if owner is None:
owner = helpers.get_type(helpers.get_caller_context(context))
attribute_store = helpers.get_attribute_store(context)
attribute_store = helpers.get_attribute_store()
result = attribute_store.get(this.object, owner, name)
return default if result is None else result

View File

@ -18,7 +18,6 @@ from yaql import yaqlization
from murano.dsl import dsl
from murano.dsl import dsl_types
from murano.dsl import helpers
from murano.dsl import meta
@ -154,8 +153,7 @@ def method_owner(murano_method):
@specs.name('invoke')
@specs.method
def method_invoke(context, method, __object, *args, **kwargs):
executor = helpers.get_executor(context)
return method.invoke(executor, __object, args, kwargs, context)
return method.invoke(__object, args, kwargs, context)
@specs.yaql_property(dsl_types.MuranoPackage)

View File

@ -18,6 +18,7 @@ from yaql import utils
from murano.dsl import dsl
from murano.dsl import dsl_types
from murano.dsl import helpers
class ObjRef(object):
@ -26,7 +27,8 @@ class ObjRef(object):
def serialize(obj, executor):
return serialize_model(obj, executor, True)[0]['Objects']
with helpers.with_object_store(executor.object_store):
return serialize_model(obj, executor, True)[0]['Objects']
def _serialize_object(root_object, designer_attributes, allow_refs,
@ -53,11 +55,12 @@ def serialize_model(root_object, executor, allow_refs=False):
attributes = []
serialized_objects = set()
else:
tree, serialized_objects = _serialize_object(
root_object, designer_attributes, allow_refs, executor)
tree_copy, _ = _serialize_object(root_object, None, allow_refs,
executor)
attributes = executor.attribute_store.serialize(serialized_objects)
with helpers.with_object_store(executor.object_store):
tree, serialized_objects = _serialize_object(
root_object, designer_attributes, allow_refs, executor)
tree_copy, _ = _serialize_object(root_object, None, allow_refs,
executor)
attributes = executor.attribute_store.serialize(serialized_objects)
return {
'Objects': tree,

View File

@ -151,7 +151,7 @@ class TypeScheme(object):
@specs.parameter('version_spec', yaqltypes.String(True))
@specs.method
def class_(value, name, default_name=None, version_spec=None):
object_store = None if this is None else this.object_store
object_store = helpers.get_object_store()
if not default_name:
default_name = name
murano_class = name.type
@ -163,8 +163,7 @@ class TypeScheme(object):
obj = value.object
elif isinstance(value, utils.MappingType):
obj = helpers.instantiate(
value, owner, object_store, root_context,
calling_type, default_name)
value, owner, root_context, calling_type, default_name)
elif isinstance(value, six.string_types) and object_store:
obj = object_store.get(value)
if obj is None:

View File

@ -29,7 +29,7 @@ class Spec(object):
def transform(self, value, this, owner, context, default=None):
if default is None:
default = self.default
executor = helpers.get_executor(context)
executor = helpers.get_executor()
if isinstance(this, dsl_types.MuranoTypeReference):
this = this.type
if isinstance(this, dsl_types.MuranoType):

View File

@ -47,15 +47,12 @@ def cast(context, object_, type__, version_spec=None):
@specs.parameter('__object_name', yaqltypes.String(True))
def new(__context, __type_name, __owner=None, __object_name=None, __extra=None,
**parameters):
object_store = helpers.get_object_store(__context)
executor = helpers.get_executor(__context)
new_context = __context.create_child_context()
for key, value in six.iteritems(parameters):
if utils.is_keyword(key):
new_context[key] = value
return __type_name.type.new(
__owner, object_store, executor, name=__object_name)(
new_context, **parameters)
__owner, name=__object_name)(new_context, **parameters)
@specs.parameter('type_name', dsl.MuranoTypeParameter())
@ -160,7 +157,7 @@ def obj_attribution_static(context, cls, property_name):
@specs.inject('operator', yaqltypes.Super(with_context=True))
@specs.name('#operator_.')
def op_dot(context, receiver, expr, operator):
executor = helpers.get_executor(context)
executor = helpers.get_executor()
type_context = executor.context_manager.create_type_context(receiver.type)
obj_context = executor.context_manager.create_object_context(receiver)
ctx2 = helpers.link_contexts(
@ -174,7 +171,7 @@ def op_dot(context, receiver, expr, operator):
@specs.inject('operator', yaqltypes.Super(with_context=True))
@specs.name('#operator_.')
def op_dot_static(context, receiver, expr, operator):
executor = helpers.get_executor(context)
executor = helpers.get_executor()
type_context = executor.context_manager.create_type_context(
receiver.type)
ctx2 = helpers.link_contexts(context, type_context)

View File

@ -240,11 +240,10 @@ def _build_native_stub_function_definitions(murano_method):
@specs.parameter('__receiver', yaqltypes.NotOfType(
dsl_types.MuranoTypeReference))
def payload(__context, __receiver, *args, **kwargs):
executor = helpers.get_executor(__context)
args = tuple(dsl.to_mutable(arg, engine) for arg in args)
kwargs = dsl.to_mutable(kwargs, engine)
return helpers.evaluate(murano_method.invoke(
executor, __receiver, args, kwargs, __context, True), __context)
__receiver, args, kwargs, __context, True), __context)
@specs.method
@specs.name(murano_method.name)
@ -252,23 +251,21 @@ def _build_native_stub_function_definitions(murano_method):
@specs.parameter('__receiver', yaqltypes.NotOfType(
dsl_types.MuranoTypeReference))
def extension_payload(__context, __receiver, *args, **kwargs):
executor = helpers.get_executor(__context)
args = tuple(dsl.to_mutable(arg, engine) for arg in args)
kwargs = dsl.to_mutable(kwargs, engine)
return helpers.evaluate(murano_method.invoke(
executor, murano_method.declaring_type,
(__receiver,) + args, kwargs, __context, True), __context)
murano_method.declaring_type, (__receiver,) + args, kwargs,
__context, True), __context)
@specs.method
@specs.name(murano_method.name)
@specs.meta(constants.META_MURANO_METHOD, murano_method)
@specs.parameter('__receiver', dsl_types.MuranoTypeReference)
def static_payload(__context, __receiver, *args, **kwargs):
executor = helpers.get_executor(__context)
args = tuple(dsl.to_mutable(arg, engine) for arg in args)
kwargs = dsl.to_mutable(kwargs, engine)
return helpers.evaluate(murano_method.invoke(
executor, __receiver, args, kwargs, __context, True), __context)
__receiver, args, kwargs, __context, True), __context)
if murano_method.usage in dsl_types.MethodUsages.InstanceMethods:
return specs.get_function_definition(payload), None
@ -297,9 +294,7 @@ def _build_mpl_stub_function_definitions(murano_method):
def _create_instance_mpl_stub(murano_method):
def payload(__context, __receiver, *args, **kwargs):
executor = helpers.get_executor(__context)
return murano_method.invoke(
executor, __receiver, args, kwargs, __context, True)
return murano_method.invoke(__receiver, args, kwargs, __context, True)
fd = _create_basic_mpl_stub(murano_method, 1, payload, False)
receiver_type = dsl.MuranoObjectParameter(
@ -310,9 +305,7 @@ def _create_instance_mpl_stub(murano_method):
def _create_static_mpl_stub(murano_method):
def payload(__context, __receiver, *args, **kwargs):
executor = helpers.get_executor(__context)
return murano_method.invoke(
executor, __receiver, args, kwargs, __context, True)
return murano_method.invoke(__receiver, args, kwargs, __context, True)
fd = _create_basic_mpl_stub(murano_method, 1, payload, False)
receiver_type = dsl.MuranoTypeParameter(
@ -323,10 +316,9 @@ def _create_static_mpl_stub(murano_method):
def _create_extension_mpl_stub(murano_method):
def payload(__context, __receiver, *args, **kwargs):
executor = helpers.get_executor(__context)
return murano_method.invoke(
executor, murano_method.declaring_type,
(__receiver,) + args, kwargs, __context, True)
murano_method.declaring_type, (__receiver,) + args, kwargs,
__context, True)
return _create_basic_mpl_stub(murano_method, 0, payload, True)

View File

@ -104,7 +104,7 @@ def with_original(context, **kwargs):
@specs.parameter('mock_name', yaqltypes.String())
def inject_method_with_str(context, target, target_method,
mock_object, mock_name):
ctx_manager = helpers.get_executor(context).context_manager
ctx_manager = helpers.get_executor().context_manager
current_class = helpers.get_type(context)
mock_func = current_class.find_single_method(mock_name)
@ -114,9 +114,8 @@ def inject_method_with_str(context, target, target_method,
result_fd = original_function.instance_stub.clone()
def payload_adapter(__context, __sender, *args, **kwargs):
executor = helpers.get_executor(__context)
return mock_func.invoke(
executor, mock_object, args, kwargs, __context, True)
mock_object, args, kwargs, __context, True)
result_fd.payload = payload_adapter
existing_mocks = ctx_manager.class_mock_ctx.setdefault(
@ -130,7 +129,7 @@ def inject_method_with_str(context, target, target_method,
@specs.parameter('target_method', yaqltypes.String())
@specs.parameter('expr', yaqltypes.Lambda(with_context=True))
def inject_method_with_yaql_expr(context, target, target_method, expr):
ctx_manager = helpers.get_executor(context).context_manager
ctx_manager = helpers.get_executor().context_manager
original_class = target.type
original_function = original_class.find_single_method(target_method)

View File

@ -101,9 +101,9 @@ class Runner(object):
cls = obj if isinstance(obj, dsl_types.MuranoType) else obj.type
runtime_version = cls.package.runtime_version
yaql_engine = yaql_integration.choose_yaql_engine(runtime_version)
return dsl.to_mutable(cls.invoke(
name, self.executor, obj, tuple(final_args), final_kwargs),
yaql_engine)
with helpers.with_object_store(self.executor.object_store):
return dsl.to_mutable(cls.invoke(
name, obj, tuple(final_args), final_kwargs), yaql_engine)
except dsl_exception.MuranoPlException as e:
if not self.preserve_exception:
original_exception = getattr(e, 'original_exception', None)
@ -145,3 +145,6 @@ class Runner(object):
@preserve_exception.setter
def preserve_exception(self, value):
self._preserve_exception = value
def session(self):
return helpers.with_object_store(self.executor.object_store)

View File

@ -16,10 +16,6 @@
import mock
from murano.common import exceptions as exc
from murano.dsl import constants
from murano.dsl import helpers
from murano.dsl import yaql_integration
from murano.engine import execution_session
from murano.engine.system import agent
from murano.engine.system import agent_listener
from murano.tests.unit.dsl.foundation import object_model as om
@ -36,15 +32,12 @@ class TestAgentListener(test_case.DslTestCase):
model = om.Object(
'AgentListenerTests')
self.runner = self.new_runner(model)
self.context = yaql_integration.create_empty_context()
self.context[constants.CTX_EXECUTION_SESSION] = \
execution_session.ExecutionSession()
def test_listener_enabled(self):
self.override_config('disable_murano_agent', False, 'engine')
al = self.runner.testAgentListener().extension
self.assertTrue(al.enabled)
with helpers.contextual(self.context):
with self.runner.session():
try:
al.subscribe('msgid', 'event')
self.assertEqual({'msgid': 'event'}, al._subscriptions)

View File

@ -45,10 +45,12 @@ class TestActionManager(tda.ModifyActionTestCase):
self.assertRaises(ValueError, manager.load_action, 'no-such-action')
def test_action_apply(self):
manager = am.ModifyActionManager()
action_spec = 'remove-object: {object_id: %s}' % self._dict_member.id
manager.apply_action(self._obj,
action_spec)
with self._runner.session():
manager = am.ModifyActionManager()
obj_id = self._dict_member.id
action_spec = 'remove-object: {object_id: %s}' % obj_id
manager.apply_action(self._obj,
action_spec)
def test_action_apply_invalid_spec(self):
manager = am.ModifyActionManager()

View File

@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import murano.policy.modify.actions.default_actions as da
import murano.tests.unit.dsl.foundation.object_model as om
import murano.tests.unit.dsl.foundation.test_case as tc
@ -39,34 +38,40 @@ class ModifyActionTestCase(tc.DslTestCase):
class TestRemoveObjectAction(ModifyActionTestCase):
def test_remove(self):
self.assertIsNotNone(self._obj.get_property('sampleClass'))
object_id = self._obj.get_property('sampleClass').object_id
da.RemoveObjectAction(object_id=object_id).modify(self._obj)
self.assertIsNone(self._obj.get_property('sampleClass'))
with self._runner.session():
self.assertIsNotNone(self._obj.get_property('sampleClass'))
object_id = self._obj.get_property('sampleClass').object_id
da.RemoveObjectAction(object_id=object_id).modify(self._obj)
self.assertIsNone(self._obj.get_property('sampleClass'))
def test_remove_from_list(self):
self.assertEqual(1, len(
self._obj.get_property('sampleClass')
.get_property('classProperty')))
da.RemoveObjectAction(object_id=self._list_member.id).modify(self._obj)
self.assertEqual(0, len(
self._obj.get_property('sampleClass')
.get_property('classProperty')))
self.assertNotIn(self._list_member.id, repr(self._obj))
with self._runner.session():
self.assertEqual(1, len(
self._obj.get_property('sampleClass')
.get_property('classProperty')))
da.RemoveObjectAction(object_id=self._list_member.id).modify(
self._obj)
self.assertEqual(0, len(
self._obj.get_property('sampleClass')
.get_property('classProperty')))
self.assertNotIn(self._list_member.id, repr(self._obj))
def test_remove_from_dict(self):
self.assertEqual(1, len(
self._obj.get_property('sampleClass')
.get_property('dictClassProperty')))
da.RemoveObjectAction(object_id=self._dict_member.id).modify(self._obj)
self.assertEqual(0, len(
self._obj.get_property('sampleClass')
.get_property('dictClassProperty')))
self.assertNotIn(self._dict_member.id, repr(self._obj))
with self._runner.session():
self.assertEqual(1, len(
self._obj.get_property('sampleClass')
.get_property('dictClassProperty')))
da.RemoveObjectAction(object_id=self._dict_member.id).modify(
self._obj)
self.assertEqual(0, len(
self._obj.get_property('sampleClass')
.get_property('dictClassProperty')))
self.assertNotIn(self._dict_member.id, repr(self._obj))
def test_remove_not_exists(self):
action = da.RemoveObjectAction(object_id='not_exists')
self.assertRaises(ValueError, action.modify, self._obj)
with self._runner.session():
action = da.RemoveObjectAction(object_id='not_exists')
self.assertRaises(ValueError, action.modify, self._obj)
class TestSetPropertyAction(ModifyActionTestCase):
@ -89,42 +94,46 @@ class TestSetPropertyAction(ModifyActionTestCase):
{1: 'b', 2: 'c'})
def _test_set_value(self, property, raw_input, expected):
sample = self._obj.get_property('sampleClass')
da.SetPropertyAction(sample.object_id, prop_name=property,
value=raw_input).modify(self._obj)
self.assertEqual(expected, sample.get_property(property))
with self._runner.session():
sample = self._obj.get_property('sampleClass')
da.SetPropertyAction(sample.object_id, prop_name=property,
value=raw_input).modify(self._obj)
self.assertEqual(expected, sample.get_property(property))
class TestRemoveRelationAction(ModifyActionTestCase):
def test_remove(self):
self.assertIsNotNone(self._obj.get_property('sampleClass'))
da.RemoveRelationAction(self._obj.object_id,
prop_name='sampleClass').modify(self._obj)
self.assertIsNone(self._obj.get_property('sampleClass'))
with self._runner.session():
self.assertIsNotNone(self._obj.get_property('sampleClass'))
da.RemoveRelationAction(self._obj.object_id,
prop_name='sampleClass').modify(self._obj)
self.assertIsNone(self._obj.get_property('sampleClass'))
class TestAddRelationAction(ModifyActionTestCase):
def test_add(self):
sample = self._obj.get_property('sampleClass')
self.assertIsNone(self._obj.get_property('anotherSampleClass'))
da.AddRelationAction(source_id=self._obj.object_id,
relation='anotherSampleClass',
target_id=sample.object_id).modify(self._obj)
self.assertIsNotNone(self._obj.get_property('anotherSampleClass'))
rel_target = self._obj.get_property('anotherSampleClass').object_id
self.assertEqual(sample.object_id, rel_target)
with self._runner.session():
sample = self._obj.get_property('sampleClass')
self.assertIsNone(self._obj.get_property('anotherSampleClass'))
da.AddRelationAction(source_id=self._obj.object_id,
relation='anotherSampleClass',
target_id=sample.object_id).modify(self._obj)
self.assertIsNotNone(self._obj.get_property('anotherSampleClass'))
rel_target = self._obj.get_property('anotherSampleClass').object_id
self.assertEqual(sample.object_id, rel_target)
class TestAddObjectAction(ModifyActionTestCase):
def test_add_object(self):
self._obj.set_property('sampleClass', None)
self.assertIsNone(self._obj.get_property('sampleClass'))
da.AddObjectAction(
self._obj.object_id,
'sampleClass',
'SampleClass1',
{'stringProperty': 'test_add_obj'}).modify(self._obj)
self.assertIsNotNone(self._obj.get_property('sampleClass'))
self.assertEqual('test_add_obj',
self._obj.get_property('sampleClass')
.get_property('stringProperty'))
with self._runner.session():
self._obj.set_property('sampleClass', None)
self.assertIsNone(self._obj.get_property('sampleClass'))
da.AddObjectAction(
self._obj.object_id,
'sampleClass',
'SampleClass1',
{'stringProperty': 'test_add_obj'}).modify(self._obj)
self.assertIsNotNone(self._obj.get_property('sampleClass'))
self.assertEqual('test_add_obj',
self._obj.get_property('sampleClass')
.get_property('stringProperty'))