Oracle9i Application Developer's Guide - XML Release 1 (9.0.1) Part Number A88894-01 |
|
This chapter contains the following sections:
Oracle Advanced Queuing (AQ) provides database integrated message queuing functionality. AQ:
Integration of message queuing with Oracle9i database brings the integrity, reliability, recoverability, scalability, performance, and security features of Oracle9i to message queuing. Integration with Oracle9i also facilitates the extraction of intelligence from message flows.
XML has emerged as a standard format for business communications. XML is being used not only to represent data communicated between business applications, but also, the business logic that is encapsulated in the XML.
In Oracle9i, AQ supports native XML messages and also allows AQ operations to be defined in the XML-based Internet-Data-Access-Presentation (IDAP) format. IDAP, an extensible message invocation protocol, is built on Internet standards, using HTTP and email protocols as the transport mechanism, and XML as the language for data presentation. Clients can access AQ using this.
See "Internet-Data-Access-Presentation (IDAP)" .
Figure 9-1 shows an Oracle9i database using AQ to communicate with three applications, with XML as the message payload. The general tasks performed by AQ in this scenario are:
This is an intra- and inter-business scenario where XML messages are passed asynchronously among applications using AQ.
Oracle uses this in its enterprise application integration products. XML messages are sent from applications to an AQ hub, here shown as an OIS hub. This serves as a "message server" for any application that wants the message. Through this hub and spoke architecture, XML messages can be communicated asynchronously to multiple loosely-coupled receiving applications.
Figure 9-1 shows XML payload messages transported using AQ in the following ways:
A critical challenge facing enterprises today is application integration. Application integration involves getting multiple departmental applications to cooperate, coordinate, and synchronize in order to execute complex business transactions.
Advanced Queuing enables hub-and-spoke architecture for application integration. It makes integrated solution easy to manage, easy to configure, and easy to modify with changing business needs.
Message management provided by AQ is not only used to manage the flow of messages between different applications, but also, messages can be retained for future auditing and tracking, and extracting business intelligence.
AQ also provides SQL views to look at the messages. These SQL views can be used to analyze the past, current, and future trends in the system.
AQ provides the flexibility of configuring communication between different applications.
You can now perform AQ operations over the Internet by using Internet Data Access Presentation (IDAP). IDAP defines the message structure using XML. IDAP- structured message is sent over the Internet using using transport protocols such as HTTP or SMTP.
The Internet Data Access Presentation (IDAP) uses the Content-Type of text/xml
to specify the body of the request containing an XML-encoded method request. XML provides the presentation for IDAP request and response messages as follows:
Figure 9-2 shows the following components needed to send HTTP messages:
The AQ client program sends XML messages (conforming to IDAP) to the AQ servlet. Any HTTP client, for example Web browsers, can be used. The Web server/ServletRunner hosting the AQ servlet interprets the incoming XML messages. Examples include Apache/Jserv or Tomcat. The AQ servlet connects to the Oracle database server and performs operations on the users' queues.
Figure 9-3 shows IDAP architecture when using SMTP. For SMTP, you will need the following two additional components:
The Email server verifies client signatures using certificates stored in LDAP and then routes the request to the AQ servlet.
A method invocation is performed by creating the request header and body and processing the returned response header and body. The request and response headers can consist of standard transport protocol-specific and extended headers.
The POST
method within the HTTP request header performs the IDAP method invocation. The request should include the header IDAPMethodName,
whose value indicates the method to be invoked on the target. The value consists of a URI followed by a "#", followed by a method name (which must not include the "#" character), as follows:
IDAPMethodName: http://ns.oracle.com/AQ/schemas/access#AQXmlSend
The URI used for the interface must match the implied or specified namespace qualification of the method name element in the IDAP:Body
part of the payload.
In the case of SMTP (email), the method invocation can be done by the filter interface of the email server, which invokes a Java method with the email-message-body as argument. This results in remote invocation of the POST
method on the AQ servlet. The response is emailed directly to the recipient specified in the reply of the message. The response header can contain SMTP-protocol-related headers also.
IDAP structures a message request or response as follows:
The tag of this root element is IDAP:Envelope
. IDAP defines a global attribute IDAP:encodingStyle
that indicates serialization rules used instead of those described by the IDAP specification. This attribute may appear on any element and is scoped to that element and all child elements not themselves containing such an attribute. Omitting IDAP:encodingStyle
means that type specification has been followed (unless overridden by a parent element).
The IDAP envelope also contains namespace declarations and additional attributes, provided they are namespace-qualified. Additional namespace-qualified subelements can follow the body.
The tag of this first element under the root is IDAP:Header
. An IDAP header passes necessary information, such as the transaction ID, with the request. The header is encoded as a child of the IDAP:Envelope
XML element. Headers are identified by the name element and are namespace-qualified. A header entry is encoded as an embedded element.
The IDAP body, tagged IDAP:Body
, contains a first subelement whose name is the method name. This method request element contains elements for each input and output parameter. The element names are the parameter names. The body also contains IDAP: Fault
, indicating information about an error.
For performing AQ operations, the IDAP body must contain an AQ XML document. The AQ XML document has the namespace http://ns.oracle.com/AQ/schemas/access
IDAP method invocation consists of a method request and optionally a method response. The IDAP method request and method response are HTTP request and response, respectively, whose content is an XML document that consists of the root and mandatory body elements. This XML document is referred to as IDAP payload in the rest of this chapter.
The IDAP payload is defined as follows:
At the receiving site, a request can have one of the following four outcomes:
In (c) and (d), additional message headers may, for extensibility, again be present in the request results.
The results of the request are provided in a request-response format. The HTTP response must be of Content-Type "text/xml".
An IDAP result indicates success. An a error indicates failure. The method response will never contain both a result and an error. The different types of responses and errors are described in the next section
The body of an IDAP message is an AQ XML document, which represents:
Client requests for enqueue--SEND
and PUBLISH
requests--use the following methods:
AQXmlSend
--to enqueue to a single-consumer queue
AQXmlPublish
--to enqueue to multiconsumer queues/topics
AQXmlSend
and AQXmlPublish
take the arguments and argument attributes shown in Table 9-1. Required arguments are shown in bold.
AQ supports messages of the following types:
All these types of queues can be accessed using IDAP. If the queue holds messages in RAW, Oracle object, or JMS format, XML payloads are transformed to the appropriate internal format during enqueue and stored in the queue. During dequeue, when messages are obtained from queues containing messages in any of the above formats, they are converted to XML before being sent to the client.
The message payload type depends on the type of the queue on which the operation is being performed. A discussion of the queue types follows:
The contents of RAW queues are raw bytes. The user must supply the hex representation of the message payload in the XML message. For example, <raw>023f4523</raw>
.
For ADT queues that are not JMS queues (that is, they are not type AQ$_JMS_*
), the type of the payload depends on the type specified while creating the queue table that holds the queue. The XML specified here must map to the SQL type of the payload for the queue table.
Assume the queue is defined to be of type EMP_TYP
, which has the following structure:
create or replace type emp_typ as object ( empno NUMBER(4), ename VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7,2), comm NUMBER(7,2) deptno NUMBER(2));
The corresponding XML representation is:
<EMP_TYP> <EMPNO>1111</EMPNO> <ENAME>Mary</ENAME> <MGR>5000</MGR> <HIREDATE>1996-01-01 0:0:0</HIREDATE> <SAL>10000</SAL> <COMM>100.12</COMM> <DEPTNO>60</DEPTNO> </EMP_TYP>
For queues with JMS types (that is, those with payloads of type AQ$_JMS_*
), there are four different XML elements, depending on the JMS type. Hence, IDAP supports queues/topics with the following JMS types:
Table 9-2 lists the JMS types and XML components. The distinct XML element for each JMS type is shown in its respective column. Required elements are shown in bold.
All JMS messages consist of the following common elements:
oracle_jms_properties
, which consists of
type
--type of the message
reply_to
--consists of an agent_name
, address
, and protocol
userid
--supplied by AQ; client cannot specify
appid
--application identifier
groupid
--group identifier
group_sequence
--sequence within the group identified by group_id
timestamp
--the time the message was sent, which cannot be specified during enqueue. It is automatically populated in a message that is dequeued.
recv_timestamp
--the time the message was received
user_properties
--in addition to the above predefined properties, users can also specify their own message properties as name-value pairs. The user_properties
consists of a list of property elements. Each property is a name-value pair consisting of the following:
name
--property name
int_value
--integer property value or
string_value
--string property value or
long_value
--long property value or
double_value
--double property value or
boolean_value
--boolean property value or
float_value
-- float property value or
short_value
--short property value or
byte_value
--byte property value or
The following examples show enqueue requests using the different message and queue types.
The queue QS.NEW_ORDER_QUE
has a payload of type ORDER_TYP
.
<?xml version="1.0"?> <Envelope xmlns= "http://ns.oracle.com/AQ/schemas/envelope"> <Body> <AQXmlSend xmlns = "http://ns.oracle.com/AQ/schemas/access"> <producer_options> <destination>QS.NEW_ORDERS_QUE</destination> </producer_options> <message_set> <message_count>1</message_count> <message> <message_number>1</message_number> <message_header> <correlation>ORDER1</correlation> <sender_id> <agent_name>scott</agent_name> </sender_id> </message_header> <message_payload> <ORDER_TYP> <ORDERNO>100</ORDERNO> <STATUS>NEW</STATUS> <ORDERTYPE>URGENT</ORDERTYPE> <ORDERREGION>EAST</ORDERREGION> <CUSTOMER> <CUSTNO>1001233</CUSTNO> <CUSTID>MA1234555623212</CUSTID> <NAME>AMERICAN EXPRESS</NAME> <STREET>EXPRESS STREET</STREET> <CITY>REDWOOD CITY</CITY> <STATE>CA</STATE> <ZIP>94065</ZIP> <COUNTRY>USA</COUNTRY> </CUSTOMER> <PAYMENTMETHOD>CREDIT</PAYMENTMETHOD> <ITEMS> <ITEMS_ITEM> <QUANTITY>10</QUANTITY> <ITEM> <TITLE>Perl</TITLE> <AUTHORS>Randal</AUTHORS> <ISBN>ISBN20200</ISBN> <PRICE>19</PRICE> </ITEM> <SUBTOTAL>190</SUBTOTAL> </ITEMS_ITEM> <ITEMS_ITEM> <QUANTITY>20</QUANTITY> <ITEM> <TITLE>XML</TITLE> <AUTHORS>Micheal</AUTHORS> <ISBN>ISBN20212</ISBN> <PRICE>59</PRICE> </ITEM> <SUBTOTAL>590</SUBTOTAL> </ITEMS_ITEM> </ITEMS> <CCNUMBER>NUMBER01</CCNUMBER> <ORDER_DATE>2000-08-23 0:0:0</ORDER_DATE> </ORDER_TYP> </message_payload> </message> </message_set> </AQXmlSend> </Body> </Envelope>
The multiconsumer queue AQUSER.EMP_TOPIC
has a payload of type EMP_TYP
. EMP_TYP
has the following structure:
create or replace type emp_typ as object ( empno NUMBER(4), ename VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7,2), comm NUMBER(7,2) deptno NUMBER(2));
A PUBLISH
request has the following format:
<?xml version="1.0"?> <Envelope xmlns= "http://ns.oracle.com/AQ/schemas/envelope"> <Body> <AQXmlPublish xmlns = "http://ns.oracle.com/AQ/schemas/access"> <producer_options> <destination>AQUSER.EMP_TOPIC</destination> </producer_options><message_set> <message_count>1</message_count> <message> <message_number>1</message_number> <message_header> <correlation>NEWEMP</correlation> <sender_id> <agent_name>scott</agent_name> </sender_id> </message_header> <message_payload> <EMP_TYP> <EMPNO>1111</EMPNO> <ENAME>Mary</ENAME> <MGR>5000</MGR> <HIREDATE>1996-01-01 0:0:0</HIREDATE> <SAL>10000</SAL> <COMM>100.12</COMM> <DEPTNO>60</DEPTNO> </EMP_TYP> </message_payload> </message> </message_set> </AQXmlPublish> </Body> </Envelope>
The JMS queue AQUSER.JMS_TEXTQ
has payload type JMS Text message (SYS.AQ$_JMS_TEXT_MESSAGE). The send request has the following format:
<?xml version="1.0"?> <Envelope xmlns= "http://ns.oracle.com/AQ/schemas/envelope"> <Body> <AQXmlSend xmlns = "http://ns.oracle.com/AQ/schemas/access"> <producer_options> <destination>AQUSER.JMS_TEXTQ</destination> </producer_options> <message_set> <message_count>1</message_count> <message> <message_number>1</message_number> <message_header> <correlation>text_msg</correlation> <sender_id> <agent_name>john</agent_name> </sender_id> </message_header> <message_payload> <jms_text_message> <oracle_jms_properties> <appid>AQProduct</appid> <groupid>AQ</groupid> </oracle_jms_properties> <user_properties> <property> <name>Country</name> <string_value>USA</string_value> </property> <property> <name>State</name> <string_value>California</string_value> </property> </user_properties> <text_data>All things bright and beautiful</text_data> </jms_text_message> </message_payload> </message> </message_set> </AQXmlSend> </Body> </Envelope>
<?xml version="1.0"?> <Envelope xmlns= "http://ns.oracle.com/AQ/schemas/envelope"> <Body> <AQXmlPublish xmlns = "http://ns.oracle.com/AQ/schemas/access"> <producer_options> <destination>AQUSER.EMP_TOPIC</destination> </producer_options> <message_set> <message_count>1</message_count> <message> <message_number>1</message_number> <message_header> <correlation>NEWEMP</correlation> <sender_id> <agent_name>scott</agent_name> </sender_id> </message_header> <message_payload> <EMP_TYP> <EMPNO>1111</EMPNO> <ENAME>Mary</ENAME> <MGR>5000</MGR> <HIREDATE>1996-01-01 0:0:0</HIREDATE> <SAL>10000</SAL> <COMM>100.12</COMM> <DEPTNO>60</DEPTNO> </EMP_TYP> </message_payload> </message> </message_set> <AQXmlCommit/> </AQXmlPublish> </Body> </Envelope>
Client requests for dequeue use the AQXmlReceive
method. Table 9-3 lists AQXmlReceive
method's arguments and argument attributes. Required arguments are shown in bold.
The following examples show dequeue requests using different attributes of AQXmlReceive
.
Using the single-consumer queue QS.NEW_ORDERS_QUE
, the receive request has the following format:
<?xml version="1.0"?> <Envelope xmlns= "http://ns.oracle.com/AQ/schemas/envelope"> <Body> <AQXmlReceive xmlns = "http://ns.oracle.com/AQ/schemas/access"> <consumer_options> <destination>QS.NEW_ORDERS_QUE</destination> <wait_time>0</wait_time> </consumer_options> </AQXmlReceive> </Body> </Envelope>
Using the multiconsumer queue AQUSER.EMP_TOPIC
with subscriber APP1
and condition deptno=60
, the receive request has the following format:
<?xml version="1.0"?> <Envelope xmlns= "http://ns.oracle.com/AQ/schemas/envelope"> <Body> <AQXmlReceive xmlns = "http://ns.oracle.com/AQ/schemas/access"> <consumer_options> <destination>AQUSER.EMP_TOPIC</destination> <consumer_name>APP1</consumer_name> <wait_time>0</wait_time> <selector> <condition>tab.user_data.deptno=60</condition> </selector> </consumer_options> </AQXmlReceive> </Body> </Envelope>
In the dequeue request examples, if you include AQXmlCommit
at the end of the RECEIVE
request, the transaction is committed upon completion of the operation. In "IDAP Dequeue Request Example 1-- Receiving Messages from a Single-Consumer Queue", the receive request can include the commit flag as follows:
<?xml version="1.0"?> <Envelope xmlns= "http://ns.oracle.com/AQ/schemas/envelope"> <Body> <AQXmlReceive xmlns = "http://ns.oracle.com/AQ/schemas/access"> <consumer_options> <destination>QS.NEW_ORDERS_QUE</destination> <wait_time>0</wait_time> </consumer_options> <AQXmlCommit/> </AQXmlReceive> </Body> </Envelope>
Messages are dequeued in REMOVE
mode by default. To receive messages from QS.NEW_ORDERS_QUE
in BROWSE
mode, modify the receive request as follows:
<?xml version="1.0"?> <Envelope xmlns= "http://ns.oracle.com/AQ/schemas/envelope"> <Body> <AQXmlReceive xmlns = "http://ns.oracle.com/AQ/schemas/access"> <consumer_options> <destination>QS.NEW_ORDERS_QUE</destination> <wait_time>0</wait_time> <dequeue_mode>BROWSE</dequeue_mode> </consumer_options> </AQXmlReceive> </Body> </Envelope>
Client requests for registration use the AQXmlRegister
method. Table 9-4 lists AQXmlRegister
's arguments and argument attributes. Required arguments are shown in bold.
To notify an email address of messages enqueued for consumer APP1
in queue AQUSER.EMP_TOPIC
, the register request has the following format:
<?xml version="1.0"?> <Envelope xmlns= "http://ns.oracle.com/AQ/schemas/envelope"> <Body> <AQXmlRegister xmlns = "http://ns.oracle.com/AQ/schemas/access"> <register_options> <destination>AQUSER.EMP_TOPIC</destination> <consumer_name>APP1</consumer_name> <notify_url>mailto:app1@hotmail.com</notify_url> </register_options> <AQXmlCommit/> </AQXmlRegister> </Body> </Envelope>
A request to commit all actions performed by the user in a session uses the AQXmlCommit
method.
A commit request has the following format.
<?xml version="1.0"?> <Envelope xmlns="http://ns.oracle.com/AQ/schemas/envelope"> <Body> <AQXmlCommit xmlns="http://ns.oracle.com/AQ/schemas/access"/> </Body> </Envelope>
A request to roll back all actions performed by the user in a session uses the AQXmlRollback
method. Actions performed with IMMEDIATE
visibility are not rolled back.
A rollback request has the following format:
<?xml version="1.0"?> <Envelope xmlns="http://ns.oracle.com/AQ/schemas/envelope"> <Body> <AQXmlRollback xmlns="http://ns.oracle.com/AQ/schemas/access"/> </Body> </Envelope>
The response to an enqueue request to a single-consumer queue uses the AQXmlSendResponse
method. The components of the response are shown in Table 9-5.
The result of a SEND
request to the single consumer queue QS.NEW_ORDERS_QUE
has the following format:
<?xml version = '1.0'?> <Envelope xmlns="http://ns.oracle.com/AQ/schemas/envelope"> <Body> <AQXmlSendResponse xmlns="http://ns.oracle.com/AQ/schemas/access"> <status_response> <status_code>0</status_code> </status_response> <send_result> <destination>QS.NEW_ORDERS_QUE</destination> <message_id>12341234123412341234</message_id> </send_result> </AQXmlSendResponse> </Body> </Envelope>
The response to an enqueue request to a multiconsumer queue or topic uses the AQXmlPublishResponse
method. The components of the response are shown in Table 9-6.
The result of a SEND
request to the multiconsumer queue AQUSER.EMP_TOPIC
has the following format:
<?xml version = '1.0'?> <Envelope xmlns="http://ns.oracle.com/AQ/schemas/envelope"> <Body> <AQXmlPublishResponse xmlns="http://ns.oracle.com/AQ/schemas/access"> <status_response> <status_code>0</status_code> </status_response> <publish_result> <destination>AQUSER.EMP_TOPIC</destination> <message_id>23434435435456546546546546</message_id> </publish_result> </AQXmlPublishResponse> </Body> </Envelope>
The response to a dequeue request uses the AQXmlReceiveResponse
method. The components of the response are shown in Table 9-7.
The result of a RECEIVE
request on the queue AQUSER.EMP_TOPIC
with a payload of type EMP_TYP
has the following format:
<?xml version = '1.0'?> <Envelope xmlns="http://ns.oracle.com/AQ/schemas/envelope"> <Body> <AQXmlReceiveResponse xmlns="http://ns.oracle.com/AQ/schemas/access"> <status_response> <status_code>0</status_code> </status_response> <receive_result> <destination>AQUSER.EMP_TOPIC</destination> <message_set> <message_count>1</message_count> <message> <message_number>1</message_number> <message_header> <message_id>1234344545565667</message_id> <correlation>TKAXAP10</correlation> <priority>1</priority> <delivery_count>0</delivery_count> <sender_id> <agent_name>scott</agent_name> </sender_id> <message_state>0</message_state> </message_header> <message_payload> <EMP_TYP> <EMPNO>1111</EMPNO> <ENAME>Mary</ENAME> <MGR>5000</MGR> <HIREDATE>1996-01-01 0:0:0</HIREDATE> <SAL>10000</SAL> <COMM>100.12</COMM> <DEPTNO>60</DEPTNO> </EMP_TYP> </message_payload> </message> </message_set> </receive_result> </AQXmlReceiveResponse> </Body> </Envelope>
The response to a register request uses the AQXmlRegisterResponse
method, which consists of status_response
. (SeeTable 9-7 for a description of status_response
.)
The response to a commit request uses the AQXmlCommitResponse method, which consists of status_response
. (SeeTable 9-7 for a description of status_response
.)
The response to a commit request has the following format:
<?xml version = '1.0'?> <Envelope xmlns="http://ns.oracle.com/AQ/schemas/envelope"> <Body> <AQXmlCommitResponse xmlns="http://ns.oracle.com/AQ/schemas/access"> <status_response> <status_code>0</status_code> </status_response> </AQXmlCommitResponse> </Body> </Envelope>
The response to a rollback request uses the AQXmlRollbackResponse
method, which consists of status_response
. (SeeTable 9-7 for a description of status_response
.)
When an event for which a client has registered occurs, a notification is sent to the client at the URL specified in the REGISTER
request. AQXmlNotification
consists of:
In case of an error in any of the above requests, a FAULT
is generated. The FAULT
element consists of:
faultcode
- error code for fault
faultstring
- indicates a client error or a server error. A client error means that the request is not valid. Server error indicates that the AQ servlet has not been set up correctly
detail
, which consists of
IDAP presentation exposes the following two schemas to the client. All documents sent by the Parser are validated against these two schemas:
http://ns.oracle.com/AQ/schemas/envelope
This describes the structure of the document. Each document has an envelope, header, and body.
http://ns.oracle.com/AQ/schemas/access
This describes the IDAP body contents for Internet access to AQ features.
AQXMLServlet
is a Java class that extends oracle.AQ.xml.AQxmlServlet
class. AQxmlServlet
class in turn extends javax.servlet.http.HttpServlet
class.
The general AQ client procedure making a request using HTTP to the AQ Servlet, is as follows:
This opens a connection to port 8000 on aq.us.oracle.com
<?xml version="1.0"?> <Envelope xmlns="http://ns.oracle.com/AQ/schemas/envelope"> <Body> <AQXmlSend xmlns = "http://ns.oracle.com/AQ/schemas/access"> <producer_options> <destination>OE.OE_NEW_ORDERS_QUE</destination> </producer_options> <message_set> <message_count>1</message_count> <message> <message_number>1</message_number> <message_header> <correlation>XML_ADT_SINGLE_ENQ</correlation> <sender_id> <agent_name>john</agent_name> </sender_id> </message_header> <message_payload> <ORDER_TYP> <ORDERNO>100</ORDERNO> <STATUS>NEW</STATUS> <ORDERTYPE>NORMAL</ORDERTYPE> <ORDERREGION>EAST</ORDERREGION> <CUSTOMER> <CUSTNO>1001233</CUSTNO> <CUSTID>JOHN</CUSTID> <NAME>AMERICAN EXPRESS</NAME> <STREET>EXPRESS STREET</STREET> <CITY>REDWOOD CITY</CITY> <STATE>CA</STATE> <ZIP>94065</ZIP> <COUNTRY>USA</COUNTRY> </CUSTOMER> <PAYMENTMETHOD>CREDIT</PAYMENTMETHOD> <ITEMS> <ITEMS_ITEM> <QUANTITY>10</QUANTITY> <ITEM> <TITLE>Perl</TITLE> <AUTHORS>Randal</AUTHORS> <ISBN>ISBN20200</ISBN> <PRICE>19</PRICE> </ITEM> <SUBTOTAL>190</SUBTOTAL> </ITEMS_ITEM> </ITEMS> <CCNUMBER>NUMBER01</CCNUMBER> <ORDER_DATE>2000-08-23 0:0:0</ORDER_DATE> </ORDER_TYP> </message_payload> </message> </message_set> </AQXmlSend> </Body> </Envelope>
The AQ servlet's general procedure for making a request using HTTP is as follows:
init( )
method is invoked. The init()
method creates a connection pool to the Oracle9i server using the AQxmlDataSource
parameters (sid, host, port, aq servlet super-user name, password) provided by the client.
<Envelope xmlns="http://ns.oracle.com/AQ/schemas/envelope"> <Body> <AQXmlSendResponse xmlns="http://ns.oracle.com/AQ/schemas/access"> <status_response> <status_code>0</status_code> </status_response> <send_result> <destination>OE.OE_NEW_ORDERS_QUE</destination> <message_id>12341234123412341234123412341234</message_id> </send_result> </AQXmlSendResponse> </Body> </Envelope>
The response also includes the session id in the HTTP headers as a cookie. For example: Tomcat sends back session ids as JSESSIONID=239454ds2343
Advanced Queuing (AQ) supports the storage of XML documents in queues and provides the ability to query the XML documents. XML can be used with Oracle AQ in the following two cases:
With Oracle AQ, you can use object types to structure and manage the payload of messages. Using strongly typed content, content whose format is defined by an external type system, the following AQ features are made available:
You can create queues with payloads that contain XMLType attributes. These can be used for transmitting and storing messages that contain XML documents. By defining Oracle objects with XMLType attributes, you can do the following:
XMLType.existsNode()
, XMLType.extract()
, and so on.
For details on XMlType operations refer to Application Developer's guide - XML
XMLType.existsNode()
and XMLType.extract()
.
In the BooksOnline application, assume that the Overseas Shipping site represents the order as ORDER_XML_TYP
, with the order information in an XMLType attribute. The Order Entry site represents the order as an Oracle object, ORDER_TYP
.
ORDER_XML_TYP
is a composite type that contains an XMLType attribute:
CREATE OR REPLACE TYPE order_xml_typ as OBJECT ( orderno NUMBER, details XMLTYPE);
The Overseas queue table and queue are created as follows:
BEGIN dbms_aqadm.create_queue_table( queue_table => 'OS_orders_pr_mqtab', comment => 'Overseas Shipping MultiConsumer Orders queue table', multiple_consumers => TRUE, queue_payload_type => 'OS.order_xml_typ', compatible => '8.1'); END; BEGIN dbms_aqadm.create_queue ( queue_name => 'OS_bookedorders_que', queue_table => 'OS_orders_pr_mqtab'); END;
You can specify transformations between different Oracle and user-defined types. Transformations can be created in any of the following ways:
with a return type of the target type.
Only one-to-one message transformation is supported. The transformation engine is integrated with Advanced Queuing to facilitate transformation of messages as they move through the database messaging system.
An Advanced Queuing application can enqueue or dequeue messages from a queue in the format specified by the application. An application can also specify a message format when subscribing to queues.
The AQ propagator transforms messages to the format of the destination queue message, as specified by the remote subscription. The transformation function cannot write the database state or commit/rollback the current transaction. Transformations are exported with a schema or a full database export.
An Order Entry site represents the order as Oracle object, ORDER_TYP
.
Since the Overseas Shipping site subscribes to messages in the OE_BOOKEDORDERS_QUE
queue, a transformation is applied before messages are propagated from the Order Entry site to the Overseas Shipping site.
ORDER_XML_TYP
is a composite type that contains an XMLType attribute:
CREATE OR REPLACE TYPE order_xml_typ as OBJECT ( orderno NUMBER, details XMLTYPE);
The transformation is defined as follows:
CREATE OR REPLACE FUNCTION CONVERT_TO_ORDER_XML(input_order TYPE OE.ORDER_TYP) RETURN OS.ORDER_XML_TYP AS xdata SYS.XMLType; new_order OS.ORDER_XML_TYP; BEGIN xdata := XMLType.createXML(input_order, NULL); new_order := OS.ORDER_XML_TYP(input_order.orderno, xdata); RETURN new_order; END CONVERT_TO_ORDER_XML; execute dbms_transform.create_transformation( schema => 'OS', name => 'OE2XML', from_schema => 'OE', from_type => 'ORDER_TYP', to_schema => 'OS', to_type => 'ORDER_XML_TYP', transformation => 'CONVERT_TO_ORDER_XML(source.user_data)'); /* Add a rule-based subscriber for Overseas Shipping to the Booked orders queues with Transformation. Overseas Shipping handles all non-US orders: */ DECLARE subscriber aq$_agent; BEGIN subscriber := aq$_agent('Overseas_Shipping','OS.OS_bookedorders_que',null); dbms_aqadm.add_subscriber( queue_name => 'OE.OE_bookedorders_que', subscriber => subscriber, rule => 'tab.user_data.orderregion = ''INTERNATIONAL''' transformation => 'OS.OE2XML'); END;
Assume that an application processes orders for customers in Canada. This application can dequeue messages using the following procedure:
/* Create procedures to enqueue into single-consumer queues: */ create or replace procedure get_canada_orders() as deq_msgid RAW(16); dopt dbms_aq.dequeue_options_t; mprop dbms_aq.message_properties_t; deq_order_data OS.order_xml_typ; no_messages exception; pragma exception_init (no_messages, -25228); new_orders BOOLEAN := TRUE; begin dopt.wait := 1; /* Specify dequeue condition to select Orders for Canada */ dopt.deq_condition := 'tab.user_data.xdata.extract(
''/ORDER_TYP/CUSTOMER/COUNTRY/text()'').getStringVal()=''CANADA'''; dopt.consumer_name : = 'Overseas_Shipping'; WHILE (new_orders) LOOP BEGIN dbms_aq.dequeue( queue_name => 'OS.OS_bookedorders_que', dequeue_options => dopt, message_properties => mprop, payload => deq_order_data, msgid => deq_msgid); commit; dbms_output.put_line(' Order for Canada - Order No: ' || deq_order_data.orderno); EXCEPTION WHEN no_messages THEN dbms_output.put_line (' ---- NO MORE ORDERS ---- '); new_orders := FALSE; END; END LOOP; end;
We are exchanging XML documents from one business area to another using Oracle Advanced Queuing. Each message received or sent includes an XML header, XML attachment (XML data stream), DTDs, and PDF files. We need to store all this information, including some imagery files, in the database table, in this case, the queuetable.
Can we enqueue this message into an Oracle queue table as one record or one piece? Or do we have to enqueue this message as multiple records, such as one record for XML data streams as CLOB type, one record for PDF files as RAW type? Then somehow specify that these sets of records are correlated? Also, we want to ensure that we dequeue this.
You can achieve this in the following ways:
Does this mean that we specify the payload type as CLOB first, then enqueue and store all the pieces, XML message data stream, DTDs, and PDF,... as a single message payload in the Queue table? If so, how can we separate this single message into individual pieces when we dequeue this message?
No. You create an object type, for example:
CREATE TYPE mypayload_type as OBJECT (xmlDataStream CLOB, dtd CLOB, pdf BLOB);
Then store it as a single message.
We want to use the queue table to support message assignments. For example, when other business areas send messages to Oracle, they do not know who should be assigned to process these messages, but they know the messages are for Human Resources (HR). So all messages will go to the HR supervisor.
At this point, the message has been enqueued in the queue table. The HR supervisor is the only recipient of this message, and the entire HR staff have been pre-defined as subscribers for this queue). Can the HR supervisor add new recipients, namely additional staff, to the message_properties.recipient_list on the existing the message in the queue table?
We do not have multiple consumers (recipients) when the messages are enqueued, but we want to replace the old recipient, or add new recipients after the message has already been in the queue table. This new message will then be dequeued by the new recipient. Is this workable? Or do we have to remove the message from old recipient, then enqueue the same message contents to the new recipient?
You cannot change the recipient list after the message is enqueued. If you do not specify a recipient list then subscribers can subscribe to the queue and dequeue the message.
In your case, the new recipient should be a subscriber to the queue. Otherwise, you will have to dequeue the message and enqueue it again with the new recipient.
In the OTN document, "Using XML in Oracle Database Applications, Part 4, Exchanging Business Data Among Applications" Nov. 1999, it says that an Oracle database can enqueue and dequeue XML messages and process them. How does it do this?
Do I have to use XML SQL Utility (XSU) in order to insert an XML file into a table before processing it, or can I enqueue an XML file directly, parse it, and dispatch its messages via the AQ process? Must I use XML SQL Utility every time I want to INSERT or UPDATE XML data into an Oracle Database?
AQ supports enqueing and dequeing objects. These objects can have an attribute of type XMLType containing an XML Document, as well as other interested "factored out" metadata attributes that might make sense to send along with the message. Refer to the latest AQ document, Oracle9i Application Developer's Guide - Advanced Queuing, to get specific details and see more examples.
We need a tool to parse messages with XML content, from an AQ queue and then update tables and fields in an ODS (Operational Data Store). In short, we want to retrieve and parse XML documents and map specific fields to database tables and columns.
Is Oracle9i Text (intermedia Text/Context) a solution?
The easiest way to do this is using Oracle XML Parser for Java and Java Stored Procedures in tandem with AQ inside Oracle9i.
We can use XML SQL Utility if we go with a custom solution. Our main concentration is supply-chain. We want to get metadata information such as, AQ enqueue/dequeue times, JMS header information,.... based on queries on certain XML tag values. Can we just store the XML in a CLOB and issue queries using Oracle9i Text (intermedia Text)?
You can combine Oracle9i Text (interMedia Text) XML searching with some amount of redundant metadata storage as "factored out" columns and use SQL statements that combine normal SQL predicates with the Oracle9i Text (interMedia Text) CONTAINS() clause to have the best of both.
We receive XML messages from clients as messages and need to process them as soon as they come in. Each XML document takes about 15 seconds to process. We are using PL/SQL.
One PL/SQL procedure starts the listener and Dequeues the message and calls another procedure to process the XML document. The problem is that the listener is held up until the XML document is processed. Meanwhile messages accumulate in the queue.
What is the best way to handle this? Is there a way for the listener program to call the XML processing procedure asynchronously and return to listening? Java is not an option at this point.
After receiving the message, you can submit a job using the DBMS_JOB package. The job will be invoked asynchronously in a different database session.
Oracle9i has added PL/SQL callbacks in the AQ notification framework. This allows you register a PL/SQL callback which is invoked asynchronously when a message shows up in a queue.
|
Copyright © 1996-2001, Oracle Corporation. All Rights Reserved. |
|