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) --Title: JMS URL Syntax
JMS URL Syntax For the Apache Axis Project
<author: Dave Chappell [EMAIL PROTECTED]> <author: Ray Chun [EMAIL PROTECTED]> <author: Jaime Meritt [EMAIL PROTECTED] > SummaryThis 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.
BackgrounderWhen 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 SyntaxRather 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.
ExamplesUsing 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 PropertiesProperties 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).
Example: URL-based JMS transportService 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
|
begin:vcard n:Chappell;Dave tel;cell:617-510-6566 tel;work:781-999-7099 x-mozilla-html:FALSE url:www.sonicsoftware.com org:Sonic Software Corp. <BR><BR><A HREF="http://www.sonicsoftware.com/products/sonicxq.htm">Read about SonicXQ</A> - the first product to deliver <br>on the promise of the enterprise service bus.<BR><BR><A HREF="http://www.sonicsoftware.com"><IMG BORDER="0" SRC="http://www.sonicsoftware.com/media/email_signatures/schulte_quote_logo2.gif"></A> adr:;;14 Oak Park;Bedford;MA;01730;USA version:2.1 email;internet:[EMAIL PROTECTED] title:vice president & chief technology evangelist<a href="http://www.oreillynet.com/weblogs/author/207">[weblog]</a> fn:Dave Chappell end:vcard