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

在Vorto中使用自定义javascript转换解析非固定格式的二进制负载,java,rhino,nashorn,eclipse-vorto,Java,Rhino,Nashorn,Eclipse Vorto,我们现在主要使用Vorto作为规范化格式,并开始研究使用映射引擎将不同的有效负载格式映射到Vorto模型。我或多或少了解如何使用xpath和转换函数从JSON或二进制负载映射functionblock属性。但是,我不清楚如何支持使用此方法解析非固定格式的二进制有效负载。 例如,我们有一个现成的LoRaWAN传感器,其传输格式如下: []其中length是总帧长,传感器id(例如温度、湿度、电池等)描述了如何解析传感器值(即长度、数据类型)。在一帧中,这些读数的倍数可能以随机顺序出现 例如,在lo

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

例如,在loraserver.io中,可以使用一个小的javascript函数轻松地进行解析,该函数迭代所有字节,然后返回解析的属性。同样的方法也适用于同上的负载映射引擎afaik。 但是,目前我不知道如何在Vorto映射中执行类似的操作。当然,这只是一个特定的传感器示例,但市场上还有更多使用类似动态有效载荷格式的示例。我知道改进文档已经有一个悬而未决的问题(#1535),但是如果知道使用映射DSL是否可以进行这种灵活的解析,这将是非常有帮助的

我尝试将原始负载作为bytearray传递给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的第一个元素

因此,函数似乎没有接收bytarray参数。 模型配置了
。withXPathStereotype(“自定义:提取温度(数据)”,“演示”)
,因此有效负载被传递(作为
BinaryData
),传递方式与
testMappingBinaryContaining2DataPoints
测试中的方式相同(
。withXPathStereotype(“自定义:转换(vorto\u转换1:byteArrayToInt(数据,0,0,2)),“演示”)
)。我现在看到的唯一区别是,在
testMappingBinaryContaining2DataPoints
测试中,byetarray参数被传递给Java函数,而不是javascript函数。还是我遗漏了什么

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

在gitter,我收到了以下回复(以及将讨论转移到SO的建议)

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

然而,我不认为这是解决问题的办法。如上所述,这只是现成传感器有效载荷格式的一个示例,我不知道如何将其推广到映射引擎中作为通用函数。我认为不需要在Java中实现特定于传感器的转换,因为(作为物联网平台的最终用户,希望部署新的传感器类型)开发和部署它比在mapping spec中运行时可以修改的一点javascript函数要复杂得多。我认为能够在javascript中进行简单的映射很有价值,就像这可以在示例和中完成一样

我认为能够将字节数组传递给javascript是第一步。我还想知道在javascript中允许循环的风险到底在哪里?例如,同上,javascript沙盒()中也有一些限制,但这允许循环,并且只防止无休止的循环和递归。 它们声明如下:

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

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


PS:有足够的SO声誉点数的人可以添加标签
eclipse vorto

我为您创建了一个问题,请求在Javascript转换器中支持这一点:

如本期所述,作为当前的解决方法,您可以使用Java注册自己的自定义转换器函数,并在映射中重复使用此函数。在这些java转换器函数中,您拥有java语言的所有转换功能,可以从任意列表中提取right属性。
为了了解如何用Java实现您自己的自定义转换器功能,请看这里:

自从Eclipse Vorto 0.12.3发布以来,您的请求有了一个修复程序。有了它,就可以将数组对象传递给javascript转换器,也可以用于javascript函数中的循环。你可能想试试。 请参阅发行说明