1
votes

We are currently struggeling with Batch Query, which seems to ignore the filter expressions on S4 side caused by a wrong URL encoding.

/sap/opu/odata/sap/ZP2M_A_CONTRACT_SEARCH_HDR_CDS/ZP2M_A_CONTRACT_SEARCH_HDR?$filter=PurchaseContractID eq %274600002020%27&$select=*&$format=json

Executing the query using FluentHelperRead.execute(HttpClient) the returned list of entities contains the expected result with exactly one entity.


Executing the query as Batch Query the following request is logged in console:

GET ZP2M_A_CONTRACT_SEARCH_HDR?%24filter%3DPurchaseContractID+eq+%25274600002020%2527%26%24select%3D*%26%24format%3Djson HTTP/1.1

The collected list from all batch result parts contains all entities.


It seems, that the query URL is encoded in wrong way
and that S4 ignored the filter expressions when encoded in this way.
e.g. $filter is encoded to %24filter which is ignored by S4.

This seems to be a bug in BatchRequestImpl.getRequest(ODataQueryImpl) method,
where URL encoding is done a 2nd time on already encoded URL parts.

if(systemQuery.indexOf("$format=json&$count=true") != -1)
{
    systemQuery = systemQuery.substring(0, systemQuery.indexOf("$format=json&$count=true") -1);
    keysUrl.append("/$count");
}
systemQuery = URLEncoder.encode(systemQuery, "UTF-8"); // this code line which encodes the query 2nd time
keysUrl.append("?");

The code line systemQuery = URLEncoder.encode(systemQuery, "UTF-8"); located in
  BatchRequestImpl(1.38.0) - line 295
  BatchRequestImpl(1.42.2) - line 307
encodes the systemQuery string again (including the already encoded parts of FilterExpression as well).

When undoing the changes of this code line in debugger and replacing the scapces by %20 or '+' the Batch Query looks like that

GET ZP2M_A_CONTRACT_SEARCH_HDR?$filter=PurchaseContractID%20eq%20%274600002020%27&$select=*&$format=json HTTP/1.1

GET ZP2M_A_CONTRACT_SEARCH_HDR?$filter=PurchaseContractID+eq+%274600002020%27&$select=*&$format=json HTTP/1.1

and it returns the expected result (exactly 1 entity).


This wrong encoding appears when using these library versions:
sdk-bom: 3.16.1
connectivity: 1.38.0

This issue appears in newest SDK versions as well:
sdk-bom: 3.21.0
connectivity: 1.39.0

This issue appears with connectivity JAR in newest version too:
sdk-bom: 3.21.0
connectivity: 1.40.2

Debugging together with a ABAP/S4 colleague figures out,
that S4 only applies filter expressions, if the keyword $filter is found in request,
%24filter%3D is ignored (the cause why we get all entities running the Batch Query).

My suggestion to solve it would be

// decode query first (to decode the filter expression)
systemQuery = URLDecoder.decode(systemQuery, "UTF_8");
// encode query
systemQuery = org.apache.commons.httpclient.util.URIUtil.encodeQuery(systemQuery, "UTF_8");

My code, how I am calling the batchRequest:

FluentHelperRead<?, MyEntity, ?> queryApi = myService.getAll... // with adding some filter expression

BatchRequestBuilder batchRequestBuilder = BatchRequestBuilder.withService(MyService.DEFAULT_SERVICE_PATH);
ODataQuery query = queryApi.toQuery();
batchRequestBuilder.addQueryRequest(query);
HttpClient httpClient = HttpClientAccessor
    .getHttpClient(DefaultErpHttpDestinationAccessor.get());
BatchRequest request = batchRequestBuilder.build();
BatchResult result = request.execute(httpClient);
// ... evaluate response

I think, this is a general issue in the Cloud SDK.
Would is be possible to get this fixed in next Cloud SDK release?

2
Hi Adam, thanks for such a quality bug report! We'll reproduce the issue shortly and will do our best to release a fix in the next SDK release. We have a bi-weekly release cadence, which means the next one is settled. After confirming, reproducing, and agreeing on the fix we'll update you on the release number it will be fixed with.Artyom Kovalyov
What's you deadline for this?Artyom Kovalyov
This issue affects my customer's production environment. So it would be greate to have it as soon as possible.Adam K.

2 Answers

1
votes

Can you share your code for Batch request? Do you use BatchRequestImpl directly?

The thing is SAP Cloud SDK relies on some dependencies one of which introduces the BatchRequestImpl and if it's called directly the bug is on the dependency side. I have already informed them to investigate this double encoding issue. Unfortunately, we can't directly influence how fast it is resolved and sometimes it takes longer than we'd like.

The good news, we're working on replacing this dependency with our own implementation to solve exactly this kind of problem. The batch is work in progress and should be available in Beta around the end of next month for OData V4 and hopefully around the same time for OData V2 (it's not a hard commitment and depends on other priorities).

From here we have to wait for whatever happens first:

  • The bug is fixed on the dependency side
  • Internal OData client implementation is ready together with Batch

I hope it helps and explains current solution path. If you share a bit around your deadlines and the potential impact we'll be happy to consider that.

1
votes

This has been fixed within the dependency and as of version 3.25.0 the SAP Cloud SDK includes the fix.