Validate the Response for the Correct Status code inside the Response Body - citrus-framework

I need a help on validating or fetching the status code from the response body.
The below response I received from the server.
INBOUND_MESSAGE:
HTTP/1.1 200 OK Server:Apache-Coyote/1.1 Content-Type:application/json
Content-Length:253 Date:Wed, 16 Aug 2017 17:34:21 GMT
{"statusCode":201,"message":"Product added successfully with name :
StudentGuide","result":{"id":"5994821d1aee56c4dad4f04a","name":"StudentGuide","description":"StudentsGuide","price":123.0,"forSale":true,"category":"Books"},"errors":null,"others":null}
Is there a way to validate the "statusCode" inside the response body?
I tried all the possible way but didn't succeed.

Citrus provides various methods for message validation, as described in the Citrus Documentation.
Using JSONPath validation, validation could look like this (using Java DSL):
receive(yourEndpoint)
.messageType(MessageType.JSON)
.validate("$.statusCode", "201");

Related

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)
}

Scooping headers off of one Postman request and injecting them into others

My web service uses JWT-based authorization bearer token authentication:
HTTP clients send a valid POST to /v1/auth/signIn with a valid JSON request entity (includes username + password info)
If they authenticate successfully, that endpoint sends back an auth bearer token as an HTTP response header that (from curl) looks like:
Response from curl:
HTTP/1.1 200 OK
Date: Tue, 04 Sep 2018 01:18:28 GMT
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Access-Control-Expose-Headers: Authorization
Authorization: Bearer <big_huge_string>
Content-Length: 0
Subsequent service calls to authenticated endpoints just need to include the token as an HTTP request header whose key/name is Authorization and whose value is "Bearer <xyz>" (where <xyz>) is the <big_huge_string> that came back on the sign in call above. Pretty basic standard JWT stuff.
I'm trying to write a Postman collection that starts with a "Sign In Request" that successfully signs in and gets a JWT token from the service, and then adds the appropriate HTTP request header in each subsequent call. Any ideas as to how I can:
Extract the <big_huge_string> off the HTTP response header that I'll get back from my Sign In Request?; and then
How to save that <big_huge_string> as a variable and inject that as an HTTP request header for all subsequent calls?
Thanks in advance!
Update
Tried the suggestion:
Getting closer, but console.log(...) isn't printing anything to Postman (or at least I don't know where to look for it). I should mention I'm not using the Chrome Application version of Postman, but the standalone app/executable (Version 6.1.4):
Any ideas how/where I can get console.log(...) working? I'm concerned about just changing the test to:
pm.test("Can Extract JWT", function() {
var authHeader = pm.response.headers.toObject().Authorization;
pm.expect(authHeader).to.not.be.equal(null);
pm.globals.set('token', authHeader)
});
Without first seeing what that authHeader even is. Any ideas?!
Once you have that Token value you can reference it in each of the request headers using the {{token}} syntax. It's getting the sign in Auth header that's the harder part.
You could use pm.response.headers to get a list of the Headers and then extract out the value that you need.
This is returned as a list so maybe using something like Lodash or converting this to an object can help get the value you need. It would be something like pm.response.headers.toObject().Authorization - I haven't tried it so my syntax might be slightly wrong.
You can log the Headers out to the Postman console and narrow it down that way to - just wrap it in a Console.log() statement.
When you get that value, it's just a basic pm.globals.set('token, pm.response.headers.toObject().Authorization) to save this globally.

InvalidXmlRequest error for Azure REST API request

I am using the Azure REST API to create an Azure storage account using the documentation at: http://msdn.microsoft.com/en-us/library/hh264518.aspx
I keep getting the 400 error with code InvalidXmlRequest ("The request body's XML was invalid or not correctly specified."). The only related thread seemed to be at Management API - The request body XML was invalid or not correctly specified - I have tried several variations on my request (like removing xml header, removing empty elements from body, etc.) but still see the same error.
There is no requestId in the response header either (to get more info using GET OperationStatus).
The complete RAW request and response (for one of my trials) is below.
Any ideas on what I am missing here?
Request:
POST https://management.core.windows.net/<mysubscriptionid>/services/storageservices HTTP/1.1
x-ms-version: 2011-06-01
Content-Type: application/xml
Host: management.core.windows.net
Content-Length: 350
Expect: 100-continue
<?xml version="1.0" encoding="utf-8"?><CreateStorageServiceInput xmlns="http://schemas.microsoft.com/windowsAzure"><ServiceName>gjhgkjhgkgk</ServiceName><Description /><Label>gjhgkjhgkgk</Label><AffinityGroup /><Location>North Central US</Location><GeoReplicationEnabled>true</GeoReplicationEnabled><ExtendedProperties /></CreateStorageServiceInput>
Response:
HTTP/1.1 400 Bad Request
Content-Length: 228
Content-Type: application/xml; charset=utf-8
Server: Microsoft-HTTPAPI/2.0
Date: Sun, 20 Oct 2013 02:33:08 GMT
<Error xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Code>InvalidXmlRequest</Code><Message>The request body's XML was invalid or not correctly specified.</Message></Error>
2 things I noticed:
Value in label element should be base64 encoded as mentioned in the documentation here: http://msdn.microsoft.com/en-us/library/windowsazure/hh264518.aspx.
Label Required. A name for the storage account specified as a
base64-encoded string. The name may be up to 100 characters in length.
The name can be used identify the storage account for your tracking
purposes.
Not related to your problem per se but you're trying to create a storage account in North Central US region. Please note that you can't create new resources in North Central and South Central US region.

