8.5 JAXM Client and Provider Configuration
Java Web Services Developer's Pack. There is no equivalent for the J2EE 1.4 platform, since JAXM is not included.
The Java API for XML Messaging (JAXM) provides a means to send and receive SOAP messages via a provider instead of using a direct connection from the sender to the receiver. The benefits of this arrangement, as discussed in Chapter 4, are:
- Asynchronous operation
Clients deliver outgoing messages to their provider. The provider then has responsibility for arranging the delivery of each message to the provider local to the intended recipient. If the receiving provider is not active or not reachable , it will be necessary to retry delivery until it succeeds or a preconfigured limit is reached.
Messages can be received for a client that is not active and stored within the provider for delivery later.
- Location transparency
Whereas SAAJ applications need to know the address of the recipient of each message they send, a JAXM client can use an address token that is independent of the real address of the receiving application. The mapping from an address token to an actual address is configured in the provider, where it can be more easily changed if necessary.
In order to provide these features, two levels of configuration are required. First, the provider has to be configured with the details of the token-to-address mappings that provide location transparency for applications and with other information, such as how many times to retry a failed message delivery. Secondly, the client application needs to be configured with information required by its provider. This section covers the configuration details for the JAXM reference implementation.
8.5.3 Provider Configuration
Provider configuration information is held in a file called provider.xml , which is located in the /WEB-INF directory of the deployed JAXM provider. The format of the file content is shown in Example 8-10.
Example 8-10. The JAXM provider.xml file
<ProviderConfig> <Profile profileId="profile"> <!-- 1 or more --> <Transport> <!-- 1 or more --> <Protocol>protocol</Protocol> <!-- Endpoint mappings for this protocol --> <Endpoint type="uri urn"> <!-- 1 or more --> <URI>token</URI> <URL>targetAddress</URL> </Endpoint> <ErrorHandling> <!-- 0 or 1 ---> <Retry> <MaxRetries>N</MaxRetries> <RetryInterval>M</RetryInterval> </Retry> </ErrorHandling> <Persistence> <!-- 0 or 1 --> <Directory>path</Directory> <RecordsPerFile>N</RecordsPerFile> </Persistence> </Transport> <ErrorHandling> <!-- 0 or 1 --> <Retry> <MaxRetries>N</MaxRetries> <RetryInterval>M</RetryInterval> </Retry> </ErrorHandling> <Persistence> <!-- 0 or 1 --> <Directory>path</Directory> <RecordsPerFile>N</RecordsPerFile> </Persistence> </Profile> </ProviderConfig>
Nested within the top-level ProviderConfig element, the provider.xml file contains a separate Profile element for each message profile that it supports, where the profileId attribute identifies the profile. Valid values for profileId in the reference implementation are soaprp and ebxml ; therefore, there are typically two Profile elements, each of which configures the address mapping and other policy details for its particular profile.
A profile may operate over one or more transport mechanisms, each of which requires a nested Transport element whose first child element supplies the name of the protocol. The reference implementation recognizes the values http and https as valid protocol identifiers. The remaining child elements of the Transport element configure endpoint mappings, error handling, and local storage for the provider when using the profile given by the containing Profile element over the specified transport protocol.
The ProviderConfig element may also have nested ErrorHandling and Persistence elements that configure default settings for all transports. These elements can appear within any Transport element if it is necessary to override the defaults for a specific transport type. Only one instance of each element can appear within the ProviderConfig element and within each Transport element.
188.8.131.52 Endpoint mappings
The Endpoint elements map the address tokens used by JAXM client programs to the transport addresses to which messages using those tokens are to be sent. Here is typical example of an Endpoint element configured for the soaprp profile:
<Endpoint> <URI>urn:SOAPRPEcho</URI> <URL>http://localhost:8081/jaxm-provider/receiver/soaprp</URL> </Endpoint>
This element causes SOAP-RP messages in which the to address has the value urn:SOAPRPEcho to be sent to the URL http://localhost:8081/jaxm-provider/receiver/soaprp . The destination address in the URL element should always be that of a JAXM provider and is formed as follows :
The first part of the URL ” in this case, http://localhost:8081/jaxm-provider ” corresponds to the URL of the JAXM provider web application that should receive the message. In this case, the target provider is on the same machine as the sender, but this is not usually the case in the real world. Port number 8081 is correct for the default installation of the JWSDP when running in the Tomcat web container.
The second part of the URL is receiver/soaprp if the receiver at the receiving endpoint expects messages to be built using the SOAP-RP profile and receiver/ebxml for ebXML profile messages. The client application must, of course, be coded to use the same profile. If more profiles are added in the future, then each will need its own unique URL for receiving messages.
The address token given by the URI element can be any URI that is considered to be a valid address for the profile being configured. In this example, it happens to be a URN, but it could also be a URL. In practice, the provider does not attempt to interpret this token other than to match it against the destination address of a message being sent by a client. 
 The URI element has an optional type attribute that, according to its DTD, can have the value uri or urn . These values are curious ” it seems more logical to require url or urn . In any case, there is no need to supply a value for this attribute, and, at least at the time of this writing, any value that is supplied is ignored.
