You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@qpid.apache.org by eugene <eu...@gmail.com> on 2012/03/13 12:33:14 UTC

Red Hat MRG alt-exchange

Hello, 

So I am pretty much a newbie here with Qpid.
I have a simple question if I may, how do I use the alt-exchange in java
with AMQP/QPid?

Suppose I want to send the message to a non-existent queue (but I am
completely unaware of that), can I use the alt-exchange to "catch" all those
messages that actually have nowhere to go?

Something like that :

I have not created anything yet on the MRG side.

Queue myQueue = session.createQueue("myQueue; {create:never, delete:never,
assert: always, node:{type:queue, x-declare:{alt-exchange: DLQ_QUEUE}} }");

Then send a simple message. 

Of course I have tried that, but all I get is :

"The name 'myQueue' supplied in the address doesn't resolve to an exchange
or a queue"

Can someone explain me then the purpose of alt-exchange? 

Thank You,
Eugene.

--
View this message in context: http://apache-qpid-developers.2158895.n2.nabble.com/Red-Hat-MRG-alt-exchange-tp7368166p7368166.html
Sent from the Apache Qpid developers mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


Re: Red Hat MRG alt-exchange

Posted by eugene <eu...@gmail.com>.
In case someone else hits the same issue we did, here are the lines that
Gordon Sim provided (we were using the 0.10 version of the qpid-client from
maven and the issue came from that):


"Ok, that is the official Qpid jars. These differ slightly from the MRG
jars. MRG takes Qpid releases as a starting point. The MRG 0.10 has some
additional patches over the Qpid 0.10 and this fix was one of them (the fix
was submitted upstream as well, but is then included in the next Qpid
release, i.e. 0.12)"

So, what we did is switch to the 0.12 in maven:

<dependency>
		<groupId>org.apache.qpid</groupId>
		<artifactId>qpid-client</artifactId>
		<version>0.12</version>
</dependency>

And everything started to work ok again, the messages were sent to the
alternate-exchange.

Gordon, thank you!

--
View this message in context: http://apache-qpid-developers.2158895.n2.nabble.com/Red-Hat-MRG-alt-exchange-tp7368166p7374896.html
Sent from the Apache Qpid developers mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


Re: Red Hat MRG alt-exchange

Posted by Gordon Sim <gs...@redhat.com>.
On 03/14/2012 12:59 PM, eugene wrote:
> Thx again for the known issue link, usefull!
>
> But I've removed the delete:receiver declaration and still nothing gets
> routed to the FANOUT_EXCHANGE.
>
> To be more verbose here is what I do:
>
> 1. qpid-config add exchange fanout FANOUT_EXCHANGE
> 2. qpid-config add queue FANOUT_QUEUE
> 3. qpind-config bind FANOUT_EXCAHNGE FANOUT_QUEUE
>
> Run the same sample without delete:receiver
>
> Queue myQueue = session.createQueue("MY_QUEUE; {create:always,
> assert:always, node:{x-declare:{auto-delete:true, exclusive: true,
> alternate-exchange: FANOUT_EXCHANGE}}}");
>
> Well, the output is the same FANOUT_QUEUE is empty and MY_QUEUE is DELETED.
>
> Sounds like a bug to me...

It works for me (against trunk and 0.14 release). What version are you 
using? I didn't run in eclipse, I just killed the process after it had 
received the message (I assume that has the same behaviour). The message 
was then correctly routed through FANOUT_EXCHANGE to FANOUT_QUEUE.

If you start qpidd with --log-enable notice+ --log-enable 
trace+:amqp_0_10 --log-to-file qpidd.log and send me the file (along 
with the version you are using) I'll see if I can spot anything.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


Re: Red Hat MRG alt-exchange

Posted by eugene <eu...@gmail.com>.
Thx again for the known issue link, usefull!

But I've removed the delete:receiver declaration and still nothing gets
routed to the FANOUT_EXCHANGE.

To be more verbose here is what I do:

1. qpid-config add exchange fanout FANOUT_EXCHANGE
2. qpid-config add queue FANOUT_QUEUE
3. qpind-config bind FANOUT_EXCAHNGE FANOUT_QUEUE 

Run the same sample without delete:receiver 

Queue myQueue = session.createQueue("MY_QUEUE; {create:always,
assert:always, node:{x-declare:{auto-delete:true, exclusive: true,
alternate-exchange: FANOUT_EXCHANGE}}}");

