Starting a jms Connection with standalone MQ Clientdriver - jms

I want to check if a JMS-Connection to a remote queuing is working. As this should be kind of J-Unit Test I can't use a Server (in my case would be Websphere. Is there any driver implementation or API I could use to initialize the connection ?

No; without a backend Queuemanager there's nothing to respond to the connection. Messaging is inherently a distributed / networked product. There isn't something like a 'mock' QueueManager. In order for the connection to be properly created the mock would need to implement a lot of real function.

Related

Does Elastic High Level Rest Client need connection pool implements on my own in appliation

I use high-level-rest-client as my java client in my applicaton, and just use it by autowiring highRestClient in my business service code, not unlike using some connection pool in database connecting. For now, its performance is ok, but I wonder whether the bottom implementation of the client have use some kinds of connection pools. If not, is there any need to implement connection pools using high-level-rest-client on my own to improve its performance?
From the official Documentation RestHighLevelClient initialization, it looks like ES pools the connection.
The high-level client will internally create the low-level client used to perform requests based on the provided builder. That low-level client maintains a pool of connections and starts some threads so you should close the high-level client when you are well and truly done with it and it will in turn close the internal low-level client to free those resources. This can be done through the close

Can you check to see if an IBM MQ topic is up and available through a Java application before attempting to create a connection?

I would like to add some conditional logic to our Java application code for attempting to create a JMS Topic Connection. I have seen problems in the past stemming from attempting to create a connection when the MQ server had been restarted or was currently down. One improvement I added was to check for the quiescent state, and another was to increase the timer before attempting reconnection to our durable topic queue.
Is there a way to confirm with the MQ server/topic/channel that it is up and running and a connection request can safely be made?
The best way to confirm that a queue manager (and the channel you are using to connect to the queue manager) is up and running is to attempt to connect to it.
If your connection attempt fails, you will get an MQ Reason code telling you exactly why. This is a much better way to confirm than any administrative command, because it also confirms that your application, and it's security context is correct and able to connect to the queue manager. It is completely possible to have an up-and-running queue manager but an application that is not yet correctly configured to use it. So connect from the application and if it works, the queue manager is up-and-running.
Your comment about having an increased timer before attempting to reconnect after a failure is well made. It doesn't help anyone if you hammer the queue manager with lots of repeated and close together connection attempts until it is ready to accept your connection, but still anything that is going to test the availability of the queue manager needs to ultimately connect to it, so very simply, just connect.

ActiveMQ - Stomp over websockets - Same Origin Policy

I have a process that runs in California that wants to talk to a process in New York, using Stomp over Websockets.
Also note that my process is not a web app, but I implemented a stomp over websocket client in C++, in order to connect things up to my backend. Maybe this was or wasn't a good idea. So, I want my client to talk to the server and subscribe, where their client pushed messages.
I was implementing my own server when I saw that ApacheMQ supported Stomp over Websockets. So, I started reading the docs.
It says with the last line under 'configuration' at
http://activemq.apache.org/websockets :
One thing worth noting is that web sockets (just as Ajax) implements ? > the same origin policy, so you can access only brokers running on the > same host as the web application running the client.
it says it again in several related searches such as http://sensatic.net/activemq/activemq-54-stomp-over-web-sockets.html
Is this a limitation of the server or the web client?
With that limitation, if I understand right, the server is not going to accept websocket connections from a client, of any kind, that is not on the same machine?
I am not sure I see the point of that...
If that is indeed its meaning, then how do I get around it in order to implement my scenario?
I've not found that bit of documentation you are referring to but from what I know of the STOMP implementation on the broker this seems incorrect. There shouldn't be any limit to the transport connector accepting connect requests from an outside host by default and I don't think the browser treats the websocket requests the same as it does other things like an Ajax case in terms of the same origin policy.
This probably a case that is best checked by actually trying it to see if it works, I've connected just fine from outside the same host using AMQP over websockets on ActiveMQ so I'd guess the STOMP stack should also work fine.

JMS with clustered nodes

