Rabbitmq - how to listen to messages on an exchange - rabbitmq

I have a program in Java that sends messages to RabbitMQ. All I know is the exchange name. No queues, bindings, and so on.
My question is this: how can I see if the program sends these successfully, knowing only the exchange name?
Thanks.
Regards,
Serban

You can enable publisher confirmation with RabbitMQ. It's like having a send-transaction, where RabbitMQ will tell you whether or not the message was sent successfully.

Assume that we have RabbitMQ Exchange we need to create an queue to push the message to the exchange and consume it from the queue as following
private static final String EXCHANGE_NAME = "2022";
private static final String QUEUE_NAME = "2022";
private final static boolean durable = true;
// now we need to create a connection to rabbitmq server //
ConnectionFactory factory = new ConnectionFactory();
factory.setUsername("guest");
factory.setPassword("guest");
factory.setVirtualHost("/");
factory.setHost("127.0.0.1");
factory.setPort(5672);
Connection conn = factory.newConnection();
// create rabbitmq connection chaneel
Channel channel = conn.createChannel();
//Declare Exchange //
channel.exchangeDeclare(EXCHANGE_NAME, "topic", true);
// push message to rabbitmq exchange
channel.basicPublish(EXCHANGE_NAME, "routingkey", null, yourmessage.getBytes());
the above work as producer now we need to create queue consumer
private static final String EXCHANGE_NAME = "2022";
private static final String QUEUE_NAME = "2022";
private final static boolean durable = true;
// now we need to create a connection to rabbitmq server //
ConnectionFactory factory = new ConnectionFactory();
factory.setUsername("guest");
factory.setPassword("guest");
factory.setVirtualHost("/");
factory.setHost("127.0.0.1");
factory.setPort(5672);
Connection conn = factory.newConnection();
// create rabbitmq connection chaneel
Channel channel = conn.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, "topic", true);
//Queue Declare //
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
//Queue bind //
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "routingkey");
// Queue Consume //
QueueingConsumer consumer = new QueueingConsumer(channel);
while (true)
{
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(" [x] Received '" + message + "'");
}

Please look here: https://www.rabbitmq.com/tutorials/tutorial-three-java.html
String queueName = channel.queueDeclare().getQueue();
channel.queueBind(queueName, "EXCHANGE_NAME", "");
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
Consumer consumer = new DefaultConsumer(channel) {
#Override
public void handleDelivery(String consumerTag,
Envelope envelope,
AMQP.BasicProperties properties,
byte[] body) throws IOException
{
String message = new String(body, "UTF-8");
System.out.println(" [x] Received '" + message + "'");
}
};
channel.basicConsume(queueName, true, consumer);
In a few words, you have to:
create a queue, in this case anonymous queue
bind the queue to your exchange
It is important to know what kind of the exchange you have since the binding can change, between fanout or topic or direct
In this example is fanout

Related

RabbitMQ queue declare never ends

I'm just trying to make a simple test for RabbitMQ, and I have Erlang installed as well as RabbitMQ running.
My receiver:
private final static String QUEUE_NAME = "hello";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
Consumer consumer = new DefaultConsumer(channel) {
#Override
public void handleDelivery(String consumerTag, Envelope envelope,
BasicProperties properties, byte[] body) throws IOException
{
// TODO Auto-generated method stub
String message = new String(body, "UTF-8");
System.out.println(" [x] Received '" + message + "'");
}
};
channel.basicConsume(QUEUE_NAME, true, consumer);
}
It never prints out the first sysout, because it gets stuck declaring the queue on "channel.queueDeclare" line.
Rabbit log says it is accepting AMQP connection and user guest gets authenticated and granted access to vhost.
Any help would be appreciated.
I just copied/pasted your code with no problems...
[*] Waiting for messages. To exit press CTRL+C
[x] Received 'foo'
I suggest you enable the management plugin and explore the admin UI.
Why did you add the spring-amqp spring-rabbitmq tags since this question has nothing to do with Spring and you are using the native client directly?

Identify ActiveMQ asyncrhonous message failures?

