Message Queue Listener and RESTful integration - java

My project publishes RESTful/SOAP services. One of these sends messages to a JMS queue on a Websphere application server. The application runs on the same application server. What I need is to define a listener to this queue. How can I activate this listener without a direct call from the service?
The project structure looks like this:
Project:
-ejb
-rest
-soap
The user calls methods on the service, which calls the EJB component, so I dont have any main method where I can init the listener.
I need a solution which activates a permanent listener to the queue.
I already have the source code I just don't know how to initialize the listener.

Not sure where you have the issues:
Do something like:
define the JMS resources in WebSphere
inject the javax.jms.Queue as a Resource (or maybe using CDI? Not sure if CDI supports this) in a EJB
use this Queue to send messages
define a MDB (#MessageDriven) to listen for messages

WebSphere MDB with a lot of configuration it works!!!! But look at this:
#MessageDriven(activationConfig={
#ActivationConfigProperty(propertyName="destination", propertyValue="myDestination"),
#ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue")
})
public class MsgBean implements javax.jms.MessageListener {
public void onMessage(javax.jms.Message msg) {
String receivedMsg = ((TextMessage) msg).getText();
System.out.println("Received message: " + receivedMsg);
}
}

Related

How to enable/disable JMS listener on runtime? Can I create one api which enables/disables listener on runtime?

I am working on a Problem where I need to enable/disable a JMS listener on runtime(without restarting application). I want to create a rest service which will be hit manually and it has to turn on/turn off the listener on runtime.
You should provide more information about how you are using the framework. Assuming you mean #JmsListener, you can use the registry to stop/start the listener container...
#JmsListener(id = "foo")
...
#Autowired
private JmsListenerEndpointRegistry registry;
...
registry.getListenerContainer("foo").stop();
...
registry.getListenerContainer("foo").start();
If you have control over your processing model (synchronous/asynchronous) you could choose to use synchronously getting the messages: MessageConusmer.receive(long timeout)
Then you would simply stop making this call while 'logged out' and start making this call while being logged in.
If you are forced to use async. reception (with onMessage() ) then your receive will continuously receive messages unless you stop the session with Session.close(). To restart you would have to re-create and restart the session and re-create your MessageConsumer

Store Soap Response Message in Citrus Framework

Good Morning:
I'm new in Citrus Framework. Actually i work in a Test Case that consumes one soap webservice. I can send request message from a xml file and i need to store response message from server into another xml file for trazability and audit.
I try some options but still not working. Can you help me with posibles solutions to this requirement?
My test look like this:
public class DummyIT extends TestNGCitrusTestDesigner {
#Autowired
private WebServiceClient DummyClient;
#Test
#CitrusTest
public void dummyTest() {
soap()
.client(DummyClient)
.send()
.messageType(MessageType.XML)
.charset("UTF-8")
.contentType("text/xml")
.payload(new ClassPathResource("templates/DummyRequest.xml"));
soap()
.client(DummyClient)
.receive()
.schemaValidation(false);
}
I'm using Citrus Framework version 2.7.2.
Thanks for your help.
You can add a message tracing test listener to the Spring application context. This listener is called with all inbound and/or outbound messages. With a custom implementation you can write the message content as file to an external folder.
There is a default message listener implementation available that is a good starting point. See if this default tracing listener fits your requirements. Otherwise you would have to implement the listener logic on your own.
You can add the default listener to the application context as bean:
#Bean
public MessageTracingTestListener tracingTestListener() {
return new MessageTracingTestListener();
}
After that you should see .msgs files in target/citrus-logs/trace/messages folder containing all exchanged inbound and outbound messages.
Here is the default implementation: https://github.com/citrusframework/citrus/blob/master/modules/citrus-core/src/main/java/com/consol/citrus/report/MessageTracingTestListener.java

Scheduled websocket push with Springboot

I want to create a simple news feed feature on the front end that will automatically update through websocket push notifications.
The technologies involved are:
Angular for the general front-end application
SockJS for creating websocket communication
Stomp over webosocket for receiving messages from a message broker
Springboot Websockets
Stomp Message Broker (the java related framework)
What I want to achieve on the front end is:
Create a websocket connection when the view is loaded
Create s stomp provider using that websocket
Have my client subscribe to it
Catch server pushed messages and update the angular view
As far as the server side code:
Configure the websocket stuff and manage the connection
Have the server push messages every X amount of time (through an executor or #Scheduled?).
I think I have achieved everything so far except the last part of the server side code. The example I was following uses the websocket in full duplex mode and when a client sends something then the server immediately responds to the message queue and all subscribed clients update. But what I want is for the server itself to send something over Stomp WITHOUT waiting for the client to make any requests.
At first I created a spring #Controller and added a method to it with #SendTo("/my/subscribed/path") annotation. However I have no idea how to trigger it. Also I tried adding #Scheduled but this annotation works only on methods with void return type (and I'm returning a NewsMessage object).
Essentially what I need is to have the client initialize a websocket connection, and after have the server start pushing messages through it at a set interval (or whenever an event is triggered it doesn't matter for now). Also, every new client should listen to the same message queue and receive the same messages.
Before starting, make sure that you have the websocket dependencies in your pom.xml. For instance, the most important one:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${org.springframework-version}</version>
</dependency>
Then, you need to have your configuration in place. I suggest you start with simple broker.
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/portfolio").withSockJS();
}
#Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.setApplicationDestinationPrefixes("/app");
config.enableSimpleBroker("/topic", "/queue");
}
}
Then your controller should look like this. When your AngularJs app opens a connection on /portfolio and sends a subscription to channel /topic/greeting, you will reach the controller and respond to all subscribed users.
#Controller
public class GreetingController {
#MessageMapping("/greeting")
public String handle(String greeting) {
return "[" + getTimestamp() + ": " + greeting;
}
}
With regard to your scheduler question, you need to enable it via configuration:
#Configuration
#EnableScheduling
public class SchedulerConfig{}
And then schedule it:
#Component
public class ScheduledUpdatesOnTopic{
#Autowired
private SimpMessagingTemplate template;
#Autowired
private final MessagesSupplier messagesSupplier;
#Scheduled(fixedDelay=300)
public void publishUpdates(){
template.convertAndSend("/topic/greetings", messagesSupplier.get());
}
}
Hope this somehow clarified the concept and steps to be taken to make things work for you.
First of all you can't send (push) messages to clients without their subscriptions.
Secondly to send messages to all subscribers you should take a look to the topic abstraction side.
That is a fundamentals of STOMP.
I think you are fine with #Scheduled, but you just need to inject SimpMessagingTemplate to send messages to the STOMP broker for pushing afterwards.
Also see Spring WebSockets XML configuration not providing brokerMessagingTemplate

