One of our products implements the following one-way web service structure:
Server <--------------------- Middleware <---------------- Client
SOAP over JMS (queue) SOAP over HTTP
In this model, clients send SOAP messages over HTTP to our middleware (Progress SonicMQ). The messages get pushed into JMS queues by SonicMQ and our server fetches them from there. However, as you can see, the server does not send a response to the client (asynchronous JMS).
We would like to implement a response-channel to this model. The often suggested solution is to create a temporary replyTo-queue (on the fly) in the middleware, allowing server to send a response to that queue. Then, client can fetch the response and the replyTo-queue is closed. This sounds convenient enough, but unfortunately our clients operate over plain HTTP and not over JMS, so their clients can not easily set up replyTo queues.
One approach to achieving a response channel in such hybrid HTTP/JMS SOAP model would be to configure the middleware to open the replyTo queue on each succesful SOAP receive, append the replyTo-queue and sender information to the SOAP message and push the message to the queue, where it would be fetched by the server. After receiving and processing the message, the server could send a response to the indicated replyTo-queue in the middleware. Finally, the middleware would send the response (SOAP) over HTTP back to the original client by using the data from the SOAP message (the data that was inserted there in the middleware procedures when the request was first received).
While propably possible, this sounds kind of a hacky. So the question is: any cleaner ways of achieving such request/response model on our case? The server end has been implemented in Java.
The solution:
Progress SonicMQ supports "Content Reply Send" HTTP Acceptor, which allows to easily send JMS reply. The Content Reply Send acceptor works in a following way:
Acceptor receives the HTTP message a client sent
Acceptor creates a temporary JMS queue
Acceptor builds up a JMS message, containing the HTTP body, and adds the temporary queue's identification to the newly created JMS message
Acceptor pushes the JMS message into its destination queue (not the temporary queue)
Acceptor starts consuming the temporary reply-To queue
When client fetches message from original destination queue, it contains the set reply-To queue identification
Client consumes message
Client sends reply to the reply-To queue
Acceptor receives message from the queue
Acceptor sends message as HTTP to the client that originally sent the HTTP message
Should consumer ("server" in our case) fail and not send reply causing timeout, Sonic's HTTP Acceptor sends an HTTP message to the client indicating the timeout. This is a very standard feature in SonicMQ. I suppose it exists in other products as well.
This allows using standard SOAP over JMS (see skaffman's answer) in the "server" end avoids any custom programming in the middleware.
I still see some problems in the JMS model though, but this is definitely an improvement.
Update 2009-11-05:
After researching this issue even more, it turns out my suspicion against HTTP<-->middleware<-->JMS has been relevant.
There are a few critical problems in this model. Synchronous-asynchronous model with middleware simply isn't convenient. Either have both ends implement JMS connection (which should rock) or go with HTTP in both ends. Mixing them results only in headaches. Of these two, SOAP-over-HTTP is simpler and better supported than SOAP-over-JMS.
Once more: if you are designing this kind of a system... DON'T.
I don't think your suggested solution is hack at all, I think that's the right solution. You have the client-middle layer with a synchronous protocol, and then the middle-server layer using an asynchronous layer, to which you have to add a reply path in order to satisfy the synchronous semantics. That's what middleware is for. Remember that that JMS provides explicit support for temporary reply-to queues, you won't need to mess with the payload at all.
A more left-field possibility is the leverage the fact that SOAP 1.2 was designed with JMS in mind, and so you could use web service layer between middleware and server layer which does SOAP-over-JMS. That means you can keep SOAP from end-to-end, with the middleware changing only the transport.
The only web service stack that I know of that supports JMS transport is Spring Web Services, where the process and development is documented here. This would also give you the opportunity to port your SOAP layer to Spring-WS, which kicks ass :)
Why not add a link to a page that lets users check to see when a response is ready, a la a Fed Ex tracker ID? Give your users the tracker ID when they send the request.
This would fit into the HTTP request/response idiom, and your users would still know that the request is "fire and forget".
Related
I want to run a Java based message broker that will route messages to web clients. Web client connections are handled on our server using our custom Java websocket code, which authenticates users against the user database.
I think my server side websocket handler code would connect to ActiveMQ and perform subscription management via AQMP.
I have a specific requirement however:
route messages for a topic specifically to one or more web clients
Note that I don't need to retain messages if a client is not connected. Messages are being used to inform the web client applications of actions they need to take.
I'm considering ActiveMQ but I was hoping people with experience of the product could clarify if it supports this requirement?
If ActiveMQ isn't the best option, could you recommend something else?
Thanks
Yes, ActiveMQ is a great choice for this.
As far as specific approach goes, it depends on your data model and message flow.
You have several options, including:
Produce and consume to a topic-per-client
a. Messages for Client ABC go to topic://CLIENTS.ABC, for Client XYZ go to topic://CLIENTS.XYZ, and the subscribers connect accordingly.
Produce a message with a header and use a consumer-side selector (aka 'filters' in AMQP) to filter messages on a per-client basis. (abc client subscribes to-- ClientId = ABC, xyz client subscribe to-- ClientId = XYZ)
When using WebSockets, you might also look to STOMP which is text-based protocol. (Just depends on your programming language and available libraries that you had in mind)
Good morning, I am currently managing a queue jms [wso2] message broker.
I have a java client who sends a message in the queue and a java ServletContextListener which activates every time a message is being delivered.
And everything works ok.
My bosses have asked me now if it was possible that once the message arrives in the queue, it automatically makes a call to a service.
I was reading something like [wso2] ESB Message Processor.
My questions are:
1) Is it possible to do such a thing without using [wso2] ESB? but only [wso2] message Broker.
If you have some ideas.
2) at this point [wso2] ESB would be a consumer and a call from them?
3) If someone can give me an example of how to handle the ESB once the message ne [wso2] Message Broker has arrived.
Thanks in advance
Not sure if I got it right, but here are some thoughts that come into my mind.
1.) I'm not familiar with wso2 mb (using activemq) but I assume that its not possible according to the documentation
2.) Yes, the esb acts as a message consumer (like your java client) and can do various things then. You can call other services, forward the message to another queue etc...Maybe the ESB can do the things you're servlet is doing
3.)You can create a simple proxy in esb that takes the jms message and forwards it to your servlet,service or whatever. There are plenty of cases, regarding jms messages the following link might help.
ESB JMS
One other thing I'm thinking of, if you send your jms message to a jms topic from your java client, you can then create several consumers for the same message. So your existing implementation will subscribe to that topic and you can create a simple second client (or use the esb) that connects to that topic as well. Both will receive the same message and can do whatever processing is needed.
Hope that helps.
I use microservice architecture in my project. And for interservice communication I use message queue NATS. I wrote a gateway, that handle all http requests and put it to queue. All end point services are subscribed to this queue.
At endpoint services I use Xitrum based on Netty IO. When I get request from queue, I deserialise it to FullHttpRequest. But I don't know how to send it to my netty server, that can handle it according to business logic (without using external httpclient, for example, that can send it to localhost)
Is there any possibility to send FullHttpRequest instance to netty server (listening localhost:8000) using netty api? Or may be another solution. What is the common approach?
Please see the netty examples which has everything you need:
https://github.com/netty/netty/tree/4.1/example/src/main/java/io/netty/example/http/snoop
I'm designing a REST API where some operations are propagated to AMQP queues. When message is processed (with error or successfully) the client must be notified. My first thoughts were to boot lightweight embedded HTTP server when client library is initialized, so message processing mechanism can also emit an HTTP request to the server about how went the operation execution. Any other / better ideas of how to implement this?
I'm learning JMS and wonder how a JMS client (e.g MessageListener) can notice about a new message in queue it registed. Is it frequently send requests to broker via TCP to see if there's a new message? If so, is this request synchronousor asynchronous?
JMS is just an API. It does not specify any wire level protocol. So you can't really tell how the client will behave with the broker. It could use a homing piegon for all we know. Ok, maybe not, but brokers like WebSphere MQ and ActiveMQ both supply in memory transport as well as TCP based.
Most vendors have thier own properitary protocols even though AMQP is visible on the horizon as a wire protocol standard (but far from all vendors have started to look at it).
When talking TCP there is no need to poll as long as there is a live connection going on. The broker can easily notify the client that there is a new message published while the client sleeps and the other way around.
A common way, however, is to actually do poll. But rather poll for consumer.receive(TIMEOUT); in some longer intervals (seconds). This makes it possible to use distributed transactions in frameworks like spring. Still the broker sends actual TCP messages to the client on demand.
If it would not have been like this, then JMS/Messaging would not have been such a fast, wide psread and scalable technology
1) First of all, JMS does not have something called absolute synchronous messaging. You can definitely implement so called JMS Synchronous messaging by implementing Sync service methods but in fact it just appears to be mimicking as Synchronous messaging. In fact it is also Async Messaging.
2) Technically it is the JMS Server / Broker which sends Messages to Message Consumers through dedicated queues. Broker simply delivers the message to Message Consumer's onMessage() method. And then Container executes onMessage() method.