def inspect_expressions(self, parent=None): if parent and not parent.get("spec_path", None): raise ValueError("Parent context is missing spec path.") if parent and not parent.get("schema_path", None): raise ValueError("Parent context is missing schema path.") errors = [] properties = {} schema = self.get_schema(includes=None) for prop_name, prop_type in six.iteritems(schema.get("properties", {})): properties[prop_name] = getattr(self, prop_name) for prop_name_regex, prop_type in six.iteritems(schema.get("patternProperties", {})): for prop_name in [key for key in self.keys() if re.findall(prop_name_regex, key)]: properties[prop_name] = getattr(self, prop_name) for prop_name, prop_value in six.iteritems(properties): spec_path = self.get_spec_path(prop_name, parent=parent) schema_path = self.get_schema_path(prop_name, parent=parent) if isinstance(prop_value, SequenceSpec): for i in range(0, len(prop_value)): item = prop_value[i] item_spec_path = spec_path + "[" + str(i) + "]" item_schema_path = schema_path + ".items" item_parent = {"spec_path": item_spec_path, "schema_path": item_schema_path} errors.extend(item.inspect_expressions(parent=item_parent)) continue if isinstance(prop_value, MappingSpec): for k, v in six.iteritems(prop_value): item_spec_path = spec_path + "." + k item_schema_path = schema_path + ".patternProperties.^\\w+$" item_parent = {"spec_path": item_spec_path, "schema_path": item_schema_path} errors.extend(v.inspect_expressions(parent=item_parent)) continue if isinstance(prop_value, Spec): item_parent = {"spec_path": spec_path, "schema_path": schema_path} errors.extend(prop_value.inspect_expressions(parent=item_parent)) continue result = expr_base.validate(prop_value).get("errors", []) for entry in result: entry["spec_path"] = spec_path entry["schema_path"] = schema_path errors += result return errors
def test_mix_types(self): expr = '<% ctx().foo %> and {{ ctx().foo }}' expected_errors = [{ 'type': None, 'expression': expr, 'message': 'Expression with multiple types is not supported.' }] result = expr_base.validate(expr) self.assertListEqual(expected_errors, result.get('errors', []))
def test_mix_types(self): expr = "<% ctx().foo %> and {{ ctx().foo }}" expected_errors = [{ "type": None, "expression": expr, "message": "Expression with multiple types is not supported.", }] result = expr_base.validate(expr) self.assertListEqual(expected_errors, result.get("errors", []))
def evaluate(expression, data): """ Evaluate the given YAQL expression on the given YAML :param str expression: the YAQL expression :param str|dict data: the YAML/JSON (as a string or dict (json)) :return: the query result :rtype: str :raises YamlException: if the input YAML is invalid :raises YaqlException: if the YAQL is malformed """ # Parse YAML try: loaded_yaml = yaml.safe_load(data) if isinstance(data, str) else data except yaml.parser.ParserError as pe: raise YamlException("Invalid YAML: " + str(pe)) except Exception as e: raise YamlException("Exception loading YAML: " + str(e)) # Evaluate YAQL expression against the YAML try: # res = _evaluate(yaql_expression, loaded_yaml, legacy) # if isinstance(res, types.GeneratorType): # res = list(res) from orquesta.expressions.base import validate, evaluate res = validate(expression) if len(res['errors']) > 0: raise Exception("Invalid Expression: {}".format('\n'.join( res['errors']))) else: res = evaluate(expression, loaded_yaml) return {'evaluation': escape(res), 'payload': loaded_yaml} except yaql.language.exceptions.YaqlParsingException as pe: raise YaqlException("Invalid expression: " + str(pe)) except Exception as e: raise YaqlException("Exception evaluating expression: " + str(e))
def inspect_expressions(self, parent=None): if parent and not parent.get('spec_path', None): raise ValueError('Parent context is missing spec path.') if parent and not parent.get('schema_path', None): raise ValueError('Parent context is missing schema path.') errors = [] properties = {} schema = self.get_schema(includes=None) for prop_name, prop_type in six.iteritems(schema.get('properties', {})): properties[prop_name] = getattr(self, prop_name) for prop_name_regex, prop_type in six.iteritems( schema.get('patternProperties', {})): for prop_name in [ key for key in self.keys() if re.findall(prop_name_regex, key) ]: properties[prop_name] = getattr(self, prop_name) for prop_name, prop_value in six.iteritems(properties): spec_path = self.get_spec_path(prop_name, parent=parent) schema_path = self.get_schema_path(prop_name, parent=parent) if isinstance(prop_value, SequenceSpec): for i in range(0, len(prop_value)): item = prop_value[i] item_spec_path = spec_path + '[' + str(i) + ']' item_schema_path = schema_path + '.items' item_parent = { 'spec_path': item_spec_path, 'schema_path': item_schema_path } errors.extend(item.inspect_expressions(parent=item_parent)) continue if isinstance(prop_value, MappingSpec): for k, v in six.iteritems(prop_value): item_spec_path = spec_path + '.' + k item_schema_path = schema_path + '.patternProperties.^\\w+$' item_parent = { 'spec_path': item_spec_path, 'schema_path': item_schema_path } errors.extend(v.inspect_expressions(parent=item_parent)) continue if isinstance(prop_value, Spec): item_parent = { 'spec_path': spec_path, 'schema_path': schema_path } errors.extend( prop_value.inspect_expressions(parent=item_parent)) continue result = expr.validate(prop_value).get('errors', []) for entry in result: entry['spec_path'] = spec_path entry['schema_path'] = schema_path errors += result return errors
def validate(self, expr): return expr_base.validate(expr).get('errors', [])
def validate(self, expr): return expressions.validate(expr).get('errors', [])