猿问

使用 Vorto 中的自定义 JavaScript 转换解析非固定格式的二进制有效负载

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


解析这个可以很容易地在 loraserver.io 中使用一个小的 javascript 函数来完成,该函数迭代所有字节并返回解析的属性。同样的方式也适用于 Ditto 有效负载映射引擎 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 是使用的字节数组的第一个元素。


另外,我注意到JavaScript 代码中不允许使用像for和这样的循环关键字。while因此,即使我可以访问 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 映射中构建循环?



鸿蒙传说
浏览 115回答 2
2回答

牛魔王的故事

我为您创建了一个问题,请求在 Javascript 转换器中支持此操作: https:&nbsp;//github.com/eclipse/vorto/issues/2029如问题中所述,作为当前的解决方法,您可以使用 Java 注册您自己的自定义转换器函数,并在映射中重复使用此函数。在这些 java 转换器函数中,您可以使用 java 语言进行转换以从任意列表中提取正确的属性。为了了解如何使用 Java 实现您自己的自定义转换器功能,请查看此处:https:&nbsp;//github.com/eclipse/vorto/tree/master/mapping-engine#Advanced-Usage

临摹微笑

自 Eclipse Vorto 0.12.3 发布以来,已提供针对您请求的修复。这样就可以将数组对象传递给 javascript Converter 以及在 javascript 函数内使用 for 循环。你可能想尝试一下。请参阅发行说明https://github.com/eclipse/vorto/blob/master/docs/release-notes.md
随时随地看视频慕课网APP

相关分类

Java
我要回答