The ebXML initiative aims to create a framework for applications that allow organizations to carry out electronic business by exchanging XML-based messages. The ebXML Transport, Routing, and Packaging (ebXML-TRP) specification (lcoated at http://www.ebxml.org/specs/ebMS.pdf) defines the packaging model for ebXML messages, which is based on SOAP with attachments and is therefore compatible with both SAAJ and JAXM. This section briefly describes the ebXML packaging model and looks at how it is supported by the JAXM ebXML profile. The ebXML profile implements Version 1.0 of the ebXML-TRP specification.
Like WS-Routing, ebXML-TRP uses SOAP headers to carry protocol information. Unlike WS-Routing, however, ebXML-TRP also defines elements that may be added to the SOAP message body. Many of the features described in the ebXML-TRP specification are optional, so we'll restrict ourselves to briefly discussing just the mandatory parts of the specification, which are the only parts actually provided in the JAXM reference implementation. For a definitive description, refer to the ebXML-TRP specification itself.
ebXML-TRP considers a SOAP message to be made up of two separate parts:
Despite its name, the header container corresponds to the entire SOAP part of the message and therefore consists of both the SOAP header and the SOAP body. The specification defines six elements that may appear in the header, and four that can be used in the message body. The JAXM ebXML profile supports only one header element and one body element, since the others are optional.
An ebXML-TRP message may have zero or more payload containers that carry information that supplements the XML in the header container. Each payload container is realized as a SOAP message attachment; therefore, it can carry data of any type that has a MIME representation, such as an image or an XML document. Since SAAJ already provides the ability to add attachments to a message, no additional API is required in the ebXML profile to handle payload containers. However, the application must ensure that each payload container in the message has a corresponding reference in the ebXML-TRP Manifest element in the body of the header container, as described shortly.
All ebXML-TRP elements and attributes are in the namespace identified by the URI http://www.ebxml.org/namespaces/messageHeader.
The MessageHeader element must appear in the header container of every ebXML-TRP message. The specification defines 10 child elements for this header, of which only the 7 listed in Table 4-5 are supported by the ebXML profile.
Element |
Description |
---|---|
A string that identifies in some way that is known to the application the terms of the agreement entered into between the parties to the message exchange. ebXML defines the concept of a Collaboration Profile Agreement (CPA) that encompasses these terms. The CPAId is typically a URI that refers to such a CPA. |
|
A unique, application-defined identifier that is attached to each of the messages that make up a single conversation. What consititutes a conversation is, of course, application-dependent. |
|
Specifies the service supplied by the message receiver that should act upon the message. A service is identified by a combination of a type and a value, in which the type defaults to URI to indicate that the value is itself a URI. Other types may be defined for private use by applications. A typical service description, encoded as a URI, might be urn:services:OrderProcessing. |
|
Qualifies the service description by specifying the action to be performed by the target service on receipt of the message. This element is simply a string defined by the service, such as PlaceOrder. |
|
Identifies the intended recipient of the message. A message may have multiple recipients, each of which has a corresponding child element of type Party. The value of the Party element is the recipient's address, which is typically a URI, but may be a different style of address by prior agreement between the sender and the receiver. If the address is not a URI, then its actual type must be specified using the type attribute of the Party element. |
|
Identifies the message sender. As with the To element, the sender's address is supplied in the form of a Party element. |
|
Contains child elements that allow an individual message to be uniquely identified. The reference implementation supports only the following three child elements:
The TimeToLive element is not supported. |
The optional SequenceNumber, Description, and QualityOfServiceInfo elements of MessageHeader are not implemented in the ebXML profile; neither are the TraceHeaderList, ErrorList, Signature, Acknowledgement, and Via header elements.
The Manifiest element appears in the body of the SOAP message. It consists of one or more child elements of type Reference that describe payload objects that appear in the body of the message in a payload container or as external resources, such as documents on the Internet.[8] A Manifest element is required only if there is payload to be referenced.
[8] Although the SOAP body may contain payload elements, the specification recommends that this not be done.
A typical Manifest element looks like the following, in which the namespace prefix eb is assumed to be mapped to the ebXML-TRP namespace URI:
<eb:Manifest eb:id="payload01" xlink:type="simple" xlink:href="cid:attachment-01" xlink:role="urn:purchaseOrder">
The attributes are used as described in Table 4-6.
Attribute |
Description |
---|---|
eb:id |
This is a standard id attribute that can be used to refer to the element from elsewhere in the message. This attribute is optional. |
xlink:type and xlink:href |
These attributes together constitute a simple link to the payload content, as described by the XML XLink specification (a description of which can be found in XML in a Nutshell, by Elliotte Rusty Harold and W. Scott Means (O'Reilly). The xlink:type attribute always has the value simple, which means that the xlink:href attribute is a URI. There are three cases to be distinguished:
|
xlink:role |
An optional attribute that identifies the type or use of the payload in some way that has meaning to the application. Like href, this must be a valid URI formed according to the XML XLink specification. |
A Reference element may also have the following child elements:
A Schema element that refers to a schema document (typically an XML-Schema document) that describes the content of the payload. This element is required only for structured content (such as XML) that can be described in this way, and is not included for images or other binary payloads.
Zero or more Description elements that contain a textual description of the payload. This element has an attribute called lang that specifies the language in which the text is written. If more than one Description element is present, typically to provide the same information in more than one language, then each should have a lang attribute with an appropriate value.
The sample code for this book includes a pair of web services that send and echo an ebXML-TRP message in the same way as the SOAP-RP message echoing example that was described earlier in this chapter. In order to run these examples, start the Tomcat web server and deploy them both as follows:
Change your working directory to chapter4\ebXMLecho relative to the installation directory of the example source code.
Type the command ant deploy.
Change your working directory to chapter4\ebXMLsender relative to the installation directory of the example source code.
Type the command ant deploy.
Next, you need to configure the JAXM provider so that it knows how to route messages to these web services. Using a browser, connect to the JAXM provider administration web page (at http://localhost:8081/jaxm-provideradmin), select the HTTP protocol under the ebXML profile, add the mappings shown in Table 4-7, and press "Save to Profile".
URI |
Target URL |
---|---|
urn:ebXMLEcho |
http://localhost:8081/jaxm-provider/receiver/ebxml |
urn:ebXMLSender |
http://localhost:8081/jaxm-provider/receiver/ebxml |
Note that the last component of these URLs is ebxml rather than soaprp, since the messages need to be directed to the provider's received message queues for ebXML messages.
To run the example, point your web browser at the URL http://localhost:8080/ebXMLSender/request. After a short delay, you should see the message that was transmitted by and returned to the sender, which is shown in Example 4-8.
<?xml version="1.0" encoding="UTF-8"?> <soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"> <soap-env:Header> <eb:MessageHeader xmlns:eb= "http://www.ebxml.org/namespaces/messageHeader" eb:version="1.0" soap-env:mustUnderstand="1"> <eb:From> <eb:PartyId eb:type="URI">urn:ebXMLEcho</eb:PartyId> </eb:From> <eb:To> <eb:PartyId eb:type="URI">urn:ebXMLSender</eb:PartyId> </eb:To> <eb:CPAId>urn:EchoCollaborationAgreement</eb:CPAId> <eb:ConversationId>1</eb:ConversationId> <eb:Service eb:type="URI">urn:ECHOSERVICE</eb:Service> <eb:Action>ECHO</eb:Action> <eb:MessageData> <eb:MessageId>7b683c87-3d44-4135-b397-ef436d1437aa</eb:MessageId> <eb:RefToMessageId>0c3e1841-29bb-4c6c-bc3f-d4b419846b26 </eb:RefToMessageId> <eb:Timestamp>1030880701373</eb:Timestamp> </eb:MessageData> </eb:MessageHeader> </soap-env:Header> <soap-env:Body> <tns:Sent xmlns:tns="urn:ebXMLSender">This is the content</tns:Sent> <eb:Manifest xmlns:eb="http://www.ebxml.org/namespaces/messageHeader" eb:id="ID1" eb:version="1.0"> <eb:Reference eb:id="ID2" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.ora.com"> <eb:Description xml:lang="en">O'Reilly Home Page</eb:Description> </eb:Reference> <eb:Reference eb:id="ID3" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.amazon.com"> <eb:Description xml:lang="en">Online bookstore</eb:Description> </eb:Reference> </eb:Manifest> </soap-env:Body> <tns:Date xmlns:tns="urn:ebXMLEcho">Sun Sep 01 12:45:01 BST 2002</tns:Date> </soap-env:Envelope>
The code that was used to create this message will be shown in the next section. For now, note the content of the MessageHeader element in the SOAP header and the Manifest element in the body, which refers to two payloads that are Internet resources and are therefore not included as part of the message itself.
To use the ebXML profile, you first need to get a MessageFactory that can create ebXML messages. Having done this, you can then call the createMessage( ) method to get such a message. The code that creates the message just shown can be found in Example 4-9.
MessageFactory msgFactory = conn.createMessageFactory("ebxml"); EbXMLMessageImpl message = (EbXMLMessageImpl)msgFactory.createMessage( ); // Set attributes held in the MessageHeader message.setAction("ECHO"); message.setService(new Service("urn:ECHOSERVICE", "URI")); message.setCPAId("urn:EchoCollaborationAgreement"); message.setConversationId("1"); // Set the sending and receiving parties. message.setReceiver(new Party("urn:ebXMLEcho")); message.setSender(new Party("urn:ebXMLSender")); // Add a Manifest with two references to external locations Manifest manifest = new Manifest("ID1", "1.0"); Reference ref = new Reference("ID2", "http://www.ora.com", null); Description desc = new Description("en"); desc.setText("O'Reilly Home Page"); ref.setDescription(desc); manifest.addReference(ref); ref = new Reference("ID3", "http://www.amazon.com", null); desc = new Description("en"); desc.setText("Online bookstore"); ref.setDescription(desc); manifest.addReference(ref); message.setManifest(manifest);
The message that the createMessage( ) method returns is of type com.sun.xml.messaging.jaxm.ebxml.EbXMLMessageImpl.[9] To use the convenience methods provided by the API, cast the method's return value to this type.
[9] Note the spelling of the last component of this name � the second character is a lowercase "b".
The first section of code sets the values of child elements that appear in the ebXML MessageHeader element, which will be created in the SOAP message header. This element is mandatory and therefore it is always present. The specification requires that all of the child elements listed in Table 4-5 must appear in an ebXML message; it is your responsibility to ensure that valid values are supplied for them. Elements for which you do not supply values will not be included in the MessageHeader, which may cause the receiver to reject the message. Table 4-8 briefly describes the values that need to be supplied as arguments to the EbXMLMessageImpl methods that install these elements. In some cases, the arguments are instances of other classes that are also part of the com.sun.xml.messaging.jaxm.ebxml package. Documentation for these simple classes can be found in the reference section of this book.
Method |
Argument |
---|---|
A string, the value of which is defined by the target service. |
|
A Service object. This object has two attributes: a type and an identifier, which are both supplied as strings. By default, the type attribute is assumed to be URI. However, you should explicitly set this value because the reference implementation transmits the type as an empty string if you do not, which may cause interoperability problems. The target service defines the set of type and identifier values that it understands. |
|
A string value, determined (in advance) by agreement between the sender and receiver. |
|
A string value that uniquely identifies a related set of messages. |
|
These methods set to To and From elements, respectively. They each require an argument of type Party, which, like Service, has both a type and an identifier. The default for the type attribute is URI; in this case, the reference implementation handles this default properly; therefore, there is no need to supply it explicitly. In the example used in this chapter, the identifier is the URI of the message sender or receiver, and is the key used by the provider to route the message. |
There are a couple of points to note regarding the handling of the To and From elements in the reference implementation:
While the specification allows either of these elements to contain one or more nested Party elements, at the time of this writing the implementation supports only one. Therefore, you cannot address a message to more than one recipient.
Despite the fact that the elements are called To and From, the methods that set them are setReceiver( ) and setSender( ), respectively. This is because the superclass of EbXMLMessageImpl defines the setTo( ) and setFrom( ) methods to have arguments of type Endpoint, while application code more naturally deals with objects of type Party. When transmitting a message, the provider needs an Endpoint and therefore uses the getTo( ) method to obtain the target address. This method gets the Party object set by setReceiver( ), extracts the identifier part, and then uses it to create the corresponding Endpoint object.
You'll note that the code in Example 4-9 does not explicitly set any values for the MessageData element. Nevertheless, this element appears in the message because the timestamp and a unique message identifier are installed automatically by the MessageFactory. In the case of a reply message, the RefToMessageId element must be set to the unique identifier of the message to which it relates. This is not done automatically, but you can set it using the same technique used for the SOAP-RP relatesTo element:
// Get the message ID and install it as the "RefToMessageId" value replyMsg.setRefToMessageId(soapMsg.getMessageId( ));
If an ebXML message has any kind of payload, its body must include a Manifest element with one Reference element for each item of payload. These elements are represented in the ebXML message API by the Manifest and Reference classes, respectively.
Manifest is a simple class that is constructed with an XML ID (used to refer to it from elsewhere in the message, if required) and a version number, which must be the version number of the ebXML-TRP specification to which the overall message conforms (in this case, "1.0"). The specification requires that a valid XML ID be provided. The implementation, however, does not prevent the use of null for this attribute, which would result in the creation of a message that is technically not valid. Once you have a Manifest object, you can use its addReference( ) method to add any number of payload references. The code shown in Example 4-9 installs two references, both to external data that is not actually part of the message itself.
To construct a Reference object, you need to supply an XML ID and appropriate values for its role and href attributes. In order to construct a valid message, an appropriate id and href must be supplied, but the role attribute may be null if appropriate. Following construction, you can associate a Schema and/or a Description with the Reference object using the setSchema( ) and setDescription( ) methods, respectively. There are two items to note regarding these methods:
The setSchema( ) method requires an argument of type Schema. Schema is a simple container class that is constructed from the URI that defines the schema and the schema version number.
The setDescription( ) method uses an argument of type Description. The constructor of the Description class requires a string that specifies the language for the associated text (such as en, en_US, en_GB, etc.), whereas the text itself is added using the setText( ) method. Although the ebXML-TRP specification allows a Reference element to be associated with any number of descriptions, the reference implementation allows only zero or one.