Well, the output is the same FANOUT_QUEUE is empty and MY_QUEUE is DELETED.

Sounds like a bug to me...

Thank You,
Eugene.


--
View this message in context: http://apache-qpid-developers.2158895.n2.nabble.com/Red-Hat-MRG-alt-exchange-tp7368166p7371714.html
Sent from the Apache Qpid developers mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


Re: Red Hat MRG alt-exchange

Posted by Gordon Sim <gs...@redhat.com>.
On 03/14/2012 12:06 PM, eugene wrote:
> Hey Gordon, here is what I really mean. I think that this is way more useful

Yes, code is usually unambiguous:-)

It looks like this might be 
https://issues.apache.org/jira/browse/QPID-3481, which is fixed in the 
upcoming 0.16 release (now in beta).

In the meantime, one workaround is to remove the delete:receiver part of 
your address. You already have auto-delete set, so it isn't strictly 
necessary.

In that case the session close will cause the queue deletion and will 
also release any locked messages, meaning they will be re-routed to your 
alternate exchange.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


Re: Red Hat MRG alt-exchange

Posted by eugene <eu...@gmail.com>.
Hey Gordon, here is what I really mean. I think that this is way more useful
:


import java.util.Properties;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class AlternateExchangeTest {
	
	public static void main(String[] args) throws JMSException, NamingException
{
		new AlternateExchangeTest().runTest();
	}
	
	
	private void runTest() throws JMSException, NamingException { 
		
		Connection connection = null;
		Context context = null;
		
    	try { 
    		Properties properties = new Properties(); 
           
properties.load(this.getClass().getResourceAsStream("/mrg/mrg.properties")); 
            properties.put(Context.INITIAL_CONTEXT_FACTORY,
"org.apache.qpid.jndi.PropertiesFileInitialContextFactory");
            
            context = new InitialContext(properties);   
            
            ConnectionFactory connectionFactory = (ConnectionFactory)
context.lookup("qpidConnectionfactory"); 
            connection = connectionFactory.createConnection();   
            connection.start(); 

            Session
session=connection.createSession(false,Session.CLIENT_ACKNOWLEDGE); 
            Queue myQueue = session.createQueue("MY_QUEUE; {create:always,
delete:receiver, assert:always, node:{x-declare:{auto-delete:true,
exclusive: true, alternate-exchange: FANOUT_EXCHANGE}}}");  
            
            TextMessage message = session.createTextMessage("Sample");
            MessageProducer producer = session.createProducer(myQueue);
            producer.send(message);
            
            /**
             * You could un-comment this sleep to see that the queue
MY_QUEUE really exists and it has one message
             */
            //Thread.sleep(1000000);
            
            MessageConsumer messageConsumer =
session.createConsumer(myQueue);
            
            Message messageResponse = null;
            
            System.out.println("Receiving!");
            
            do{
            	messageResponse = messageConsumer.receive(100);
            } while(messageResponse == null);
            
            System.out.println("Received!");
            
            /**
             * When I end up here, the queue exists and it has one message
according to qpid-stat -q
             * Then I stop the Thread - big red button in Eclipse Console
             * run qpid-stat -q again and notice that the queue is now
deleted, but the FANOUT_EXCHANGE reports no messages
             * thus my message is deleted and forever gone?
             */
            Thread.sleep(1000000);
            
            
    	} catch (Exception exp) { 
    		exp.printStackTrace(); 
        } finally{
        	connection.close();
        	context.close();
        }
    } 
}

Thank You,
Eugene.

--
View this message in context: http://apache-qpid-developers.2158895.n2.nabble.com/Red-Hat-MRG-alt-exchange-tp7368166p7371609.html
Sent from the Apache Qpid developers mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


Re: Red Hat MRG alt-exchange

Posted by Gordon Sim <gs...@redhat.com>.
On 03/14/2012 10:31 AM, eugene wrote:
> I have tried a simple scenario where I have something like this:
>
> 1. Create a queue and one fanout exchange - bind them.
> 2. Create a queue like this: "myQueue; {create:receiver, delete:receiver,
> assert:always, node:{x-declare:{auto-delete:true, exclusive: true,
> alt-exchange: FANOUT_EXCHANGE}}}" //alternate-exchange does not work either

alternate-exchange is the correct key name and that works for me with 
the latest JMS client (by works I mean simply that the queue thus 
created has the desired exchange set)

