I have two services hosted under the same context file in Spring + Apache CXF (Services A and B). There is a third-party service C, that I have to call from service A, and that will send the response to service B. (by means of addressing). I have managed to perform the communication between services A -> C -> B. Everything OK there. The problem is I would like to perform some logic in service A according to the response sent to service B. That means I would like to do something like this in service A
ServiceC_Client clientC = ....
....
clientC.callOperation();
// somehow wait for a signal from service B or until a timeout have been reached.
// The response will be correlated to this particular thread by means of
// WS-Addressing MessageId field
// Read relevant data response sent to B (B stores the relevant data in database)
....
// continue operation of method of A
In service B, I would have something like this
public void callBackResponse(ResponseData response){
// Perform operations with response and store relevant data in database
// Service A will know data is sent to a particular run of A thanks to
// Addressing MessageID and RelatesTo fields
// Notify Service A a response was received
}
Is this possible? Can I achieve this in Java? Maybe Java Message Queues? I don't really know if it is possible.
Related
I have a problem, and I don't know exactly what to search for.
I have a spring boot app which broadcast the message via web socket with a stomp javascript client. The question is if I can put a lock on the message when it is sent because I want no one to send another message at the same time. The system that I want to make is like a traffic light.
If you can give me an example or what to look for.
You should use synchronized keyword and wait for the client response. synchronized keyword ensures that only one thread can execute the method at the same time. And you need client response because you can sequentially send two messages, say in two seconds interval, but your client will get them at the same time. Response can be some dummy ok-message.
public class Traffic {
synchronized void Send() {
// write message to websocket
// read response from websocket
}
}
Is there an elegant way to subscribe to updates only after I trigger first update of my data using rabbitMQ?
Or.. Is there a way to know when a new consumer is added and trigger sending the data?
For example:
Service A is getting updates from Service B (using rabbitMQ, Service B pushes IPs that I need to send the data to).
Service A is also getting requests from Service C and sends each request to all the IPs from Service B.
My problem is when Service A is up, there might be 1-5 minutes until Service B pushes an update. Meanwhile, Service C can send 100 requests, and I'll have no ips to send these requests ...
If the queue could have known that a new consumer is added - we could trigger sending all the ips..
I hope it explains my problem.
Any help would be very appreciated.
Let's say I have a Load Balancer (LB) in front of 1..n VertX (V) instances, each VertX instance is connected to a queue (Q), and I have 1..m Backends (BE).
A user clicks on a button which makes a post request or even opens a web socket, the load balancer forwards the request to one of the VertX instances, which fires a request to the queue, one of the Backends consumes the message and sends a response back; if the correct VertX instance consumes it, it can lookup the response handler and write a response to the user, if the wrong VertX instance consumes it, there won't be a response handler to write a response to and the user will wait indefinitely for a response.
See this sketch:
Alternatively, V2 dies and the load balancer reconnects the user to V1 which means even if I could send it back to the exact same one that made the request, it's not guaranteed to still be there once the response comes back, but the user might still be there awaiting a response via another VertX instance.
What I'm currently doing is to generate a GUID for each new connection, then as soon as the websocket connects, store the websocket handler inside a hashmap against the GUID and then when the BE wants to respond, it does a fanout to all 1..n VertX instances, the one that currently has the correct GUID in its hashmap can then write a response to the user.
Same for handling POST / GET in this manner.
Pseudocode:
queue.handler { q ->
q.handler {
val handler = someMap.get(q.guid)
// only respond if handler exists
if (handler != null){
handler.writeResponse(someresponsemessagehere)
}
}
}
vertx.createHttpServer().websocketHandler { ws ->
val guid = generateGUID()
someMap.put(guid, ws)
ws.writeFinalTextFrame("guid=${guid}")
ws.handler {
val guid = extractGuid(it)
// send request to BE including generated GUID
sendMessageToBE(guid, "blahblah")
}
}.requestHandler { router.accept(it) }.listen(port)
This does however mean that if I have a 1000 VertX applications running, that the backend will need to fanout its message to a 1000 frontend instances of which only one will make use of the message.
VertX seems like it already takes care of async operations very well, is there a way in VertX to identify each websocket connection instead of having to maintain a map of GUIDs mapped to websocket handlers / post handlers?
Also, referring to the picture, is there a way for V3 to consume the message, but still be able to write a response back to the websocket handler that's currently connected to V2?
What you're missing from your diagram is the Vertx EventBus.
Basically you can assume that your V1...Vn are interconnected:
V1<->V2<->...<->Vn
Let's assume that Va receives your outbound Q message (the red line), that is intended for Vb.
It then should send it to Vb using EventBus:
eventBus.send("Vb UUID", "Message for Vb, also containing WebSocket UUID", ar -> {
if (ar.succeeded()) {
// All went well
}
else {
// Vb died or has other problems. Your choice how to handle this
}
});
How can I deliver some data to server side while subscribing to server?
As an example,
When I subscribing /alert/12345, I want to send some other information such as alert_type, date_time etc to CometD server.
You can pass a data map in subscribe:
cometd.subscribe(channelId, undefined, callback, { data: data })
But as far as I could see, you can only get a reference to the data map in org.cometd.bayeux.server.Authorizer. I couldn't get it via org.cometd.bayeux.server.BayeuxServer.SubscriptionListener because there is no reference to the ServerMessage.
You can see my use of it here:
https://github.com/uklance/tapestry-cometd/blob/master/src/main/resources/org/lazan/t5/cometd/PushTarget.js#L37
https://github.com/uklance/tapestry-cometd/blob/master/src/main/java/org/lazan/t5/cometd/services/internal/AuthorizersImpl.java#L67
I am intercepting messages that are sent through JBossESB. I am using pipeline interceptors to do so.
The problem is, that altough the sender is a service (for example PortReference < logical:BlueServiceESB#BlueListener >), the name of the receiver is a queue (not a service). That is logical because in some case, multiple services can receive messages from a given queue, but usually, each queue is mapped to only one service.
I would like to know which queue is mapped to which service, so I can display/save this information and have it displayed like message: service ---> service (not service ---> queue).
I know that I can get the name of the queue mapped to a service using the registry like this:
System.setProperty("javax.xml.registry.ConnectionFactoryClass", "org.apache.ws.scout.registry.ConnectionFactoryImpl");
// Retrieving information from the ESB Registry
Registry reg = RegistryFactory.getRegistry();
System.out.println(reg.findAllServices());
List<EPR> eprs = reg.findEPRs("FirstServiceESB", "SimpleListener");
System.out.println(eprs);
I would like to reverse this approach - queue is the input and service (EPR = end point reference = service) is the output. Is there any way how to do this or am I just trying to do the impossible here. I have found no tutorials or questions on this topic whatsoever.
Thanks for any tips!
As this question has 25 up-votes, this seems to be an useful feature. JBossESB is open source software. Thus, implement the feature yourself and commit it to the community! Or just create a change request hopping that somebody else will do it...
Try querying for all of the queues and building a reverse-lookup map. But I don't think there is any function that allows searching for services using a queue.