BIOS固件导出,当task完成时,HTTP Status Code需要为201

问题描述

Redfish触发BIOS固件导出:


查询Task任务进度:

期望结果

Task状态为Completed之后,HTTP返回码需要为201

答案内容由AI生成,仅供参考:

5. 结论

当前实现中,在 Task 为 Completed 时通过 GET 查询返回 200 是符合 Redfish 标准的。
期望返回 201 是不符合标准且不合理的;若必须满足特定客户需求,建议改为在异步触发时返回 202,并在 Task 完成后通过事件订阅通知,而非修改查询接口的状态码。

点击此处查看详细分析解答

根据您提供的场景和期望,当前行为与 Redfish 标准规范存在细微差异。以下是对您问题的分析说明:

1. 当前行为分析

  • 您通过 POST 请求触发 BIOS 固件导出(Bios.DumpBios),服务器返回了 HTTP 200 状态码,响应体是一个 Task 对象。
  • 随后您通过 GET 请求查询该 Task 的进度,当 Task 状态变为 "Completed" 时,服务器返回的依然是 HTTP 200 状态码。

2. 标准期望

根据 Redfish 规范(DMTF DSP0266):

  • 异步操作(Action):当操作需要长时间执行,服务器应返回 202 Accepted,并在响应体中提供 Task 资源的 @odata.id
  • 查询 Task 资源GET 请求成功时,无论 Task 处于 Running 还是 Completed 状态,HTTP 状态码均应为 200 OK

您的期望(201) 通常仅用于 资源成功创建 的场景(例如 POST 创建一个新的 Session 或 ManagerAccount),而不是用于异步任务完成后的查询。

3. 为何触发 POST 时返回了 200 而非 202?

根据上下文中的记录(文档【已评审】映射器新增ActionResponseBody语法):

“只有响应码为200或者201的action类型的Post接口才支持自定义响应体”

这说明当前实现的 Bios.DumpBios 动作可能被定义为 同步式响应(即服务器认为操作能立即完成,但实际上将其包装为 Task 并立即返回 Task 对象)。这种做法在实现上是不规范且容易引起混淆的:

  • 若操作是异步的,应返回 202201(当 Task 资源已被创建时)。
  • 当前返回 200 意味着请求已成功处理完成,但实际任务仍在后台运行,这违反了 REST 的语义。

4. 建议修正方向

  • 规范做法:修改 DumpBios 动作的 Redfish 实现,使其在触发时返回 202 Accepted,并在 Location 头部或响应体中指向 Task 资源。
  • 查询 Task:保持 GET /redfish/v1/TaskService/Tasks/1 在成功时返回 200 OK,这是正确的。
  • 如果业务要求“Task 完成后必须返回 201”,只有一种可能:在 Task 完成时,服务器主动向某个 Webhook 或 Event Subscription 发送一个 POST 请求,其中携带 201 状态码作为通知。但这不是通过查询接口来实现的。

5. 结论

当前实现中,在 Task 为 Completed 时通过 GET 查询返回 200 是符合 Redfish 标准的。
期望返回 201 是不符合标准且不合理的;若必须满足特定客户需求,建议改为在异步触发时返回 202,并在 Task 完成后通过事件订阅通知,而非修改查询接口的状态码。

①需要确保/opt/bmc/extend/xxx/apps/xxx/plugins/redfish/custom_request_response.lua文件存在。
文件中返回rsp_postprocess函数,以便于触发定制响应码机制。(需要注意一下,这里涉及所有redfish响应的定制)

②见下方示例,函数中入参有五个,返回值有三个。

  1. 可以先根据extra_info中的uri和method确认当前调用的是哪个redfish接口。
  2. 再通过body可以获取到任务的Name属性来确定具体任务。
  3. 最后根据任务状态来判断返回的响应码是否修改为201

③redfishcustom_request_response.lua的示例

local cjson = require 'cjson'
local function rsp_postprocess(code, body, header, manufacture, extra_info)
    local ok, ret_body, ret_header = pcall(function ()
        -- 下载接口的响应体保持原有二进制格式返回
        if header and header['Content-Disposition'] ~= nil then
            return body, header, code
        end

        local rsp_body
        if body and body ~= '' then
            rsp_body = cjson.json_object_ordered_decode(body)
        else
            rsp_body = cjson.json_object_new_object()
        end
        return cjson.json_object_ordered_encode(rsp_body), header
    end)

    if not ok then
        log:info('rsp postprocess failed, ret=%s', ret_body)
        return body, header, code
    end

    return body, header, code
end

return {
    ['rsp_postprocess'] = rsp_postprocess
}

④extra_info参数说明

extra_info = {
    uri = uri,                     //redish接口的uri
    method = method                //redfish接口的方法
}

开源仓直接实现就可以了吗?需要配套闭源模块开发吗?

配套闭源redfish组件版本要大于等于1.120.2

我们现在用的是2026330的iBMC_SDK版本,redfish组件版本1.120.2是在哪个iBMC_SDK版本?

还未发布,可以看下redfish这个组件版本号

这个大概什么时间点发布

可以咨询一下厂商