Receiving a SystemFault when I query Item - intuit-partner-platform

Using V3 when I attempt to query for Items I receive a generic error with a SystemFault type.
I am attempting to perform Select * From Item Where Name = 'Something'
This does work in the API Explorer, and I believe I am re-creating the HTTP request accurately.
My HTTP GET is:
GET /v3/company/redacted/query?query=Select%20*%20From%20Item%20Where%20Name%20=%20'Something'%20STARTPOSITION%201%20MAXRESULTS%2020 HTTP/1.1
Accept application/xml
Accept-Encoding gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Authorization OAuth oauth_consumer_key="redacted", oauth_nonce="redacted", oauth_signature="redacted", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1386704546", oauth_token="redacted", oauth_version="1.0"
Host qb.sbfinance.intuit.com
And the response I am receiving:
<IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2013-12-10T11:42:03.147-08:00">
<Fault type="SystemFault">
<Error code="10000">
<Message>An application error has occurred while processing your request</Message>
<Detail>System Failure Error: Unexpected Internal Error. (-30000)</Detail>
</Error>
</Fault>
</IntuitResponse>
Am I missing something obvious? Thank you.

It's not obvious, but from the documentation found here, it looks like you must encode the ' and = present on your query.
So instead of:
/v3/company/redacted/query?query=Select%20*%20From%20Item%20Where%20Name%20=%20'Something'%20STARTPOSITION%201%20MAXRESULTS%2020
You should use
/v3/company/redacted/query?query=Select%20*%20From%20Item%20Where%20Name%20%3D%20%27Something%27%20STARTPOSITION%201%20MAXRESULTS%2020
Encoding ' to %27, and = to %3D.

Related

Microsoft Ads 'AccountPerformanceReportRequest' data contract. The deserializer has no knowledge of any type that maps to this contract