184.108.40.206 Error handling
The ErrorHandling element determines the actions that the provider takes when it is unable to deliver a message immediately. There are two conditions that trigger error recovery:
A provider attempts to send a message to a remote provider and fails to do so because the provider is not active or is not currently accessible for some other reason. In this case, the message is held in the outgoing queue for retransmission.
A provider receives a message and attempts to deliver it to a local client whose endpoint is not currently active. In this case, the message is held in the receiver queue in the expectation that the client will shortly connect to the provider.
A typical ErrorHandling element looks like this:
<ErrorHandling> <Retry> <MaxRetries>3</MaxRetries> <RetryInterval>2000</RetryInterval> </Retry> </ErrorHandling>
The MaxRetries element determines how many times the provider will retry an attempt to deliver the message (this does not count the initial attempt). The RetryInterval element gives the time between successive attempts to deliver a message, in milliseconds . In the example shown here, a total of four attempts will be made to deliver a message, with one attempt being made approximately every two seconds.
If the ErrorHandling element appears within a Transport element, its values apply only to that transport type. This element may also appear directly beneath the ProviderConfig element, in which case it supplies default values that apply to all transports that do not have a nested instance. In the case where a Transport element does not provide its own error-handling values and there is no default ErrorHandling element, then the provider attempts 10 retries separated by approximately 2 seconds (these being hardcoded values).
220.127.116.11 Message persistence
The Persistence element specifies the directory within which the provider implements its outgoing and received message queues as well as the way in which messages are mapped to temporary storage files in that directory.
The Directory element gives the relative pathname of a directory for a set of queues. In the current implementation, this directory is created in the location reserved by the hosting container for a web application's temporary files. Beneath this directory, the provider creates four subdirectories, each of which represents a separate queue and is described here:
Contains messages that have been received and successfully delivered to the local client that they were intended for
Contains messages that have been successfully sent to the appropriate remote provider
Contains messages that have not yet been successfully delivered to a remote provider
Contains messages received for local clients that have not yet been successfully delivered
Within a queue, the messages are written to files. The order of messages in the queue is reflected by the creation date of each file and by the order of the messages within each file ” that is, the messages in the oldest file come first, and so on. As messages are successfully transmitted, they are removed from their containing file and, when the file is empty, it is deleted. The maximum number of messages that are placed in each individual file is given by the RecordsPerFile element.
According to the DTD for the provider.xml file, the Persistence element may appear either as a child element of a Transport element or as a direct child of the ProviderConfig element. In the former case, it is intended to configure the queues for a particular profile when operating over a specific transport mechanism. In the latter case, presumably, it provides a single queue location for those transports that do not have their own configuration. At the time of this writing, however, each Transport element is required to contain its own Persistence element, and a Persistence element appearing below the ProviderConfig element is ignored.
8.5.4 Client Application Configuration
JAXM client applications are always associated with a provider. However, the application code itself does not explicitly provide the address of that provider. Instead, this information is provided in a configuration file called client.xml that must appear in the application's CLASSPATH . A JAXM client that uses the provider only as a means of building profile-specific messages and uses the synchronous message delivery mechanism provided by SAAJ may be implemented as a standalone J2SE-based application. All other JAXM clients must be container-based . At the present time, this means that such clients must be hosted by a servlet.
The layout of the client.xml file is shown in Example 8-11.
Example 8-11. The JAXM client.xml file
<ClientConfig> <Endpoint>URI</Endpoint> <CallbackURL>URL</CallbackURL> <Proxy> <!-- Any number (including none) allowed <Host>hostname</Host> <Port>portNumber</Port> </Proxy> <Provider> <URI>providerURI</URI> <URL>providerURL</URL> </Provider> </ClientConfig>
The Endpoint element supplies the URI associated with the client itself. This is the URI that appears as the from address in all messages sent from this client (if the profile in use carries that information), and is the destination address to which messages sent to this client should be addressed. It may be a real URL, but is more likely to be a logical address. Providers that need to deliver messages to the client at this URI must be configured to send them to the client's local provider by including an Endpoint mapping in their provider.xml file, where the value associated with its URI child element matches the value of this URI element. Refer to Section 4.4.3 for a full description of the message delivery path and the way in which the values assigned to these elements are used.
The CallbackURL element is used when the provider receives a message addressed to the endpoint. As just noted, JAXM clients that receive asynchronous messages from a provider must be hosted in a servlet environment. This is most easily achieved by implementing the client as a subclass of JAXMServlet , which is part of the JAXM reference implementation. The value of the CallbackURL is the URL that corresponds to the instance of this servlet containing the JAXM client. See Section 4.3 for a complete example of a JAXM client hosted by JAXMServlet . In the case of a JAXM client hosted by a J2SE application, this value is unused.
The optional Proxy element can be used to configure the host and port number for an HTTP proxy that resides between the client application and its provider, if there is one. This element should not be included if the client can directly access the provider. Although the DTD for the client.xml file indicates that there can be any number of Proxy elements, at the time of this writing, only the first such element found is used.
The Provider element is used to locate the provider with which the client is associated. The URI child element contains a unique URI that identifies the provider implementation. For the JAXM provider supplied with the reference implementation, this must have the value http://java.sun.com/xml/jaxm/provider . The URL child element contains the URL for the outgoing message queue of the provider, which is constructed as follows:
The leading part of the URL is http://host:8081/jaxm-provider .
The final part of the URL is always sender , which selects the outgoing message queue.
A typical Provider element therefore looks like this:
<Provider> <URI>http://java.sun.com/xml/jaxm/provider</URI> <URL>http://localhost:8081/jaxm-provider/sender</URL> </Provider>