Thanks Robbie, that was a very helpful collection of useful insights - I don't think I would have found or understood these points just by reading around the web and docs!!

FYI, my initial attempt at contributing to this list from my work email account was doomed to failure as our work filters are blocking the list subscription responses to which we need to reply in order to join in the first place - hence my using my home account as the fallback.

There are definitely some gems in those answers that help me better understand what's going on under the covers in the Qpid JMS implementation so thank you very much for taking the time to answer those points. By the way, your point in your answers about moving the getTopicName() call somewhat worked. When I moved it down a couple of lines as you suggested for the first test specifying destination.topicExchange, the call no longer returned 'null', but instead returned what seemed to be the binding key for that scenario - i.e. '#'. In that way, it matches the topic.topicExchange test, in which the same call returned "news-service2" which in that case was the binding key there also.

So it looks like the next tranche of effort will involve looking at the possibilities of using JMS/Qpid clients/brokers in combination with ActiveMQ clients/brokers. I guess my main worry/concern before starting this exercise is just how feasible this endeavour will be.
From what I understand, ActiveMQ is currently only compatibile with AMQP
1.0, correct?

If anyone has a tried this, or can confirm:
will it be possible to have a JMS client using an ActiveMQ broker on one machine (or maybe a producer/consumer pair), ultimately sending a message which then routes to a Qpid broker and associated local JMS consumer on a second machine (preserving all standard and application-specific JMS message headers/properties). Has this been done and are there further tricks, considerations and caveats here? Maybe the ActiveMQ JMS consumer process on the first machine makes the routing decision and then places the message via a producer instance for the Qpid broker on the 2nd machine? Or maybe it would be possible to administratively configure the 2 brokers to be linked in a manner similar to what I've been reading about Federations of brokers??

Finally, does anyone know if it is possible to integrate a Qpid broker into an ActiveMQ 'cluster' configuration?? From the very brief reading I've done, it appears the Qpid cluster implementation may be somewhat different in its concept...

Thanks once again for all the help as I get to grips with this new subject matter.

Mark


-----Original Message----- From: Robbie Gemmell
Sent: Wednesday, February 12, 2014 11:09 AM
To: [email protected]
Subject: Re: New User JMS API Questions

Hi Mark,

Is your work email address registered on the list? if not the message may
be awaiting moderation.

Part of the issue is that you are definitely tripping up on a mixture of
JNDI configuration, some of which is of the newer 'Address' syntax variety
and some which is of the older 'Binding URL' format supported by the JMS
client.
On top of that, you may be getting confused by the use of 'topic' as the
type of an AMQP 0-x exchange, and the name of a node type in the 'Address'
syntax supported by the various Qpid clients, and finally its use in JMS
and differing behaviour of the client depending on the syntax in use.

On the terminology side:

The 'topic' type of exchanges in AMQP 0-X support pattern matching for
routing, whereas the other exchange types don't. The 'Address' syntax uses
the 'topic' to describe a node that can provide pub-sub semantics, and in
the case of AMQP 0-10 that is taken to mean an exchange ~(of any type) with
the name of the topic. The JMS client uses 'topic' in essentially the same
way when using the 'Address' syntax, but with the 'Binding URL' syntax the
topic name is used as the routing key when publishing the message to a
particular exchange (whose name may be unrelated to the topic name, and
usually is) or binding queues to the exchange to recieve messages.

On the JMS client behaviour side:

JNDI properties of the form "destination.<lookupname> = <value>" are
treated as 'Address' strings by default, but may be treated as BindingURLs
if desired (see at the bottom). "queue.<lookupname> = <value>" and
"topic.<lookupname> = <value>" values in the JNDI file are treated as a
shorthand form of BindingURL that results in Queue usage with bindings and
publications to the amq.direct exchange using the queue name as the key,
and Topic usage with bindings and publications to the amq.topic exchange
using the topic name as the key.

In your first test, by specifying "destination.topicExchange =
news-service2" you thus got an 'Address' based Destination. The client
'resolves' the Address string against the broker when you create your
producer/consumer to determine if the address is actually for a queue or a
topic (i.e an exchange) node. Prior to that it is returning null from the
'getTopicName' method, whereas looking at the code I expect it would return
you the exchange name if you move that line down bit.

On your second test, by using "topic.topicExchange = news-service2" you
ended up with a BindingURL based Destination, which in this case told the
client to use the "amq.topic" exchange and send the messages with a routing
key of "news-service2", and to bind a temporary queue to amq.topic with the
binding key "new-service2".

For your third test, using "queue.topicExchange = some_queue_name" got you
a BindingURL based Destination, which told the client to use the
"amq.direct" exchange and send the messages with a routing key of
"some_queue_name". The consumer creation had the side effect of creating
the queue and binding it ot the amq.direct exchange, because you were using
a BindingURL based destination an this is the historic consumer behaviour
the client had with that syntax. For the Address syntax, it doesnt do that
by default but you can make it do something similar using the options of
the Address string.

