【问题标题】:Azure Job submission fails with 400 complaining about EtagAzure Job 提交失败,400 抱怨 Etag
【发布时间】:2017-09-20 11:16:26
【问题描述】:

序幕

我正在尝试使用 Python 2 和 requests 包,使用 Azure REST API 为 Azure IoT 中心创建一个“ScheduleUpdateTwin”作业。

分析

响应请求

我将从requests 日志行开始(隐藏中心名称):

DEBUG:urllib3.connectionpool:https://<myhubname>.azure-devices.net:443 "PUT /jobs/v2/j1505904104?api-version=2017-06-30 HTTP/1.1" 400 441

确实,req.status_code400

req.content 是(稍微修改了跟踪 ID):

{"Message":"ErrorCode:ArgumentInvalid;Error: BadRequest {\"Message\":\"ErrorCode:ArgumentInvalid;作业类型 ScheduleUpdateTwin 的 etag 缺失或无效。 ScheduleUpdateTwin 作业类型为强制更新,仅接受 \'*\' 作为 Etag。\",\"ExceptionMessage\":\"Tracking ID:xxxxxxxxxx8844a48f81e29359ba0279-TimeStamp:09/20/2017 10:41:45\" }","ExceptionMessage":"跟踪 ID:xxxxxxxxxxe14888a51434047aef23d0-G:5-TimeStamp:09/20/2017 10:41:46"}

响应标题

{'Content-Length': '441',
 'Content-Type': 'application/json; charset=utf-8',
 'Date': 'Wed, 20 Sep 2017 11:10:12 GMT',
 'Server': 'Microsoft-HTTPAPI/2.0',
 'iothub-errorcode': 'ArgumentInvalid'}

请求标头

我的请求的标头(发送到 Azure API 端点)是(再次,修改私有数据):

{'Accept': '*/*',
 'Accept-Encoding': 'gzip, deflate',
 'Authorization': 'SharedAccessSignature '
                  'sr=<myhubname>.azure-devices.net%2Fjobs&skn=<skn>&sig=<sig>&se=<se>',
 'Connection': 'keep-alive',
 'Content-Length': '227',
 'Content-Type': 'application/json',
 'If-Match': '*',
 'User-Agent': 'python-requests/2.18.1'}

请求正文

这是(为了在此处发布而精心打印,因此 Content-Length 显然会有所不同)请求正文:

{
 "maxExecutionTimeInSeconds": 3600,
 "updateTwin": {
  "properties": {
   "desired": {
    "version": "5.0.0"
   }
  },
  "tags": {
   "owner": "tzot"
  }
 },
 "jobId": "j1505904104",
 "type": "scheduleUpdateTwin",
 "queryCondition": "deviceId = 'test_rpi_01'"
}

If-None-Match 代替 If-Match

当然,应该提供If-None-Matchdocumentation 提示,因为这是PUT。所以我改变了我的代码并发送了If-None-Match: *;回复又是400

其他 REST API 调用工作正常

请注意,其他 REST API 调用,例如 devices/{device_id} 可以在没有设置 Etag 的情况下正常运行 GETPUTDELETE 操作; twins/{device_id} (GET, PATCH) 和 twins/{device_id}/methods (POST) 也是如此。

API 版本

我使用的API版本是:api-version=2017-06-30

结语

如何通过 REST API 调用向 Azure IoT 提交作业?

更新

在请求 JSON 中添加 "etag": "*"

在 Rita Han 的建议下,我在请求正文中添加了 "etag": "*" 键,变成了(注意:new jobId):

{
 "jobId": "j1505986505",
 "maxExecutionTimeInSeconds": 3600,
 "etag": "*",
 "updateTwin": {
  "properties": {
   "desired": {
    "version": "5.0.0"
   }
  },
  "tags": {
   "owner": "tzot"
  }
 },
 "type": "scheduleUpdateTwin",
 "queryCondition": "deviceId = 'test_rpi_01'"
}

结果相同:HTTP 400 状态码,响应内容相同。尝试在 HTTP 请求标头中使用 If-Match: *,然后使用 If-None-Match: *,然后使用 If-None-Match: blabla,希望没有现有的 ETag 与“blabla”匹配。一切都无济于事。反应是一样的。

解决方案

内容应在updateTwin 值内包含etag 属性。

【问题讨论】:

  • 您能出示您的请求正文吗?
  • @RitaHan-MSFT 我编辑了问题以包含请求正文。感谢您的调查。

标签: rest azure-iot-hub


【解决方案1】:

正如错误信息指出的那样:

作业类型 ScheduleUpdateTwin 的 etag 缺失或无效。 ScheduleUpdateTwin 作业类型是强制更新,只接受 \'*\' 作为 Etag。

您可以像这样修改您的请求正文:

{
 "maxExecutionTimeInSeconds": 3600,
 "updateTwin": {
  "properties": {
   "desired": {
    "version": "5.0.0"
   }
  },
 "etag":"*",
 },
 "jobId": "j1505904104",
 "type": "scheduleUpdateTwin",
 "queryCondition": "deviceId = 'test_rpi_01'"
}

更新:

添加python测试结果:

【讨论】:

  • 我试过没有用。 documentation 不清楚,但建议 If-Match、Etag 等应该在 HTTP 请求标头中。您还有其他相关文档的链接吗?
  • 所以etag 应该在updateTwin 属性内部,而不是在同一级别;那是我的错误。谢谢你,丽塔。
  • @tzot 很高兴为您提供帮助。有关文档,您可以发布 cmets here
猜你喜欢
  • 2016-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-02
相关资源
最近更新 更多