I'm trying to use the Microsoft Bing Ads' Reporting API to gather ad performance data such as clicks, spend, etc. programmatically. Below, I describe the steps taken.
There are two issues -
1 - I have to request for user consent again and again as access token
is short lived and refreshed token also giving unauthenticated token
error.
2 - After following the steps I don't get the expected SOAP
Response. Instead I get below response.
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:DeserializationFailed</faultcode>
<faultstring>The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter https://bingads.microsoft.com/Reporting/v13:ReportRequest. The InnerException message was 'Error in line 13 position 71. Element 'https://bingads.microsoft.com/Reporting/v13:ReportRequest' contains data of the ':AccountPerformanceReportRequest' data contract. The deserializer has no knowledge of any type that maps to this contract. Add the type corresponding to 'AccountPerformanceReportRequest' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details.</faultstring>
</s:Fault>
</s:Body>
</s:Envelope>
I'm using Postman to test the service and my end goal is to use http to do the same in Mulesoft later. This is the URL I am using
https://reporting.api.bingads.microsoft.com/Api/Advertiser/Reporting/V13/ReportingService.svc
Authentication
I have followed their OAuth 2.0 Authentication Flow in that, I have:
Registered my Application (using the Developer Account)
Requested user consent (through the Ad account)
Generated the Access Token and Refresh Token Every time I hit the API.
**
I generate a new Access Token by requesting user consent again and again as refreshing
token is also not working.
**
Making the Request
The documentation describes a Reporting Service Operation which follows an asynchronous approach. First we need to use SubmitGenerateReport to make a request to the Reporting Service. This returns a ResponseRequestId which we can then use to repeatedly poll the service using PollGenerateReport till we get the requested report in response.
SubmitGenerateReport
SubmitGenerateReport has to be in SOAP XML Format as stated here. Following is the document I generated for my use case looking at the provided example in the documentation. Action I am passing as header attribute - SOAPAction:SubmitGenerateReport
<x:Envelope
xmlns:x="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:v="https://bingads.microsoft.com/Reporting/v13"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<x:Header>
<v:AuthenticationToken>****</v:AuthenticationToken>
<v:CustomerAccountId>****</v:CustomerAccountId>
<v:CustomerId>****</v:CustomerId>
<v:DeveloperToken>****</v:DeveloperToken>
</x:Header>
<x:Body>
<v:SubmitGenerateReportRequest>
<v:ReportRequest i:type="AccountPerformanceReportRequest">
<v:Format>Csv</v:Format>
<v:ReportName>AccountPerformanceReportRequest</v:ReportName>
<v:Aggregation>Summary</v:Aggregation>
</v:ReportRequest>
</v:SubmitGenerateReportRequest>
</x:Body>
</x:Envelope>
I even tried passing all the input variables, scope, time etc but getting some error again. I understand error clearly tells me where the error is but the report types I am using are given in Microsoft documentations.
Any help and suggestion would be really helpful.
1. I have to request for user consent again and again as access token is short lived and refreshed token also giving unauthenticated token error.
I would like to point you to these tutorial, as reference for my code below.
https://learn.microsoft.com/en-us/advertising/guides/get-started?view=bingads-13
https://learn.microsoft.com/en-us/advertising/guides/authentication-oauth-quick-start?view=bingads-13
In the first step, you fetch code, for this you need browser verification.
$clientId = '...'
Start-Process "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=$clientId&scope=openid%20profile%20https://ads.microsoft.com/msads.manage%20offline_access&response_type=code&redirect_uri=https://login.microsoftonline.com/common/oauth2/nativeclient&state=ClientStateGoesHere&prompt=login"
$code = 'https://login.microsoftonline.com/common/oauth2/nativeclient?code=<code>&state=ClientStateGoesHere'
$code = $code -match 'code=(.*)\&'
$code = $Matches[1]
Now, using this code, you get accessToken/refreshToken.
$response = Invoke-WebRequest https://login.microsoftonline.com/common/oauth2/v2.0/token -ContentType application/x-www-form-urlencoded -Method POST -Body "client_id=$clientId&scope=https://ads.microsoft.com/msads.manage%20offline_access&code=$code&grant_type=authorization_code&redirect_uri=https%3A%2F%2Flogin.microsoftonline.com%2Fcommon%2Foauth2%2Fnativeclient"
$oauthTokens = ($response.Content | ConvertFrom-Json)
Since, this access token $oauthTokens.access_token will expire after one hour, use the refresh token to get new access and refresh tokens. This process you need to do periodically, say on 1/2 hourly basis.
Process to refresh is the following. This does not require you to login.
$response = Invoke-WebRequest https://login.microsoftonline.com/common/oauth2/v2.0/token -ContentType application/x-www-form-urlencoded -Method POST -Body "client_id=$clientId&scope=https://ads.microsoft.com/msads.manage%20offline_access&code=$code&grant_type=refresh_token&refresh_token=$($oauthTokens.refresh_token)"
$oauthTokens = ($response.Content | ConvertFrom-Json)
PS, I'm unclear if we could refresh infinitely or whether it is bound to a day. I verified that an expired accessToken could be renewed via refreshToken via this method after 1.5 hours - no need of generating code again via relogin.
2. After following the steps I don't get the expected SOAP Response. Instead I get below response
Thank you for providing the detailed soap xmls. I tried the same on my test account and able to repro exact same error message.
Here's the udpated SOAP xml request I used to get it to work.
<s:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header xmlns="https://bingads.microsoft.com/Reporting/v13">
<AuthenticationToken i:nil="false">here goes token</AuthenticationToken>
<CustomerAccountId i:nil="false">176045209</CustomerAccountId>
<CustomerId i:nil="false">169549046</CustomerId>
<DeveloperToken i:nil="false">here goes dev Token</DeveloperToken>
</s:Header>
<s:Body>
<SubmitGenerateReportRequest xmlns="https://bingads.microsoft.com/Reporting/v13">
<ReportRequest i:nil="false" i:type="AccountPerformanceReportRequest">
<Format i:nil="false">Csv</Format>
<ReportName i:nil="false">reportName1</ReportName>
<!--These fields are applicable if the derived type attribute is set to AccountPerformanceReportRequest-->
<Aggregation>Summary</Aggregation>
<Columns i:nil="false">
<AccountPerformanceReportColumn>Impressions</AccountPerformanceReportColumn>
<AccountPerformanceReportColumn>Revenue</AccountPerformanceReportColumn>
<AccountPerformanceReportColumn>AccountName</AccountPerformanceReportColumn>
</Columns>
<Scope i:nil="false">
<AccountIds i:nil="false" xmlns:a1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<a1:long>176045209</a1:long>
</AccountIds>
</Scope>
<Time i:nil="false">
<CustomDateRangeEnd i:nil="false">
<Day>22</Day>
<Month>07</Month>
<Year>2022</Year>
</CustomDateRangeEnd>
<CustomDateRangeStart i:nil="false">
<Day>01</Day>
<Month>07</Month>
<Year>2022</Year>
</CustomDateRangeStart>
</Time>
</ReportRequest>
</SubmitGenerateReportRequest>
</s:Body>
</s:Envelope>
Here's the postman result.
PS, I received error, when some fields were missing. I did not use xml namespaces.
Hope this helps.