I have two clustered managed servers running on Weblogic, and seperate JMS server1 and server2 are running on each managed server. The problem is in application properties file, we only hardcoded and pass JMS server1 JNDI name to the application. So both applications running on each node actually only uses one fixed JMS server, which is not truly distributed and clustered. If JMS server 1 is down, the whole application will be down.
My question is how to let application dynamically find JMS server in above senario? Can you please point me a direction? Thanks!
It's in the Weblogic docs at: http://docs.oracle.com/cd/E14571_01/web.1111/e13738/best_practice.htm#CACDDFJD
Basically you created a comma separated list of servers and the JMS connection logic should be automatically able to handle to case when one of the servers is down:
e.g.
t3://hostA:7001,hostB:7001
When you use a property like jms.jndi.provider.url=t3://hostA:31122,hostA:31124
it tells wls to connect to either hostA:31122 or hostA:31124.
Note your JMS client is connected to only one Host at any given time.
when you shutdown hostA the connection between JMS client and server is cut abruptly resulting in an exception, your code will have to handle this exception gracefully and attempt to connect to WLS again periodically to ensure it connects to hostB.
WLS internally will round robin the request if more than 1 instance of the JMS client is running.
When using MDB as JMS client and deploying it to a cluster and using such a url 1 mdb instance would connect to one host and the other instance would connect to another host. MDB also inherently has the ability to reconnect periodically to the JMS destination.
A easy solution to your problem could be to
1) Set the jms.jndi.provider.url=t3://hostA:31122,hostA:31124
2) Have 2 instance of the JMS client code running, so one will connect to port 31122 and other to 31124
3) Set Forward-Delay on the JMS Queue so that message dont remain in queue without getting consumed for long and get forwarded to the other queue which has an active consumer.
I am updating my progress here instead of adding more comments. I have tested using a standalone JMS client by changing properties file from t3://hostA:7001 to t3://hostA:7001,hostB:7001 for JMS provider. The failover is automatically handled by WLS. No code change. The exception I got above is caused by using wlclient.jar, it is working after it changed to wlfullclient.jar.
I followed this link to generate wlfullclient.jar.
Thanks everyone!

Sending message to ActiveMQ over internet

I want to implement messaging over internet. But didn't have IP Public yet.
So I want to ask any one here about sending message to ActiveMQ using JMS over internet?
Could It be done ?
Yes, it exposes a normal TCP based endpoint(by default at port 61616). However, this would not be a recommended deployment model - a better model will be to expose a http based endpoint using a servlet container which internally hands over the message to the activemq broker.
There a lot of good solutions that can do this -
Spring Integration , Apache Camel
Exposing a Webservice endpoint using say Apache CXF (which will bring you a standards based interface), which will internally hand over the message to ActiveMQ.
yes, It can be done. we are currently running a little under a thousand "consumers" which connect to our brokers over the internet.
As to the insecurity of traffic over the internet, i do not agree completely:
exposing a webservice is just as riskfull as exposing the broker. In the end, you are never 100% sure your own code or the code or the underlying application (Apache CXF, Webserver, application server, database server, message broker) contain flaws that could be a security risk. Second to that, HTTP is just as much TCP traffic as ActiveMQ is ( Stomp or openwire protocol)
That being said, you can take all measures to make the risk as small as possible.
we have done the following:
User & Password Required to connect to the broker (ActiveMQ suports a wide range of Authentication solutions and you can roll your own if required)
Switch port to a different number so detection is more difficult
if you have control over the consumers aswell, apply IP filters in the firewall for what ip's can connect to the broker ( unfortunately, this was not possible in our case)
encrypt your messages
We have added an application level Authentication aswell using a token. This way, every message is authenticated in our own application
-> if all of these are implemented, I think you are pretty safe and as a bonus, you do not need the extra layer of webservices ( if this application needs to scale, you will need to scale your webservices equally with your brokers.
Plain connections (openwire) should be fine. It's much simpler to stick with the standard setup than to try setting up web services and whatnot. Just make sure to encrypt the channels with SSL. If you use plain passwords, they can possibly be picked up over public networks (unlikely but anyway) - that's why I prefer SSL.
Actually, ActiveMQ is a very good way to do communication over the Internet since it supports transactions and persistence, making it cope well with network stability issues.
However, you need a public IP (or some NAT/port forwarding solution form a public IP) on the machine running the ActiveMQ server for this to work.

Resources