Using Spring AMQP onMessage() method within Flume Lifecycle

I need to listen to a Rabbit Queue in the Flume Custom Source which I have developed.This requirement may seem awkward in Flume.But this is how its needed.
As I am using Spring AMQP to listen to the queue for simplicity,I am just not able to understand how to invoke the OnMessage() method within the Flume lifecycle Start() method,So that the messages can be posted onto the Flume channel.
I have looked at the Spring MessageListenerAdapter concept but I have not been able to find any example to implement the same.
onMessage() is a part of MessageListener pattern. It is some active component, which is initiated by the external system (from big height). And it works each time by that remote command, so you can't use it as a passive componet to be initiated by the user call.
Since you have "Flume lifecycle Start()" from other side and SimpleMessageListenerContainer has the same from its side, I'd say you have to correlate their lifecycles to work in tandem.
From here you should to provide for the SimpleMessageListenerContainer some inline MessageListener implementation, which invokes the desired method to "post onto the Flume channel".
HTH
UPDATE
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
....
container.setMessageListener(new MessageListener() {
public void onMessage(Message message) {
sendMessageToFlumeChannel(message);
}
});
Where the sendMessageToFlumeChannel is a method of the holding class.
Of course it can be any POJO instead of MessageListener implementation, but the main goal to delegate listener resul to some method.

Message Driven Bean Selectors (JMS)

I have recently discovered message selectors
#ActivationConfigProperty(
propertyName="messageSelector",
propertyValue="Fragile IS TRUE")
My Question is: How can I make the selector dynamic at runtime?
Lets say a consumer decided they wanted only messages with the property "Fragile IS FALSE"
Could the consumer change the selector somehow without redeploying the MDB?
Note: I am using Glassfish v2.1
To my knowledge, this is not possible. There may be implementations that will allow it via some custom server hooks, but it would be implementation dependent. For one, it requires a change to the deployment descriptor, which is not read after the EAR is deployed.
JMS (Jakarta Messaging) is designed to provide simple means to do simple things and more complicated things to do more complicated but less frequently needed things. Message-driven beans are an example of the first case. To do some dynamic reconfiguration, you need to stop using MDBs and start consuming messages using the programmatic API, using an injected JMSContext and topic or queue. For example:
#Inject
private JMSContext context;
#Resource(lookup="jms/queue/thumbnail")
Queue thumbnailQueue;
JMSConsumer connectListener(String messageSelector) {
JMSConsumer consumer = context.createConsumer(logTopic, messageSelector);
consumer.setMessageListener(message -> {
// process message
});
return consumer;
}
You can call connectListener during startup, e.g. in a CDI bean:
public void start(#Observes #Initialized(ApplicationScoped.class) Object startEvent) {
connectListener("Fragile IS TRUE");
}
Then you can easily reconfigure it by closing the returned consumer and creating it again with a new selector string:
consumer.close();
consumer = connectListener("Fragile IS FALSE");

Categories

Resources