implementing publisher and subscriber functionality using activemq-jms from browser(web-client-application(angularjs or javascript or jsp)) - angularjs

i want to implement an application where i should be able to login as a subscriber and i should be able to see the messages/data coming from publisher which am subscribed to.then i should be able to unsubscribe and subscribe to other publishers if i want to.
using JMS,ActiveMQ,SpringBoot i have created a sample standalone application but from here how to connect and communicate to my web application back and forth.
Here is my implemented standalone application code
application.properties
spring.jms.pub-sub-domain=true
#spring.jms.template.default-destination=testTopic
Publisher.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;
#Component
public class Publisher implements CommandLineRunner{
#Autowired
private JmsTemplate jmsTemplate ;
#Autowired
private Topic topic1;
#Autowired
private Topic topic2;
#Override
public void run(String... arg0) throws Exception {
// TODO Auto-generated method stub
Thread.sleep(5000); // wait for subscriptions, unless they are durable
this.jmsTemplate.convertAndSend(this.topic1,"-----> 1st message from publisher -- topic 1");
Thread.sleep(5000);
this.jmsTemplate.convertAndSend(this.topic1,"-----> 2nd message from publisher -- topic 1");
/**
* for topic2
*/
// TODO Auto-generated method stub
Thread.sleep(5000); // wait for subscriptions, unless they are durable
this.jmsTemplate.convertAndSend(this.topic2,"-----> 1st message from publisher -- topic 2");
Thread.sleep(5000);
this.jmsTemplate.convertAndSend(this.topic2,"-----> 2nd message from publisher -- topic 2");
}
}
Subscriber.java
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
#Component
public class Subscriber {
#JmsListener(destination = "Topic1")
public void listener1(String in) {
System.out.println("Listener1: " + in);
}
#JmsListener(destination = "Topic1,Topic2")
public void listener2(String in) {
System.out.println("Listener2: " + in);
}
#JmsListener(destination = "Topic2")
public void listener3(String in) {
System.out.println("Listener3: " + in+"\n listener 3 is just ");
}
}
mainclass : springBootApplication
PubSubJmsBootApplication.java
import javax.jms.Topic;
import org.apache.activemq.command.ActiveMQTopic;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.jms.annotation.EnableJms;
#SpringBootApplication
#EnableJms
public class PubSubJmsBootApplication {
#Bean
public Topic topic1() {
return new ActiveMQTopic("Topic1");
}
#Bean
public Topic topic2() {
return new ActiveMQTopic("Topic2");
}
public static void main(String[] args) {
SpringApplication.run(PubSubJmsBootApplication.class, args);
}
}

Related

apache camel JUnit5 test case for database operation

I am trying to write Junit5 test case for apache camel router which has the DB operations.
Use case : There is an API call which will give me the data and my router is inserting those data to local database.
I have to write the test case to check the count from the database and compare it with the api data count which should match.
And the Database connection as well
My test class needs to get the count from the database and api to compare if both matches the assert satisfied .
Please help me to write test case for the same , Please refer the below for junit test case code.
Thanks in advance.
import org.apache.camel.CamelContext;
import org.apache.camel.EndpointInject;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.builder.AdviceWith;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.http.base.HttpOperationFailedException;
import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.BootstrapWith;
#CamelSpringBootTest
#ActiveProfiles("mock")
#BootstrapWith(SpringBootTestContextBootstrapper.class)
public class TestingPersonStoringDatabase {
#Autowired
protected CamelContext camelContext;
#Autowired
private ProducerTemplate template;
#EndpointInject("mock:purePersonsEndpoint")
private MockEndpoint personsMock;
#EndpointInject("mock:storePersons")
private MockEndpoint mock;
#BeforeEach
public void setup() throws Exception {
AdviceWith.adviceWith(camelContext, "storePersonsRoute",
a -> a.weaveAddLast().to("sql:select count(*) as results from persons").setBody()
.simple("${body[0][RESULTS]}").log("RESULTS: ${body}").to("mock:storePersons"));
camelContext.start();
}
#Test
public void testPersons() throws Exception {
personsMock.whenAnyExchangeReceived(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
throw new HttpOperationFailedException("", 400, "Simulated API error", null, null, null);
}
});
//MockEndpoint.assertIsSatisfied(camelContext);
mock.expectsMessageCount(142);
personsMock.expectsMessageCount(142);
mock.assertIsSatisfied();
}
}
storePersonsRoute this router has a inserting data in the database

