Oracle9iAS InterConnect Adapter for MQ Series Installation and User's Guide Release 2 (9.0.2) Part Number A95443-01 |
|
This chapter describes the design time and runtime concepts for the MQ Series adapter.
The MQ Series adapter can handle XML and D3L structured payload, for example:
<?xml...
.
A DTD can be imported using iStudio that governs how the MQ Series adapter parses a received XML document into an Oracle9iAS InterConnect Application View event and back again, and how an inbound Application View message is converted into an XML document. Use the XML message type when defining a new integration point in the event wizards.
The ota.type
parameter in the adapter.ini
file must be set to XML
and not D3L
.
When the MQ Series adapter operates in the XML payload mode, no transformations between the native view and the application view are performed on the messages that are sent or received through the MQ Series adapter, apart from the implied straight ASCII <-> Java object conversion or parsing. Any XSLT transformations take place before sending an XML document to Oracle9iAS InterConnect, or after receiving one from Oracle9iAS InterConnect.
In addition to pure XML documents, the MQ Series adapter also handles messages that conform to D3L data type definitions, which describe data translations between application view messages and native format.
An application based on the MQ Series adapter can use the use the D3L message type and import D3L data types. When these are selected in the correct wizard, messages received or sent by the MQ Series adapter must adhere to the fixed byte level lay-out defined in an D3L XML file.
Importing D3L data types can also be used to define common view data types.
This section describes the runtime concepts for the MQ Series adapter.
The MQ Series adapter is comprised of the MQ Series bridge and the agent. The following topics describe how the MQ Series adapter works.
Outbound messages are processed using the following steps:
mq.default.polling_interval
parameter. A new message in this queue indicates a new outbound message from MQ Series waiting to be received by the MQ Series adapter.
ota.type
parameter, builds the corresponding Oracle9iAS InterConnect application view message, and hands it off the Oracle9iAS InterConnect agent.
The relevant parameters in adapter.ini
pertaining to the outbound MQ Series endpoint are mq.default.receiver.*
and mq.default.event.*
.
If the ota.type
parameter is set to D3L
, the MQ Series bridge uses the D3L processor to parse from native or byte format to an Oracle9iAS InterConnect message object, which then is handed over to the agent as an application view event.
When the MQ Series adapter receives a message from the outbound MQ Series queue while operating in D3L mode, the message is construed as an opaque sequence of bytes. The challenge then becomes how to determine to which Oracle9iAS InterConnect event, and ultimately to which D3L file this message corresponds.
The MQ Series adapter provides six methods to determine this through a combination of header values found in the configured D3L files and the value of one of the mq.default.event.*
parameters in the adapter.ini
file. These methods are described below.
Using this parameter is the most primitive mode of operation. Using a hard coded event name for all outbound messages received from MQ Series is one example.
mq.default.event.name=Employee.updateInfo
This example requires that exactly one D3L file has the following header:
<?xml version="1.0" encoding="US-ASCII"?> <!DOCTYPE message SYSTEM "d3l.dtd"> <message name="updateInfo" object="Employee" type="... ...
Use this method if the sending MQ Series application is able to inform the MQ Series adapter about which event a message corresponds to by setting a specified message property to a given value.
To use this method, complete the following:
mq.default.event.property
parameter to the name of the message property which will contain the native event name.
mq.default.event.property=SAP_EvNm
This property will only assume the two distinct values Order.evtPut
and Order.evtGet
. Considering this, the following two D3L files should be defined:
Set the ota.d3ls
parameter to sap_put.xml,sap_get.xml
.
The name
and object
headers should correspond to the associated Oracle9iAS InterConnect event and business object names.
The MQ Series adapter also supports D3L disambiguation using the header and value attributes. For the MQ Series adapter, transport message headers corresponds to the MQ Series message properties. Consequently, transport message header values means the MQ Series message property values.
This mode allows the MQ Series message format property to be used to select the corresponding event name. This property is often referred to as the following:
MQFMT
com.ibm.mq.jms.JMSC.FORMAT_PROPERTY
Assume the MQFMT
field of a received message from MQ Series has the value Cus.new
.
This requires the following adapter.ini setting:
and the following D3L file:
<?xml version="1.0" encoding="US-ASCII"?> <!DOCTYPE message SYSTEM "d3l.dtd"> <message name="new" object="Cus" type="..." ...
Optionally, if the values in the MQFMT
field do not easily map into the Oracle9iAS InterConnect event names, the user can define a the mqfmt2event.ini
mapping file in the same directory where adapter.ini
is located. If present, it will be read and the specified event name mappings applied when a message is received. The format of the file is as follows:
<MQMFMT-field-value-1>=<OAI-business-object-name1>.<OAI-event-name1> <MQMFMT-field-value-2>=<OAI-business-object-name2>.<OAI-event-name2> ... <MQMFMT-field-value-n>=<OAI-business-object-namen>.<OAI-event-namen>
This event name resolution method allows a Java class call-out to be registered which is given a reference to the received JMS message. In return, the Java class call-out must tell the bridge which event name to which the message corresponds. The Java class must implement the oracle.oai.agent.adapter.mqseries.MQEventExit
interface, which has the following signature:
public interface MQEventExit { public String getEventName(javax.jms.Message jmsMessage) throws oracle.oai.agent.adapter.mqseries.MQBridgeException;
myEventExit.java
import oracle.oai.agent.adapter.mqseries.MQBridgeException; public class myEventExit implements oracle.oai.agent.adapter.mqseries.MQEventExit { public String getEventName(Message jmsMessage) throws MQBridgeException { try { if (jmsMessage instanceof TextMessage) { String body = ((TextMessage)jmsMessage).getText(); String bizObj = body.substring(1,10); String event = body.substring(21,30); return bizObj + "." + event; } else throw new MQBridgeException("Wrong message type"); } catch (Exception e) { throw new MQBridgeException("Error", e); } } }
The D3L syntax allows a magic header attribute to be specified. If specified, the header corresponds to a sequence of bytes, specified in UTF-8 bytes, hexadecimal, or octal, that should occur at the very beginning of the native-format message. If the magic attribute in one of the registered D3L files (defined in the ota.d3ls
parameter) matches the bytes at the beginning of the native message, that D3L header name and object attributes are chosen as the event name.
prod_getprice.xml
<?xml version="1.0" encoding="US-ASCII"?> <!DOCTYPE message SYSTEM "d3l.dtd"> <message name="getPrice" object="Product" type="..." magic="SYSPR01GETPRC" ...
If the byte stream of a received message begins with the characters SYSPR01GETPRC
, the event is resolved as Product.getPrice
and the shown D3L file is subsequently used to transform the native byte message into an Oracle9iAS InterConnect Message Object.
If any of the above methods fail, the MQ Series adapter falls back to a trial-and-error resolution scheme where each registered D3L file is tried until one succeeds. This means applying all files in the order they are listed in the ota.d3ls
parameter in the adapter.ini
file. If none of the D3L files succeed, the entire D3L disambiguation process for a given message will terminates and an error message is logged. The failed message is saved in the directory where the adapter.ini
file is located, under a name such as MQ.FailedMsg.<message-id>
.
The above disambiguation methods are tried in the following order:
The MQ Series adapter only supports sending to a single MQ Series inbound endpoint, as shown in Figure 3-2. A future edition of the MQ Series adapter will support multiple inbound endpoints.
The mq.default.sender.*
parameter in the adapter.ini
file pertains to the default inbound MQ Series endpoint.
The MQ Series adapter supports the Oracle9iAS InterConnect PUBLISH, REQUEST, and REPLY message types. Expressed in iStudio terms, the MQ Series adapter can publish or subscribe any event and invoke or implement any procedure.
The support for invoke and implement messages, such as Procedure calls, is enabled by the native support for request and reply messages in MQ Series, including its message correlation capability. It is only available when the MQ Series adapter operates in D3L mode.
In order to take advantage of this capability, a few extra steps need to be performed during configuration, including modifying the D3L files and defining correlation fields in iStudio.
The following instructions are based on a small example:
These data types must be defined in two separate D3L files, one defining the native input (request) data structure, and one defining the native output (reply) data structure. The following two D3L files could serve this purpose.
<?xml version="1.0" encoding="US-ASCII"?> <!DOCTYPE message SYSTEM "d3l.dtd"> <message type="getPriceInput" name="getPrice" object="Product"> <!-- ID type --> <unsigned4 id="ID" endian="little" /> <struct id="getPriceInput"> <field name="ProductID"> <typeref type="ID" /> </field> <field name="CustomerID"> <typeref type="ID" /> </field> </struct> </message>
<?xml version="1.0" encoding="US-ASCII"?> <!DOCTYPE message SYSTEM "d3l.dtd"> <message type="getPriceOutput" name="getPrice" object="Product" reply="Y"> <!-- ID type --> <unsigned4 id="ID" endian="little" /> <!-- Float, as decimal number format enclosed by '$' --> <number id="Float"><limstring delimiter="$" /></number> <struct id="getPriceOutput"> <field name="ProductID"> <typeref type="ID" /> </field> <field name="Price"> <typeref type="Float" /> </field> <field name="Discount"> <typeref type="Float" /> </field> </struct> </message>
It is assumed that the 'partner' application will be based on the Database adapter.
The next paragraphs describe the two possible scenarios, and how to correctly setup Oracle9iAS InterConnect to handle them:
To invoke a procedure using the MQ Series adapter in iStudio:
The Invoke Wizard--Select a Procedure page displays.
The Define Application View page displays.
getPriceIn.xml
file and mark as it as IN.
getPriceOut.xml
file and mark as it as OUT.
On... | Go to... |
---|---|
Windows |
|
UNIX |
|
ota.d3ls=getPriceIn.xml,getPriceOut.xml
getPriceOut.xml
D3L file as the REPLY. The MQ Series adapter does not allow two D3L files defining the same BusinessObject and EventName. Use the D3L message element attribute reply as follows:
<message type="getPriceOutput" name="getPrice" object="Product" reply="Y">
getPriceIn.xml
D3L file when it reads an outbound message from MQ Series, using header/value disambiguation. For example:
<message type="getPriceInput" name="getPrice" object= "Product" header="D3Lselector" value="getprice">
// This 3rd party application will send a REQUEST message to // OAI (Invoke role), and then await a REPLY. BytesMessage reqMessage = session.createBytesMessage(); byte[] getPriceMsg = new byte[] { 20, 0, 0, 0, 10, 0, 0, 0 }; reqMessage.writeBytes(nativeBytes, 0, nativeBytes.length); reqMessage.setJMSReplyTo((Destination)replyQueue); reqMessage.setStringProperty("D3Lselector", "getprice"); reqMessage.setIntProperty("JMS_IBM_MsgType", (int)1); // REQUEST // Send REQUEST queueSender.send(reqMessage); session.commit(); ... // Await REPLY Message replyMessage = queueReceiver.receive(); if (replyMessage instanceof BytesMessage) { if (replyMessage.getJMSCorrelationID(). equals(reqMessage.getJMSMessageID())) // Got my reply back!
PROCEDURE getprice(productID IN OUT INTEGER, customerID IN INTEGER, price OUT NUMBER, discount OUT NUMBER) IS BEGIN -- Just return something price := 1499.95; discount := 10.0; END;
Which gets invoked from the stub generated by iStudio:
PACKAGE BODY Product AS PROCEDURE imp_getPrice_QA_V1(io_PRODUCTID IN OUT NUMBER, i_CUSTOMERID IN NUMBER, o_PRICE OUT NUMBER, o_DISCOUNT OUT NUMBER) AS BEGIN getprice(io_PRODUCTID, i_CUSTOMERID, o_PRICE, o_DISCOUNT); END imp_getPrice_QA_V1;
To implement a procedure using the MQ Series adapter in iStudio:
The Implement Wizard--Select a Procedure page displays.
The Define Application View page displays.
getPriceIn.xml
file and mark as it as IN.
getPriceOut.xml
file and mark as it as OUT.
The Define Correlation Fields page displays.
On... | Go to... |
---|---|
Windows |
|
UNIX |
|
adapter.ini
file, for example:
ota.d3ls=getPriceIn.xml,getPriceOut.xml
getPriceOut.xml
D3L file as the REPLY. The MQ Series adapter does not allow two D3Ls defining the same BusinessObject and EventName. Use the D3L message element attribute reply, as follows:
<message type="getPriceOutput" name="getPrice" object="Product" reply="Y">
getPriceOut.xml
D3L file when it reads an outbound message from MQ Series. The following example uses header/value disambiguation:
<message type="getPriceOutput" name="getPrice" object="Product" reply="Y" header="D3Lselector" value="getpricereply">
// This 3rd party application will consume/read a REQUEST message from // OAI (Implement role), and return a REPLY. // Read REQUEST Message reqMessage = queueReceiver.receive(); if (reqMessage instanceof BytesMessage) { // Extract ProductID from request byte[] productID = new byte[4]; ((BytesMessage)reqMessage).readBytes(productID); // Construct reply (binary lay-out message) byte[] getPriceReply = new byte[] { 0, 0, 0, 0, // Product ID '$', '2','0','0','.','7','5','$', // Price '$', '1','5','.','1','0','$' // Discount }; // Copy the Product ID received in Request into the Reply // so OAI can correlate the reply to the original request. for (int i = 0; i < 4; i++) getPriceReply[i] = productID[i]; .... BytesMessage replyMessage = session.createBytesMessage(); replyMessage.writeBytes(getPriceReply, 0, getPriceReply.length); replyMessage.setJMSCorrelationID(reqMessage.getJMSMessageID()); replyMessage.setIntProperty("JMS_IBM_MsgType", (int)2); // REPLY replyMessage.setStringProperty("D3Lselector", "getpricereply"); // Send REPLY queueSender.send(replyMessage); session.commit();
-- Invoking procedure PROCEDURE INVGETPRICE(prodID IN NUMBER, custID IN NUMBER) AS moid NUMBER; aoid NUMBER; naoid NUMBER; BEGIN Product.crMsg_getPrice_QA_V1(moid, aoid); naoid := Product.cr_getPriceInput_getPriceInput(prodID, custID, moid, aoid); Product.inv_getPrice_QA_V1(moid, 'DBAPP'); END;
When Oracle9iAS InterConnect receives back a reply back from the MQ Series application, it invokes a procedure, for example:
PROCEDURE sub_getPrice_QA_V1(getPriceOutput IN dbapp_getPriceOutput_QA_V1) AS BEGIN -- Save Reply INSERT INTO price_reply (prodid, price, discount) VALUES (getPriceOutput.ProductID, getPriceOutput.Price, getPriceOutput.Discount); END sub_getPrice_QA_V1;
Start the MQ Series adapter using the start
script in the directory named after the MQ Series adapter. On Windows or Windows 2000, start it from the Service window available from the Start menu.
On... | Choose... |
---|---|
Windows NT |
Start > Settings > Control Panel > Services |
Windows 2000 |
Start > Settings > Control Panel > Administrative Tools > Services |
The Services window displays.
On... | Choose... |
---|---|
Windows NT |
Choose Start. |
Windows 2000 |
Right click the service and choose Start from the menu that displays. |
The following file displays an MQ Series adapter that was started successfully:
D:\oracle\ora902\oai\9.0.2\adapters\mqapp>D:\oracle\ora902\oai\9.0.2·in\JavaService.exe -debug "Oracle OAI Adapter 9.0.2 -mqapp" D:\oracle\ora9021\oai\9.0.2\adapters\mqapp\adapter.ini The Adapter service is starting.. Registering your application (MQAPP).. Initializing the Bridge oracle.oai.agent.adapter.mqseries.MQBridge.. Starting the Bridge oracle.oai.agent.adapter.mqseries.MQBridge.. Service started successfully.
Stop the MQ Series adapter using the stop
script in the directory named after the MQ Series adapter. On Windows NT or Windows 2000, stop the adapter from the Services window available from the Start menu.
On... | Choose... |
---|---|
Windows NT |
Start > Settings > Control Panel > Services |
Windows 2000 |
Start > Settings > Control Panel > Administrative Tools > Services |
The Services window displays.
On... | Choose... |
---|---|
Windows NT |
Choose Stop. |
Windows 2000 |
Right click the service and choose Stop from the menu that displays. |
Stop status can be verified by viewing the oailog.txt
files in the appropriate timestamped subdirectory of the log directory of the adapter directory.
|
Copyright © 2002 Oracle Corporation. All Rights Reserved. |
|