Warm tip: This article is reproduced from serverfault.com, please click

sap cloud sdk-尝试创建简单的联系人出现错误:PATCH 请求需要更新组件

(sap cloud sdk - Attempt to create simple Contact gives error: PATCH requests require components to be updated)

发布于 2021-03-10 21:48:19

我目前使用的SDK版本3.39.0和版本0004的的API_MKT_CONTACT服务定义来创建云计算市场一个新的联系人用下面的代码:

ContactOriginData contact =
        ContactOriginData.builder()
            .originOfContact(origin)
            .originTimestamp(ZonedDateTime.now())
            .externalContactID(pii.getId().toString())
            .firstName(pii.getFirstName())
            .lastName(pii.getLastName())
            .language(pii.getLanguage())
            .countryReg(pii.getRegion())
            .build();

// use low level API as a work around for https://github.com/SAP/cloud-sdk/issues/156
ODataRequestUpdate contactRequest = service
          .updateContactOriginData(contact)
          .withHeader("Sap-Cuan-RequestTimestamp", getFormattedTime(System.currentTimeMillis()))
          .withHeader("Sap-Cuan-SequenceId", "UpdatePatch")
          .withHeader("Sap-Cuan-SourceSystemType", "EXT")
          .withHeader("Sap-Cuan-SourceSystemId", "sdk-test")
          .toRequest();

String servicePath = "/sap/opu/odata/SAP/API_MKT_CONTACT_SRV;v=0004";
ODataRequestBatch requestBatch =  new ODataRequestBatch(servicePath, ODataProtocol.V2);
requestBatch.beginChangeset().addUpdate(contactRequest).endChangeset();
HttpClient httpClient = HttpClientAccessor.getHttpClient(destination);
ODataRequestResultMultipartGeneric batchResult = requestBatch.execute(httpClient);

运行它会产生以下错误:

{
  "error": {
    "code": "/IWFND/CM_MGW/096",
    "message": {
      "lang": "en",
      "value": "PATCH requests require components to be updated"
    },
    "innererror": {
      "application": {
        "component_id": "CEC-MKT-DM-IC",
        "service_namespace": "/SAP/",
        "service_id": "API_MKT_CONTACT_SRV",
        "service_version": "0004"
      },
      "transactionid": "3B63A2A6CC920630E0060492A51E7EE7",
      "timestamp": "20210310210334.4378960",
      "Error_Resolution": {
        "SAP_Transaction": "For backend administrators: use ADT feed reader \"SAP Gateway Error Log\" or run transaction /IWFND/ERROR_LOG on SAP Gateway hub system and search for entries with the timestamp above for more details",
        "SAP_Note": "See SAP Note 1797736 for error analysis (https://service.sap.com/sap/support/notes/1797736)",
        "Batch_SAP_Note": "See SAP Note 1869434 for details about working with $batch (https://service.sap.com/sap/support/notes/1869434)"
      },
      "errordetails": []
    }
  }
}

但是,如果我在 Postman 中执行类似的请求,它可以正常工作:

Request Payload:

--batch
Content-Type: multipart/mixed; boundary=changeset

--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary

PATCH ContactOriginData(ContactOrigin='<ContactOrigin>',ContactID='24D8F7F6-440D-44F8-A24B-552435477688') HTTP/1.1
Accept: application/json
Content-Type: application/json
Content-Length: 172
Sap-Cuan-RequestTimestamp: '2021-03-10T14:07:00.000'
Sap-Cuan-SequenceId: UpdatePatch
Sap-Cuan-SourceSystemType: EXT
Sap-Cuan-SourceSystemId: postman-test

{"OriginDataLastChgUTCDateTime":"/Date(1615410479885)/","EmailAddress":"samantha.cook@theoasis.com","FirstName":"Samantha","LastName":"Cook","Country":"US","Language":"EN"}

--changeset--
--batch--

Response Payload:

--1D7E85E6BC66B34E61ACF0EF3964CBD90
Content-Type: multipart/mixed; boundary=1D7E85E6BC66B34E61ACF0EF3964CBD91
Content-Length:       430

--1D7E85E6BC66B34E61ACF0EF3964CBD91
Content-Type: application/http
Content-Length: 262
content-transfer-encoding: binary

HTTP/1.1 204 No Content
Content-Length: 0
dataserviceversion: 2.0
sap-message: {"code":"HPA_STAGING_AREA/037","message":"Payload is processed via staging area. See Import Monitor for details.","target":"","severity":"info","transition":false,"details":[]}


--1D7E85E6BC66B34E61ACF0EF3964CBD91--

--1D7E85E6BC66B34E61ACF0EF3964CBD90--

我应该注意,我也尝试过使用.replacingEntity()which 也不起作用并产生完全不同的错误:

Inline component is not defined or not allowed (HTTP PUT)

SDK 中是否存在我遗漏或未正确使用的内容?任何帮助,将不胜感激!

干杯!

Questioner
kurts
Viewed
0
MatKuhr 2021-03-12 15:37:51

要更新实体,你应该首先从服务中获取它。无论你是否使用:

  1. PATCH 这将只更新更改的字段
  2. PUT将发送完整的实体对象

当前,你正在通过 builder 创建一个新的实体对象:ContactOriginData.builder()相反,请使用getContactOriginDataByKey()你服务的相应方法首先从服务中检索要更新的实体。实际上,许多服务会强迫你这样做,以确保你始终编辑最新版本的数据。这通常通过ETag发生,SDK 也会自动为你处理

你可以在文档 上的 SDK 中找到有关更新策略的更多信息


编辑:正如你在评论中指出的,实际目标是创建一个实体,而有问题的特定服务仅允许 PUT 和 PATCH创建对象。

在这种情况下 using replacingEntity()(转换为PUT)应该已经可以与你的代码一起使用了。你也可以通过用构造函数调用 + setter 方法替换构建器方法来使 PATCH 工作。