How to return JMS answer in REST - rest

So I am writing REST Service in which I want to return JMS answer from queue.
Everythink looks like this:
#Controller
#RequestMapping("/rest")
public class UserService {
#Autowired
JMSProducer jmsproducer;
#RequestMapping(value="/users", method=RequestMethod.GET)
public String getUsers(){
return jmsproducer.send();
}
}
Method send() send message to queue to BACKEND ( backend have connection to DataBase ) then backend send in queue message all users to my rest and then my JMSProducer class with method onMessage from MessageListener receive sended message. (using MessageProducer's and MessageConsumer's)
Question is: How can i receive this all users from queue on this method getUsers because onMessage function is void type.
Please help me, i don't have any idea how to do that in a good way.
I am using ActiveMQ.

Related

VertX multiple Worker Instances processing same message

I have a simple Vertx worker vertical with 4 instances for scaling as defined below. When multiple requests come, I was expecting that each worker instances will process individual request concurrently (4 requests at a time).
Vertx vertx = Vertx.vertx();
DeploymentOptions deploymentOptions = new DeploymentOptions()
.setWorker(true)
.setInstances(4);
vertx.deployVerticle(MailVertical.class.getName(), deploymentOptions);
some code to plumb incoming mail message to publishing method.
// This is executed once per incoming message
this.vertx.eventBus().publish("anAddress", messageString);
Vertical Consumer code to log incoming mail message
public class MailVertical extends AbstractVerticle {
private static final Logger logger = LoggerFactory.getLogger(MailVertical.class);
#Override
public void start(Promise<Void> future) {
logger.info("Welcome to Vertx: MailVertical.");
vertx.eventBus().consumer("anAddress", message -> {
String msg = message.body().toString();
for(int i=0;i<50;i++){
logger.info(msg);
}
try {
updateStatusInDB(msg);
} catch (SQLException e) {
e.printStackTrace();
}
});
}
However, I am observing that each request is processed by all 4 instances somewhat concurrently i.e. if 1 request come in, total 4 processing events occur = 200 log messages.
...
...
[vert.x-worker-thread-7] INFO com.vertx.mailproject.MailVertical - {"msg":"sample message for app-2123x mail notification","appname":"app-1","msgid":"64fd684b-45a8-48c7-9526-4606d6adc311"}
[vert.x-worker-thread-6] INFO com.vertx.mailproject.MailVertical - Msg: sample message for app-2123x mail notification updated to SENT in DB.
[vert.x-worker-thread-7] INFO com.vertx.mailproject.MailVertical - Msg: sample message for app-2123x mail notification updated to SENT in DB.
[vert.x-worker-thread-4] INFO com.vertx.mailproject.MailVertical - Msg: sample message for app-2123x mail notification updated to SENT in DB.
[vert.x-worker-thread-5] INFO com.vertx.mailproject.MailVertical - Msg: sample message for app-2123x mail notification updated to SENT in DB.
Any suggestion what am I doing wrong here? Or is this expected.
vertx-core = 4.2.3
Yes this is indeed a correct behavior. You are starting 4 worker threads and then registering all of them against the same address "anAddress".
Publish Subscribe pattern is being used here. With the method publish() all the registered consumer/handler will receive this event. see Publish / subscribe messaging
If you want only one of worker to receive this event, then use Point-to-point and Request-Response messaging. Basically replace publish() with send()
But looking at your code, I would suggest instead of using worker verticle use executeBlocking in standard verticle

RxJava disposing Observable/Flowable in a microservice Server project

I am using RxJava for a server microservice project, where using Jetty as HTTP Servlet server.
I am handling requests either from client or main server with Observable for different flows.
When a request hitting the api below, I will return a Response after Observable finishes the job.
#GET
#Path("{uuid}")
#Produces(MediaType.APPLICATION_JSON)
public Response doThingsForClient(#PathParam("uuid") String uuid) {
Worker worker = new Worker(uuid);
worker.run();
return Response.ok("Awesome").build();
}
class Worker {
String uuid = null;
public Worker(String uuid) {
this.uuid = uuid;
}
public void run() {
Observable.concat(Observable1,Observable2,Observable3);
}
}
I am wondering if I need to dispose these Observables or Flowables.
According to this: Does RxJava2 auto dispose observable when they call completed or error?
and the RxJava3 sourcecode, i don't think Flowable at least is disposed automatically?
If I need to manually dispose the resources,
Is it better to create a CompositeDisposable, then add disposable to the CompositeDisposable at each Observer(Observable1...Observable3)'s onSubscribe() being called, call compositeDisposable.dispose() after the concat finishes.
Should I also monitor the Jetty AbstractLifeCycle to dispose these Observables(It sounds similar as Android)? I am not sure how other people are using RxJava at the server side, open to any suggestions to these questions and general Rx approach at server projects.
Thanks!

Camel keep sending messages to queue via JMS after 1 minute

I am currently learning Camel and i am not sure if we can send messages to a activemq queue/topic from camel at fixed interval.
Currently i have created code in Scala which looks up the database and create a message and sends it to queue after every minute can we do this in camel.
We have a timer component in camel but it does not produce the message. I was thinking something like this.
from("timer://foo?fixedRate=true&period=60000")
.to("customLogic")
.to("jms:myqueue")
Timer will kick after a minute.
Custom logic will do database look up and create a message
Finally send to jms queue
I am very new to Camel so some code will be really helpful thanks
Can you please point me to how can i create this customeLogic method that can create a message and pass it to next ".to("jms:myqueue")". Is there some class that in need to inherit/implement which will pass the the message etc.
I guess your question is about how to hook custom java logic into your camel route to prepare the JMS message payload.
The JMS component will use the exchange body as the JMS message payload, so you need to set the body in your custom logic. There are several ways to do this.
You can create a custom processor by implementing the org.apache.camel.Processor interface and explicitly setting the new body on the exchange:
Processor customLogicProcessor = new Processor() {
#Override
public void process(Exchange exchange) {
// do your db lookup, etc.
String myMessage = ...
exchange.getIn().setBody(myMessage);
}
};
from("timer://foo?fixedRate=true&period=60000")
.process(customLogicProcessor)
.to("jms:myqueue");
A more elegant option is to make use of Camel's bean binding:
public class CustomLogic {
#Handler
public String doStuff() {
// do your db lookup, etc.
String myMessage = ...
return myMessage;
}
}
[...]
CustomLogic customLogicBean = new CustomLogic();
from("timer://foo?fixedRate=true&period=60000")
.bean(customLogicBean)
.to("jms:myqueue");
The #Handler annotation tells Camel which method it should call. If there's only one qualifying method you don't need that annotation.
Camel makes the result of the method call the new body on the exchange that will be passed to the JMS component.

Recursive Calls to toApp in my Quickfix/J Application implementation

I'm doing something like this in my Quickfix/J Application implementation:
public void toApp(Message message, SessionID sessionID) throws DoNotSend {
try {
Session.sendToTarget(message, sessionID);
} catch (SessionNotFound e) {
e.printStackTrace();
}
}
but the code in Session.Java itself calls application.toApp(message, sessionID);
in the method
private boolean sendRaw(Message message, int num) {
what is the correct way to send messages?
The toApp method is a callback function that is called whenever a message is sent to the counterparty. Looking at your code, I feel that your logic is recursive in itself. SendToTarget calls toApp and toApp calls sendToTarget. A simple way to send messages is to use the concrete session object, say mySession. Then you may do mySession.send(Message).
If you are trying to send a message in response to a received message, you'll want to do that in the fromApp callback method instead.
The toApp callback is for outgoing messages. This can be useful if you want to do some extra validation or risk management on outgoing messages. If you don't want to send the message, then throw a DoNotSend exception.

CometD Subscription Listeners

I’m having a problem processing Subscription Requests from Clients and carrying out some processing based on the request. I’d like to be able to invoke a method and carry out some processing when an incoming subscription request is received on the Server. I’ve had a look at the following CometD documentation and tried the example outlined in “Subscription Configuration Support” but I’m not having much luck.
http://www.cometd.org/documentation/2.x/cometd-java/server/services/annotated
I’ve already created the Bayeux Server using a Spring Bean and I’m able to publish data to other channel names I’ve created on the Server side. Any help or additional info. on the topic would be appreciated!
The code example I’m using:
#Service("CometDSubscriptionListener")
public class CometDSubscriptionListener {
private final String channel = "/subscription";
private static final Logger logger = Logger.getLogger(CometDSubscriptionListener.class);
private Heartbeat heartbeat;
#Inject
private BayeuxServer bayeuxserver;
#Session
private ServerSession sender;
public CometDSubscriptionListener(BayeuxServer bayeuxserver){
logger.info("CometDSubscriptionListener constructor called");
}
#Subscription(channel)
public void processClientRequest(Message message)
{
logger.info("Received request from client for channel " + channel);
PublishData();
}
Have a look at the documentation for annotated services, and also to the CometD concepts.
If I read your question correctly, you want to be able to perform some logic when clients subscribe to a channel, not when messages arrive to that channel.
You're confusing the meaning of the #Subscription annotation, so read the links above that should clarify its semantic.
To do what I understood you want to do it, you need this:
#Service
public class CometDSubscriptionListener
{
...
#Listener(Channel.META_SUBSCRIBE)
public void processSubscription(ServerSession remote, ServerMessage message)
{
// What channel the client wants to subscribe to ?
String channel = (String)message.get(Message.SUBSCRIPTION_FIELD);
// Do your logic here
}
}