Jersey Client proper way to execute parallel POST requests - java

I'm looking for the proper way of executing POST requests using jersey client (with apache http client 4.x)
Since Client instance and WebResource instance are thread-safe, the natural way of coding the method will be:
public AuthorizedAccount createAuthTokenFromUserPass(Credentials credentials)
throws AuthenticationServiceClientException {
ClientResponse response = resource.accept("application/x-protobuf").post(
ClientResponse.class, credentials);
return getAuthorizedAccountFromResponse(response);
}
ClientResponse instance is properly released.
When this method is executed from multiple threads, it ends-up by POSTing same credential instance to the server, for each thread.
A solution will be to synchronise the method, but will end-up by executing the POSTs in sequence.
Is there a different way to do it? (avoiding the re-creation of Client instance)

After spending a lot of time trying to figure out what is not working properly, I found out that the issue was not really in jersey client implementation but in my own code. I have used a custom implementation of MessageBodyWriter, where I was not careful enough. I did not read properly the contract of the interface. I have shared an instance variable between call of getSize() and writeTo(), and the MassageBodyWriter is reused.

Related

Spring boot - Threads / Feign-Client / Messaging / Streamlistener

We struggle to find a solution for the following scenario:
Situation
Receive a message via Spring Cloud Streamlistener
Invoke a REST-Service via Feign-Client
We have configured several Feign-RequestInterceptor to enrich
request header data.
We want to avoid passing every request header on the method call and like the central configuration approach of the request interceptors.
Problem:
How to access data from a specific message, which contains informations, that need to be added to every request call via the Feign-RequestInterceptor.
We don't have a Request-Context, as we come from a message.
Can we be sure , that the message consumption and the REST call is happening on the same thread? If yes, we could use the NamedThreadLocal to store the information.
Yes, unless you hand off to another thread in your StreamListener, the rest call will be made on the same thread (assuming you are using RestTemplate and not the reactive web client).

Java commons-httpclient: Testing timeout values

Abstract: how do devs Integration TEST timeouts for http requests?
Backstory: My team is having issues related to unusually long lasting HTTP web requests. We use the commons-httpclient version 3 by Apache. The code looks similar to this:
PostMethod post = new PostMethod(endpoint);
post.getParams().setSoTimeout(someInt);
httpClient.executeMethod(post);
The time to complete this request is usually acceptable (2 seconds or so), but occasionally, we will see 50-60 second requests despite having our SO timeout set to 4 seconds. This prompted me to do some research and found that most people are setting Connection Timeouts ANNNNND SO timeouts. It appears that SO timeouts should be set lower (as they simply time the distance between bytes in transit) and the the connection timeout is what we originally planned to use (i.e. initial delay between request and 1st byte returned).
Here is the code we scraped and plan on using:
httpClient.getHttpConnectionManager().getParams()
.setConnectionTimeout(someInt);
httpClient.getHttpConnectionManager().getParams()
.setSoTimeout(someInt);
The main pain here is that we are unable to integration test this change. More precisely, we are confused on how to integration test the delays coming from a socket connection to a foreign server. After digging through the commons-httpclient, I see protected and private classes that we will have to reproduce (because they are unextendable and unusable from outside the class), mock and string together the classes to ultimately get down to the socket class in java (which relies on a java native method -- which we would also need to reproduce and inject via mocks -- something I dont see frequently at that level).
The reason I am reaching out to Stack Overflow is to see how others are testing this/not testing this. I want to avoid testing this functionality in a performance environment at all costs.
Another thought of mine was to set up a mockserver to respond to the httpclient with a programmable delay time. I haven't seen an example of that yet.
First of all, there is no such thing as unit testing http requests - that would be integration testing.
Secondly, you can use a tool like JMeter to send http requests and test whether the response is being received in a certain amount of time as shown here in JMeter.
Taking the mock server route, I managed to set up a small web server with an API endpoint that I could test against. Here is the related code:
Lightweight server setup:
TJWSEmbeddedJaxrsServer server = new TJWSEmbeddedJaxrsServer();
server.setPort(SERVER_PORT);
server.getDeployment().getResources().add(new TestResource());
server.start();
API Endpoint:
/**
* In order to test the timeout, the resource will be injected into an embedded server.
* Each endpoint should have a unique use case.
*/
#Path("tests")
public class TestResource {
#POST
#Produces({MediaType.APPLICATION_XML})
#Path("socket-timeout")
public Response testSocketTimeout() throws InterruptedException {
Thread.sleep(SOCKET_TIMEOUT_SLEEP);
return Response.ok().build();
}
}
Within the api endpoint related class, I can control the sleep timeout which then triggers a socket timeout within the httpclient class. Its a bit hacky, but it works to test the functionality in the way I wanted to (simple, lightweight and effective).

RPC over STOMP using Spring, and correctly handling server side errors propagated to clients