Some other info:

You can see more details of the Address syntax at the following location,
though it is more tailored to the C++ etc APIs and the JMS client doesn't
necessarily support all of the options in the same way:
http://qpid.apache.org/releases/qpid-0.24/programming/book/section-addresses.html

Some details of the expanded BindingURL format usable in the "destination."
JNDI entries is at:
https://cwiki.apache.org/confluence/display/qpid/BindingURLFormat

You can change the clients default syntax at a client level by setting the
system property qpid.dest_syntax to the value BURL (or ADDR), or you can
prefix the <value> part of the JNDI property to override the default, using
BURL: to indicate a BindingURL, or ADDR: to indicate an Address.

Robbie

On 12 February 2014 03:14, Mark Barker wrote:

Apologies in advance if this shows up twice, but I seem to have had
problems sending from my work account...

---

Hello.

I have been playing around with the Hello.java example that came with
qpid-java-client-0.24.tar.gz.
I have installed the qpidd package (the broker) on a Ubuntu 12.04 LTS
platform along with the qpid-tools package
(from the Ubuntu Software Centre).

I am looking to try and integrate the Qpid broker with JMS-based clients.
I am brand new to all of the concepts and my
understanding is possibly being confused by the differences in terminology
between JMS and Qpid elements.
I would greatly appreciate if you can indulge a few questions arising from
my initial foray...

By modifying the code to use the pub/sub API, I have arrived at this
source (Hello2.java):

--------
package org.apache.qpid.example;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import java.util.Properties;

public class Hello2
{
   public Hello2()
   {
  }
   public static void main(String[] args)
   {
       Hello2 hello2 = new Hello2();
       hello2.runTest();
   }
   private void runTest()
   {
       try {
           Properties properties = new Properties();
           properties.load(this.getClass().getResourceAsStream("hello2.
properties"));
           Context context = new InitialContext(properties);
           TopicConnectionFactory topicConnectionFactory =
(TopicConnectionFactory) context.lookup("qpidConnectionfactory");
           TopicConnection topicConnection = topicConnectionFactory.
createTopicConnection();
           topicConnection.start();
TopicSession topicSession = topicConnection.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
           Topic topic = (Topic) context.lookup("topicExchange");
           System.out.println(topic.getTopicName());

           TopicPublisher topicPublisher = topicSession.createPublisher(
topic);
TopicSubscriber topicSubscriber = topicSession.createSubscriber(
topic);
           TextMessage message = topicSession.createTextMessage("Hello
world!");
           topicPublisher.publish(message);
           message = (TextMessage)topicSubscriber.receive();
           System.out.println(message.getText());
           topicConnection.close();
           context.close();
       }
       catch (Exception exp)
       {
           exp.printStackTrace();
       }
   }
}
--------

Now, hello2.properties looks like this:
--------
java.naming.factory.initial = org.apache.qpid.jndi.
PropertiesFileInitialContextFactory
# register some connection factories
# connectionfactory.[jndiname] = [ConnectionURL]
connectionfactory.qpidConnectionfactory = amqp://guest:guest@clientid/?
brokerlist='tcp://localhost:5672'
# Register an AMQP destination in JNDI
# destination.[jniName] = [Address Format]
destination.topicExchange = news-service2
#topic.topicExchange = news-service2
--------

Before running the program, I adminstratively create the topic exchange
via qpid-config:
% qpid-config add exchange topic news-service2

Now... "AS-IS", the above code/properties combination "works" - i.e. when
I compile and run Hello2.jar, I see this output:
--------
null
Hello world!
--------

If I use the command-line "qpid-stat -e", I do indeed see msgIn and msgOut
counters incrementing for the "news-service2"
topic exchange.
What I don't understand (my first question) here is why the
"topic.getTopicName()" call is returning "null" in this instance?

When I substitute "topic.topicExchange" for "destination.topicExchange" in
the hello2.properties file, I get this output:
--------
news-service2
Hello world!
--------

Here, "topic.getTopicName()" actually returns the expected string
"news-service2".
However, in this case "qpid-stat-e" shows that the corresponding topic
exchange "news-service2" has NOT changed its
msgIn/msgOut counters, BUT the counts for amq.topic have changed instead.
My second question therefore is why have these
messages ended up in amq.topic?

A final question (more of a related query). If I use the default
(original) example code Hello.java, but in hello.properties
substitute "destination.topicExchange = amq.topic" for
"queue.topicExchange = some_queue_name", I note that even if
"some_queue_name" did not exist in the broker prior to running Hello, then
it is created. This behaviour doesn't seem to work
for "topic.topicExchange" so I was wondering why the discrepancy.

Thanks for indulging these newbie questions!

Mark.

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]




---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to