replacement for camel cxfbean

we are currently struggling with updating our legacy service (non spring, jee + deltaspike, weld) and it's dependencies.
We try to upgrade from camel 2.16.2 to 3.x (due to java 11 compatibility).
We have already read through the migration guide several times, but could not find any reference to your replacement of the cxfbean component.
e.g.:
public class MonitoringRoute extends RouteBuilder {
#Override
public void configure() throws Exception {
from("servlet:///monitoring?matchOnUriPrefix=true")
.to("cxfbean:monitoringService")
.setId("MonitoringRoute");
}
}
#Named("monitoringService")
public class MonitoringService implements MonitoringAPI {
#Override
public String status() {
return "OK";
}
}
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
public interface MonitoringAPI {
#GET
#Path("status")
#Produces(MediaType.TEXT_PLAIN)
String status();
}
We already tried cxfrs:monitoringService, but this will led to "Uri is not absolute" exception.
Any idea to replace cxfbean properly?

Stopping Camel route when no messages in queue (jms, seda)

I have a Camel route that moves messages from a jms queue to another. That route is by default stopped and it is started by a call to a jetty route using controlBus.
As I need to move the messages on demand, once the source jms queue is empty, I need to disable the "mover" route, so messages that arrive later are not processed until the "mover" route is activated again.
Is there a way to achieve that?
You could try to obtain the queue message count using JmsTemplate and then shutting down the route from another thread using a processor. Downsides might be a dependency to org.springframework.jms.core.JmsTemplate and some gotchas related to it.
package com.example;
import java.util.Collections;
import javax.jms.ConnectionFactory;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.junit.EmbeddedActiveMQBroker;
import org.apache.camel.CamelContext;
import org.apache.camel.RoutesBuilder;
import org.apache.camel.ServiceStatus;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.jms.JmsComponent;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.jms.core.JmsTemplate;
public class QueueConsumerTests extends CamelTestSupport {
#Rule
public EmbeddedActiveMQBroker broker = new EmbeddedActiveMQBroker();
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
"vm://localhost?broker.persistent=false");
#Test
public void stopesQueueListenerRouteAfterConsumingAllMessages() throws Exception {
MockEndpoint jmsMockEndpoint = getMockEndpoint("mock:jmsMockEndpoint");
jmsMockEndpoint.expectedMessageCount(5);
for (int i = 1; i <= 5; i++) {
template.sendBody("direct:test", "Message " + i);
}
context().getRouteController().startRoute("queueListener");
Thread.sleep(5000);
ServiceStatus routeStatus = context().getRouteStatus("queueListener");
assertEquals(routeStatus, ServiceStatus.Stopped);
jmsMockEndpoint.assertIsSatisfied();
}
#Override
protected RoutesBuilder createRouteBuilder() throws Exception {
JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
return new RouteBuilder() {
#Override
public void configure() throws Exception {
from("direct:test")
.to("jms:queue:test");
from("jms:queue:test")
.routeId("queueListener")
.autoStartup(false)
.log("message from queue: ${body}")
.to("mock:jmsMockEndpoint")
.setBody().exchange(e -> {
int messageCount = jmsTemplate.browse("test", (session, browser) -> {
return Collections.list(browser.getEnumeration()).size();
});
return messageCount;
})
.filter(body().isEqualTo(0))
.to("seda:stopPolling")
.end();
from("seda:stopPolling?concurrentConsumers=1&multipleConsumers=false")
.log("stop polling")
.process(e -> e.getContext().getRouteController().stopRoute("queueListener"))
.setProperty("stopped").constant(false)
.loopDoWhile(exchangeProperty("stopped").isEqualTo(false))
.delay(100)
.setProperty("stopped").exchange(e -> {
return e.getContext().getRouteStatus("queueListener").isStopped();
})
.end()
.log("stopped queueListener");
}
};
}
#Override
protected CamelContext createCamelContext() throws Exception {
CamelContext context = new DefaultCamelContext();
JmsComponent jmsComponent = new JmsComponent();
jmsComponent.setConnectionFactory(connectionFactory);
context.addComponent("jms", jmsComponent);
return context;
}
}
Alternative could be to use timer with poll-enrich with timeout and shutdown the route if it results in null body. This however is slower and possibly less robust due to how you need to specify frequency of polling and timeout.
package com.example;
import javax.jms.ConnectionFactory;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.junit.EmbeddedActiveMQBroker;
import org.apache.camel.CamelContext;
import org.apache.camel.RoutesBuilder;
import org.apache.camel.ServiceStatus;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.jms.JmsComponent;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Rule;
import org.junit.Test;
public class QueueConsumerTests2 extends CamelTestSupport {
#Rule
public EmbeddedActiveMQBroker broker = new EmbeddedActiveMQBroker();
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
"vm://localhost?broker.persistent=false");
#Test
public void stopesQueueListenerRouteAfterConsumingAllMessages() throws Exception {
MockEndpoint jmsMockEndpoint = getMockEndpoint("mock:jmsMockEndpoint");
jmsMockEndpoint.expectedMessageCount(5);
for (int i = 1; i <= 5; i++) {
template.sendBody("direct:test", "Message " + i);
}
context().getRouteController().startRoute("queueListener");
Thread.sleep(10000);
ServiceStatus routeStatus = context().getRouteStatus("queueListener");
assertEquals(routeStatus, ServiceStatus.Stopped);
jmsMockEndpoint.assertIsSatisfied();
}
#Override
protected RoutesBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
#Override
public void configure() throws Exception {
from("direct:test")
.to("jms:queue:test");
from("timer:moverTimer?period=500")
.routeId("queueListener")
.autoStartup(false)
.pollEnrich("jms:queue:test", 1000)
.choice()
.when(body().isNotNull())
.log("message from queue: ${body}")
.to("mock:jmsMockEndpoint")
.otherwise()
.to("seda:stopPolling")
.end();
from("seda:stopPolling?concurrentConsumers=1&multipleConsumers=false")
.log("stop polling")
.process(e -> e.getContext().getRouteController().stopRoute("queueListener"))
.setProperty("stopped").constant(false)
.loopDoWhile(exchangeProperty("stopped").isEqualTo(false))
.delay(100)
.setProperty("stopped").exchange(e -> {
return e.getContext().getRouteStatus("queueListener").isStopped();
})
.end()
.log("stopped queueListener");
}
};
}
#Override
protected CamelContext createCamelContext() throws Exception {
CamelContext context = new DefaultCamelContext();
JmsComponent jmsComponent = new JmsComponent();
jmsComponent.setConnectionFactory(connectionFactory);
context.addComponent("jms", jmsComponent);
return context;
}
}
Now as a disclaimer haven't tested these patterns thoroughly so there might be some edge cases (and better ways to do this). There's also the fact that Camel documentation uses java.lang.Thread to stop route inside a processor instead of using seda consumer so there might be something in to that.
Use of Thread.sleep in unit test is also quite messy and not something I would recommend unless you just want to quickly experiment on something with camel.
Used Dependencies:
org.apache.camel/camel-core/2.24.2
org.apache.camel/camel-jms/2.24.2
Test scope:
org.apache.camel/camel-test/2.24.2
org.apache.activemq.tooling/activemq-junit/5.16.3
org.apache.activemq/activemq-broker/5.16.3

