Jersey response containing incorrect data - java

Apologies: I don't have a simple test case that reproduces this problem, as it happens very intermittently. However, I would greatly appreciate some help regarding how to even begin diagnosing the issue.
I have a Jersey server running on Tomcat.
When the client makes a request, sometimes a response from a totally different request is mixed in with the correct response.
The "correct" request can be of any kind, but the "bad" response which gets mixed in is always from an SSE stream (EventOutput) or an AsyncResponse.
For example, this is the output received by a client through a normal request:
event: message_sent
id: 1
data: {"value":"hello world"}
{"event-id":"13"}event: message_sent
id: 2
data: {"value":"hello world"}
The genuine response {"event-id":"13"} is present... but surrounding that there are two erroneous SSE events.
The method to handle this request returns simply:
return Response.created(uri).entity(eventId).build();
So I don't understand at which point the unwanted data gets sent (unless Response.created() is returning a response object which had already been used for an SSE stream).
The server logs always show the correct output. We know the client is not at fault, however, as we used a packet sniffer to confirm the responses are malformed.
Notes:
For SSE streams, I always check that the EventOutput is not closed before writing to them
When writing to AsyncResponse objects, I always check isSuspended() first (and they are injected with the #Suspended annotation)
Again, any hints or pointers would be such a great help. I've run out of ideas!

After a lot of research, I've concluded that my problem must be (of course) a user error even though I couldn't reproduce the error when I removed the apache proxy from the equation. In my case, I had to be more careful about when considering EventOutputs as closed -- since you can only tell if the connection is open when trying to write to it. In general though, my findings are:
A bug of this kind occurs when you keep references to response objects around, and then write to them after Tomcat has re-used them for another request. This could be a list of e.g. AsyncResponse or EventOutput objects which you need to keep around to resume or write to at a later time.
However, if it's a bug which is difficult to track down and you need a solution, there is a Tomcat setting which will disable the re-use of these objects at the cost of performance, as it says here: https://tomcat.apache.org/tomcat-8.0-doc/security-howto.html
Setting org.apache.catalina.connector.RECYCLE_FACADES system property
to true will cause a new facade object to be created for each request.
This reduces the chances of a bug in an application exposing data from
one request to another.
(Don't be confused by the name; RECYCLE_FACADES=true means that the facades will not get reused, and new ones will get created as they are needed).
There are examples of application bugs like this only manifesting when behind an apache proxy, so if the bug disappears if you access Tomcat directly it doesn't necessarily mean that apache is at fault.
As I say, it's unlikely for this to be caused by a bug in Tomcat, Apache or the mod_proxy_ajp... but if you are an unlucky one, you can try using another connector (mod_jk, for example).

Related

How to analyse Websocket close reason 1011

First time using websockets. I have two machines that need to communicate using them. The server works fine, if I send a message with Postman, it replies correctly.
For the client I used one of the examples I found, like this. But in the client, when I create the WebsocketClientEndpoint :
final WebsocketClientEndpoint clientEndPoint =
new WebsocketClientEndpoint(new URI("ws://myserver.com/endpoint"));
it calls the onOpen and immediately after the onClose, returning a 1011 close reason, that I read is an unexpected condition in the server.
I would need some clue to analyse what can be happening, because as I said, the server replies well in Postman. The url is the same, of course. The examples I find are quite identical, and I am not doing anything different. Any idea?
My fault. As indicated by user207421, I should have checked what was really arriving to the server. The client was not sending hardcoded data. I was sending a JSON to it and it was forwarding it to the server. That server replied well to the same JSON if sent directly. The thing was that the client, in the deserialization and serialization, was sending the final reconstructed JSON with a missing field, and that made the server fail to reply. As dumb as that. The risk of assuming things.
First, I would recommend not to try to instantiate an instance of WebsocketClientEndpoint() as the only implementation of the class I can find uses static connect() methods, which require either an existing instance of WebSocketClient() or WebSocketContainer() - See this example. Instead, I would recommend creating a class that extends WebSocketClient and work with that instead - see an implementation of that here.
Also, another thing that might cause a different sort of problem is the possibility of an Unhandled Exception causing code execution to prematurely abort. The URI class throws a URISyntaxException, and if you are not wrapping your new URI object instantiation in a try/catch block or denoting the current scope method/class as throws URISyntaxException (or throws Exception to handle the other exceptions that might be thrown by WebsocketClient() as well) and have the thrown Exception(s) handled in a try/catch block in outer calling context, your code may be crashing due to that.

How is request (socket connections) bean scoping handled in absence of http requests?

I'm building a back-end service which needs to handle 100,000 requests per day (mvp) and up to 1 million thereafter.
Our requests are not HTTP requests (due to high demand) so a request is received in industry standard format (assume fixed length text file) which is converted to a java object and that object is later written to socket which my app will receive.
Traditionally I would have assumed that all beans should be request scoped since that is essentially what I want, but since requests are not HTTP I'm very confused about how to scope this correctly. Each socket transmission should get its own set of beans and it should not interfere with the previous or following transmission.
Could you kindly help point me in the right direction? Http and request aware annotations (#RequestScope) seem to not apply in my case but yet that's very close to what I want to achieve. Likewise I'm unable to meaningfully research since I am unsure what vocabulary to use. Thank you very much in advance.
How about introducing your own scope as described here. You can use ThreadLocal storage to keep the beans or even use the thread scope See here

Which HTTP method to use for this client request?

I am developing a REST web service in Java which on clients' request processes the request body and gives the output to the client. The request body sent by the client consists of a GO(programing language) program which the server executes(runs) on the server machine and returns the standard output of the program back to the client. Now since the request body contains some text(program), I cannot use HTTP GET method to do that. I can use PUT or POST, but I have learnt that they(PUT and POST) are generally used for updating/creating a resource. Since, I am not creating any resource here, is it conceptually correct to use PUT or POST. If not, which is the HTTP method that I need to use?
Looking at the problem you are solving and comparing to an existing production solution , I suggest that you can use POST in your scenario.
Reasoning - Example Production code solving similar problem:-
Assuming that the problem you are trying to solve is this:-
Clients submit code in Go programming language, Your server compiles it, runs it and then gives the output. Assuming also that, it is somewhat similar to many online coding websites like hackerEarth, their API documentation page and the sample python code provided show that we can use HTTP:POST to submit code to the server for its processing.
Reasoning - RFC for HTTP POST, PUT :-
POST is designed to allow a uniform method to cover the following functions:
Providing a block of data, such as the result of submitting a
form, to a data-handling process;
The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server.
Referring to the above statements, we can conclude that in the context of this problem which you are solving, you are requesting the server to do some data-handling for the enclosed entity, so you can use POST.

Camel route loops after a specific number of requests

I'm having a problem with a Camel route I'm trying to solve for days now.
As I'm not a specialist for this technical issue, there might be omissions for the information you need to know...
First, the goal of my route is to connect to a distant server via an endpoint, requesting xml responses from xml requests via jaxb marshalling.
Nothing special in this route, which is the following one:
routeX.from("direct:requeteObjects)
.setHeader("element")
.constant(element)
.to("bean:importStructureI2VGestionnaireImpl?method=sendRequestObjects)
.to(endpoint)
.to("bean:importGestionnaireImpl?method=" + getObjects)
The server sends responses by pieces : for example, I'm expecting 3000 objects, received by packages of 30 objects.
My method that creates the request "sendRequest" is renewed and asks for the next objects.
After treating the response, I'm sending this request back to the endpoint, which gets the response, which is sent to the getObjects method, that processes the response.
Everything works well, I'm getting my responses. But after 5 requests/responses, after entering the endpoint, nothing happens. Debugging the code, it looks like there's a loop inside my route as the code keeps on going in the AsyncProcessor class, in the process method, etc. No logs, nothing. it doesn't stop.
I have no idea why it's going like that. I thought it might be because I was using the same route definition. So I created a route for each request, stopping and removing the old one. With this, I'm getting to 6 responses. But then, the same problem happens.
I tried setting the context maximum endpoint cache size and the context maximum cache pool size, multiplying by 10 the default values. I checked if the values were taken into account : they were. But still, I'm getting the same problem.
Also, the exchange object is always a new one, so my responses are never piled up inside one big exchange object.
Do you know where the problem could be? Can the context become too large? Or the endpoint? Where should I look?
Thank you for your answers. If you need any more information , I'll be pleased to add it.
PS : I tried applying the answer in this topic : Camel route inside routeContext executing infinitely, but no changes :-(

Pausing and notifying particular threads in a Java Webservice

I'm writing a Java webservice with CXF. I have the following problem: A client calls a method from the webservice. The webservice has to do two things in parallel and starts two threads. One of the threads needs some additional information from the client. It is not possible to add this information when calling the webservice method, because it is dependent from the calculation done in the webservice. I cannot redesign the webservice becuase it is part of a course assignement and the assignements states that I have to do it this way. I want to pause the thread and notify it when the client delivers the additional information. Unfortunately it is not possible in Java to notify a particular thread. I can't find any other way to solve my problem.
Has anybody a suggestion?
I've edited my answer after thinking about this some more.
You have a fairly complex architecture and if your client requires information from the server in order to complete the request then I think you need to publish one or more 'helper' methods.
For example, you could publish (without all the Web Service annotation):
MyData validateMyData(MyData data);
boolean processMyData(MyData data);
The client would then call validateMyData() as many times as it liked, until it knew it had complete information. The server can modify (through calculation, database look-up, or whatever) the variables in MyData in order to help complete the information and pass it back to the client (for updating the UI, if there is one).
Once the information is complete the client can then call processMyData() to process the complete request.
This has the advantage that the server methods can be implemented without the need for background threads as they should be able to do their thing using the request-thread supplied by the server environment.
The only caveat to this is if MyData can get very large and you don't want to keep passing it back and forth between client and server. In that case you would need to come up with a smaller class that just contains the changes the server wants to make to MyData and exclude data that doesn't need correcting.
IMO it's pretty odd for a web service request to effectively be incomplete. Why can't the request pass all the information in one go? I would try to redesign your service like that, and make it fail if you don't pass in all the information required to process the request.
EDIT: Okay, if you really have to do this, I wouldn't actually start a new thread when you receive the first request. I would store the information from the first request (whether in a database or just in memory if this is just a dummy one) and then when the second request comes in, launch the thread.

Categories