> 3. Send the message to myQueue, there I have a Listener configured, as soon
> as I hit the onMessage, wait forever (while(true){} for example) without
> acknowledging the message, thus the message is still inside myQueue.

So does your session have CLIENT_ACKNOWLEDGE mode set, or you are just 
delaying acknowledgement by never returning from the onMessage()?
>
> Check the queue size with qpid-tool, show<ID>  : myQueue has one message
> which I expect to happen, because I did not do message. acknowledge() so
> far.
>
> Stop the running Thread at all - the application if you want. the queue will
> be deleted because of the declaration of it, thus the message inside it will
> be orphaned, thus, from my understanding it will be sent to the
> alternate-exchange, which does not happen.

The queue be deleted either when the session that declared it closes 
(due to the auto-delete and exclusive combination) or when the 
MessageConsumer is closed (due to the delete:receiver).

> Is there anything that I am missing or may be this is a known-issue?

Has the queue actually been deleted? If you run qpid-stat -q for 
example, does it show up?

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


Re: Red Hat MRG alt-exchange

Posted by eugene <eu...@gmail.com>.
Thank You Gordon so much!

Still another question from me, the use-case where we wanted to use the DLQ
aka alternate-exchange is for re-submitting purposes. I have read inside the
MRG doc that rejected and/or orphaned messages must be redirected to the
alternate-exchange in case one exists.

I have tried a simple scenario where I have something like this:

1. Create a queue and one fanout exchange - bind them.
2. Create a queue like this: "myQueue; {create:receiver, delete:receiver,
assert:always, node:{x-declare:{auto-delete:true, exclusive: true,
alt-exchange: FANOUT_EXCHANGE}}}" //alternate-exchange does not work either
3. Send the message to myQueue, there I have a Listener configured, as soon
as I hit the onMessage, wait forever (while(true){} for example) without
acknowledging the message, thus the message is still inside myQueue. 

Check the queue size with qpid-tool, show <ID> : myQueue has one message
which I expect to happen, because I did not do message. acknowledge() so
far. 

Stop the running Thread at all - the application if you want. the queue will
be deleted because of the declaration of it, thus the message inside it will
be orphaned, thus, from my understanding it will be sent to the
alternate-exchange, which does not happen.

Is there anything that I am missing or may be this is a known-issue?

Thank you for your time,
Eugene.

--
View this message in context: http://apache-qpid-developers.2158895.n2.nabble.com/Red-Hat-MRG-alt-exchange-tp7368166p7371373.html
Sent from the Apache Qpid developers mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


Re: Red Hat MRG alt-exchange

Posted by Gordon Sim <gs...@redhat.com>.
On 03/13/2012 11:33 AM, eugene wrote:
> Hello,
>
> So I am pretty much a newbie here with Qpid.
> I have a simple question if I may, how do I use the alt-exchange in java
> with AMQP/QPid?
>
> Suppose I want to send the message to a non-existent queue (but I am
> completely unaware of that), can I use the alt-exchange to "catch" all those
> messages that actually have nowhere to go?

Unfortunately not. To send 'to a queue' you actually send to the 
'default exchange' (an AMQP 0-10 term). The specification doesn't rule 
out having an alternate exchange defined for the default exchange but it 
doesn't state that it should and so at present the c++ broker at least 
does not do so. That should probably be changed however.

You could define your own exchange to which messages would be sent, bind 
in queues as appropriate and have an alternate exchange set for your 
exchange. That way any message sent to that exchange that did not match 
any queue would be re-routed through the alternate exchange where you 
could arrange for it to deliver the message to a dead letter queue or 
queues.

> Something like that :
>
> I have not created anything yet on the MRG side.
>
> Queue myQueue = session.createQueue("myQueue; {create:never, delete:never,
> assert: always, node:{type:queue, x-declare:{alt-exchange: DLQ_QUEUE}} }");

This does something different. This creates a queue with the alternate 
exchange as defined. If the queue is deleted while still holding 
messages those messages will be routed to that alternate exchange. It 
won't do anything for messages that fail to reach the queue in the first 
place however.

> Then send a simple message.
>
> Of course I have tried that, but all I get is :
>
> "The name 'myQueue' supplied in the address doesn't resolve to an exchange
> or a queue"
>
> Can someone explain me then the purpose of alt-exchange?

It is largely similar in purpose to dead letter queues - i.e. a way to 
handle delivery failures or orphaned messages - just not quite as simple 
to explain and configure.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org