Seems like a good approach to me. Robbie
On 20 October 2011 11:05, 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? > > 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]
