ActiveMQ; how to make a broker distribute messages among several transportConnectors - activemq

is it possible to make the ActiveMQ broker distribute messages received on one transportConnector to other transportConnectors as well?
The concrete use case is this: I have a Java client sending messages using the openwire transportConnector and I would like to be able to read them on the mqtt transportConnector.
I use the sample jndi.properties file that is on the ActiveMQ page http://activemq.apache.org/jndi-support.html:
java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory
# use the following property to configure the default connector
java.naming.provider.url = tcp://localhost:61616
# use the following property to specify the JNDI name the connection factory
# should appear as.
#connectionFactoryNames = connectionFactory, queueConnectionFactory, topicConnectionFactry
# register some queues in JNDI using the form
# queue.[jndiName] = [physicalName]
queue.MyQueue = example.MyQueue
# register some topics in JNDI using the form
# topic.[jndiName] = [physicalName]
topic.MyTopic = example.MyTopic
I had to replace the default 'vm' transportConnector with the 'tcp' one because it did not execute using 'vm'.
The messages are pushed to my Java MessageListener instance but my mqtt client does not show them. I tried with different topics, started with 'example.MyTopic' up to '/example/MyTopic'.
Any help would be much appreciated.
Many thanks,
Roman

The broker does that by default so you are not doing something right, check the admin console for producers and consumer registered on the given destinations to see what is going on. You must remember that a Topic consumer will not receive messages sent to that Topic unless it was online at the time they were sent or you had previously created a durable topic subscription.

Related

ActiveMQ failover transport options not working as expected

