提问人:Danny Kruitbosch 提问时间:12/15/2020 最后编辑:Danny Kruitbosch 更新时间:1/13/2021 访问量:940
通过连接服务的 OData 批处理请求始终返回 202 已接受
OData batch request through connectivity service always returns 202 Accepted
问:
我们在 SAP CloudFoundry 上部署了一个 springboot/sap-cloud-sdk (3.34.1) 应用程序。我们的应用程序连接到本地 SAP Gateway for OData 服务,并使用 CF 目标和连接服务。在大多数情况下,这工作正常。 我们最近开始对 SAP OData 服务使用批处理请求。
针对 SAP 网关的本地测试表明,批处理请求处理正常。当我们发送一个应该失败的请求时,我们会得到正确的错误结果,当我们发送一个好的请求时,它也得到了很好的处理。
但是,当我们在 SAP CF 上部署应用程序,并且请求通过连接服务路由时,我们始终会收到 HTTP 202 Accepted 响应。无论 SAP 网关返回什么。如果我们在 SAP 网关上执行一些调试和跟踪,我们会看到预期的请求传入,还会看到来自 SAP 网关的预期响应。
因此,连接服务似乎无法以某种方式将响应传递回我们的应用程序。
上图显示了请求传递的组件。我们的 PMD 应用程序使用云 sdk 创建批处理请求,解析目标并通过连接服务将其发送到 SAP 网关。网关返回正确的响应,但我们从未在应用中看到该响应。相反,我们总是得到 202 Accepted 的响应。
-- 更新 2020-12-15 16:39 --
我们使用的是 OData V2。我们已经做了更多的测试,它不是连接服务。我们只关注 SAP 网关的响应有效负载。但显然,批处理响应始终包含在 202 Accepted 响应中。如果我们更仔细地观察,就会发现我们得到以下响应:
HTTP/1.1 202 Accepted
content-type: multipart/mixed; boundary=6C34B07793A6EA7C8AAFC5BC339BDAEC0
content-length: 709
dataserviceversion: 2.0
cache-control: no-cache, no-store, must-revalidate
sap-perf-fesrec: 1300458.000000
--6C34B07793A6EA7C8AAFC5BC339BDAEC0
Content-Type: application/http
Content-Length: 1171
content-transfer-encoding: binary
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=utf-8
Content-Length: 1050
dataserviceversion: 1.0
{"error":{"code":"ZCU/100","message":{"lang":"nl","value":"Service 0000000003 0000000010 niet gevonden voor operatie 0410"},"innererror":{"application":{"component_id":"","service_namespace":"/SAP/","service_id":"ZCU_PE_ORDER_SRV","service_version":"0001"},"transactionid":"23F2932D54040110E005FD84A23B406E","timestamp":"20201215151501.0634490","Error_Resolution":{"SAP_Transaction":"Run transaction /IWFND/ERROR_LOG on SAP Gateway hub system (System Alias ) 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":[{"code":"ZCU/100","message":"Service 0000000003 0000000010 niet gevonden voor operatie 0410","propertyref":"","severity":"error","target":""},{"code":"/IWBEP/CX_MGW_BUSI_EXCEPTION","message":"Fout bij wijzigen PE order.","propertyref":"","severity":"error","target":""}]}}}
--6C34B07793A6EA7C8AAFC5BC339BDAEC0--
不知何故,SAP Cloud SDK 无法正确读取响应的内容。
在我们的代码中,我们发送 1 个带有请求的变更集。以下方法是我们批量调用的核心。执行请求。其他方法只是准备批处理请求的帮助程序。batchUpdatePEOrderById
我们期望会解开第一个变更集的结果,或者至少在我们的示例请求中会导致 Try.failure(),但它总是会导致 Try.success()f.get(0)
private Either<DomainError, ExternalId> batchUpdatePEOrderById(final ExternalId id, List<ServiceChange> serviceChanges, final String jwtToken) {
final HttpDestination sapMatrix = httpDestinationProvider.providePrincipalPropagationDestination(jwtToken);
// See https://sap.github.io/cloud-sdk/docs/java/features/odata/use-typed-odata-v2-client-in-sap-cloud-sdk-for-java#batch-requests
var f = prepareBatchRequest(id, serviceChanges)
.executeRequest(sapMatrix);
return f.get(0).toEither()
.bimap(error -> getDomainError(id, error), result -> {
log.warn("Updated PE-Order {} successfully: {}", id, result.getCreatedEntities());
return id;
});
}
private ZCUPEORDERSRVServiceBatch prepareBatchRequest(ExternalId id, List<ServiceChange> serviceChanges) {
var batch = peOrderService.batch();
var changeSet = batch.beginChangeSet();
// Split service changes and add to batch operation
var newServices = mapServiceChanges(ChangeType.ADDED, serviceChanges, id);
var updatedServices = mapServiceChanges(ChangeType.QUANTITY_CHANGED, serviceChanges, id);
var deletedServices = mapServiceChanges(ChangeType.DELETED, serviceChanges, id);
if (!newServices.isEmpty()) {
buildServiceChangeSet(changeSet, newServices, ChangeType.ADDED);
}
if (!updatedServices.isEmpty()) {
buildServiceChangeSet(changeSet, updatedServices, ChangeType.QUANTITY_CHANGED);
}
if (!deletedServices.isEmpty()) {
buildServiceChangeSet(changeSet, deletedServices, ChangeType.DELETED);
}
return changeSet.endChangeSet();
}
private void buildServiceChangeSet(ZCUPEORDERSRVServiceBatchChangeSet changeSet, final List<Dienst> services, final ChangeType changeType) {
switch (changeType) {
case ADDED:
services.forEach(changeSet::createDienst);
break;
case QUANTITY_CHANGED:
services.forEach(changeSet::updateDienst);
break;
case DELETED:
services.forEach(changeSet::deleteDienst);
break;
default:
changeSet.endChangeSet();
}
}
任何想法这里可能有什么问题吗?
谢谢
丹尼
答:
此 bug 已从 SAP Cloud SDK 开始修复。3.34.1
查看相应的发行说明。
评论
3.34.1
评论
f.get(0).getCreatedEntities()
return f.get(0)....
f.get(0).getCreatedEntities
f.get(0).get().getCreatedEntities()
f.get(0).isSuccess()
true