On 20 October 2011 16:36, Rajith Attapattu <[email protected]> wrote: > On Thu, Oct 20, 2011 at 6:05 AM, Rob Godfrey <[email protected]> wrote: >> Sorry for being a little late responding to this thread... >> >> Stepping back for a second I think it's probably worth laying out how we >> think this should work, and if we can come to agreement about that then we >> can aim to have a complete solution in place for our next release (not this >> one). >> >> My view (and having discussed with Rafi, I think he is on broadly the same >> page) is: >> >> 1) The Destination object should not contain any protocol specific >> information >> 2) The Destination object should not contain any information about the >> syntax used to generate it >> 3) Resolution information (based on interacting with the broker) should be >> determined by, and stored in the Session/Connection (and is therefore >> potentially protocol specific) >> >> In practice this would mean creating factory classes to create destination >> objects. I would expect our destination object to be modelled after the >> properties defined in the addressing syntax. Each existing syntax would >> need a parser/factory which would parse strings of the given syntax and >> create a Destination object with the appropriate properties. For BURL style >> addresses this would obviously be slightly more work as there is some >> concept translation going on. note that with this approach it will be >> entirely possible (though not necessarily very desirable) to use both >> syntaxes with both protocols. >> >> I also strongly favour making the destination objects themselves immutable. >> >> One of the major issues of debate has been how the destination objects >> defined as are instantiated as concrete implementations of the JMS >> Destination hierarchy. What I would suggest is the following: >> >> 1) The implementations of classes implementing Topic/Queue are simple >> derived classes from our base Destination class with only implementations of >> extra methods such as getTopicName() and getQueueName() respectively (with >> both these simply being delegations to getName() on the base class). >> 2) The factories can be told explicitly to create a Topic or a Queue from an >> address string (thus passing a string into the createQueue(..) method will >> always result in a Queue object being returned). >> 3) For the ADDR syntax addresses, if the string includes an explicit node >> type, then this is used to determine which sort of instance to create. (For >> BURL syntax the existing conventions it uses should be followed) >> 4) When generating destination objects from reply-to fields in incoming >> messages, the logic is necessarily protocol specific. The 0-8/9 style >> carries a full address string, and the normal factory can be used; for 0-10 >> we can use similar techniques to those that we must currently be using (i.e. >> resolution may be attempted prior to calling the factory). >> 5) For all JMS defined methods which take either a queue or topic argument, >> we should ensure that we also have a method defined in our implementations >> which takes the more generic destination object (obviously calls to these >> methods may fail if it happens that the node on the broker is not suitable >> for the requested operation). >> >> At the end of this we should have a clean implementation where protocol >> specific features are solely in connection/Session related classes (i.e. in >> the protocol specific parts of the implementation), and address syntax parts >> are soley in the parsers for those syntaxes. >> >> What are people's thoughts/questions? > > I agree with most of your thoughts. > I strongly agree that Destinations should be immutable (it was > certainly a goal in my effort to refactor). > I fully support points # 1-5 about the JMS Destination hierarchy which > is pretty much what I envisioned too. > > (Robbie raised some concerns about address resolution and the need to > have destinations created having either Queue or Topic interfaces > instead of just the generic Destination interface - has the above 5 > points sufficiently answered Robbie's concerns ?) >
There will still be some room for things to only implement Destination, but the ones that are specified with a type will be able implement Queue or Topic, which sufficiently pleases me as it allows us to fullfill the entire JMS API from JNDI generated destinations rather than just 1/3rd of it. > The only thing I wasn't sure about was (and the major debating point > so far at least for me) that not having protocol specific destination > classes, and instead moving that to Session/Connection classes. The > existing system which follows this model is an epic failure, so I > thought I'd experiment with a different idea and see. I felt there was > more flexibility in that model. > > But clearly I'm in the minority and most people think it's a bad idea > and I'm happy to go with the majority decision. > I'm happy to work on a solution that everybody feels is appropriate > and desirable. > > Rajith > >> Cheers, >> Rob >> On 17 October 2011 23:09, Robbie Gemmell <[email protected]> wrote: >> >>> On 17 October 2011 20:58, Rajith Attapattu <[email protected]> wrote: >>> > On Mon, Oct 17, 2011 at 12:39 PM, Robbie Gemmell >>> > <[email protected]> wrote: >>> >> On 17 October 2011 16:01, Rajith Attapattu <[email protected]> wrote: >>> >>> On Mon, Oct 17, 2011 at 5:54 AM, Robbie Gemmell >>> >>> <[email protected]> wrote: >>> >>>> Why do we resolve Address node types? This question arose during >>> >>>> review of proposed updates to the Address syntax implementation for >>> >>>> the Java client, but ultimately looks to be a wider question for all >>> >>>> the clients and so I am asking it here outwith that review. >>> >>>> >>> >>>> The documentation for the Address syntax on the Qpid and MRG websites >>> >>>> states that nodes can be specified as Queues or Topics, but that nodes >>> >>>> are Queues by default. >>> >>> >>> >>> Throughout my reply the word 'node' means Queues & Exchanges in 0-10 >>> speak. >>> >>> The default applies when the node referred to by the address name does >>> >>> not exist and the client has received instructions to create it. >>> >>> (The documentation does have a lot of gaps and that's a all together a >>> >>> separate discussion :) ..) >>> >>> >>> >> >>> >> The client should give the same default behaviour regardless of what >>> >> another user has done, so I dont think the above is correct behaviour. >>> >> Whether an exchange exists with that name should be irrelevant if >>> >> queues are the default. It also certainly isnt what the documentation >>> >> says: >>> > >>> > As I said I don't think the documentation does a good job of >>> > explaining the concepts clearly. >>> > >>> >>> The documentation seems perfectly reasonable. >>> >>> >> >>> >> "The node-type is one of: >>> >> >>> >> topic: in the AMQP 0-10 mapping, a topic node defaults to the >>> >> topic exchange, x-declare may be used to specify other exchange types >>> >> >>> >> queue: this is the default node-type" >>> > >>> > Robbie the address syntax was posted a while ago and all the clients >>> > implement it in the same way. >>> > AFAIK the C++ client (and the python if I am not mistaken) behaves >>> > exactly the same way. >>> > >>> > Your argument has winder consequences as it isn't limited to just the >>> > Java client. >>> > So I'd let Gordon & Rafi to also weigh in on their opinions on this. >>> > >>> >>> I am aware the syntax was posted a while ago. As it is documented it >>> does not describe the need for doing what I now see the implementation >>> does in automagically picking node types if you dont specify one, and >>> I would have objected at the time if I thought it did. As we said in >>> the original email, its entirely possible we could do different thing >>> for all the clients in this regard, although I dont personally believe >>> that to be sensible. >>> >>> >> >>> >> >>> >>>> It appears that the clients (at least the Java >>> >>>> one) instead ignore that statement and decide that if the user hasn't >>> >>>> specified a type then it should decide one for them, querying the >>> >>>> broker and figuring out whether there is a Queue or Exchange with the >>> >>>> node name and then picking Queue or Topic as the node type depending >>> >>>> on which exists (or throwing an exception if both do because the type >>> >>>> is ambiguous). >>> >>> >>> >>> In general applications should not be creating nodes (Queues & >>> >>> exchanges in 0-10 speak) in the broker. >>> >> >>> >> That is odd, since the API supports it quite explicitly, more so now >>> >> than it ever did before. >>> > >>> > When you say API are you referring to the JMS API or the addressing >>> syntax? >>> >>> Addressing syntax. >>> >>> > Either way in my experience Queues are usually administered separately >>> > and the applications merely use them. >>> > Also I didn't say that we prohibit the explicit creation either. Just >>> > that in general applications tend to use already created Queues (other >>> > temp queues ..etc). >>> > >>> >>> I would direct you to the user list for evidence of people doing >>> otherwise, and I can think of a wide number of off-list users who just >>> love to use such functionality; its farily widely used. >>> >>> >> Seems like people can, will, and heavily do >>> >> use that feature, so we should probably take it into consideration >>> >> more fully. >>> > >>> > Again the address syntax does nto prohibit explicit creation, just >>> > that it's not the default. >>> > The JMS client with the BURL had this very undesirable behaviour of >>> > creating queues and exchanges (and only through consumers) which did >>> > cause issues with several application situations. >>> > >>> >>> Noone said it is the default anymore but, as you note, it was for many >>> years (entrenched user base = true) and is still entirely possible to >>> do (its easier now), so its impact needs to be considered. >>> >>> >>> Therefore when an address is given, the client will attempt to verify >>> >>> the existence of the node referred by the address name. >>> >>> It also important to figure out what type of a node if the type is not >>> >>> explicitly specified. >>> >> >>> >> The documentation says that the default is Queue, so why should we >>> >> bother to figure anything out? It seems entirely unreasonable that the >>> >> client can pick from different values (well, all the values, since >>> >> there are only 2 choices, Queue and Topic) if a node type is not >>> >> specified. Depending on what someone else might have done to the >>> >> broker, you could get a different answer each time, i.e it basically >>> >> doesnt have a default. >>> > >>> > I'd let Rafi and Gordon comment on this. >>> > >>> >>> This makes it easy for applications to specify addresses, as in most >>> >>> cases and address is simply a "name". >>> >>> >>> >>> The "type" is important as it helps to figure out if it's a Queue or a >>> Topic. >>> >>> As the semantics differ based on the type. >>> >> >>> >> That the type is important isnt in question, that we allow the client >>> >> to be in a position where we pick this for them (perhaps differently >>> >> than we did a previous time) is. We should pick a fixed default (as we >>> >> have documented), or make it a mandatory property and throw an >>> >> exception if it isnt present. >>> > >>> > Making the type mandatory maybe a reasonable compromise. >>> > Again I'd let others weigh in on this as well. >>> > >>> >>> This would solve both the design issues (i.e Queue and Topic >>> destinations not implementing the appropriate JMS interfaces) and the >>> usability issues (clients automagically picking different node types >>> based on / impacted by other users actions), and so would seem a >>> logicial choice. Although, it ultimately doesnt seem much different to >>> respecting the syntax documentation and saying that the node is a >>> queue unless noted to be a topic (eg by specifying the node type >>> explicitly in the address string, or implicitly by using the >>> session.createTopic() JMS method). >>> >>> >>> >>> >>>> I would like to understand why this auto-resolving behaviour was >>> >>>> introduced. I believe that this needs to be removed from the Java >>> >>>> client entirely so that we can properly implement the Destination >>> >>>> hierarchy and provide an implementation to our users which actually >>> >>>> lets them use all of the JMS API easily. I would also argue it should >>> >>>> be removed from any of the other clients that are doing it due to the >>> >>>> behavioural ambiguities it seems to introduce. >>> >>>> >>> >>>> >>> >>>> >>> >>>> >>> >>>> For those wanting more of a read, here is some further elaboration to >>> >>>> the above (since the email got a lot longer than expected :D) >>> >>> >>> >>> Appreciate you taking the time to elaborate on your concerns. :) >>> >>> >>> >>>> In reviewing the proposed changes, Alex and I noted that it opened >>> >>>> possibility for creating Destination objects that don't implement >>> >>>> either the Topic or Queue interface, and instead use isTopic() and >>> >>>> isQueue() methods to check the answer against delegates which do >>> >>>> implement them. Rajith responded to our query on this that it was >>> >>>> because when creating an Address syntax based Destination from a >>> >>>> String, you cant tell what type of node it is until it is later >>> >>>> resolved against the broker. >>> >>> >>> >>> I think this was more of an issue with my implementation rather than a >>> >>> design issue with the addressing syntax in general. >>> >>> >>> >>> If we attempt to resolve the destination early, rather than when it's >>> >>> used to create a consumer or a producer we can solve this issue. >>> >> >>> >> Not really, if you dont have a Connection when the destination is made >>> >> (eg JNDI lookup) then you certainly cant resolve anything. >>> >> >>> >>> Lets look at the two cases where destinations are created/retrieved. >>> >>> >>> >>> 1. When creating queues/topics directly using the session. >>> >>> We need to resolve the address and verify the name supplied before the >>> >>> method returns. >>> >>> Ex ssn.createQueue(String name) & ssn.createTopic(String name) >>> >>> >>> >>> Currently my patch doesn't do that and if that is implemented then we >>> >>> guarantee that the Object returned is indeed representing a 'Queue' or >>> >>> a 'Topic' on the broker (not just implementing the jms interface). >>> >>> >>> >> >>> >> This doesnt seem necessary or entirely reasonable given what the >>> >> createQueue method says it does (makes a queue representation object, >>> >> therefore no reoslution necessary as it isnt making a queue on the >>> >> broker and its definitely not a Topic) >>> >> >>> >>> 2. Specifying addresses in the JNDI file. >>> >>> As you correctly pointed out this becomes an issue when we create >>> >>> destinations from the jndi file. >>> >>> As in this case when an application performs Destination dest = >>> >>> (Destination)ctx.lookup("my-dest"), we are unable to return a >>> >>> javax.jms.Topic or javax.jms.Queue implementation bcos we don't know >>> >>> the type unless explicitly specified. >>> >>> >>> >>> *** Perhaps this maybe the very reason why in JMS 1.1 they introduced >>> >>> the generic Destination interface.*** >>> >>> >>> >>> Off the top of my head, I see two solutions to this. >>> >>> >>> >>> (a) . The users needs to explicitly specify the "type" when they >>> >>> specify addresses in the jndi file. And we use that to return a >>> >>> destination object that works specifically with the Queue or Topic >>> >>> interface. >>> >> >>> >> This doesnt seem too unreasonable, however having a default node type >>> >> that is actually respected seems even more reasonable. Our docs >>> >> explicitly say that if type is not provided then node type is queue. >>> >> This seems like a sensible approach, so perhaps we should actually try >>> >> doing what the documentation says :) >>> >> >>> >>> (b.1) Or not use the JMS 1.0 interfaces (which requires the >>> >>> specialized Queue or Topic interfaces) if a type is not specified. >>> >>> Obviously if they attempt to use a destination impl which >>> >>> simply implements the generic interface with the JMS 1.0 interfaces >>> >>> they would get a class cast exception. >>> >>> Please note The JMS 1.1 interfaces will work correctly with >>> >>> the generic Destination interface. >>> >> >>> >> The Topic and Queue related parts of JMS 1.0 are still part of JMS 1.1. >>> >> >>> >> Dropping of support for those interfaces is in no way a reasonable >>> >> solution to what is effectively an implementation issue with the >>> >> Address syntax. >>> >> >>> >>> (b.2) Another solution would be something akin to the >>> >>> AMQAnyDestination (not a big fan of this). That is the >>> >>> AddressBasedDestination implements both the Topic & Queue interfaces >>> >>> allowing it to be passed into the JMS 1.0 interfaces and inside those >>> >>> method implementations we perform a check to see if they are indeed >>> >>> Queues or Topics by resolving an returning the correct >>> >>> AddressBasedTopic or AddressBasedQueue destination for the methods to >>> >>> work with. >>> >> >>> >> That is indeed not a good aproach. >>> >> >>> >>> There maybe more elegant solutions to this problem. I need to think a >>> >>> bit more here. But I'm sure we can come up with something better. >>> >> >>> >> >>> >> The best solution would appear to be stopping unecessarily querying >>> >> the broker to resolve destinations and always respect the user setting >>> >> (or lack thereof) for a node type. >>> > >>> > The querying and verifying the address is fundamental in the address >>> syntax. >>> > IMO, wthout that it wouldn't really work the way it was designed for. >>> > >>> >>> Querying to verify the address once it is known seems fine, but >>> querying to decide what the address is in the first place (by >>> automagically picking a node type if it wasnt specified) is another >>> matter entirely. >>> >>> >>>> This is troubling for various reasons, e.g. that it makes the code >>> >>>> uglier, >>> >>> >>> >>> This can be worked out. As I mentioned the proposed changes is the >>> >>> first step in a series of patches. >>> >>> I think we can do better with the code to make it less ugly and I'm >>> >>> experimenting to get there. >>> >>> >>> >>>> and then the slightly more pressing issue that it means it >>> >>>> wont be possible for users to use the majority of the JMS API with the >>> >>>> destinations they create from JNDI since many of the methods require >>> >>>> destinations which implement the Queue or Topic interface and not just >>> >>>> the super Destination interface. >>> >>> >>> >>> Again I'd like to draw your attention to the distinction between JMS >>> >>> 1.0 and JMS 1.1 interfaces. >>> >>> The JMS 1.1 interfaces will work very well with the generic >>> >>> javax.jms.Destinaitons. >>> >>> >>> >>> And by using the solution I outlined above we could ensure we provide >>> >>> the specialized interfaces required by the 'older' JMS 1.0 interfaces. >>> >>> >>> >>>> This behaviour seems highly undesirable to me, as in addition to the >>> >>>> design related issues discussed above that it provokes that sparked >>> >>>> the question, it simply seems unreasonable that we should be making >>> >>>> those decisions for the user (especially since we have documented that >>> >>>> we don't). This auto-resolution system also seems to open the >>> >>>> possibility of one users configuration unwittingly altering the >>> >>>> behaviour of another users application e.g. by creating an Exchange >>> >>>> with a given name later on, causing another users code to switch >>> >>>> without their consent from using Queues which might have been >>> >>>> auto-delete to using Topics, or by creating an Exchange where a Queue >>> >>>> with the same name already exists and causing another users client to >>> >>>> throw exceptions it didn't previously because the type can no longer >>> >>>> be auto-resolved. It also isn't clear how this is meant to interact >>> >>>> with the 'assert' functionality; surely we will sometimes be able to >>> >>>> pass an assertion for a decision we made, even if that isn't what the >>> >>>> user code used to be asserting against? >>> >>>> >>> >>>> Furthermore, it has been pointed out on the user list that this type >>> >>>> of querying can be a point of performance degradation, forcing (it >>> >>>> doesn't seem to be configurable?) the client to somewhat needlessly >>> >>>> round-trip to the broker in many cases it doesn't seem necessary. >>> >>>> >>> >>>> --------------------------------------------------------------------- >>> >>>> Apache Qpid - AMQP Messaging Implementation >>> >>>> Project: http://qpid.apache.org >>> >>>> Use/Interact: mailto:[email protected] >>> >>>> >>> >>>> >>> >>> >>> >>> --------------------------------------------------------------------- >>> >>> Apache Qpid - AMQP Messaging Implementation >>> >>> Project: http://qpid.apache.org >>> >>> Use/Interact: mailto:[email protected] >>> >>> >>> >>> >>> >> >>> >> --------------------------------------------------------------------- >>> >> Apache Qpid - AMQP Messaging Implementation >>> >> Project: http://qpid.apache.org >>> >> Use/Interact: mailto:[email protected] >>> >> >>> >> >>> > >>> > --------------------------------------------------------------------- >>> > Apache Qpid - AMQP Messaging Implementation >>> > Project: http://qpid.apache.org >>> > Use/Interact: mailto:[email protected] >>> > >>> > >>> >>> --------------------------------------------------------------------- >>> Apache Qpid - AMQP Messaging Implementation >>> Project: http://qpid.apache.org >>> Use/Interact: mailto:[email protected] >>> >>> >> > > --------------------------------------------------------------------- > Apache Qpid - AMQP Messaging Implementation > Project: http://qpid.apache.org > Use/Interact: mailto:[email protected] > > --------------------------------------------------------------------- Apache Qpid - AMQP Messaging Implementation Project: http://qpid.apache.org Use/Interact: mailto:[email protected]
