How to get qpid broker URL programmatically? - jms

So I have a ConnectionFactory configured from a properties file containing a broker list, meaning that when the session gets created it will have connected to one of the brokers in the list based on availability/policy and so on.
My question is: how to programmatically figure out from the Java code, at runtime, which of the broker URLs have I actually connected to.
What I am trying to achieve is to send management GET requests to the broker API programmatically, but for that I need to obtain its URL. Am I thinking about this the wrong way?
P.S. I am doing this from a Spring-boot application, but am not too fussed about using the JmsTemplate.

Related

How should you handle the retry of sending a JMS message from your application to ActiveMQ if the ActiveMQ server is down?

So using JMS and ActiveMQ, I can be sure that my message sent from my Spring Boot application using JmsTemplate will reach it's destination application even if that destination application is down at the time I send the message to ActiveMQ. As when the destination application starts up, it grabs the message from the queue. Great!
However.
What happens if my Spring Boot application tries to send a JMS message to a queue on the ActiveMQ server, but the ActiveMQ server is down at that point or the network is down and I get a connection refused exception?
What is the recommended way to make sure my application keeps trying to re-sends the message to ActiveMQ until it is successful? Is this something I have to develop into my application myself? Are there any nifty Spring tools or annotations which do this for me? Any advice on best practice or how I should be handling this scenario?
You can try Spring-Retry. Has lots of fine grain controls for it:
http://www.baeldung.com/spring-retry
https://github.com/spring-projects/spring-retry
If it is critical that you don't lose this message, you will want to save it to some alternative persistent store (e.g. filesystem, local mq server) along with whatever retry code you come up with. But for those occasional network glitches or a very temporary mq shutdown/restart, Spring-Retry alone should do the trick.
Couple of approaches I can think of
1. You can set up another ActiveMq as fallback. In your code you don't have to do anything, just change your broker url from
activemq.broker.url=tcp://amq01.blah.blah.com:61616
to
activemq.broker.url=failover:(tcp://amq01.blah.blah.com:61616,tcp://amq02.blah.blah.com:61616)?randomize=false
The rest is automatically taken care of. i.e. when one of them is down, the messages are sent to other.
Another approach is to send to a internal queue (like seda, direct) when activemq is down and read from there.
Adding failover to the url is one appropriate way.
And another reasonable way is to making sure activemq always online , as activemq has the master-slave mode(http://activemq.apache.org/masterslave.html) to get high availability.

Dynamic JMS Connections

I need to know which framework or API to use for my following requirement. I am currently using native java code for all this.
Requirement
I have an application where there could be multiple JMS/Rest/TCP connections. These connections can grow at runtime. User wil have a screen to define new incoming or outgoing connections. I am using Native and works fine but I want to make use of an efficient framework or API like Spring, Camel etc ?
Need Guidance.
I have been able to get this all working. There are multiple solutions to get do dynamic JMS
1. I used Spring JMS API and created the dynamic JMS connections by loading the dynamic child context into application. For this I followed the spring's dynamic FTP sample and inserted JMS beans in the example instead of FTP ones.
Spring Dynamic FTP Sample

Is it possible for Spring-XD to listen to more than one JMS broker at a time?

I've managed to get Spring Xd working for a scenario where I have data coming in from one JMS broker.
I potentially am facing a scenario where data ingestion could happen from different sources thereby needing me to connect to different brokers.
Based on my current understanding, I'm not quite sure how to do this as there exists a JMS config file which allows you to setup only one broker.
Is there a workaround to this?
At the moment, you would have to create a separate jms-[provider]-infrastructure-context.xml for each broker (in modules/common), say call the provider activemq2.
Then use --provider=activemq2 in the module definition.
(I recently used this technique to test sonicmq and hornetq providers).

Can I tell camel jms endpoint to share jms connections between routes?

I have a app server that runs multiple camel routes that are reading messages from a JMS Queue, each route runs with different selectors.
We have an app server for each group of clients. So at the end there are multiple connections created to the queue. And that seems to be affecting the read and write performance on the queue.
I tried to use a connection pool, (by the way i am using WMQ), the closest I got is to use spring's CachingConnectionFactory (as described in this post how to configure (spring) JMS connection Pool for WMQ).
I was hoping that the number of connections will reduce from each app server, but that did not happen. Even though i set the size to 5 on the CCFactory, i see 10 connections created to the queue. According to the documentation on CCFactory, explicit closing of the connections is required. Is it possible or does it even make sense to close the connection that is used by a camel route that is reading from a queue? Or is there a way to tell camel routes to share the connections? I thought the use of connection pool and factory will do that, but i don't see that from happening.
Can I achieve what I want to achieve?
Thanks in advance.
what you can do is have only one route reading from the queue instead of many, and then use some camel conditional logic to redirect the message to the correct processing route via direct endpoints, see also this example.
This way there would only one consumer for the queue, instead of multiple consumers each running it's own selector.

Not able to create jms queues in websphere programatically using standalone java client

I wrote a java client to connect to jms in websphere.
I was able to connect and produce and consume message.
Problem I am facing is when I do Session.createQueue(), websphere jms is not creating a new queue.
Please could some one throw some light on this issue...
Thanks in advance...
If you are working with WebSphere MQ as the messaging provider within WebSphere Application Server the queue will need to be created on the WebSphere MQ QueueManager first. This can be done either via the graphical WMQ Explorer or via the command line using the 'runmqsc' tool.
Information can be found for these via the WMQ InfoCentre - suggest doing a websearch for "WMQ Library" to get the latest link, currently though it is http://www-01.ibm.com/software/integration/wmq/library/index.html
Topics though don't need to be pre-created - though they can be if required. Various properties can be set different to the default.
If the Queue doesn't need to be permanent, for example as a temporary reply to then look into creating a temporary queue from the JMS Connection.
createQueue doesn't create a new queue. It simply creates a javax.jms.Queue object from a vendor specific identifier. javax.jms.Queue objects are just references to existing queues. Typically, you retrieve javax.jms.Queue objects from JNDI; createQueue is only useful in scenarios where using JNDI is not possible or not desirable.
Note: there is one exception to this, namely JMS providers that support autocreation of queues (I think ActiveMQ has such a feature).

Resources