Robert Godfrey wrote:
[.. snip ..]

I tend to dislike the casting approach since if you need to make more than
one or two calls it becomes quite cumbersome and people then inevitably just
declare their variables to be of the non JMS type and then it's unclear
which calls are pure JMS and which aren't.

I also think it's a bit of a hack to be required to cast as part of an API.
It's difficult to tell whether you're casting into an approved part of the
API or whether you're casting to some random implementation specific
interface that the object just happens to implement.

That is why I advocate an *interface* rather than casting into
implementation classes.

An interface if restricted to only permit features not accessible through vanilla JMS would certainly help, but I still think casting as part of the API unacceptably blurs the boundaries of the API. There is no way to tell what types you're allowed to cast and to which interfaces you're allowed to cast.

Using custom headers hides dependencies and makes things compile (or
link) even when they should fail.
This is only true if you hardcode your header values rather than using some
API to set them. Using constants will cause a compile time failure, and
using a decorator will cause both compile and link failures.

It will cause a compile time failure but not a run time failure.  You
can have the jar in your classpath without it being the JMS client
that you are actually using.

Yes, I was considering that a feature. It doesn't matter whether you have an 0-8, 0-9, 0-10, or 1-0 JMS message underneath, you still have access to the same broker extension. I would probably add an assertion based on the destination, broker vendor/version, etc to verify that the broker and recipient will understand what is being sent.

I think there are different sorts of AMQP specific behavior that we need to
think about here. For example I would make a distinction between AMQP or
Qpid specific broker features, and AMQP or Qpid specific client features. I
think accessing AMQP or Qpid specific broker features through a well defined
set of message headers is probably a reasonable way to go, and there are a
variety of ways to set these headers that provide differing levels of
compile and/or runtime protection to the application. But really for
accessing broker features there is no need to tie anything to the specific
JMS implementation in question, e.g.:

Message msg = ..;
QpidMessage qmsg = new QpidMessage(msg);
qmsg.setFoo(); // equivalent to msg.setStringProperty(QpidHeaders.FOO,
"bar") which is in turn equivalent to
msg.setStringProperty("org.apache.qpid.foo", "bar")

I think the JMS Properties should be used as intended - that is as a
way of adding to the end-to-end properties of the message (payload)
being sent.  If the extension is on the broker, and is triggered by
such a property then setting the property is the appropriate
mechanism.  However if the AMQP extension is something that should be
interpreted by the client then I do not believe that we should be
using such an ugly hack.

I wasn't suggesting using headers for controlling client local behavior. I think actually we should take appropriate advantage of the destination abstraction for that.

I understand that you have a pathalogical hatred of casts.  The java
syntax is certainly less than ideal.  However where we are depending
on AMQP specific behaviour it should be called out.

It's not casts I dislike. It's casting as part of an API that I dislike since it makes the API unnecessarily blurry. It's also quite trivial to avoid assuming you don't have a pathological hatred of static methods. ;)

My feeling is that given where we are taking the 1-0 spec there is
likely to be *much* less of this required.

The only examples I can think of off-hand on messages might be audit
trails or signatures...

Yes, I think most extensions are actually likely to be more Qpid specific than AMQP specific as well.

For AMQP or Qpid specific behavior related to the client implementation,
e.g. acking behavior, prefetch behavior, etc, I think this is something of a
different story, and I would probably take these features on a case by case
basis. I suspect it's probably not an either/or situation and we'll want
both configuration for people deploying pre-existing vanilla JMS apps, as
well as API for people writing stuff from scratch or "porting" to qpid.


My view is that you should try to avoid to using *any* AMQP or Qpid
specific extensions.  Where they are to be relied upon I (as an
architect or manager of a development team) want those dependencies to
be called out *very* explicitly.  The use of magic headers etc. is the
sort of thing that makes porting between message providers *very* hard
(been there done that).

I wasn't suggesting using magic headers for this sort of thing. I think we can do most of what we need to through the destination abstraction.

Hopefully most AMQP/QPID extensions can be isolated in cofiguration
rather than code...

I think the destination abstraction is a reasonably useful way to do this for most things. It gives us one mechanism that is mostly used via configuration but can also be used through code as well via createQueue(...) and friends.

--Rafael


---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:dev-subscr...@qpid.apache.org

Reply via email to