I have a REST service defined in Spring Boot, which exposes a synchronous REST API, to be invoked by a user from a Web based UI. The service is expected to provide a real time response.
The service talks to an external endpoint in an asynchronous fashion. That is:
- A single one - way outbound message for the request
- A single one - way inbound message for the response
How can I combine the two messages to provide an impression of a synchronous behavior? I am thinking of a few approaches like:
The Rest Service posts a request to the endpoint. Once the endpoint responds, the response is added to a ConcurrentHashMap. The Rest Service queries the HashMap every few milliseconds and once it finds the right response it exits with a valid HTTP reason code.
It is akin to polling and I am thinking if we can avoid that.
The Rest Service posts a request to the endpoint. Once the endpoint responds, the waiting thread in the Rest Service is notified. However the waiting thread should conclude only if the right response is received (i.e. matching correlation Ids etc.)
Is this possible?
I realize that this is similar to a JMS Queue Request Response scenario, where each JMS queue request opens up a listener on the response queue with a message selector criteria.
However in this case I have to implement this using HTTP.
Any thoughts on this are welcome. I am fully convinced I am missing something very basic, but am not sure what.
Thanks a lot!
Related
I have got two Spring Boot application. First one is REST application. The REST one is communicating with second application through RabbitMQ message queue. I'm sending a request to method with the #GetMapping("/") and this method producing a message to example-queue. A method with #RabbitListener(queues = {"example-queue"}) taking the message and create a object at database. Now, how can I send my response (saved object) to the method with #GetMapping("/")? I need a response from consumer to ResponseEntity.ok();. How can I do that? Thank you.
Just see if you can make the interaction with RabbitMQ consumer as a request-reply pattern.
The #RabbitListener can just return your object and be marked with a #SendTo. This way the framework will look into a replyTo property of the request message.
On the producer side you can just use an AmqpTemplate.convertSendAndReceive().
See more in docs: https://docs.spring.io/spring-amqp/docs/current/reference/html/#request-reply
How to implement one-way operation in Web Services (using Java or Spring annotations)?
I have tried to add one way as given below
#WebService
public interface DanduServices {
#Oneway
public void saveDanduInformation(#WebParam(name = "serv") ServDTO Serv, #WebParam(name = "dandu") DanduDTO danduDto);
but it is still request-response not asynchronus or one way.
Could anyone suggest to make a operation one-way in service endpoint and let other operations behave as per request-response?
You need to think in terms of the protocol as well though. In HTTP when you send a request you wait for a response, if no response comes back after an amount of time then you will receive a time-out error. So when you talk about one-way (you should rather say async request maybe) you really need to specify exactly what you mean. Do you want to have confirmation that your message was received i.e. have the server respond back with an OK status code and go off and complete it's task but you not wait for the task to be completed? Then you would need to spawn another thread. Spring has AOP for this the same way it has for transactions with #Transactional. Instead you annotated your method with #Async and return a Future<Something>. You'll also need #EnableAsync in your config. Refer to this article for an example Hot To Do #Async
If you don't even care about if the server received your request you don't want to use TCP/HTTP but instead UDP which is used in VOIP (phone over internet) for instance and is quicker, but it will depend on your client.
We want to implement the following scenario:
A producer service sends some input params to another service asking for the details based on these params.
A producer wants to specify the queue where it will be listening for the reply.
Moreover, a producer wants to provide some metadata so that it can correlate the params it sent with a result it got.
Please advice how to do this properly.
See the AsyncRabbitTemplate.
It uses the correlationId and replyTo properties to convey that information to the service that handles the request.
akka documentation for java says
http://doc.akka.io/docs/akka/2.4/java/camel.html#Consumer_timeout
Two-way communications between a Camel endpoint and an actor are initiated by sending the request message to the actor with the ask pattern and the actor replies to the endpoint when the response is ready.
And then
http://doc.akka.io/docs/akka/2.4/java/camel.html#Asynchronous_routing
A consumer endpoint sends request messages to its consumer actor using the tell method and the actor returns responses with getSender().tell once they are ready.
Which of both statements is true?
Does it depend on the Camel component?
If tell method is used, how does the endpoint know to which client respond?
Thanks.
I am developing a very simple REST web service with Eclipse, Tomcat7 and Jersey implementation, with a connection to MySQL.
Looking to the jersey documentation i know that every request create a new object of the root resource class. But i dont know if every request is independet, for example if one request have to wait a long time, the server will accept more request normaly?
The problem is :
I have 2 main classes, 1 class implements Jersey with annotations(Proxy.java), and other class that connects to a BD(Notificator.java), there is only one instance of this class (Singleton) in order to use only 1 Connection object. The classes who implements Jersey use this class. So, if one of the request is blocked , i dont know if the others will run because they are using the same (Notificator.java) instance.
The relation is N instances of(Proxy.java) uses the only one (Notificator.java) witch have one Connection to a MySQL.
Jersey is developed on top of servlets. There is a new thread for each of the incoming request. Your code is creating a bottleneck for all the threads as there is a contention for single available connection object. If you have multiple requests then only one request will be using that connection and others have to wait. If the wait is not too long then there is no problem. But if wait is more than the HTTP REQUEST TIMEOUT then your other requests may end up as TIMED OUT.
I understand that you may be having single connection bottleneck due to some business requriement/ complication. So in all such cases where we cannot process all the requests simulataneously and there can be variety of reasons for it, then we should create our web services as Asynchronous. Asynchronous web services work on the model of SUBMIT REQUEST-> REQUEST ACCEPTED(will be processed asynchronously) and JOB URL returned for polling-> CLIENT POLLS till the JOB IS NOT COMPLETED.
Hope it helps!
Try database connection pooling, more on this here:
http://en.wikipedia.org/wiki/Connection_pool
How to establish a connection pool in JDBC?