I have ActiveMQ persistent queue and due to performance i'm publishing to producer using async mode.
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(brokerURL);
factory.setUseAsyncSend(true);
PooledConnectionFactory connectionFactory = new PooledConnectionFactory(factory);
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProduer producer = session.createProducer(destination);
Queue queue = session.createQueue(qName);
producer.send(queue, message);
Is there a way to register handler to get the error/success of producer.send() method ?
Seems like jms 1.1 specification does not allow to register call back in send method and jms 2.0 allows it ( http://www.oracle.com/technetwork/articles/java/jms2messaging-1954190.html ). Since ActiveMq based on jms 1.1 there's no standard way to register callback. However ActvieMQ javax.jms.MessageProducer implementation org.apache.activemq.ActiveMQMessageProducer allows to register callback and I used that to create my solution ( but unfortunately i had to abandon PooledConnectionFactory because there was no way to get org.apache.activemq.ActiveMQMessageProducer from PooledConnectionFactory approach.
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(brokerURL);
factory.setUseAsyncSend(true);
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProduer producer = session.createProducer(destination);
Queue queue = session.createQueue(qName);
((ActiveMQMessageProducer)producer).send(queue, message, new AsyncCallback() {
#Override
public void onSuccess() {
}
#Override
public void onException(JMSException exception) {
}
};);

Rabbitmq How to read data at once without while loop

I'm reading data from RabbitMQ (java client) in this way.
while(true)
{
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(message);
}
Can I read all the data in the queue without while loop?
Have you read the tutorials on the RabbitMQ website?
this looks like the basic java code for consuming messages:
Consumer consumer = new DefaultConsumer(channel) {
#Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
throws IOException {
String message = new String(body, "UTF-8");
System.out.println(" [x] Received '" + message + "'");
}
};
channel.basicConsume(QUEUE_NAME, true, consumer);
this should send all messages to the specified consumer.

How to receive messages for a correlationid from RabbitMQ using Spring AMQP

I went through the API of RabbitTemplate. It provides only receive method which gets the message from queue. However there is no way to get a message with a particular correlation id. Can you please help me understand what I am missing here.
Currently, I am using JMS API's from ActiveMQ to receive messages using the following code which createConsumer with message selector. Looking to do the same with Spring AMQP with RabbitMQ:
private ObjectMessage receiveMessage(final String readQueue, final UUID correlationId, final boolean isBroadcastMessage, final int readTimeout) throws JMSException
{
final ActiveMQConnectionFactory connectionFactory = this.findConnectionFactory(readQueue);
Connection connection = null;
Session session = null;
MessageConsumer consumer = null;
ObjectMessage responseMessage = null;
try
{
connection = connectionFactory.createConnection();
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue(readQueue);
consumer = session.createConsumer(destination, "correlationId = '" + correlationId + "'");
final Message message = consumer.receive(readTimeout);
}
finally
{
if (consumer != null)
{
consumer.close();
}
if (session != null)
{
session.close();
}
if (connection != null)
{
connection.close();
}
}
return responseMessage;
}
You are using a messageSelector string in JMS; RabbitMQ/AMQP does not have an equivalant.
Instead, each consumer gets its own queue and you use a direct or topic exchange in the broker to do the routing. I suggest you take a look at the tutorials on the rabbitmq web site and topics.
If you are using the correlationId for request/reply processing, consider using the inbuilt sendAndReceive or convertSendAndReceive methods in the template. See the reference documentation for more information.

how to set the basic message properties for message in Rabbitmq?

i am using Rabbitmq Java client API.i want to set the Basic Properties for message and also get the message Id of the message.if possible please provide some code to understand the things.
Thanks
While sending a message through java client usually it is publish to a channel like
CHANNEL.basicPublish(EXCHANGE_NAME, QUEUE_ROUTING_KEY, MessageProperties.PERSISTENT_TEXT_PLAIN, "message".getBytes)
Here you can set message properties
You can get the msg by using a delivery agent
You have to first bind the queue like this
Channel channel = conn.createChannel();
String exchangeName = "myExchange";
String queueName = "myQueue";
String routingKey = "testRoute";
boolean durable = true;
channel.exchangeDeclare(exchangeName, "direct", durable);
channel.queueDeclare(queueName, durable,false,false,durable, null);
channel.queueBind(queueName, exchangeName, routingKey);
boolean noAck = false;
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(queueName, noAck, consumer);
Then use delivey to get msg
QueueingConsumer.Delivery delivery;
try {
delivery = consumer.nextDelivery();
} catch (InterruptedException ie) {
continue;
}
Here is how it can be done:
int PERSISTENCE_MESSAGE = 2; // Persist message
String TEXT_MESSAGE = "text/plain";
String queueName = "QUE-1";
Channel channel = this.connection.createChannel();
channel.queueDeclare(queueName, true, false, false, null);
// Build message properties
Map messageProps = new HashMap();
//messageProps.put("TIME_MSG_RECEIVED", time);
messageProps.put("SOURCE_SYS", "SRC1");
messageProps.put("DESTINATION_SYS", "DST1");
// Set message properties
AMQP.BasicProperties.Builder basicProperties = new AMQP.BasicProperties.Builder();
basicProperties.contentType(TEXT_MESSAGE).deliveryMode(PERSISTENCE_MESSAGE)
.priority(1).headers(messageProps);
channel.basicPublish("", queueName, basicProperties.build(), message.getBytes());
System.out.println(" Sent message to RabbitMQ: '" + message + "'");
channel.close();