diff --git a/mistral/config.py b/mistral/config.py index 3045cfb7..2884575c 100644 --- a/mistral/config.py +++ b/mistral/config.py @@ -80,6 +80,14 @@ api_opts = [ ) ] +js_impl_opt = cfg.StrOpt( + 'js_implementation', + default='pyv8', + choices=['pyv8', 'v8eval'], + help='The JavaScript implementation to be used by the std.javascript ' + 'action to evaluate scripts.' +) + rpc_impl_opt = cfg.StrOpt( 'rpc_implementation', default='oslo', @@ -275,6 +283,7 @@ CONF.register_opts(event_engine_opts, group=EVENT_ENGINE_GROUP) CONF.register_opts(pecan_opts, group=PECAN_GROUP) CONF.register_opts(coordination_opts, group=COORDINATION_GROUP) CONF.register_opts(profiler_opts, group=PROFILER_GROUP) +CONF.register_opt(js_impl_opt) CONF.register_opt(rpc_impl_opt) CONF.register_opt(rpc_response_timeout_opt) CONF.register_opts(keycloak_oidc_opts, group=KEYCLOAK_OIDC_GROUP) @@ -288,8 +297,8 @@ CLI_OPTS = [ default_group_opts = itertools.chain( CLI_OPTS, - [wf_trace_log_name_opt, auth_type_opt, rpc_impl_opt, os_endpoint_type, - rpc_response_timeout_opt, expiration_token_duration] + [wf_trace_log_name_opt, auth_type_opt, js_impl_opt, rpc_impl_opt, + os_endpoint_type, rpc_response_timeout_opt, expiration_token_duration] ) CONF.register_cli_opts(CLI_OPTS) diff --git a/mistral/utils/javascript.py b/mistral/utils/javascript.py index 6245ff2d..a05f79b6 100644 --- a/mistral/utils/javascript.py +++ b/mistral/utils/javascript.py @@ -15,12 +15,14 @@ import abc import json +from oslo_config import cfg from oslo_utils import importutils from mistral import exceptions as exc - +CONF = cfg.CONF _PYV8 = importutils.try_import('PyV8') +_V8EVAL = importutils.try_import('v8eval') class JSEvaluator(object): @@ -31,7 +33,7 @@ class JSEvaluator(object): pass -class V8Evaluator(JSEvaluator): +class PyV8Evaluator(JSEvaluator): @classmethod def evaluate(cls, script, context): if not _PYV8: @@ -46,8 +48,22 @@ class V8Evaluator(JSEvaluator): result = ctx.eval(script) return _PYV8.convert(result) -# TODO(nmakhotkin) Make it configurable. -EVALUATOR = V8Evaluator + +class V8EvalEvaluator(JSEvaluator): + @classmethod + def evaluate(cls, script, context): + if not _V8EVAL: + raise exc.MistralException( + "v8eval module is not available. Please install v8eval." + ) + + v8 = _V8EVAL.V8() + return v8.eval(('$ = %s; %s' % (json.dumps(context), script)).encode( + encoding='UTF-8')) + + +EVALUATOR = (V8EvalEvaluator if CONF.js_implementation == 'v8eval' + else PyV8Evaluator) def evaluate(script, context):