|
|
resin-ee
$ee/ejb-ref/burlap-draft-spec.xtp
March 15, 2002
 |  |
|
|
The Burlap protocol was created to solve a specific problem:
Allow
Java Enterprise Java Beans (EJB) services to interoperate with non-Java
servers and clients using an XML-based protocol.
The Burlap home page
contains the latest information about Burlap.
The name "Burlap" was chosed for a simple reason: it's boring.
The wire protocol for web services should be invisible
to application writers. Wire protocols should not require
external schema or IDL.
Given the EJB environment, the Burlap protocol has the
following requirements:
- It must use the simplest possible subset of XML.
- It must not require external IDL or schema definitions; it should be
invisible to application writers.
- It must have sufficient power to serialize Java.
- It must have sufficient power to support EJB.
- It must allow non-Java clients to use web services.
- It must allow web services to deployed as a Servlet.
- It must be simple so it can be effectively tested.
- It must be as fast as possible.
- It should support transaction contexts.
The design notes explain some
of the design decision in creating the Burlap protocol.
The leading XML-based RPC protocols do not meet these
requirements. UserLand's XML-RPC
is insufficiently powerful to
support Java serialization or EJB. Microsoft's
SOAP is overly
complicated and underdefined. In particular, it requires XML
namespaces, attributes, overly complicated typing, and
external schema.
Burlap uses SML (Simple Markup Language), a restricted subset of XML:
- Only elements and character data are allowed.
- No namespaces, no attributes, no processing instructions, no
comments, no DTDs, no CDATA sections.
- No mixed content: an element may contain either
elements or character data, but not both.
- Only UTF-8 encoding is allowed.
- Only numbered character entities, e.g. <, and the standard
XML entities (<, >, and &) are allowed as
escapes.
- All whitespace in character data is significant.
The smallness of SML allows less room for bugs, simplifies
testing, and makes reasonably-fast implementations feasible.
It forces conformance by eliminating ambiguities.
The SML grammar needs only six productions:
tag-list ::= (S tag)* S
tag ::= <name> tag-list </name>
::= <name> cdata </name>
S ::= (' ' | '\t' | '\r' | '\n')*
cdata ::= ([^<&] | &# [0-9]+ ; | &lt; | &gt; | &amp;)*
name ::= [a-zA-Z:_] [a-zA-Z0-9.-_:]*
SML explicitly forbids XML short tags, e.g. <tag/>,
and the XML header, e.g. <?xml version='1.0'?>
Burlap's object serialization has 9 primitive types:
- boolean
- 32-bit int
- 64-bit long
- 64-bit double
- ISO-8609 date
- 16-bit UTF8-encoded string
- 16-bit UTF8-encoded xml
- base64 binary data
- remote objects
It has 2 combining constructs:
- list for lists and arrays
- map for objects and hash tables.
Finally, it has 2 special contructs:
- null for null values
- ref for shared and circular object references.
Null represents a null pointer.
The XML short form is forbidden, i.e. <null> must have
separate open and close tags.
<null> values are allowed in place of any <string>, <xml>,
<base64>, <list>, <map>, or <remote>.
<null></null>
A boolean value expressed as an integer, 0 or 1.
<boolean>0</boolean>
A 32-bit signed integer.
<int>-32132</int>
A 64-bit signed integer.
<long>1000000000</long>
A 64-bit IEEE floating pointer number.
<double>1234.9431e12</double>
A 16-bit unicode character string encoded in UTF-8. The
UTF-8 encoding follows from the SML rules. Similarly, the only
escapes allowed are &#xx;, &lt;, &gt;, and &amp;.
All whitespace is significant.
<string>Escape the less than symbol as &lt; or
using the numeric escape &#38;</string>
An XML document encoded as a 16-bit unicode character
string encoded in UTF-8, following the rules for <string>.
Special characters, like `<' must be escaped. The only escapes allowed
are &#xx;, &lt;, &gt;, and &amp;. All whitespace is
significant.
<xml>
&lt;top&gt;
&lt;body test='foo'/&gt;
&lt;/top&gt;
</xml>
Because this document does not define the language mapping,
implementations are free to return a string when reading an <xml>
entity.
An ISO8609-encoded date.
<date>19880508T095231Z</date>
A base64-encoded binary stream. The base64 string may have
whitespace after any triplet, but not within a triplet.
<base64>
zxc9Z9
m2z8==
</base64>
An ordered list, like an array. The <type>
element describes the type of the list and the <length> element
specifies the number of values in the list. Both <type> and
<length> tags are required, but both may be empty. If the <length>
is empty, the receiver will determine the list length from the
actual number of elements before the </list>.
list = (type, length, (%object;)*)
Each <list> item is added to the reference list. See the
<ref> element.
A <list> might also be represented by a <null> or <ref>.
Parsers must be prepared to recognize any of those three.
<list>
<type>[int</type>
<length>3</length>
<int>0</int>
<int>1</int>
<int>2</int>
</list>
<list>
<type></type>
<length>3</length>
<int>0</int>
<double>1.3</double>
<string>foobar</string>
</list>
The valid values of <type> are not specified in this
document and may depend on the specific application. For example, a
Java EJB server which exposes an Burlap interface can use the <type>
information to instantiate the specific array type.
On the other hand, a Perl server would likely ignore the contents of <type>
entirely and create a generic array.
Represents serialized objects and Hashtables. The <type>
element describes the type of the map. Objects are represented by a
map from field names to their values and <type> is the class
of the object itself.
map ::= (type, ((%object;), (%object;))*)
The <type> element is mandatory, although its value may be
empty. For objects, unrecognized keys must be ignored.
Each <map> is added to the reference list. A <map> might
also be represented as <null> or <ref>.
public class Car implements Serializable {
String model = "Beetle";
String color = "aquamarine";
int mileage = 230431;
}
<map>
<type>com.caucho.test.Car</type>
<string>model<string>
<string>Beetle</string>
<string>color<string>
<string>aquamarine</string>
<string>mileage<string>
<int>230431</int>
</map>
map = new HashMap();
map.put(new Integer(1), "fee");
map.put(new Integer(75), "fie");
map.put(new Integer(932), "foe");
<map>
<type>java.util.HashMap</type>
<int>1<int><string>fee</string>
<int>75<int><string>fie</string>
<int>932<int><string>foe</string>
</map>
The <type> will depend on the specific protocol. EJB-based
protocols will use Java classes.
An integer referring to a previous <list> or <map>
instance. As each <list> or <map> is read from the
input stream, it is assigned an integer. A later <ref> can then use
the previous object.
ref ::= #CDATA
<ref> can refer to incompletely-read items. For example, a
circular linked-list will refer to the first link before the entire list
has been read.
A possible implementation would add each <map> and <list> to an
array as its read. The <ref> will return the corresponding object from the
array. To support circular structures, the implementation would store
the <map> or <list> immediately, before filling in the object's
contents.
Each <list> or <array> is stored into an array as it is
parsed. <ref> selects one of the stored objects. The first
object is numbered '0'.
list = new LinkedList();
listhead = 1;
list.tail = list;
<map>
<type>LinkedList</type>
<string>head</string><int>1</int>
<string>tail</string><ref>0</ref>
</map>
<ref> only to <list> and <map> elements. <string>
and <base64>, in particular, can't share references.
A reference to a remote object. The <type> element
specifies the object type and the <string> element specifies the remote
object's URL.
remote ::= (type, string)
Remote support is optional. Clients and servers don't need
to support <remote> if the service doesn't need it.
<remote>
<type>test.TestObj</type>
<string>http://localhost/ejbhome;ejbid=69Xm8-zW</string>
</remote>
Needed to support EJB in a reasonably portable way.
A Burlap call invokes a method on an object with an argument
list. The object is uniquely named by its URL. The arguments are
specified by Burlap serialization.
burlap:call ::= (%header;), method, (%object;)*
<burlap:call>
<method>add2</method>
<int>2</int>
<int>3</int>
</burlap:call>
<burlap:reply>
<value>
<int>5</int>
</value>
</burlap:reply>
The URL uniquely identifies the Burlap object. This spec does
not mandate any particular URL naming convention.
As an example, the following format is used for EJB:
http://hostname/ejb/ejb-name;ejbid=object-id
http://hostname/ejb identifies the EJB container. In
Resin-EJB, this will refer to the EJB Servlet. HTTP is used as an
example; Burlap does not require the use of HTTP.
/ejb-name, the path info of the request, identifies the EJB home.
EJB containers can contain several entity and session beans, each with its
own EJB home. The ejb-name corresponds to the ejb-name in the
deployment descriptor.
object-id identifies the specific object. For entity beans, the
object-id encodes the primary key. For session beans, the object-id encodes
a unique session identifier. Home interfaces have no ";ejbid=..." portion.
http://localhost/ejb/houses
http://localhost/ejb/session;ejbid=M9Zs1Zm
Method names must be unique. Overloading is permitted by
encoding the argument types in the method names. The types of
the actual arguments must not be used to select the methods.
Method names beginning with _burlap_ are reserved.
Servers should accept calls with either the mangled method name
or the unmangled method name. Clients should send the mangled method name.
See the Java binding for a possible overloading scheme.
add(int a, int b)
add_int_int
add(double a, double b)
add_double_double
add(shopping.Cart cart, shopping.Item item)
add_shopping.Cart_shopping.Item
Arguments immediately follow the method in positional order. Argument
values use Burlap's serialization.
<burlap:call>
<method>add<method>
<int>2</int>
<int>3</int>
</burlap:call>
All arguments share references, i.e. the reference list
starts with the first argument and continues for all other arguments.
This lets two arguments share values.
bean = new Bean("foo", 13);
System.out.println(remote.eq(bean, bean));
<burlap:call>
<method>eq<method>
<map>
<type>Bean</type>
<string>foo</string>
<int>13</int>
</map>
<ref>0</ref>
</burlap:call>
The number and type of arguments are fixed by the remote method.
Variable length arguments are forbidden. In other words, implementations
may take advantage of the expected type to improve performance.
Headers are key, value pairs introduced by a <header> tag.
The value of the header can be any serialized object. The reference
array is reset for each header. So a header can't point to an object
in another header.
For example, a request might include a transaction context in a
header. The client could require that the server understand the
transaction context or fail.
<burlap:call>
<header>transaction<header>
<remote>http://hostname/xa;ejbid=01b8e19a77</remote>
<method>debit<method>
<int>12300</int>
</burlap:call>
Burlap requests and responses have no explicit version id. This
is deliberate. There are several different changes that get
lumped into a 'version', but each needs different handling. In each
case, appropriate mechanisms already exist without adding a version.
- If the Burlap meta-protocol itself changes, the new protocol will
use a new top-level tag <burlap-2:call>. In other words the
top element, burlap:call, signifies version 1.0.
- If clients can take advantage of a new server capabilities, it
should use <header> version.
<burlap:call>
<method>debit<method>
<int>12300</int>
</burlap:call>
Burlap calls return either a <fault> or an object.
A successful reply returns a single <value> and possibly
some header information.
<burlap:reply>
<value>
<int>5</int>
</value>
</burlap:reply>
Failed calls return a <fault>.
Each fault has a number of informative fields, expressed like
<map> entries. The defined fields are code, message,
and detail. code is one of a short list of strings
defined below. message is a user-readable message.
detail is an object representing the exception. In Java,
detail will be a serialized exception.
<burlap:reply>
<fault>
<string>code</string>
<string>ServiceException</string>
<string>message</string>
<string>File Not Found</string>
<string>detail</string>
<map>
<type>java.io.FileNotFoundException</type>
</map>
</value>
</burlap:reply>
| ProtocolException | The Burlap request has some sort of
syntactic error.
|
| NoSuchObjectException | The requested object does not exist.
|
| NoSuchMethodException | The requested method does not exist.
|
| ServiceException | The called method threw an exception.
|
Metadata is handled by special method calls, methods beginning
with _burlap_.
_burlap_getAttribute(String key) returns a string.
The following attributes are predefined by this spec:
| attribute | meaning
|
| home-class | Java class for the home interface.
|
| remote-class | Java class for the object interface.
|
| primary-key-class | Java class for the primary key.
|
A "Micro Burlap" implementation may omit support for the "double" type.
tag-list ::= (S tag)* S
tag ::= <name> tag-list </name>
::= <name> cdata </name>
S ::= (' ' | '\t' | '\r' | '\n')*
cdata ::= ([^<&] | &# [0-9]+ ; | &lt; | &gt; | &amp;)*
name ::= [a-zA-Z:_] [a-zA-Z0-9.-_:]*
<!DOCTYPE burlap:call>
<!ENTITY % object "null | boolean | int | double | string | xml |
base64 | date | ref | map | list | remote">
<!ENTITY % header "(header, (%object;))*">
<!ELEMENT burlap:call - - ((%header;), method, (%object;)*)>
<!ELEMENT header - - #CDATA>
<!ELEMENT method - - #CDATA>
<!ELEMENT null - - EMPTY>
<!ELEMENT boolean - - #CDATA>
<!ELEMENT int - - #CDATA>
<!ELEMENT double - - #CDATA>
<!ELEMENT string - - #CDATA>
<!ELEMENT xml - - #CDATA>
<!ELEMENT base64 - - #CDATA>
<!ELEMENT date - - #CDATA>
<!ELEMENT ref - - #CDATA>
<!ELEMENT map - - (type, ((%object;), (%object;))*)>
<!ELEMENT list - - (type, length, (%object;)*)>
<!ELEMENT type - - #CDATA>
<!ELEMENT remote - - (type, string)>
<!DOCTYPE burlap:reply>
<!ENTITY % object "(null | boolean | int | double | string | xml |
base64 | date | ref | map | list | remote)">
<!ENTITY % header "(header, (%object;))*">
<!ELEMENT burlap:reply - - ((%header;), (value | fault))>
<!ELEMENT header - - #CDATA>
<!ELEMENT value - - (%object;)>
<!ELEMENT fault - - (string, (%object;))*>
<!ELEMENT null - - EMPTY>
<!ELEMENT boolean - - #CDATA>
<!ELEMENT int - - #CDATA>
<!ELEMENT double - - #CDATA>
<!ELEMENT string - - #CDATA>
<!ELEMENT xml - - #CDATA>
<!ELEMENT base64 - - #CDATA>
<!ELEMENT date - - #CDATA>
<!ELEMENT ref - - #CDATA>
<!ELEMENT map - - (type, ((%object;), (%object;))*)>
<!ELEMENT list - - (type, length, (%object;)*)>
<!ELEMENT type - - #CDATA>
<!ELEMENT remote - - (type, string)>
© Copyright 2000-2002 Caucho Technology, Inc. All Rights Reserved.
Any party may implement this protocol for any purpose without royalty
or license fee, provided that the implementation conforms to this
specification. Caucho Technology reserves the right to create a
test suite, freely available without royalty or license fee, to
validate implementation conformance. The limited permissions granted
herein are perpetual and may not be revoked by Caucho Technology or
its successors or assigns.
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published and
distributed, in whole or in part, without restriction of any kind,
provided that the above copyright notice and these paragraphs are
included on all such copies and derivative works.
This document and the information contained herein is provided on an
"AS IS" basis and CAUCHO TECHNOLOGY DISCLAIMS ALL WARRANTIES, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- Removed <burlap:envelope> and <burlap:message>.
- Removed <require> header.
- Added <burlap:envelope> and <burlap:message>
- Added <xml>
- Clarified license.
- Allowed variable length arrays.
- <require> must preceed <header> in headers.
- <remote> requires a <type> and <string> value.
- Changed name of protocol from SML-RPC to "Burlap"
- Added and rewrote verbiage.
- base64 may have whitespace between triplets.
- Added Standard XML entities ('&lt;', '&gt;', '&amp;').
- <remote> now takes a single string content, the url.
Copyright (c) 1998-2009 Caucho Technology, Inc. All rights reserved. caucho® ,
resin® and
quercus®
are registered trademarks of Caucho Technology, Inc.
|
Copyright (c) 1998-2009 Caucho Technology, Inc. All rights reserved. caucho® ,
resin® and
quercus®
are registered trademarks of Caucho Technology, Inc.
|