Ejb3 -Accessing Local Enterprise Beans Using the No-Interface View

I'm trying to learn EJB3,
I created an EJB project with just a bean class:
package com;
import javax.ejb.Local;
import javax.ejb.Stateless;
#Stateless
#LocalBean
public class MyBean {
public MyBean() {
// TODO Auto-generated constructor stub
}
public String getMessage(){
return "Hello";
};
}
I deployed this project on Jboss 6 , then i create a Java project (adding in the build path the ejbProject above and Jboss-client.jar to make RMI calls).
for testing , this is the class i created:
import javax.ejb.EJB;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import com.MyBean;
public class LanceProgram {
// #EJB
//public static MyBean mybean;
public static void main(String[] args) {
Context ctx;
try {
ctx = new InitialContext();
MyBean exampleBean = (MyBean) ctx.lookup("MyBean");
System.out.println(exampleBean.getMessage());
} catch (NamingException e) {
e.printStackTrace();
}
}
}
Normally, when running this, i should have a reference to MyBean,but it's null and i have this error message (using JNDI lookup):
Exception in thread "main" java.lang.ClassCastException: org.jnp.interfaces.NamingContext cannot be cast to com.MyBean
at LanceProgram.main(LanceProgram.java:17)
While with an EJB injection i have a NullPointerException !
this i my jndi.properties file specifications:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=localhost:1099
java.naming.factory.url.pkgs=org.jboss.ejb.client.naming
I'm trying to make a call to a bean which doesn't implements an interface.
Thanks for helping