HTTP Status 202 - how to provide information about async request completion?

What is the appropriate way of giving an estimate for request completion when the server returns a 202 - Accepted status code for asynchronous requests?
From the HTTP spec (italics added by me):
202 Accepted
The request has been accepted for processing, but the processing has not been completed. [...]
The entity returned with this response SHOULD include an indication of the request's current status and either a pointer to a status monitor or some estimate of when the user can expect the request to be fulfilled.
Here are some of thoughts:
I have glanced at the max-age directive, but using it would be abusing Cache-Control?
Return the expected wait time in the response body?
Add an application specific X- response header, but the X-headers was deprecated in RFC 6648?
Add a (non X-) specific response header? If so, how should it be named? The SO question Custom HTTP headers : naming conventions gave some ideas, but after the deprecation it only answers how HTTP headers are formatted, not how they should be named.
Other suggestions?
Definitely do not abuse existing HTTP headers for this. Since it's your own server, you get to define what the response looks like. You can (and should) pick whatever response works best for the intended recipient of this information and return the actual information in the response body.
For example, if you are only interested in displaying a human-readable message then you could return text/plain saying "Your request is likely to be processed in the next 30 minutes.".
At the other end of the spectrum, you might want to go all the REST way and return application/json, perhaps formatted like this (I totally made this up on the spot):
{
"status": "pending",
"completion": {
"estimate": "Thu Sep 08 2011 12:00:00 GMT-0400",
"rejected-after": "Fri Sep 09 2011 12:00:00 GMT-0400",
},
"tracking": {
"url": "http://server/status?id=myUniqueId"
}
}
You can use the Location header to specify the URL of the status monitor. Things like current status and estimate can either go in custom headers (which noone but your own software would use), or in the response body (which a web browser would display to a user, at least).
Although not explicitly mentioned specifically for the 202 - Accepted response code, the Retry-After header seems to be a suitable option. From the documentation:
The Retry-After response-header field can be used [...] to indicate how long the service is expected to be unavailable to the requesting client.

Rest Api Return

I'm building a rest api and was wondering about returning errors. Currently, my plan was to use the http status codes but also always return a result. The result would look like the following, if an error occured or not.
{
"Data":[the data],"
Errors":[the errors]
}
Basically, if an error occurred a Http Status code of 4xx or 5xx would be returned and the Errors collection in the returned JSON would have more details about the error, with the Data section being null. If the call succeeded a Http Status code of 200 would be returned with the data element containing the requested data, and the errors element would be empty.
Would this be a good way of returning data with error information?
In my design, I didn't include both the 'data' and the 'errors' properties in the response JSON object.
If the API succeeds, I will return the 'data' only. And the http status code is 2XXX.
If the API fails, I will return a 'error' object. The http status follows the specification defined in section 10 of RFC 2616.
An example of my error object is as below.
HTTP/1.1 404 Not Found
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 100
Date: Thu, 08 Nov 2012 07:07:05 GMT
Connection: keep-alive
{
"type": "error",
"status": 404,
"message": "Not Found",
"help_url": "/api/help.html"
}
I am also using this approach. I understand this doesn't follow standard convention. But whatever. I think it can be argued either way. For me personally, my API's are not publicly available (they are all used internally by my application). So i think it's one of those "it depends" kind of situation.
All of my API's return the same data structure with a T template payload. The data structure itself is nice because the consumer has everything they need (success status, error codes, error details, and of course the data payload itself).
This way my presentation layer can treat all http responses uniformly in a friendly way.