1

我们现在主要将 Vorto 用作规范化格式,并开始研究使用映射引擎将不同的有效载荷格式映射到 Vorto 模型。我或多或少地了解如何使用 xpath 和转换函数从 JSON 或二进制有效负载映射功能块属性。但是,我不清楚如何支持使用这种方法解析非固定格式的二进制有效负载。例如,我们有一个现成的 LoRaWAN 传感器,它以以下格式传输: <length><frame type>[<sensor-id><sensor-value>]其中 length 是总帧长度,而 sensor-id(例如温度、湿度、电池等)描述了如何解析传感器值(即长度,数据类型)。在一帧中,这些读数中的多个可能以随机顺序出现。

在 loraserver.io 中,可以使用一个小的 javascript 函数轻松完成解析,该函数遍历所有字节并返回解析的属性。同样的方法也适用于同上有效载荷映射引擎 afaik。但是,目前我看不到如何在 Vorto 映射中做类似的事情。当然,这只是一个特定的传感器示例,但市场上存在更多使用类似动态有效载荷格式的示例。我知道已经有一个未解决的问题 (#1535) 来改进文档,但是知道使用映射 DSL 是否可以进行这种灵活的解析已经很有帮助。

我尝试将原始有效负载作为字节数组传递给 javascript 函数。为了测试这一点,我复制org.eclipse.vorto.mapping.engine.converter.binary.BinaryMappingTest#testMappingBinaryContaining2DataPoints并调整了模型以使用这样的自定义 javascript 函数

    evaluator.addScriptFunction(new ScriptClassFunction("extractTemperature",
"function extractTemperature(value) { " +
        " print(\"parameter of type \" + typeof value + \", value = \" + value);" +
        " print(value[1]);" +
        "}"));

这个函数的输出是

parameter of type number, value = 1
undefined

其中值 1 是使用的字节数组的第一个元素。

所以该函数似乎没有将参数作为 bytearray 接收。模型配置为,因此有效负载以与测试 ( )中相同的方式.withXPathStereotype("custom:extractTemperature(data)", "demo")传递 (as )。我现在看到的唯一区别是,在测试中,bytearray 参数被传递给 Java 函数而不是 javascript 函数。还是我错过了什么?BinaryDatatestMappingBinaryContaining2DataPoints.withXPathStereotype("custom:convert(vorto_conversion1:byteArrayToInt(data,0,0,0,2))", "demo")testMappingBinaryContaining2DataPoints

另外,我注意到循环关键字喜欢for并且while在 javascript 代码中是不允许的。因此,即使我可以访问 javascript 函数中的 bytearray 参数,我现在也看不到如何迭代它。

在 gitter 上,我收到了以下回复(连同将讨论移至 SO 的建议)

你说的对。我们将 Javascript 函数的使用限制为非常基本的语言关键字集,不包括 for 循环,因为在那里可以实现讨厌的东西。您可以做的是在您自己的命名空间中向映射引擎注册一个 java 函数。该函数可以保存一个字节数组。稍后这个函数可以作为标准函数贡献给映射引擎,以提取某个值供其他开发人员重用。

但是,我认为这不是解决问题的方法。如上所述,这只是现成的传感器有效载荷格式的一个示例,我看不出如何将其概括到足以包含在映射引擎中的通用函数中。而且我认为不需要在 Java 中实现特定于传感器的转换,因为(作为想要部署新传感器类型的物联网平台的最终用户)这比一点 javascript 开发和部署更复杂可以在映射规范中在运行时更改的函数。我看到能够在 javascript 中进行简单映射有很多价值,就像可以在例如loraserver.ioEclipse Ditto中完成一样。

我认为能够将字节数组传递给 javascript 是第一步。另外我想知道在javascript中允许循环的风险到底在哪里?例如,Ditto 在 javascript 沙箱中也有一些限制(请参见此处),但这允许循环并且仅防止无限循环和递归。他们声明如下:

使用 Rhino 代替 Nashorn(Java 附带的较新的 JavaScript 引擎)的好处是可以以更好的方式应用沙盒。需要对不同的有效负载脚本进行沙盒处理,因为 Ditto 旨在作为云服务运行,其中同时为不同的租户管理到不同端点的多个连接。这需要隔离每个单独的脚本以避免干扰其他脚本并保护执行脚本的 JVM 免受有害代码执行。

在 Vorto 中使用 Rhino 是否也可以控制您看到的风险并允许在 Vorto 映射中构建循环?

PS:有足够的声望点的人可以添加标签eclipse-vorto吗?

4

2 回答 2

1

从 Eclipse Vorto 0.12.3 版本开始,可以根据您的请求进行修复。有了这个,就可以将数组对象传递给 javascript Converter 以及在 javascript 函数中使用 for 循环。你可能想试一试。请参阅发行说明https://github.com/eclipse/vorto/blob/master/docs/release-notes.md

于 2019-11-16T13:25:32.387 回答
1

我为您创建了一个问题,要求在 Javascript 转换器中支持此功能:https ://github.com/eclipse/vorto/issues/2029

如问题中所述,作为当前的解决方法,您可以使用 Java 注册自己的自定义转换器函数,并在您的映射中重新使用此函数。在这些 java 转换器函数中,您拥有 java 语言的所有转换功能,可以从任意列表中提取正确的属性。为了了解如何使用 Java 实现自己的自定义转换器功能,请查看此处:https ://github.com/eclipse/vorto/tree/master/mapping-engine#Advanced-Usage

于 2019-10-17T07:36:40.883 回答