Can't seem to find the issue with the requestID parameter for the request header - python-3.x

I am trying to pull data from a REST API that uses a "similar standard to JSON RPC". The params I am passing look right according to the documentation here and here.
The error I am receiving is ...message:"Header missing request ID".... I am unsure what I am missing that would properly declare the requestID.
I have looked at the documentation provided via the API I am trying to pull data from but it's not very helpful considering it's all in PHP and cURL. I am trying to complete this task using python-requests.
getParams = {'method': 'getCustomers', 'params':{'where':'', 'limit': 2}, 'id': 'getCustomers'}
Result:
{"result":null,"error":{"code":102,"message":"Header missing request ID","data":[]},"id":null}
The return result should contain a list of All Customers and their attributes in JSON format.

Turns out there is nothing wrong with the code I am using. There is an issue with the API I am attempting to call.

In my situation, I was getting the same error back and was required to send a X-Request-ID header. I fixed it by adding the following to my headers:
headers = {
'X-Request-ID': str(uuid.uuid1()) # generate GUID based on host & time
...
Note that (for me) the GUID needed to be of a specific format (e.g. matching the Regex ^[{]?[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}[}]?$
taken from https://www.geeksforgeeks.org/how-to-validate-guid-globally-unique-identifier-using-regular-expression/). For example, it still gave the same error if I just sent "test".

Related

Unable to fetch entity by ID in B2WDigital RestQL NPM package

I don't know if I can ask this question in here or not.
I am using the NPM package #b2wdigital/restql in a Node.js server and everything is working fine with dummy APIs from the internet...
But when I used it to call our API it worked for calling many entities "for example ENDPOINT/cars" but not for one entity "for example ENDPOINT/car/:id".
I figured that the issue that because I am using the "#" character in the ID so it is ignored on the request.
I tried to encode URI component on it so to became "%23" the problem the library encodes also the "%" so the ID will contain "%2523" which does not exist.
I didn't find a solution for this.
My query is below (I am passing the values as parameters):
from car
headers
Authorization = $auth
with
id = $id
My mappings are:
{
"cars": "https://www.example.com/dev/cars",
"car": "https://www.example.com/dev/cars/:id"
}
Any help will be appreciated!

Handling of etags in batch request using SAP Cloud SDK

I am trying to carry out a batch request including a create, update and a delete (all are different salesorders). As per this question here which deals with something similar, I have done a get for the items I want to update and delete before I add them to the batch request. I am using the SalesOrder.builder() to prepare the SalesOrder I want to create.
final ErpHttpDestination destination = DestinationAccessor.getDestination(DESTINATION_NAME)
.asHttp().decorate(DefaultErpHttpDestination::new);
final SalesOrderItem salesOrderItem1 = SalesOrderItem.builder().material(material)
.requestedQuantityUnit(requestedQuantityUnit).build();
final SalesOrder salesOrder1 = SalesOrder.builder().distributionChannel(distributionChannel)
.salesOrderType(salesOrderType).salesOrganization(salesOrganization)
.organizationDivision(organizationDivision).soldToParty(soldToParty)
.item(salesOrderItem1).build();
final SalesOrder orderToUpdate = new GetSingleSalesOrderCommand(orderToUpdateID, destination,
new DefaultSalesOrderService()).execute();
orderToUpdate.setSoldToParty(updateSoldToParty);
final SalesOrder orderToDelete = new GetSingleSalesOrderCommand(orderToDeleteID, destination,
new DefaultSalesOrderService()).execute();
SalesOrderServiceBatch service = new DefaultSalesOrderServiceBatch(
new DefaultSalesOrderService());
BatchResponse bRes = service.beginChangeSet().createSalesOrder(salesOrder1).updateSalesOrder(orderToUpdate)
.deleteSalesOrder(orderToDelete).endChangeSet().execute(destination);
I am then logging the BatchResponse and see I am getting a Batch Response Failure:
eTag handling not supported for http method 'POST'
I have searched for this error but can't find any resolution to it. Any ideas?
Thanks.
UPDATE: Increasing the logging to DEBUG I can see the batch request that is being sent and can see that there is an if-match header being added to the create request, which doesn't make sense as it can't match something that doesn't exist yet.
"msg":"--batch_123\r\nContent-Type: multipart/mixed;
boundary=changeset_(changeset number)\r\n\r\n--
changeset_(changeset number)\r\nContent-Type:
application/http\r\nContent-Transfer-Encoding: binary\r\n\r\nPOST
/sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrder HTTP/1.1\r\nContent-
Length:
193\r\nIf-Match: W/\"datetimeoffset'2020-05-
01T11%3A51%3A16.8631720Z'\"\r\nAccept:
application/json;odata=verbose\r\nContent-Type:......
The I get the error:
Inner Error:
"msg":"batch
responseFailure(com.sap.cloud.sdk.odatav2.connectivity.ODataException:
null: <?xml version=\"1.0\" encoding=\"utf-8\"?><error
xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">
<code>/IWFND/CM_MGW/537</code><message xml:lang=\"en\">eTag handling not
supported for http method 'POST'</message><innererror>...
However, what does work is if I wrap each request in its own changeset e.g.
service
.beginChangeSet().createSalesOrder(order).endChangeSet()
.beginChangeSet().updateSalesOrder(orderToUpdate).endChangeSet()
.beginChangeSet().deleteSalesOrder(orderToDelete).endChangeSet()
.execute(destination);
Edit:
This is fixed as of version 3.25.0.
Initial Answer:
This seems to be a bug. I was able to reproduce this with a different service and the behaviour is the same: The if-match header is incorrectly applied to the POST operation as well.
When debugging it seems like the request is build up correctly with the header only being present on update and delete. However, it seems that when the batch request is serialised to JSON it gets added to all requests.
So until this is fixed the workaround is isolating these operations via change sets, as you already pointed out.
Looks like eTag handling is not supported for your endpoint.
Now you can do the following to omit eTag headers:
orderToUpdate.setVersionIdentifier(null);
orderToDelete.setVersionIdentifier(null);
However I'm not sure how 'POST' fits the error description, because update uses PATCH and delete uses DELETE. The only POST that I expect would be coming from create. But we do not add headers for entity version identifiers (eTag) in OData create operation. If the same error still comes up, please try again without running createSalesOrder(salesOrder1).

How to pass DateTime for a SOAP request to a azure web api?

I am creating a web api on Azure (APIM). This web api access a method on from an on prem service.
The request object passed should be SOAP. This request object also contains a Date time field. I am trying from quite sometime now but my request is failing with the following error:
There was an error deserializing the object of type Core.Service.DataContracts.ExternalData. The value '' cannot be parsed as the type 'DateTime'.
I am passing the following Request Object, through Postman to test my web api:
{
"integrationpartnername" : "Hi-Marley",
"actioncategory" : "TextChat",
"actioncode" : "OpenClaim",
"actiondescription" : "Text Chat Open Claim",
"transmissionmethod" : "WebService",
"requeststatus" : "Complete",
"requestdate" : "2019-08-02T10:22:49",
"requestmessage" : "Hi Marley first third party log from apim.",
"responsedate" : "2019-08-02T10:22:49"
}
Any pointers are much appreciated.
Edit: Adding the screenshot of the Postman:
This issue may caused by the date/time string is not the expected format, you can have a try with this format: "2019-08-12T12:00:00.000Z" and change the format code in your api.
For further information, you may refer to the pages below:
http://www.mirthproject.org/community/forums/showthread.php?t=9407
http://tech.forums.softwareag.com/techjforum/posts/list/31905.page
Running the test in the portal I could see in the trace that the date was being converted from 2019-08-02T10:22:49.463Z in the JSON body to 8/12/2019 10:22:49 AM in the SOAP body. The WCF service was throwing a deserialization exception because that datetime format cannot be parsed. The solution is to format the date in the liquid syntax, like this
{{body.RequestDate | Date: "yyyy-MM-ddTHH:mm:ss"}}. The correct date format to use was not as straight forward to find since the liquid documentation says to use Ruby strftime format, but that did not work for me https://shopify.github.io/liquid/filters/date/. Apparently the APIM uses dotLiquid and not basic liquidSee https://azure.microsoft.com/en-us/blog/deep-dive-on-set-body-policy/ for reference.

SOAP UI how to configure a PUT request body programmatically

I'm configuring some requests programmatically in my test cases, I can set headers, custom properties, teardown scripts, etc. however I can't find how to set a standard json body for my put requests.
Is there any possibility from the restMethod class ?
So far I end up getting the method used :
restService = testRunner.testCase.testSuite.project.getInterfaceAt(0)
resource = restService.getOperationByName(resource_name)
request = resource.getRequestAt(0)
httpMethod = request.getMethod()
if (httpMethod.toString().equals("PUT"))
but then I'm stuck trying to find how to set a standard body for my PUT requests.
I try with the getRequestParts() method but it didn't give me what I expected ...
can anyone help, please
thank you
Alexandre
I’ve managed this. I had a tests of tests where I wanted to squirt the content of interest into the “bare bones” request. Idea being that I can wrap this in a data driven test. Then, for each row in my data spreadsheet I pull in the request body for my test. At first I simply pulled the request from a data source value in my spreadsheet, but this became unmanageable in my spreadsheet.
So, another tactic. In my test data sheet (data source) I stored the file name that contains the payload I want to squirt in.
In the test itself, I put in a groovy step immediately before the the step I want to push the payload into.
The groovy script uses the data source to firstly get the file name containing the payload, I then read the contents of the file.
In the step I want to push the data into, I just use a get from data, e.g. {groovyStep#result}.
If this doesn’t completely make sense, let me know and I’ll update with screenshot when I have access to SoapUi.

Using 'querystring.parse' built-in module's method in Node.JS to read/parse parameters

Scenario:
Consider the following code:
var querystring = require('querystring');
var ParamsWithValue = querystring.parse(req._url.query);
Then I am able to read any query string's value.
E.g: If requested string is http://www.website.com/Service.aspx?UID=Trans001&FacebookID=ae67ea324
I can get the values of query string with codes ParamsWithValue.UID & ParamsWithValue.FacebookID respectively.
Issue: I am able to get the values of any number of parameters passed in the same way described above. But for second time onwards I am getting the following error in response on browser.
Error:
{"code":"InternalError","message":"Cannot read property 'query' of undefined"}
Question: What is wrong in the approach to read the query string from the URL.
Note: I don't want to use any frameworks to parse it. I am trying to depend on built-in modules only.
Update: It responds correctly when the value of any of the parameter is changed. But if the same values requested again from even different browser it throws same error.
I think you need req.url rather than req._url.
req.url is a string, if you want a URI instance use require('url').parse(req.url)
So, you should finally have:
var ParamsWithValue = querystring.parse(require('url').parse(req.url).query);
Edit: I corrected a typo in point 1, the last req.url -> req._url

Resources