我们现在主要将 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 函数。还是我错过了什么?BinaryData
testMappingBinaryContaining2DataPoints
.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.io和Eclipse Ditto中完成一样。
我认为能够将字节数组传递给 javascript 是第一步。另外我想知道在javascript中允许循环的风险到底在哪里?例如,Ditto 在 javascript 沙箱中也有一些限制(请参见此处),但这允许循环并且仅防止无限循环和递归。他们声明如下:
使用 Rhino 代替 Nashorn(Java 附带的较新的 JavaScript 引擎)的好处是可以以更好的方式应用沙盒。需要对不同的有效负载脚本进行沙盒处理,因为 Ditto 旨在作为云服务运行,其中同时为不同的租户管理到不同端点的多个连接。这需要隔离每个单独的脚本以避免干扰其他脚本并保护执行脚本的 JVM 免受有害代码执行。
在 Vorto 中使用 Rhino 是否也可以控制您看到的风险并允许在 Vorto 映射中构建循环?
PS:有足够的声望点的人可以添加标签eclipse-vorto
吗?