I need to implement RPC over STOMP, where the client runs with javascript in a browser, and the server side is implemented using Spring messaging capabilities.
While using #MessageMapping is fine for normal messaging, I find using #SendToUser quite limitating for implementing RPC because the client has an hard time to understand which reply is associated with which request in a scenario when multiple simultaneous requests are being made from the client.
Of course there is no problem when just only one request is made, and the client waits for its reply, but problems arise when the client has to keep track of multiple "open" rpc calls.
I've managed to make the system mostly fine by associating an ID with every request, i.e.: the client sends an id together with the message, and the server replies with a special message wrapper that contains this id, so the client is able to associate asynchronous replies with requests.
This works fine but has several limitations:
I have to develop code that needs to understand this structure, and that defies the uitlity to have simple annotated methods
when the server side code generates an Exception the Spring #MessageExceptionHandler get called and the correct Exception is returned to the client, but the request id is lost because the handler has no (easy) way to access it.
I know that with rabbitmq we can add "reply-to" header to every request that needs to be associated with a special reply (the rpc response), and this is implemented by creating a special temporary queue that the user is automatically subscribed to, but how may I use this scheme in Spring? Also, that would tie me a specific broker.
How may I elegantly implement a correct RPC call in Spring that correctly handles server side exceptions?
I find this a general problem and I think Spring could benefit greatly to implement it natively.
This not exactly what you demand, but maybe you can attempt something like this :
Path variables in Spring WebSockets #SendTo mapping
You define an ID on your client and send id to the queue /user/queue/{myid}
On the serveur side you will have a class who looks like this :
#MessageMapping("/user/queue/{myid}")
public void simple(#DestinationVariable String id, Object requestDto) {
simpMessagingTemplate.convertAndSendToUser(userId, "/user/queue/" + id, responseDto);
}
This solution can work with the same principle as the rabbit mq solution you mention.
Hope this helps.
If you do not need the exception/reason on the client, but only want to know which message failed you could send ack messages for successful messages. For successful messages you always have easy access to the message id / headers. By the absence of the ack message the client knows which message has failed.
Of course this comes at the costs of sending all the ack messages and knowing the timout of requests. Also additional code is required to keep track on the client side, but this can be done using a middleware and would end up in an ok-ish dev experience for the business logic.

Redirect/Forward SOAP Web Service Requests to another Web Service

I have a use case that required all calls to NewWebService are routed to OldWebService, if the SOAP request does not validate against NewWebService's XSD and WSDL. NewWebService is located on ServerA and OldWebService is on ServerB.
Abstractly, I know I need some mechanism that will allow me to take a SOAP request that hits NewWebService, send it to OldWebService, then return the SOAP result back to the client. My limited experience with spring-ws is making it difficult to decide how to accomplish that.
My first thought was to build a SOAP client into the NewWebService that calls the OldWebService whenever the payload cannot be validated. Is this the best solution, or is there a better way to allow the NewWebService to act as a pass-through for certain requests?
My solution was to write a custom SoapRequestFilter that implements a javax.servlet.Filter and a new class that extends HttpServletRequestWrapper. Since HttpServletRequestWrapper implements the HttpServletRequest interface, extending the wrapper allows you to copy the HttpRequest and act on the stream without consuming the object and causing issues downstream.
Once I had the filter and wrapper, I was able to parse the endpoint and payload from the HttpRequest. If the request needed to be redirected, I created a new HttpUrlConnection to the old SOAP WebService and set the InputStream from that response to the OutputStream of the HttpResponse.
I think Apache Camel can help you in an efficient way.
You can take a look at its proxy example, it's simple and easy to fulfill your requirement.
http://camel.apache.org/cxf-proxy-example.html

How to clone a detached HttpServletRequest and HttpServletResponse provided by the Servlet Container?

I want to implement the following logic:
when I receive HttpServletRequeset and HttpServletResponse in main servlet's doService method (in the main web Container thread),I start A,B,C three threads (thread managed by my own program) to process other servlet in parallel mode,and then join each response from these servlet in main thread,and if one of my own thread (assume A thread) work slow,the main thread will finish,so main response will return to user.and the A thread must continue work properly,I will request the response of the A thread using AJAX in browser side later.
So,I want to clone the HttpServlettRequest and HttpServletResponse provided by the Servlet Container,and the cloned request and response must be detached(When container's HttpServletTrequest and HttpServletResponse finished,the cloned request and reponse still work properly).
The behave of the cloned request and response must be same as the Container's from my code's view.It can be followed and included.
Any idea?
Thanks very much!
L.J.W
Cloning HTTP request and response is possible via HttpServletResponseWrapper class http://docs.oracle.com/javaee/1.3/api/javax/servlet/http/HttpServletResponseWrapper.html. You can find an example of usage on Sun documentation https://web.archive.org/web/20120626033905/http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/Servlets8.html.
Notice this was a workaround from (at that time) Sun to address this problem as it was never planned that you could modify request and response information before committed.
You can use the wrapper to make a copy of Http information and the pass it to a different thread.
Sounds like you need to create classes to act as a delegate to the HttpRequest and HttpResponse objects and then pass a reference to on to a Runnable object to process.
There are certain operations that can only be done once to an HttpRequest object ( reading from the inputstream springs to mind ), the delegate class would have to cater for this.
Not sure what you're going to do if the A, B and C threads make conflicting changes to the HttpResponse object though.
I think I'd prefer to not pass the HttpResponse object through to the processing threads and leave the logic for populating the response in the controlling servlet class
I think you are asking to much of the HttpServletRequest. Once a request has been completed you shouldn't count on the request object being of any use. I don't recommend threading inside a J2EE container in most cases anyway but that's a different issue.
If you must handle the request in parallel I recommend you extract the data you need from the request object and send that to your threads and make the worker threads mostly Servlet ignorant with the exception of the HttpSession where they could store their computed values for the Ajax retrieval.
The request and response classes aren't designed to be cloned or accessed from multiple threads. If you try to do so, you're bound to run into problems. I suggest that you re-think your requirements.

Categories

Resources