injecting Session bean from another session bean in JBoss 7.1

I am not able to inject a SLSB in another SLSB. Actually created 3 projects
1) created a EJB project with an MDB
2) created a EJB project with a stateless session bean for posting the message
3) created a EJB project with a stateless session bean for injecting the above session bean
But while injecting I am not able to inject the EJB it is returning null
the code is as below
1) MDB:
#MessageDriven(
activationConfig = {
#ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
#ActivationConfigProperty(propertyName = "destination", propertyValue = "activemq/queue/TestQueue"),
#ActivationConfigProperty(propertyName="acknowledgeMode", propertyValue="Auto-acknowledge")
})
#ResourceAdapter("activemq-ra.rar")
public class ConsumerMDB implements MessageListener {
public void onMessage(Message message) {
try {
System.out.println("Queue: Received a TextMessage at " + new Date());
TextMessage msg = (TextMessage) message;
System.out.println("Message is : " + msg.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
2) Session Bean 1
package com.springboard.session;
import javax.annotation.Resource;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.TextMessage;
#Stateless
#LocalBean
public class ProducerSession implements ProducerSessionLocal {
#Resource(mappedName="java:jboss/activemq/QueueConnectionFactory")
public static QueueConnectionFactory factory;
#Resource(mappedName = "java:jboss/activemq/queue/TestQueue")
public static Queue queue;
#Override
public void sendMessage(String msg) {
System.out.println("****************Entering into method********************");
try {
System.out.println(queue.getQueueName());
QueueConnection qConnection = factory.createQueueConnection();
QueueSession qSession = qConnection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
TextMessage message = qSession.createTextMessage();
message.setText(msg);
QueueSender qSender = qSession.createSender(queue);
qSender.send(message);
qSender.close();
qSession.close();
qConnection.close();
} catch (JMSException e) {
e.printStackTrace();
}
System.out.println("****************Exiting into method********************");
}
}
and the interface is
package com.springboard.session;
import javax.ejb.Local;
#Local
public interface ProducerSessionLocal {
public void sendMessage(String msg);
}
3) Second session bean to inject the first session
#Stateless
public class TestProducerLocalBean implements TestProducerLocalBeanLocal {
#EJB(mappedName = "java:global/ProducerSessionActiveMQ/ProducerSession!com.springboard.session.ProducerSessionLocal")
public ProducerSessionLocal producer;
public TestProducerLocalBean() {
System.out.println("*************Testing Producer****************");
if(producer!=null){
producer.sendMessage("This Message is from SessionBean to Session Bean to MDB");
}
else{
System.out.println("EJB is null");
}
System.out.println("**********End************************");
}
#Override
public void messageSend(String msg) {
// TODO Auto-generated method stub
}
and for testing purpose used a class
import javax.ejb.EJB;
import com.springboard.session.test.TestProducerLocalBean;
public class testEJB {
#EJB
public static TestProducerLocalBean local =new TestProducerLocalBean();
public static void main(String[] args) {
}
}
At producer EJB always retuns null. With using servlet to inject ProducerSession i am able to do it. but injecting with another EJB i not able to get it.
Could any one please help me out what i am missing
Thanks in advance
It's incorrect to use initialization ... = new Xyz() when using injection because initialization of those fields is the responsibility of the container. You probably attempted that because you noticed that the field was null, and that's because injection (including #EJB) is not supported in the main class unless you use an application client container.

Resources