I would like to use the ActiveMQ failover transport as described in https://activemq.apache.org/failover-transport-reference.html.
The default "retry forever" failover options work as expected.
However, since "forever" is sometimes too long, I tried to set some options in order to terminate the retry earlier.
For example, at startup I would like to terminate the application immediately if the connection to a broker can not be established at the first attempt.
I tried the simplest option:
failover:tcp://localhost:61616?startupMaxReconnectAttempts=0
but to my surprise, the retry goes on "forever" nevertheless.
I have tried many other combinations of options, like
failover:tcp://localhost:61616?startupMaxReconnectAttempts=0&maxReconnectDelay=10&maxReconnectAttempts=0&timeout=10
but without the desired result.
What am I doing wrong? How can I configure the failover transport such that it will terminate reconnection attempts at startup if a broker is not available?
I am using ActiveMQ version 5.15.9 (https://hub.docker.com/r/rmohr/activemq) and the Apache.NMS.ActiveMQ lib version 1.8.
The relevant code snippet is
var factory = new ConnectionFactory(connectionString);
var connection = factory.CreateConnection();
var session = connection.CreateSession(); // hangs here
There is Apache.NMS.ActiveMQ specific URI configuration: https://activemq.apache.org/components/nms/providers/activemq/uri-configuration which is not consistent with https://activemq.apache.org/failover-transport-reference.html, which brings a lot of confusion.
Following the NMS documentation I came up with a working solution:
failover:(tcp://localhost:61616)?transport.startupMaxReconnectAttempts=1
the composite URI must be in parentheses: failover:(tcp://localhost:61616)?... and not failover:tcp://localhost:61616?....
transport specific options must be prefixed with transport.
option transport.startupMaxReconnectAttempts=0 corresponds to infinite retries

Configuring SSL channel connectivity on MQ client machine

From Linux server with MQ client installed we are trying to set up connection to secured channel. I am ETL person and our MQ admin is struggling. Anyways I will explain what I tried (which obviously hasn't worked yet ) and anyone please let me know what else needs to be done to set up the connectivity.. Thanks :)
tmp/mqmutility/keyrepmodmq> ls
AMQCLCHL.TAB key.kdb key.rdb key.sth MODE_MODELTAP_DEV_keyStLst.txt
export MQSSLKEYR=/tmp/mqmutility/keyrepmodmq/key
export MQCHLLIB=/tmp/mqmutility/keyrepmodmq
export MQCHLTAB=AMQCLCHL.TAB
/opt/mqm/samp/bin> amqsputc <queue_name> <queue_manager_name>
Sample AMQSPUT0 start
MQCONN ended with reason code 2058
Note: I can connect to the same queue manager for a non-SSL channel.
Any help will be great and other approaches you follow for SSL channel connectivity from client machine will also be helpful.
When using a Client Channel Definition Table (CCDT) file - your AMQCLCHL.TAB file, a return code of 2058 usually means that the queue manager name the application tried to use - your 'queue_manager_name' - was not found in any of the channel entries in the CCDT file.
If you're using. MQ V8 you can very easily display the entries in your CCDT file and the queue manager names they are configured for using the following command:
runmqsc -n
DISPLAY CHANNEL(*) QMNAME
If none of the channels in your file have the queue manager name you are using when running the amqsputc sample then this is the cause of your 2058 reason code.
Hopefully it will be clear when you see the entries in the file listed out which queue manager name you should be using, but if not, update your question with some more details (like the contents of said file and the queue manager details) and we can help further.
You must ensure that you have a CLNTCONN channel defined which has the queue manager name you want to use in the QMNAME field, and that you have a matching named SVRCONN channel defined on the queue manager. Since you are using SSL, you must also ensure that these two channels are using the same SSLCIPH.
Please read Creating server-connection and client-connection definitions on the server and it's child topics.

How to abort code when publish message on non exist queue in rabbitmq

I have wrote server-client application.
Server Side
server will initilise a queue queue1 with routing key key1 on direct exchange.
After initilise and declaration it consume data whenever someone write on it.
Client Side
client will publish some data on that exchange using routing key key1 .
Also i have set mandotory flag to true before i publish.
Problem
everything is fine when i start server first .but i got problem when i start client first and it publish data with routing key. When client published data there is no exception from broker.
Requirement
I want exception or error when i published data on non existing queue.
If you will publish messages with mandatory flag set to true, then that message will returned back in case it cannot be routed to any queue.
As to nonexistent exchanges, it is forbidden to publish messages to non-existent exchanges, so you'll have to get an error about that, something like NOT_FOUND - no exchange 'nonexistent_exchange' in vhost '/'.
You can declare exchanges an queues and bind them as you need on client side too. These operations are idempotent.
Note, that creating and binding exchanges and queues on every publish may have negative performance impact, so do that on client start, not every publish.
P.S.: if you use rabbitmq-c, then it is worth to cite basic_publish documentation
Note that at the AMQ protocol level basic.publish is an async method:
this means error conditions that occur on the broker (such as publishing to a non-existent exchange) will not be reflected in the return value of this function.
I spend a lot time to find do that. I have a example code in python using pika lib to show how to send messsage with delivery mode to prevent waiting response when send message to noneexist queue(broker will ignore meessage so that do not need receive response message)
import pika
# Open a connection to RabbitMQ on localhost using all default parameters
connection = pika.BlockingConnection()
# Open the channel
channel = connection.channel()
# Declare the queue
channel.queue_declare(queue="test", durable=True, exclusive=False, auto_delete=False)
# Enabled delivery confirmations
channel.confirm_delivery()
# Send a message
if channel.basic_publish(exchange='test',
routing_key='test',
body='Hello World!',
properties=pika.BasicProperties(content_type='text/plain',
delivery_mode=1),
mandatory=True):
print('Message was published')
else:
print('Message was returned')
Reference:
http://pika.readthedocs.org/en/latest/examples/blocking_publish_mandatory.html

How to publish message to existing exchange

I'm playing with Bunny, and trying to publish message to existing queue.
Unfortunately inside Bunny documentation are snipent for consumer creation but not for produser.
So for example when I try to bind to some exchange, it throws an error
PRECONDITION_FAILED - cannot redeclare exchange 'test' in vhost '/' with different type, durable, internal or autodelete value
Code:
conn = Bunny.new()
conn.start
ch = conn.create_channel
x = ch.direct("test")
Do you know why it's trying to redeclare.
Maybe I need first bind to a queue?
Thanks for any help.
The error message is telling you that you tried to redeclare an exchange but you changed some of its arguments.
If you are just testing, then delete the exchange and re run your script.
We also have a set of tutorials here: http://www.rabbitmq.com/getstarted.html
I've ran into this problem too. If you've already setup the exchange in RabbitMQ. Make sure that you bind the exchange to your queue. You can either do that in the RabbitMQ admin or via the command line using the rabbitmqctl command.
Next, verify that the exchange you are using is a "direct" exchange. By default, when creating an exchange in the RabbitMQ admin it will generate a "topic" exchange. After you verify they are the same, then you should not get the error message.

WebSphere MQ 6.0: Can't switch from non-durable to durable

When I switch from non-durable to durable topic subscriber, I am unable to look up the topic name that I could read before (using JNDI).
It gives an error in the admin console as the topic is being looked up:
An error occurred during activation of changes, please see the log for details.
ERROR: Could not activate itft-jmsmodule!ITFT-JMS-1#ItftTopic
The Messaging Kernel ITFT-JMS-1 has not yet been opened
I am using Oracle WebLogic Server Administrative Console to set up the WebSphere queue. On the console, I made these changes:
For the Persistent Stores, On the Configuration tab, Added a file store called ItftFileStore
For the Persistent Stores, On the Configuration tab, Added a directory.
For the JMS Servers, On the Configuration -> General tab, Changed the Persistent Store to ItftFileStore
For the JMS Servers, On the Configuration -> General tab -> Advanced, Checked the Store Enabled field.
For the ItftTopic, Configuration -> Override tab, Changed Delivery Mode Override to Persistent.
This is the code which I am running. There are some comments on the pertinent lines.
public void start() throws Exception {
try {
LOG.info("Starting the FC MQ message consumer / listener ...");
InitialContext initialContext = getInitialContext();
topicConnectionFactory = (TopicConnectionFactory) initialContext.lookup(jmsFactory);
topicConnection = topicConnectionFactory.createTopicConnection();
topicConnection.setClientID(clientId);
LOG.info("1"+topicConnection.getClientID());
topicSession = topicConnection.createTopicSession(false, Session.CLIENT_ACKNOWLEDGE);
LOG.info("2"+topicConnection.getClientID());
//topicConnection.setExceptionListener(connectionExceptionListener);
jmsTopic = (Topic) initialContext.lookup(topic); // Error being thrown here
LOG.info("3"+topicConnection.getClientID());
//topicSubscriber = topicSession.createSubscriber(jmsTopic); // Works as a non-durable subscriber
topicSession.createDurableSubscriber(jmsTopic,subscriberName);
LOG.info("4"+topicConnection.getClientID());
topicSubscriber.setMessageListener(messageListener);
topicConnection.start();
The fundamental aspect of the problem is that you are connecting WebLogic to a Websphere JMS topic, this has become clear with the last edit of your question but it is not clear whether you are using WebLogic Messaging Bridge or not. The Messaging Bridge is the proper way of configuring a foreign JMS server in WebLogic. I suggest reading this FAQ and this how-to that is specific for Websphere.