SOAP Fault response from Wiremock not detected as SOAPFault by API-Connect 2018

When I call the actual SOAP service (using Postman and SoapUI) with an invalid parameter value, it causes a SOAP-Fault response, with HTTP 200 .
I copied the body of the response into a Wiremock response file, whose corresponding mapping file returns HTTP 200.
When I use Postman to invoke the SOAP service and the mocked one, the 'Body' of the responses are identical (apart from headers, as the mocked response doesn't explicitly set any).
When my API invokes the actual SOAP service, the SOAPError is caught, the processing stops and the API is processed as defined in the 'catch' section.
However, when the API invokes the mocked SOAP service, the SOAPError is not detected after 'invoke', processing continues and produces an incorrect response.
This suggests that there is something 'extra' returned in a fault from a real SOAP service, that APIC uses to detect a SOAPError. What is it?
I would add it to the mocked response, if only I knew what it should be.
BTW: The response headers are the same for both valid parameters and the SOAP Fault for an invalid one.
[edit]
Thanks #Jan Papenbrock. Adding "Content-Type = text/xml" sorted it out.
I don't know why I thought I was receiving the same headers from real and mocked responses - total rubbish!
John
[/edit]
Had the same error with WireMock and fixed it with the help of answers to this question. In my case, the Content-Type header was missing.
I suggest you try the following:
Send Content-Type: text/xml as response header (or try application/soap+xml)
Return HTTP status code 500 for the SOAP fault response, according to the specification (note: status 400 did not work for me).
My stub generation looks like this:
static ResponseDefinitionBuilder errorInvalidStopResponse() {
responseWithBodyFile('response-error-invalid-stop.xml')
.withStatus(500)
}
static ResponseDefinitionBuilder responseWithBodyFile(String responseBodyFileName) {
aResponse()
.withStatus(200)
.withHeader("Content-Type", "text/xml")
.withBodyFile(responseBodyFileName)
}

Which HTTP code should be return from REST API?

im currently working on a website which has Spring at backend and Angularjs at front side and we had discussed about back end responses to handle frontend's message dialogs and i have a question to ask:
Lets say i have an API :
GET : /getstatistics
Request params : fromTime,toTime ( in timestamp format)
And if client make a request with invalid params like a string, which response code should be returned from server ? HTTP 400 bad request and response body with a message " fromTime and toTime should be in timestamp format" or HTTP 200 with same message?
I saw some Google's APIs for example Oauth, they're returning code 200 for a request with invalid access_token but ,in our project my opinion it should be HTTP 400 because Javascript has success and error callbacks, is it better for it just pop a red color dialog with message inside rather than a HTTP 200 code then still need to check the content of the message?
Any advides and opinions are appreciated.
Thanks!
You should be returning a 400 error for bad request. Check out this reference.
The server cannot or will not process the request due to something
that is perceived to be a client error (e.g., malformed request
syntax, invalid request message framing, or deceptive request
routing).
Please have a look at RFC7231#section-6
A client MUST understand the class of any status code, as indicated by
the first digit
and,
4xx (Client Error): The request contains bad syntax or cannot be
fulfilled
Bad syntax can be something like you've mentioned in your question (making a request with invalid parameters, like a string).
I keep these two references handy whenever I'm designing RESTful APIs, might be helpful for you too:
https://httpstatuses.com/
http://www.restapitutorial.com/httpstatuscodes.html
Yes you are right, the http code should be 400 in your case. Your discussion here normally should be whether you need to return 400 or 422. For this you can check the accepted response for this SO question 400 vs 422 response to POST of data
I think it has something to do with how the parameters are used. If you use the resource, then a 404 should return. If the data is simply not valid then we decide to set a 409 Status to the request. It can't full fill it at 100% because of missing/invalid parameter.
HTTP Status Code "409 Conflict" was for us a good try because it's
definition require to include enough information for the user to
recognize the source of the conflict.
Reference: w3.org/Protocols/
Edit:
In any case, the status code 200 is incorrect here because there is an error. In response, you can then return specific information like this:
{
"errors": [
{
"userMessage": "Sorry, the parameter xxx is not valid",
"internalMessage": "Invalid Time",
"code": 34,
"more info": "http://localhost/"
}
]
}

WSO2 API Manager - Publishing API with non-XML response

I am trying to proxy the following call through WSO2 API Manager
http://api.qrserver.com/v1/create-qr-code/?data=HelloWorld&size=100x100
which returns a QR code image. I published the API using http://api.qrserver.com/v1/ as endpoint, no problem there. But when I perform the call through the API Manager, I get the following error:
curl -H 'Authorization:Bearer 7q6W4LteX9idveFWbSa_oaGPhVsa' 'http://ec2-xx-xx-xx-xx.eu-west-1.compute.amazonaws.com:8280/qrcode/1.0.0/create-qr-code/?data=HelloWorld&size=100x100'
<Exception>Unexpected response received. HTTP response code : 200 HTTP status : OK exception : com.ctc.wstx.exc.WstxIOException: Invalid UTF-8 start byte 0x89 (at char #1, byte #-1)</Exception>
when performing the call directly the response header seems good to me (the mime type image/png is correctly set), but the WSO2 API proxy refuses the response... what I am doing wrong? Setting a wadl file with response mediaType="image/png" does not seem to help either.
Thanks in advance
I have a similar problem in wso2 esb. Seems that the response works with short xml files but not with a big one.
This problem is due to not having match message builders and formatters by default in API manager's axis2.xml. Please add following parameters to axis2.xml.
<messageBuilder contentType=".*" class="org.wso2.carbon.relay.BinaryRelayBuilder"/>
<messageFormatter contentType=".*" class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>
Thanks.
Sanjeewa.

HTTP Status code for malformed POST body

What status code should a REST service return in response to a POST request containing a malformed / unparseable message body?
400 Bad Request
Straight from the specification:
The request could not be understood by the server due to malformed
syntax. The client SHOULD NOT repeat the request without
modifications.
Alternatively, if you need a more specific status you can create your own 4XX status for whatever API you might be designing.
400 - Bad Request
From Hypertext Transfer Protocol -- HTTP/1.1 (RFC-2616):
400 Bad Request
The request could not be understood by the server due to malformed
syntax. The client SHOULD NOT repeat the request without
modifications.
I'd say 412 Precondition Failed