Network Deployment (Distributed operating systems), v8.0 > Develop and deploying applications > Develop web services - Invocation framework (WSIF) > Use WSIF to invoke web services > Link a WSIF service to the underlying implementation of the service > Link a WSIF service to a JMS-provided service
Write the WSDL extensions that let your WSIF service access a service at a JMS destination
Use the native Java Message Service (JMS) provider, Web Services Invocation Framework (WSIF) clients can treat a service that is available at a JMS destination as a Web service. Use this information, and associated code fragments, to help you to write the WSDL extensions. This topic assumes that you chose and configured a JMS provider when you installed WAS (either the default messaging provider, or another provider such as the WebSphere MQ messaging provider). If not, do so now as described in Choosing a messaging provider.
The WSDL extensions for JMS are identified with the namespace prefix jms. For example, <jms:binding>.
The supported operations are either one-way operations (send for JMS point-to-point messaging, or publish for JMS publish and subscribe messaging) or request-response operations (send and receive for JMS point-to-point messaging). The WSDL operations therefore specify either an input message only, or an input and an output message.
Operations that describe message interfaces with a native JMS binding do not have fault messages. No assumptions are made about the message schema or the semantics of message properties, therefore no distinction can be made between output and fault messages.
Use the following procedure, and associated code fragments, to help you to write the WSDL extensions that enable your WSIF service to access an underlying service at a JMS destination.
Procedure
- Set the JMS message body type.
You use the <jms:binding> extension to specify the JMS message body type:
<wsdl:binding ... > <jms:binding type="messageBodyType" /> ... </wsdl:binding>where messageBodyType is either ObjectMessage or TextMessage.
- Specify the parts to use for the input and output messages.
For JMS text messages and JMS object messages created from one or more WSDL message parts, you use the <jms:input> and <jms:output> extensions to specify the message parts to use for the JMS messages:
<wsdl:input ... > <jms:input parts="part1 part2 ..." /> </wsdl:input> <wsdl:output ... > <jms:output parts="part1 part2 ..." /> </wsdl:output>In the next example, the WSDL message has just one part that contains the complete message body. This message body might result from a mapping of some other representation (see the next step "Map the data types").
<wsdl:input ... > <jms:input parts="part1" /> </wsdl:input>If no parts are defined, then all the message parts are used.
- Map the data types.
You use the <format> extensions to map data types:
<wsdl:binding ... > <jms:binding type="..." /> <format:typeMapping encoding="Java" style="Java"> <format:typeMap typeName="..." formatType="targetType"/> </format:typemapping> ... </wsdl:binding>The value of targetType is dependent on the JMS message body type (see the step "Set the JMS message body type"). For JMS object messages, the target data type implements the java.io.Serializable class. For JMS text messages, the target data type is always java.lang.String.
The <format> extensions are also used in other bindings that deal with Java interfaces.
- Set the JMS headers and properties.
JMS does not make assumptions about message headers. For example, if the JMS provider is MQSeries then each JMS message carries an RFH2 header. However you can access data in this message header indirectly, by getting and setting JMS message properties.
When you want the application to pass a property into the Web Services Invocation Framework (WSIF) as a part on the WSIF message, you use a <jms:property> tag. When to hard code a property value into the WSDL, you use a <jms:propertyValue> tag. The <jms:propertyValue> tag contains a specification of a literal value and its associated XML schema type.
We can specify <jms:property> and <jms:propertyValue> extensions within the <wsdl:input> tag in the binding operation, and also within the <jms:address> tag. For the <wsdl:output> tag in the binding operation, you can only specify the <jms:property> extension. Property values that are set in the <jms:property> tag take precedence over values set in the < <jms:propertyValue> tag, and property values that are set in the binding operation (in the <input> and <output> tags) take precedence over values set in the <jms:address> tag.
Here is an example of the <jms:property> and <jms:propertyValue> tags nested within the <input> and <output> tags:
<wsdl:input ... > <jms:property name="propertyName" part="partName" /> <jms:propertyValue name="propertyName" type="xsdType" value="actualValue" /> </wsdl:input> <wsdl:output ... > <jms:property name="propertyName" part="partName" /> </wsdl:output>where propertyName identifies the JMS property that is associated with the header field, and partName identifies the message part that is associated with the property.
The JMS property identified by propertyName can be user-defined, or it can be one of the following predefined header fields:
Predefined JMS message header fields.
Column 1 specifies the header field value, and column 2 specifies the data type for that header field value.
Value Java type JMSMessageId java.lang.String JMSTimeStamp long JMSCorrelationId byte [ ] or java.lang.String JMSReplyTo javax.jms.Destination JMSDestination javax.jms.Destination JMSDeliveryMode int JMSRedelivered boolean JMSType java.lang.String JMSExpiration long JMSTimeToLive long See the JMS specification for restrictions that apply when setting JMS header field values. Attempts to set restricted values are ignored.
For application-defined JMS message properties, the Java types used in the native JMS binding implementation (used for calls to the corresponding JMS methods) are derived from the XML schema type in the abstract interface ( <wsdl:part> tag), and from the type mapping information in the format binding ( <format:typemap> tag).
- Handle transactions.
Independent of other JMS properties, the asynchronous processing of request-response operations has implications for callers running in a transaction scope. The send request part and the receive response part are separated into two transactions, because the send needs to be committed in order for the request message to become visible. Implementations that process WSDL for asynchronous request-response operations (such as WSIF) must therefore take the following additional actions:
- They must ensure that the send request transaction returns a correlation ID to the user, and provides a callback with which users can pass in the response message to process the receive response transaction.
- They might implement their own response message listener in order to recognize the arrival of response messages, and to manage the correlation to the request message.
Example
Example 1: JMS Text Message
The JMS text message contains a java.lang.String. In this example, the WSDL message contains only one part that represents the whole message body:
<wsdl:definitions ... > <!-- simple or complex types for input and output message --> <wsdl:types> ... </wsdl:types> <wsdl:message name="JmsOperationRequest"> ... </wsdl:message> <wsdl:message name="JmsOperationResponse"> ... </wsdl:message> <wsdl:portType name="JmsPortType"> <wsdl:operation name="JmsOperation"> <wsdl:input name="Request" message="tns:JmsOperationRequest"/> <wsdl:output name="Response" message="tns:JmsOperationResponse"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="JmsBinding" type="JmsPortType"> <jms:binding type="TextMessage" /> <format:typemapping style="Java" encoding="Java"> <format:typemap name="xsd:String" formatType="String" /> </format:typemapping> <wsdl:operation name="JmsOperation"> <wsdl:input message="JmsOperationRequest"> <jms:input parts="requestMessageBody" /> </wsdl:input> <wsdl:output message="JmsOperationResponse"> <jms:output parts="responseMessageBody" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="JmsService"> <wsdl:port name="JmsPort" binding="JmsBinding"> <jms:address destinationStyle="queue" jndiConnectionFactoryName="myQCF" jndiDestinationName="myDestination"/> </wsdl:port> </wsdl:service> </wsdl:definitions>As an extension to the previous JMS message example, the following example WSDL describes a request-response operation in which specific JMS property values of the request and response message are set for the request message and retrieved from the response message.
The JMS properties in the request message are set according to the values in the input message. Likewise, selected JMS properties of the response message are copied to the corresponding values of the output message. The direction of the mapping is determined by the appearance of the <jms:property> tag in the input or output section, respectively.
Example 2: JMS Message with JMS Properties
<wsdl:definitions ... > <!-- simple or complex types for input and output message --> <wsdl:types> ... </wsdl:types> <wsdl:message name="JmsOperationRequest"> <wsdl:part name="myInt" type="xsd:int"/> ... </wsdl:message> <wsdl:message name="JmsOperationResponse"> <wsdl:part name="myString" type="xsd:String"/> ... </wsdl:message> <wsdl:portType name="JmsPortType"> <wsdl:operation name="JmsOperation"> <wsdl:input name="Request" message="tns:JmsOperationRequest"/> <wsdl:output name="Response" message="tns:JmsOperationResponse"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="JmsBinding" type="JmsPortType"> <!-- the JMS message type might be any of the above --> <jms:binding type="..." /> <format:typemapping style="Java" encoding="Java"> <format:typemap name="xsd:int" formatType="int" /> ... </format:typemapping> <wsdl:operation name="JmsOperation"> <wsdl:input message="JmsOperationRequest"> <jms:property message="tns:JmsOperationRequest" parts="myInt" /> <jms:propertyValue name="myLiteralString" type="xsd:string" value="Hello World" /> ... </wsdl:input> <wsdl:output message="JmsOperationResponse"> <jms:property message="tns:JmsOperationResponse" parts="myString" /> ... </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="JmsService"> <wsdl:port name="JmsPort" binding="JmsBinding"> <jms:address destinationStyle="queue" jndiConnectionFactoryName="myQCF" jndiDestinationName="myDestination"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
WSIF and WSDL
Write the WSDL extension that lets your WSIF service access a SOAP over JMS service
Enable a WSIF client to invoke a web service through JMS
Link a WSIF service to a JMS-provided service
Related
JMS message header: The TimeToLive property reference