为什么在最近的 Azure API 管理升级后之前稳定且有效的 Liquid 模板会失败?
Why would a previously stable and working Liquid template fail after the most recent Azure API Management upgrade?
我们有一个 Azure API 管理端点,它接收以下格式的请求:
{
"messageType": "EVENT",
"eventData": {
"installedApp": {
"installedAppId": "xxx",
"locationId": "yyy"
},
"events": [
{
"eventTime": "2020-11-13T13:14:50.8011105+00:00",
"eventType": "DEVICE_EVENT",
"deviceEvent": {
"eventId": "3a08b3f3-25b1-11eb-962f-975d499d1166",
"locationId": "yyy",
"ownerId": "a975533a-a1ae-49f7-88f1-94368bd4d605",
"ownerType": "LOCATION",
"deviceId": "c3fdc7c6-08f2-4ba3-92b3-0cdfa2b141f5",
"componentId": "main",
"capability": "motionSensor",
"attribute": "motion",
"value": "inactive",
"valueType": "string",
"stateChange": true,
"data": {},
"subscriptionName": "all_motion_sub"
}
}
]
}
}
它通过 Liquid 模板传递它们:
<set-body template="liquid">{
"id": "{{context.Variables["RequestId"]}}",
"API": "SmartThings",
"InstalledAppId": "{{body.eventData.installedApp.installedAppId}}",
"LocationId": "{{body.eventData.installedApp.locationId}}",
"DeviceEvents":[
{% assign device_events = body.eventData.events | Where: "eventType", "DEVICE_EVENT" %}
{% JSONArrayFor event in device_events %}
{
"EventId": "{{event.deviceEvent.eventId}}",
"LocationId": "{{event.deviceEvent.locationId}}",
"DeviceId": "{{event.deviceEvent.deviceId}}",
"ComponentId": "{{event.deviceEvent.componentId}}",
"Capability": "{{event.deviceEvent.capability}}",
"Attribute": "{{event.deviceEvent.attribute}}",
"Value": "{{event.deviceEvent.value}}",
"StateChange": {{event.deviceEvent.stateChange}},
"EventTime": "{{event.eventTime | Date: "yyyy-MM-ddTHH:mm:sszzz" | Default: context.Variables["RequestDateTime"] }}"
}
{% endJSONArrayFor %}
],
"EventTime": "{{context.Variables["RequestDateTime"]}}"
}</set-body>
并生成发送到逻辑应用程序进行进一步处理的输出:
{
"id": "d5e2a032-14b3-40ca-9c6b-4e13f8d2285c",
"API": "SmartThings",
"InstalledAppId": "xxx",
"LocationId": "yyy",
"DeviceEvents": [
{
"EventId": "3a08b3f3-25b1-11eb-962f-975d499d1166",
"LocationId": "yyy",
"DeviceId": "c3fdc7c6-08f2-4ba3-92b3-0cdfa2b141f5",
"ComponentId": "main",
"Capability": "motionSensor",
"Attribute": "motion",
"Value": "inactive",
"StateChange": true,
"EventTime": "2020-11-13T13:14:50.8011105+00:00"
}
],
"EventTime": "2020-11-13T13:14:50.8011105+00:00"
}
直到 2020 年 11 月 11 日 23:00Z 左右,它按预期工作,并且已经在生产环境中工作了几个月。从那时开始,Liquid 映射开始失败,而是生成:
{
"id": "2c93647c-f9ef-4747-adfb-985805a71f0c",
"API": "SmartThings",
"InstalledAppId": "xxx",
"LocationId": "yyy",
"DeviceEvents": [
{
"EventId": "",
"LocationId": "",
"DeviceId": "",
"ComponentId": "",
"Capability": "",
"Attribute": "",
"Value": "",
"StateChange": ,
"EventTime": "2020-11-13T13:14:50.8011105+00:00"
}
],
"EventTime": "2020-11-13T13:14:50.8011105+00:00"
}
从星期四午夜开始,我们在 'Upgrade API Management' 的日志中安排了维护事件,所以看起来好像有某种重大更改。
是什么改变导致了这个问题,我们该如何解决?
这个问题,我在我这边测试了一下,也重现了你的情况。 APIM中似乎存在液体模板的错误。重现您的问题后,我在另一个 APIM 中进行了测试,但没有显示相同的问题,液体模板在该 APIM 中工作正常。然后我在多个 APIM 中进行测试(具有相同的设置主体策略和请求主体)并将结果总结如下:
根据多次测试和上面的测试结果,我猜测可能是升级APIM后的一些bug。该错误可能 与位置或定价层有关(我不确定) 因为除了位置和定价层外,我找不到这些 APIM 之间的任何差异。所以我建议你在另一个 APIM(具有不同的位置和定价层)中做同样的工作,它会暂时解决问题。
===============================更新=== ==========================
我做了一些进一步的测试并找到了解决这个问题的方法。我发现问题是由行 {% assign device_events = body.eventData.events | Where: "eventType", "DEVICE_EVENT" %}
引起的。如果我们不把body.eventData.events
赋值给device_events
,而是像{% JSONArrayFor event in body.eventData.events %}
一样在for循环中直接使用body.eventData.events
。那么液体模板就可以正常工作了。
所以我们可以去掉“assign”这一行,在for循环中做“where”条件。请参考下面我的液体模板:
我们有一个 Azure API 管理端点,它接收以下格式的请求:
{
"messageType": "EVENT",
"eventData": {
"installedApp": {
"installedAppId": "xxx",
"locationId": "yyy"
},
"events": [
{
"eventTime": "2020-11-13T13:14:50.8011105+00:00",
"eventType": "DEVICE_EVENT",
"deviceEvent": {
"eventId": "3a08b3f3-25b1-11eb-962f-975d499d1166",
"locationId": "yyy",
"ownerId": "a975533a-a1ae-49f7-88f1-94368bd4d605",
"ownerType": "LOCATION",
"deviceId": "c3fdc7c6-08f2-4ba3-92b3-0cdfa2b141f5",
"componentId": "main",
"capability": "motionSensor",
"attribute": "motion",
"value": "inactive",
"valueType": "string",
"stateChange": true,
"data": {},
"subscriptionName": "all_motion_sub"
}
}
]
}
}
它通过 Liquid 模板传递它们:
<set-body template="liquid">{
"id": "{{context.Variables["RequestId"]}}",
"API": "SmartThings",
"InstalledAppId": "{{body.eventData.installedApp.installedAppId}}",
"LocationId": "{{body.eventData.installedApp.locationId}}",
"DeviceEvents":[
{% assign device_events = body.eventData.events | Where: "eventType", "DEVICE_EVENT" %}
{% JSONArrayFor event in device_events %}
{
"EventId": "{{event.deviceEvent.eventId}}",
"LocationId": "{{event.deviceEvent.locationId}}",
"DeviceId": "{{event.deviceEvent.deviceId}}",
"ComponentId": "{{event.deviceEvent.componentId}}",
"Capability": "{{event.deviceEvent.capability}}",
"Attribute": "{{event.deviceEvent.attribute}}",
"Value": "{{event.deviceEvent.value}}",
"StateChange": {{event.deviceEvent.stateChange}},
"EventTime": "{{event.eventTime | Date: "yyyy-MM-ddTHH:mm:sszzz" | Default: context.Variables["RequestDateTime"] }}"
}
{% endJSONArrayFor %}
],
"EventTime": "{{context.Variables["RequestDateTime"]}}"
}</set-body>
并生成发送到逻辑应用程序进行进一步处理的输出:
{
"id": "d5e2a032-14b3-40ca-9c6b-4e13f8d2285c",
"API": "SmartThings",
"InstalledAppId": "xxx",
"LocationId": "yyy",
"DeviceEvents": [
{
"EventId": "3a08b3f3-25b1-11eb-962f-975d499d1166",
"LocationId": "yyy",
"DeviceId": "c3fdc7c6-08f2-4ba3-92b3-0cdfa2b141f5",
"ComponentId": "main",
"Capability": "motionSensor",
"Attribute": "motion",
"Value": "inactive",
"StateChange": true,
"EventTime": "2020-11-13T13:14:50.8011105+00:00"
}
],
"EventTime": "2020-11-13T13:14:50.8011105+00:00"
}
直到 2020 年 11 月 11 日 23:00Z 左右,它按预期工作,并且已经在生产环境中工作了几个月。从那时开始,Liquid 映射开始失败,而是生成:
{
"id": "2c93647c-f9ef-4747-adfb-985805a71f0c",
"API": "SmartThings",
"InstalledAppId": "xxx",
"LocationId": "yyy",
"DeviceEvents": [
{
"EventId": "",
"LocationId": "",
"DeviceId": "",
"ComponentId": "",
"Capability": "",
"Attribute": "",
"Value": "",
"StateChange": ,
"EventTime": "2020-11-13T13:14:50.8011105+00:00"
}
],
"EventTime": "2020-11-13T13:14:50.8011105+00:00"
}
从星期四午夜开始,我们在 'Upgrade API Management' 的日志中安排了维护事件,所以看起来好像有某种重大更改。
是什么改变导致了这个问题,我们该如何解决?
这个问题,我在我这边测试了一下,也重现了你的情况。 APIM中似乎存在液体模板的错误。重现您的问题后,我在另一个 APIM 中进行了测试,但没有显示相同的问题,液体模板在该 APIM 中工作正常。然后我在多个 APIM 中进行测试(具有相同的设置主体策略和请求主体)并将结果总结如下:
根据多次测试和上面的测试结果,我猜测可能是升级APIM后的一些bug。该错误可能 与位置或定价层有关(我不确定) 因为除了位置和定价层外,我找不到这些 APIM 之间的任何差异。所以我建议你在另一个 APIM(具有不同的位置和定价层)中做同样的工作,它会暂时解决问题。
===============================更新=== ==========================
我做了一些进一步的测试并找到了解决这个问题的方法。我发现问题是由行 {% assign device_events = body.eventData.events | Where: "eventType", "DEVICE_EVENT" %}
引起的。如果我们不把body.eventData.events
赋值给device_events
,而是像{% JSONArrayFor event in body.eventData.events %}
一样在for循环中直接使用body.eventData.events
。那么液体模板就可以正常工作了。
所以我们可以去掉“assign”这一行,在for循环中做“where”条件。请参考下面我的液体模板: