How should one send ACKs to Mirth from a web service? - http

I want to write a simple "web service" that I can use Mirth to send HL7 messages to. This "web service" could be as simple as a CGI script, and would just need to accept the HL7 message as a string (and possibly a couple of other values) as a POST request using Mirth's HTTP sender.
This seems simple enough, but how should this "web service" send back the ACK to let Mirth know if everything is OK or something went wrong? Is there a specific format that Mirth is expecting as a response? Or is there some way to tell Mirth what to expect?
Note: I do not want to use Mirth on the receiving end.

The short answer is that it's completely up to you... Mirth Connect can accommodate any response (or lack thereof) and perform custom user-logic to decide whether the response is "successful" or not.
You could have your external web service generate an HL7 v2.x ACK and send that back. Then on the HTTP Sender side, make sure your Response data types are set to HL7 v2.x, and enable "Validate Response" in the destination settings.
You can also have your web service generate a completely custom response and do custom validation on the MC side. For example if you have your web service send back a response like this:
{
"success": true,
"message": "Message received successfully."
}
Then you can set your Response data types to JSON, and do this in the response transformer:
if (msg.success !== true) {
responseStatus = ERROR;
}
responseStatusMessage = msg.message;
You can also validate purely on the response status code. By default with an HTTP Sender, the message status will be set to SENT only if the HTTP request returned with a status of < 400. Anything else and the status will be left as QUEUED (or ERROR if queuing is disabled).
You can override that behavior in the response transformer though. Maybe you only want it to be SENT if the status is specifically 200 (and not other 2xx or 3xx codes). Set your Response data types to Raw (so that the response transformer will execute even when there is no response), and do this in the response transformer:
var responseStatusLine = $('responseStatusLine');
var responseCode = parseInt(responseStatusLine.split(' ')[1], 10);
if (responseCode != 200) {
responseStatus = ERROR;
responseStatusMessage = responseStatusLine.substr(responseStatusLine.indexOf(' ')).trim();
}

Related

How can I test a http request in JMeter when the service is not available

I am trying to test a http request but the service is not available, is there a way to create a dummy response in JMeter? The purpose of this is to test the request that is actually being sent
The dummy sampler has been recommended however, if another tester has not got this plugin then they will not be able to test it. Is there another sampler or tool already built-in that can be used?
Actually, you ultimately can do whatever you want with JSR223 Sampler.
And it's fairly easy to code an HTTP request in Groovy, as the HTTP Client functionality is effectively embedded into the environment, something like:
def urlString = 'http://' + restHost + ':' + restPort + '/' + restPath + '?' + paramString.toString()
def url = urlString.toURL()
def response = url.getText()
As simple as that.
You can catch the protocol error then, and respond with whatever you want - you've got full access to your SampleResult object from script:
try {
...
} catch(IOException ioe) {
SampleResult.setResponseCode("200")
SampleResult.setResponseMessage("FAKE OK")
SampleResult.setResponseData("My dummy response!", "UTF-8")
SampleResult.setSuccessful(true)
}
P.S. Not sure I truly understand the reasoning behind a request like this.
If situation is so unfortunate that the team responsible for the service under test is refusing to cooperate that badly, I would rather quickly do a the mock service, and leave the test pure, simple & versatile.
The request will not be sent as you need to establish underlying TCP connection prior to sending whatever data over the wire.
If you want to test the fact that the server is down you can define connect and response timeouts, the settings live under "Advanced" tab of the HTTP Request sampler (or even better HTTP Request Defaults)
The above configuration will "tell" JMeter to attempt to establish the connection and if there will be no response in 1 second - the sampler will be marked as failed:
If this is the behaviour you expect you can configure JMeter to accept this response by adding a Response Assertion as a child of the request and configuring it like:
Field to Test: Response Code
Pattern Matching Rules: Equals
Patterns to Test: Non HTTP response code: org.apache.http.conn.ConnectTimeoutException
Tick Ignore Status box
This way JMeter will treat the timed-out request as successful:

I send some values to another url and about that

I send some values using spring httpClient to other url. And about that question as I know if I send name=mister age=30 values, received page get that values not http status values, right?
Http status values are for sending page's not receive page's.
I mean, if I send those values, receiving page gets http values.
If receiving page want to get that values, I have send that values, is that right?
My team manager said to me that http has request and response so, if you send some values to other url, other url gets http status values.
But as I thought that is little bit anyway I can't understand my team manager's saying, please let me know, receiving page gets http status when I send some values.
Your team manager's statement is correct. ("the http status have to be written.", "http has request and response. so there should have that http status value result"). What he/she mentioned is HTTP response status code, which should be returned (with correct code) whatever the response is.
No matter your result (name=mister and age =30 etc.) is a static page or an Ajax response, the response code should be 200 OK when the result is generated successfully (correct business logic, no error happens). But when something bad happens, it is important to let client know why server failed to return result -- maybe it is because the request format is incorrect (400 Bad Request), there is a typo in request url (404 Not Found) or some error in server code (500 Internal Server Error). Send name=null and age=null to client with 200 OK is incorrect and bug prone. Without definition of these error status code in document, backend engineer have to communicate with frontend engineer during the development, API by API, case by case, which is very time consuming and inefficient.
I think your TODO is: for the API that accepts name=mister and age =30, define success case and different failure case, then assign correct response code to them.

HTTP Response Objects

Does every HTTP request need to be paired with a response? When you do some POST or DELETE actions, my understanding is that sometimes you don't need to send back data. I've always been told to send back an empty object, but is that necessary? Also, is sending a status code considered a response?
Q1: Does every HTTP request need to be paired with a response?
Yes, unless client cancel the request. Actually, one HTTP request needs to be paired with one or more HTTP responses. According to RFC7231:
A server listens on a connection for a request, parses each message received, interprets the message semantics in relation to the identified request target, and responds to that request with one or more response messages.
Q2: When you do some POST or DELETE actions, my understanding is that sometimes you don't need to send back data. I've always been told to send back an empty object, but is that necessary?
It's NOT necessary to send back an empty object (payload). According to RFC7230, the response payload is not required:
A server responds to a client's request by sending one or more HTTP response messages, each beginning with... and finally a message body containing the payload body (if any).
However, although you don't have to "send back data", you still need to send back message, such as HTTP response statuc code and some necessary response headers.
Q3: is sending a status code considered a response?
Yes. Theoretically, a minimal HTTP response can only include HTTP protocol version, status code and status code textual phrase.

What to do with errors when streaming the body of an Http request

