David, This looks reasonable to my JMS-ignorant eyes.
Is the idea that the JMS URL would be embedded in WSDL as an address so a generated stub could use the address without knowing it was a JMS transport? -- Tom Jordahl Macromedia Server Development -----Original Message----- From: David Chappell [mailto:chappell@;sonicsoftware.com] Sent: Friday, November 01, 2002 3:14 PM To: [EMAIL PROTECTED] Subject: Re: JMS URL Syntax proposal Sorry, that last attachment was a little messed up. Try this one instead. Dave > David Chappell wrote: > > The attached html doc contains a proposal for a URL syntax to be used > by > the Call object to pass JMS'isms down to the transport layer. Among > other things, this removes the necessity to call setTransport() in the > client code in order to enable the JMS transport. The details of the > why and the how are included in the proposal. Feel free to critique, > or > pass it along to your own resident JMS experts to have at it. > Dave > > -- > Sonic Software - Backbone of the Extended Enterprise > -- > David Chappell <[EMAIL PROTECTED]> Office: (781)999-7099 > Mobile: (617)510-6566 > Vice President and Chief Technology Evangelist, Sonic Software > co-author,"Java Web Services", (O'Reilly 2002) > "The Java Message Service", (O'Reilly 2000) > "Professional ebXML Foundations", (Wrox 2001) > -- > > --------------------------------------------------------------- > > JMS URL Syntax For the Apache Axis Project > > > > <author: Dave Chappell [EMAIL PROTECTED]> > > <author: Ray Chun [EMAIL PROTECTED]> > > <author: Jaime Meritt [EMAIL PROTECTED] > > > > > Summary > > This is a proposal to define a URL syntax for use by the JMS transport > layer in Axis. The JMS URL syntax will allow a vendor-neutral way of > specifying JMS specific details, like Topic and Queue destinations, > without having to code them specifically into the client application, > or pass them from a command line. > > > > Backgrounder > > When one uses the JMS transport layer, it is hidden underneath the > client API of Axis. Axis implements the JAX-RPC API. JAX-RPC (and > Axis) provides multiple models for constructing both static and > dynamic invocations of a service. There are 2 flavors of dynamic > invocation using the Call and Stub interface, and a static model using > a WSDL2Java stub generation. Both the Call and Stub interfaces allow > the use of application-specific properties that get passed down to the > handlers, including the transport handler. > > > > Currently the model in 1.0 Axis is to specify the JMS specific > properties from the command line, or in a properties file. The client > application then obtains these and places the JMS specific properties > into the Call object by calling the setProperty() method. The > properties are then passed on to the transport handler, where they are > extracted and used to perform the appropriate actions in JMS > nomenclature. Examples of JMS specific properties are location of a > ConnectionFactory object, the name of a JMS destination, the type of > destination (topic or queue), username and password, and message > delivery options such as persistence. > > > > Example: > > > > Service service = new Service(new XMLStringProvider(wsdd)); > > > > // create the JMS transport > > JMSTransport transport = new JMSTransport(connectorMap, cfMap); > > > > // create a new Call object > > Call call = (Call) service.createCall(); > > > > // populate the call object. In this case it's a method > > // invocation with a description of the parameter list and > > // the return type. > > call.setOperationName( new QName("urn:xmltoday-delayed-quotes", > > "getQuote") ); > > call.addParameter( "symbol", > > XMLType.XSD_STRING, > > ParameterMode.IN ); > > call.setReturnType( XMLType.XSD_FLOAT ); > > > > > > // set the transport object > > call.setTransport(transport); > > > > // set some properties. These will get passed down into the > > // handlers, including the transport handler. > > call.setUsername(username ); > > call.setPassword(password ); > > call.setProperty(JMSConstants.WAIT_FOR_RESPONSE, Boolean.FALSE); > > call.setProperty(JMSConstants.PRIORITY, new Integer(5)); > > call.setProperty(JMSConstants.DELIVERY_MODE, > > new Integer(javax.jms.DeliveryMode.PERSISTENT)); > > call.setProperty(JMSConstants.TIME_TO_LIVE, new Long(20000)); > > > > call.setProperty(JMSConstants.DESTINATION, destination); > > > > ... > > > > // invoke the call > > res = (Float) call.invoke(...); > > > > > > While the current model works well, the ease of plugging in the JMS > transport can be made much more tenable by being able to specify > everything in a URL encoding. The goal is to eliminate the need to do > anything special in the client application. > > > > URL Syntax > > Rather than inventing a rigid syntax, it is desirable to use a > URL-encoded query string in accordance with RFC-1738. The intent is > to specify a minimal syntax, allowing for the most flexibility for > different JMS providers. > > Proposed syntax: jms:<vendor-uri>:* > > The vendor-uri dictates how the remainder of the URL is encoded. If > the vendor-uri is omitted, then secondary lookup of the > 'connectionfactory' and 'destination' properties is performed using > JNDI. > > > > Examples > > Using Sonic: > > With a host and port: jms:<vendor-uri>://host:port/domain?etc... > > 1. jms:sonicmq://localhost:2506/queue?destination=SampleQ1 > > With a slightly modified syntax: jms:<vendor-uri>:<domain>:* > > 2. jms:sonicmq:queue://localhost:2506?destination=SampleQ1 > > 3. > jms:sonicmq:queue;brokerurl1=url1;brokerurl2=url2;destination=SampleQ1 > > > > Using JNDI: > > 1. jms:jndi-uri://queue/MyQCF/MyQ?jmspriority=5&... > > 2. jms:jndi-uri://ldap.somewhere.com/queue?initialcontextfactory=icf& > connectionfactory=MyCF&.. > > 3. jms::queue;connectionfactory=MyQCF;destination=MyQ;... > > > > Alternative syntax: jms://<vendor-uri>/any... > > Again, omitting a vendor-uri and thus specifying the URL with > "jms:///..." will by default use JNDI as the secondary lookup. > > > > Examples > > 1. jms://sonicmq/queue?brokerurl=localhost:2506&destination=SampleQ1&... > > 2. jms:///queue?connectionfactory=MyQCF&destination=MyQ&... > > 3. jms:///queue/MyQCF/MyQ?jmspriority=5... > > > > The connection factory and destination are string properties that may > map to a JNDI lookup name. If the JMS provider supports direct > instantiation of a CF class, or a named destination, then that is > allowable as well. As far as the client application is concerned, the > CF and destination are just string properties, and the underlying > implementation of the transport can decide whether or not to use JNDI. > > > > JMS Properties > > Properties that appear in the query string may be overridden by > explicitly setting the property via call.setProperty(..). For > instance, the username and password, though optional parameters in the > query string, will likely be specified using the call object's > setUsername() and setPassword() methods. > > > > In the short term, the scope of what can be set in the query-string is > limited to the perspective of a JMS sender. The following table > illustrates the possible settings in the query string. Depending on > the syntax chosen, some properties may be set implicitly in the URL > (for instance, the domain in 'jms:queue:jndi-uri...' is specified > without a property key). > > > > Property Name Example Value Comments > > InitialContextFactory "com.sun.jndi.fscontext.RefFSContextFactory"If the secondary > lookup is JNDI > "com.sun.jndi.ldap.LdapCtxFactory" > JNDIURL "file:///JNDIStore" "" > > "ldap://localhost:123" > ConnectionFactory "MyCF", May be JNDI lookup > "com.JMSVendor.TopicConnectionFactory" name or fully > qualified class > name > Host "localhost" May be required by > CF > Port "2506" "" > Destination "MyQueue" May be JNDI lookup > name or direct > destination name > DestinationType or "Topic" or "Queue" Indicates the type > Domain of connection > factory and > destination > ReplyToDestination "ReplyToQueue" May be JNDI lookup > name or direct > destination name > Username Required in JMS to > establish a > Connection object > Password Required in JMS to > establish a > Connection object > DeliveryMode "Persistent", "non-persistent" > TTL "10000" Time-to-live in > milliseconds. > Priority 0 - 9, in accordance with JMS spec Message priority > WAIT_FOR_RESPONSE "Yes" Can be used in > conjunction with > call.setTimeout()? > > > > In the not-too-distant future, we will have asynchronous callback > support and client notification in the client engine and the client > API. When this is enabled, we will need to be able to specify a > listener and listener traits in the query-string. This is likely to > change as we evolve the API. The following table lists the possible > values: > > > > Property Name Example Value Comments > > > ListenerAction "Subscribe","Unsubscribe",The existence of the > ListenerAction > "Open","Close","Retrieve",indicates that a > listener should be > "Acknowledge" created, destroyed, > or retrieved from. > "Acknowledge" is a > special case for > CLIENT_ACKNOWLEDGE > mode. > DurableSuscriptionName Required to uniquely > identify a durable > subscription. > Specifying this > obviates the need to > have a separate > "durable" setting. > AcknowledgeMode "Client","Auto","DUPS_OK" > > > > > > The use of a URL to specify properties of a listener is unusual in > that not all things have a parallel on the send side. In the send > scenario, there is only one action to consider-send. From the > receiver's perspective, there are separate steps beyond creating a > listener like deleting a durable subscription (Unsubscribe), and > explicit acknowledgement of receipt for CLIENT_ACKNOWLEDGE and DUPS_OK > mode. An empty Call object could be created with just the URL > containing the action. The action could be performed using > Call.invoke(). In the case of "ListenerAction=Unsubscribe" this would > not actually invoke anything. It would simply be a command to tell > the transport layer to unsubscribe. When we enhance the API for > client we will have a more direct way to do this. > > > > Example: URL-based JMS transport > > Service service = new Service(new XMLStringProvider(wsdd)); > > > > // create a new Call object > > Call call = (Call) service.createCall(); > > > > // populate the call object. In this case it's a method > > // invocation with a description of the parameter list and > > // the return type. > > call.setOperationName( new QName("urn:xmltoday-delayed-quotes", > > "getQuote") ); > > call.addParameter( "symbol", > > XMLType.XSD_STRING, > > ParameterMode.IN ); > > call.setReturnType( XMLType.XSD_FLOAT ); > > > > // set the jms url > > String sampleJmsUrl = "jms:sonicmq://localhost:2506? > > "destination=SampleQ1" + > > "&deliverymode=persistent" + > > "&priority=5" + > > "&timetolive=10000"; > > call.setTargetEndpointAddress(new java.net.URL(sampleJmsUrl)); > > > > // setting properties explicitly is still supported > > // these override properties specified in the url > > call.setUsername(username ); > > call.setPassword(password ); > > call.setProperty(JMSConstants.TIME_TO_LIVE, new Long(20000)); > > > > ... > > > > // invoke the call > > res = (Float) call.invoke(...); > > > > > > Note that the call to set the JMSTransport is no longer required, as > the appropriate transport will be selected based on the protocol > specified in the endpoint address. > > > > Issues: > > > > - Lifecycle. With references to JMSTransport no longer > necessary, how will the client application dictate lifecycle? Via > commands passed in with the send? > > - How does one check the JMSRedelivered property on receipt of > a message? JMS properties table in call object? > > Futures: > > > > - Transaction support > > > > -- Sonic Software - Backbone of the Extended Enterprise -- David Chappell <[EMAIL PROTECTED]> Office: (781)999-7099 Mobile: (617)510-6566 Vice President and Chief Technology Evangelist, Sonic Software co-author,"Java Web Services", (O'Reilly 2002) "The Java Message Service", (O'Reilly 2000) "Professional ebXML Foundations", (Wrox 2001) --