How do I handle a server error in the middle of an Http message?
Assuming I already sent the header of the message and I am streaming the
the body of the message, what do I do when I encounter an unexpected error.
I am also assuming this error was caused while generating the content and not a connection error.
(Greatly) Simplified Code:
// I can define any transfer encoding or header fields i need to.
send(header); // Sends the header to the Http client.
// Using an iterable instead of stream for code simplicity's sake.
Iterable<String> stream = getBodyStream();
Iterator<String> iterator = stream.iterator();
while (iterator.hasNext()) {
String string;
try {
string = iterator.next();
catch (Throwable error) { // Oops! an error generating the content.
// What do i do here? (In regards to the Http protocol)
}
send(string);
}
Is there a way to tell the client the server failed and should either retry or abandon the connection or am I sool?
The code is greatly simplified but I am only asking in regards to the protocol and not the exact code.
Thank You
One of the following should do it:
Close the connection (reset or normal close)
Write a malformed chunk (and close the connection) which will trigger client error
Add a http trailer telling your client that something went wrong.
Change your higher level protocol. Last piece of data you send is a hash or a length and the client knows to deal with it.
If you can generate a hash or a length (in a custom header if using http chunks) of your content before you start sending you can send it in a header so your client knows what to expect.
It depends on what you want your client to do with the data (keep it or throw it away). You may not be able to make changes on the client side so the last option will not work for example.
Here is some explanation about the different ways to close. TCP option SO_LINGER (zero) - when it's required.
I think the server should return a response code start with 5xx as per RFC 2616.
Server Error 5xx
Response status codes beginning with the digit "5" indicate cases in which the server is aware that it has erred or is incapable of performing the request. Except when responding to a HEAD request, the server SHOULD include an entity containing an explanation of the error situation, and whether it is a temporary or permanent condition. User agents SHOULD display any included entity to the user. These response codes are applicable to any request method.

Spring RestTemplate - http GET with request body [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
HTTP GET with request body
I've read few discussions here which do not advocate sending content via HTTP GET. There are restrictions on the size of data that can be sent via clients (web browsers). And handling GET data also depends on servers. Please refer section Resources below.
However, I've been asked to test the possibility to send content via HTTP GET using RestTemplate. I refered few discussions on spring forum but they were not answered. (Please note sending data via http Post works fine). The discussion here suggests using POST instead.
dev env - JBoss AS 5.1, Spring 3.1.3
Client
#Test
public void testGetWithBody()
{
// acceptable media type
List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
acceptableMediaTypes.add(MediaType.TEXT_PLAIN);
// header
HttpHeaders headers = new HttpHeaders();
headers.setAccept(acceptableMediaTypes);
// body
String body = "hello world";
HttpEntity<String> entity = new HttpEntity<String>(body, headers);
Map<String, Object> uriVariables = new HashMap<String, Object>();
uriVariables.put("id", "testFile");
// Send the request as GET
ResponseEntity<String> result = restTemplate.exchange(
"http://localhost:8080/WebApp/test/{id}/body",
HttpMethod.GET, entity, String.class, uriVariables);
Assert.assertNotNull(result.getBody());
}
Server #Controller
#RequestMapping(value = "/{id}/body", method = RequestMethod.GET)
public #ResponseBody
String testGetWithBody(#PathVariable String id,
#RequestBody String bodyContent)
{
return id + bodyContent;
}
The problem -
executing this test case returns 500 Internal Server Error. On debugging, I found that the controller is not hit.
Is it correct to understand that the RestTemplate provides the way to send data as request body, but the error occurs because the server could not handle the request body ?
If the request body sent via HTTP Get is not conventional why does RestTemplate provide the APIs to allow sending it ? Does this mean there are few servers capable of handling the Request body via GET ?
Resources - discussions on sending body via HTTP GET using RestTemplate at spring forum
http://forum.springsource.org/showthread.php?129510-Message-body-with-HTTP-GET&highlight=resttemplate+http+get
http://forum.springsource.org/showthread.php?94201-GET-method-on-RestTemplate-exchange-with-a-Body&highlight=resttemplate+http+get
Resources - General discussions on sending body via HTTP GET
get-with-request-body
is-this-statement-correct-http-get-method-always-has-no-message-body
get-or-post-when-reading-request-body
http-uri-get-limit
Is it correct to understand that the RestTemplate provides the way to send data as request body, but the error occurs because the server could not handle the request body ?
You can tell by looking at network traffic (does the request get sent with a request body and a GET method?) and at server logs (the 500 result you receive must have a server-side effect that gets logged, and if not, configure the server to do so).
If the request body sent via HTTP Get is not conventional why does RestTemplate provide the APIs to allow sending it ? Does this mean there are few servers capable of handling the Request body via GET ?
Because it is a generic class that also allows you to craft requests that can include a message body.
As stated in HTTP GET with request body:
In other words, any HTTP request message is allowed to contain a message body, and thus [a server] must parse messages with that in mind. Server semantics for GET, however, are restricted such that a body, if any, has no semantic meaning to the request. The requirements on parsing are separate from the requirements on method semantics.
A body on a GET cannot do anything semantically, because you are requesting a resource. It's like you tell the server: "Give me resource X, oh, and have some apples!". The server won't care about your apples and happily serve resource X - or throw an error because it doesn't like any offers in a request.
However, I've been asked to test the possibility to send content via HTTP GET
Please tell the one who requested this that this is a case that should not have to be tested, because no sensible implementation supports it.

Resources