Skip Headers
Oracle® Retail Integration Bus Operations Guide
Release 13.2
  Go To Table Of Contents
Contents

Previous
Previous
 
 

12 Performance Considerations

The chapter discusses the performance characteristics of the Oracle Retail RIB, the factors that affect it, and a process to test it.

Performance of the RIB within a customer site is critical to the performance of the business, and is determined by factors that are very specific to a given deployment. Because of this is, it is recommended by Oracle Retail that a Performance Test be part of every deployment plan. Even if formal testing is not planned, the use of the tools and processes discussed can measure the relative performance of the RIB sub-system and can be used to diagnose bottlenecks.

It is beyond the scope of this document to discuss all of the tools and techniques available at the host, network, database, and application server level.

See the Oracle RIB Integration Bus Implementation Guide.

Performance Factors

The performance of each of these components is influential in the overall performance of the system:

There are other factors that determine the performance of the overall system. Some of these factors in a RIB environment are:

Performance Requirements

Each of the RIB Message Family volume requirements is almost always described for the end-to-end message flow. This is defined as from the publication to the completion of subscription by all Oracle Retail applications. Retail businesses express volume requirements in terms of details per hour and per day.

Each Message Family has different volume requirements and any given family may have an intermediate component between the originating publication and the end subscriber. These components are called TAFRs (Message Transform, Filtering, and Routing). This is an important concept, since it means that in a given flow, a message published by the source system may be subscribed to and then re-published by a TAFR before it is subscribed to by the destination application. This is true in many of the Message Families.

Example Volume Requirements:

Family Details Per Day Details Per Hour

Purchase Orders

355,000

355,000

ASN Inbound

19,200,000

19,200,000

Appointments

240,000

30,000

PO Receipt

240,000

30,000

Store Receipt

4,000,000

2,000,000

Transfers

1,000,000

250,000

Stock Order Allocation

600,000

75,000

Stock Order Transfer

1,000,000

75,000

Stock Order Status

600,000

75,000

ASN Outbound (BOL)

285,000

285,000

Promotions

5,000,000

250,000

Item Locations

1,000,000

300,000

Items

100,000

20,000



Note:

These examples are for illustration, but are representative of actual customer requirements.

Message construction is the same for all Oracle Retail Publishing applications and RIB adapters. There are configuration control points that allow flexibility in the size of the message. The application side has the ability to specify the number of details per message. The RIB has a setting that controls the aggregation of the messages (ribMessage) within the larger RibMessages envelope. There is a setting that controls the number of RibMessages published within a commit to the JMS.

See "Message Aggregation."

Multi-Channel

The RIB is designed to support parallel message handling to increase through-put via a mechanism call multi-channel. Multi-channel is a concept to logically partition the flow of messages within the JMS topic so that multiple publishers and subscribers can simultaneously use the same JMS topic without any contention or interference with each other and preserve publication message ordering within the logical channel.

Every adapter instance of a publisher, subscriber, or TAFR, configured in the RIB is considered to belong to a logical channel for processing messages. By multi-channel adapters, we mean multiple adapter instances for the same message family, each processing messages asynchronously and in parallel. When multiple channels are used, they must be defined and configured across all publisher, subscriber, and TAFRs that participate in an end-to-end message flow to and from all Oracle Retail applications for that message family.

Each messaging RIB component involved in publishing or subscribing to a logical channel is distinctly identified by a JMS Message property known as "threadValue" with a specific value. This JMS message property and the value it contains define the logical channel.

JMS Message properties are user-defined additional properties that are included with the message. Message properties have types, and these types define application-specific information that message consumers can use to select the messages that interest them. Each RIB subscriber has the "threadValue" property and this value is part of its JMS Durable Subscriber selector and each RIB publisher sets the "threadValue" JMS message property to a specific value for each message it publishes.

Oracle Retail RIB components are capable of being multi-channeled by making configuration changes to the system. The base RIB configuration, as shipped GA, provides each Message Family with one channel where all components set or look for "threadValue" of 1 (one). The naming convention and the RIB kernel code identify the RIB adapters by adding the logical channel to the end of the adapter class name.

The diagram below demonstrates the multi-channeling of the Purchase Order flow to two channels.

Surrounding text describes multichannel.png.

End-to-End Timing

As mentioned, the RIB's performance is judged by the average time a Message Family detail takes to flow from a publisher to consumption by all active subscribers. This is not a straight forward measurement.

Message through-put is not a calculation of the sum of the individual message times. Although the average time per message will remain fixed, messages are processed in parallel. So the total time to process n messages on a single channel will not be the serial sum of the individual messages.

Additionally, it is possible to configure multiple logical channels to increase overall through-put.

How to Calculate Average Message Size

It is important to understand the average messages in an integration flow. In the RIB where interfaces are separated into messages families with differing payloads per type of message, these calculations can be difficult. This section outlines an approach for arriving at averages using the sample XML files that ship with the RIB.

The RIB delivers sample files generated for each Message Family that contains all elements for a message type and payload with all possible characters for each element.


Note:

Several Families have variable types of "details" per header so a close investigation is required to understand what the relationship is and what a representative message can be.

In practice, of course, this size will vary depending on the number of characters that a description element may contain, but for performance testing calculations, this is a reasonable start for calculations.


Note:

An alternative is to use the audit feature of the RIB. These messages can then be used to estimate the average sizes.

The RIB message envelope, called a RibMesssages contains a variable number of ribMessage nodes. Within a ribMessage node is a Message Family payload. A minimum payload for this exercise is defined as one header and a variable number of details.

The general process to determine the size in bytes of a Message Family message per detail using the RIB sample xml messages and xsds is as follows:

  • Determine the RIB envelope size (RibMessages elements + ribMessage elements).

  • Determine the size of a single header.

  • Determine the size of a detail.

The RIB has a standard message envelope (RIBMessages.xsd) that can be easily calculated exclusive of the message family payload.

ribMessage header elements no payload 823 Bytes
RibMessages header elements 324 Bytes
RibMessages with 1 rM no payload 1147 Bytes

Each message family is comprised of message type and an associate payload (e.g. POCre uses PODesc.xsd). These relationships are defined in the RIB Integration Guide.

The sample XML messages for each release are packaged in the functional artifacts war file and with RDMT in the rib-home/tools-home/rdmt/testmsgs directory.

Select the message payload file and look at the byte count. This will always be 1 header and 1 detail(s). Be aware that this relationship will vary by family and can be complex for some message types (e.g. ItemCre and ItemDesc.xsd) where optional details can be present.

Select the payload file and remove all detail nodes and look at the byte count. This will be the standard header. Use the same procedure for the detail(s). This will be the detail size.

Example Message - PODesc
Header Size (PODesc no detail) 9413
1 Detail Size (PODtl) 1943

The next step is to determine the average number of details per message. This will vary based on the business needs and the RIB configuration that is selected.

See "Message Aggregation."

Using the desired number of details per message, this calculation is the result:

Total 1 RibMessages + 1 ribMessage + 1 Header + 1 Detail Avg Message Size

For example:

Total 1 RibMessages + 1 ribMessage + 1 PODesc + 1 PODtl 12,053

Purchase Order Example

ribMessage header elements no payload

823

RibMessages header elements

324

RibMessages with 1 rM no payload

1147



Message - PODesc


Header Size (PODesc no detail)

9413

1 Detail Size (PODtl)

1943



Total 1 RibMessages + 1 ribMessage + 1 PODesc + 1 PODtl

12,053


The following is an example using the default settings.

The RIB messages created by the Order publishing adapter (details per message):

  • Contains a maximum of 20 ribMessages per RibMessage.

  • Has 20 details per PODesc payload in a ribMessage.

For a 400 Details PO Message the calculation is:

RibMessage = 1 RibMessages header + 20 ribMessage headers + 20 PODesc + 400 PODtls

# ribMessage nodes

20

# Details

400



RibMessages Header (1)

324

ribMessage Header (20)

16,460

PODesc (20)

188,260

PODtl (400)

777,200

Total Bytes/Msg

982,644


Using the example volume requirement for the Purchase Orders, and using the same RIB message configuration settings:

Details per hour requirement (Total Through-put)

355,000

Details per Message

400

Total messages per hour (355,000/400)

887

Message/sec required (982 KB each - 60*60/887)

4.058


So:

End-to-End — 1 message with 400 details can take a max of 4.058 seconds.

End-to-End — 982,644 Bytes can take a max of 4.058 seconds (which in this example is 400 details).

So:

982644 Bytes/4.058 sec = 242149.83 bytes/sec = 0.2421498 MB/sec Total end-to-end throughput to meet the Purchase Order example requirements.

Understand the Message Family

These are end-to-end processing time requirements across the entire message flow from Publisher to Subscription completion.

The following diagram is a generic message flow.

Surrounding text describes generic_message_flow.png.

To continue the Purchase Order example, the requirements and timings have to be broken down further. The Purchase Order flow has a TAFR as well as multiple subscribers. For purposes of this example, consider the Subscribers Consume times as equivalent. As the diagram depicts, for a flow like the Purchase Orders, there are multiple components and for a single message to flow there will be, at a minimum, a message published twice and subscribed twice, as well as a marshalling and un-marshalling of the message twice (Family dependent). There will be at least one, and possibly two, Hospital Dependency checks as well.

The following diagram is a logical view of the Oracle Retail Purchase Order flow.

Surrounding text describes logical_view_po_flow.png.

The following diagram is a functional, detailed view of the Oracle Retail Purchase Order flow.

Surrounding text describes functional_view_po_flow.png.

RIB Timing Log Analysis

The performance of the RIB is a complicated subsystem to measure and involves not only host level performance, but database, network, and application server subsystems performance. To make measurement of the RIB components timing characteristics available for analysis, the RIB kernel code has been instrumented to log events as it processes events. The logging of these events is though log4j. The timings are logged per adapter. Once the timings are enabled the events are logging continuously to the file. The RIB RDMT supplies a post-processing tool to take the timing file and produce summary reports.

This table lists the currently pre-defined times that are tracked in the RIB Timings logs. The description is the definition of interval calculation.


Timing Type Description
T1 PUB_B4_GETNXT_CALL Time interval between start of the publisher and the actual GETNXT call.
T2 PUB_TIME_IN_GETNXT_CALL Time taken by the GETNXT call to the plsql app.
T3 PUB_TIME_IN_EJB_PUBLISH_CALL Time taken for the publish call in the EJB, includes RIB overhead surrounding the actual publish to the JMS.
T4 PUB_TOTAL_PUBLISH_TIME Time taken for the complete PUB process = GETNXT + hospital dependency + publish + commit.
T5 PUB_TIME_IN_REAL_JMS_PUBLISH Time taken to publish a message to the AQ JMS.
T6 SUB_TIME_IN_CONSUME_CALL Time taken by the CONSUME call to the plsql app.
T7 SUB_TOTAL_SUBSCRIBE_TIME Time taken for the complete SUB process = CONSUME/INJECT + hospital dependency + subscribe + commit.
T8 SUB_TIME_IN_EJB_SUBSCRIBE_CALL Time taken for the subscribe call in the EJB, includes RIB overhead surrounding the actual subscribe.
T9 SUB_TIME_IN_INJECT_CALL Time taken by the INJECT call to the java app.
T10 TAFR_TOTAL_MSGPROCESS_TIME Time taken in the complete message tafring Process = TAFRing + hospital dependency + publish + RIB overhead.
T11 TAFR_TIME_IN_EJB_CALL Time taken for the TAFR call in the EJB, includes RIB overhead surrounding the actual TAFRing.
T12 TAFR_TIME_IN_REAL_JMS_PUBLISH_EJB Time taken by the TAFR to publish a message to the AQ JMS.

Purchase Order Example


Note:

The following are examples illustrate the process and concepts, but not test results.

Order_pub_1 (Publisher)

TIMING_TYPE COUNT AVERAGE TIME _SUM MIN_TIME MAX_TIME
PUB_B4_GETNXT_CALL 100 0.03787 3.7904 0.036 0.07
PUB_TIME_IN_GETNXT_CALL 100 0.06546 6.5528 0.061 0.254
PUB_TIME_IN_EJB_PUBLISH_CALL 100 0.04192 4.1961 0.039 0.308
PUB_TOTAL_PUBLISH_TIME 100 0.19675 19.6947 0.186 2.738
PUB_TIME_IN_REAL_JMS_PUBLISH_EJB 100 0.02931 2.9341 0.027 0.292

OrderToOrderTafr_1 (TAFR)

TIMING_TYPE COUNT AVERAGE TIME _SUM MIN_TIME MAX_TIME
TAFR_TOTAL_MSGPROCESS_TIME 100 1.58708 158.708 1.296 4.135
TAFR_TIME_IN_EJB_CALL 100 1.51371 151.371 1.23 3.24
TAFR_TIME_IN_REAL_JMS_PUBLISH_EJB 100 1.1802 118.02 0.914 2.414

Order_sub_1

TIMING_TYPE COUNT AVERAGE TIME _SUM MIN_TIME MAX_TIME
SUB_TIME_IN_CONSUME_CALL 100 1.359 135.9 0.671 2.203
SUB_TOTAL_SUBSCRIBE_TIME 100 1.93943 193.943 0.718 5.593
SUB_TIME_IN_EJB_SUBSCRIBE_CALL 100 1.92386 192.386 0.687 5.593

In this example, to describe the serial processing through-put time to Publish 100 messages through the TAFR to Subscriber Consume:

Publisher (19.69 Sec) + TAFR (158.708 sec) + Subscriber (193.943 sec) = 372.341 seconds = Average 3.72 msg/sec

It is important to understand that the actual message through-put is not a calculation of the sum of the individual message times. Although the average time per message will remain fixed, messages are processed in parallel. So the total time to process n messages on a single channel will not be the serial sum of the individual messages.


Note:

This is an illustration. The number of message needed to arrive at a calculation of through-put requirse much higher counts, a broad spectrum of time, and system load. Other factors include average size of message.

Key Interfaces to Consider

Every customer site has unique requirements and flows, so the ones to focus on will vary. However, there are ones that always make to the list.

It is strongly recommended that during the deployment planning phase, the business requirements for these and others be gathered and analyzed. Some form of performance testing should be planned, even if only a characterization by measuring the actual flows during other test phases (for example, Integration Test).

ASN (Inbound/Outbound)

The following diagram is a functional, detailed view of the Oracle Retail ASNin/ASNOut Flows.

Surrounding text describes asn.png.

Receipts

The following diagram is logical view of the Oracle Retail Receipts Flow.

Surrounding text describes receipts_logical.png.

The following diagram is functional, detail view of the Oracle Retail Receipts Flow.

Surrounding text describes receipts_functional.png.

The Receipts Message Family is transactional data, and often a candidate for performance testing. Receiving consists of appointment and receipt messages that are published to the RIB for RMS providing open to buy visibility. An appointment is information about the arrival of merchandise at a location. A receipt message informs RMS when merchandise arrives in a warehouse or store system.

Stock Order (Allocations & Transfers)

The following diagram is a logical view of the Oracle Retail Stock Order Flow.

Surrounding text describes stock_logical.png.

The following diagram is a functional, detail view of the Oracle Retail Stock Order Flow.

Surrounding text describes stock_functional.png.

How to Approach a RIB Performance Test

There are two distinct approaches to measuring RIB performance; using actual application end-points or using the RIB API simulators. Both are useful at different phases of deployment.

Keep in mind, that performance measuring is possible at any time in any phase, performance testing is more formal and requires planning, dedicated people and systems and test data. Building test data is difficult. Do not underestimate the complexity and this time consuming aspect of testing. To do testing with the applications involved, all of the data has to be consumable without errors.

There are tools available in RDMT to assist in this, as well as the audit feature of the RIB. By enabling audit on an interface all messages are saved to a file in a form that can be played back by RDMT utilities.

The API Simulators (PL/SQL and Java EE) allow the focus to be on the RIB infrastructure and is possible without resources outside of the RIB team. The value is limited to profiling the deployment architecture independent of the application API behavior and is much simpler in terms of data generation.

The performance measures of the end-to-end flow using the application's API is the only way to match performance against requirements since the majority of the time spent in the flow is in the application API. Customers do not distinguish a separation between the RIB components and the application APIs.

The following illustrates the RIB Performance Test Harness.

Surrounding text describes rib_test_harness.png.

The RIB supplied tools to support both forms of tests are the RIB Test Harness, the API simulators, and the RDMT tools; timing utility, JMS Publish and EJB Publish.

This is a general process on how to measure the flow end-to-end.

  1. Prepare for the run.

    • Use RIB Admin GUI to stop all adapters (PUB, SUB, TAFR).

    • Use RDMT to archive all logs so that the run has clean logs.

    • Use RIB Admin GUI to enable timings logs (DEBUG) on all adapters.

    • Use RIB Admin GUI to set all other adapter logs to INFO.

  2. Determine how to generate the messages.

    • Using the Oracle Retail Application (e.g. RMS to generate some orders).

    • Using RDMT EJB Publish (will use a portion of the PUB Adapter).

    • Using RDMT JMS Publish (will not use the PUB Adapter).

  3. Start the appropriate adapters depending on the above decision.

    • Use RIB Admin GUI to start adapters (PUB, SUB, TAFR).

  4. Generate the test messages.

  5. Stop the adapters.

  6. Analyze the data.

    • Use RDMT to run the Timing Analysis Utility on each adapter timing log. This will create a .csv file.

    • Upload the .csv files for display and further analysis using a tool such as Excel.

Multi-Channel Adapters

A channel is a solution approach to maintaining the previous RIB release concept of a Logical Channel.

Multi-channel applies to the logical partitioning of the flow of messages within the JMS topic. Multiple publishers and subscribers can simultaneously use the same JMS topic without any contention or interference, thus preserving publication message ordering within the logical channel.

Every adapter instance of a publisher, subscriber, or TAFR configured in the RIB belongs to a logical channel for processing messages. Multi-channel adapters are multiple adapter instances for the same message family, each processing messages asynchronously and in parallel.

There are critical rules of behavior that must be observed and enforced to maintain the two primary RIB functional requirements of once-and-only-once successful delivery and guaranteed sequencing of messages within a message family.

To ensure that these rules are followed--and to simplify RIB configuration tasks that support a multi-channel message flow--the process has been integrated into the RIB App Builder tools.

Multiple channels must be defined and configured across all publisher, subscriber, and TAFRs that participate in an end-to-end message flow, to and from all Oracle Retail applications, for that message family. The RIB App Builder tools have checks and verification logic to prevent deployment of incomplete flows.

Use of multi-channels can increase performance, but it does not help in every situation. There is overhead and complexity associated with implementing multiple channels so they should not be considered unless a defined and performance problem exists.

Adding Multi-Channels to a Message Family

The process of adding multi-channels to a message family should be part of a performance test and tuning process. Multi-channeling capability for a message family is limited by the muti-channel support in the publishing performed by applications.

It is a known issue that currently none of the publishing APIs of RWMS do not support multi-channeling. Therefore, integration flows involving RWMS publishing cannot be multi-channeled.

For example, the Inventory Adjustment (InvAdjust) message family is published by RWMS and subscribed to by RMS. Because RWMS supports only single-channel publishing, RMS must be set up for single-channel processing for the InvAdjust message family. All RWMS subscription APIs support multi-channel processing.

The following RMS 13.2 publishing APIs support multi-channel processing:

  • Allocations Publication API

  • Item Location Publication API

  • Item Publication API

  • Merchandise Hierarchy Publishing API

  • Order Publication API

  • Receiver Unit Adjustment Publication API

  • RTV Request Publication API

  • Seed Object Publication API

  • ASNOUT Publication API

  • Transfers Publication API

  • Work Orders in Publication API

  • Work Orders out Publication API

The following RMS 13.2 publishing APIs do not support multi-channel processing:

  • Banner Publication API

  • Differentiator Groups Publication API

  • Differentiator ID Publication API

  • Partner Publication API

  • Seed Data Publication API

  • Store Publication API

  • Vendor Publication API

  • UDA Publication API

  • Warehouse Publication API

Logical Channels and threadValue

Each messaging RIB component involved in publishing or subscribing to a logical channel is distinctly identified by a JMS Message property known as "threadValue" with a specific value. This JMS message property and the value it contains define the logical channel.

JMS Message properties are user-defined additional properties that are included with the message. Message properties have types, and these types define application-specific information that message consumers can use to select the messages that interest them.

So each RIB subscriber has the "threadValue" property and this value as part of its JMS Durable Subscriber selector and each RIB publisher sets the "threadValue" JMS message property to a specific value for each message it publishes.

Oracle Retail RIB components are capable of being multi-channeled by making configuration changes to the system. The base RIB configuration, as shipped GA, provides each Message Family with one channel where all components set or look for "threadValue" of 1 (one). The naming convention and the RIB kernel code identify the RIB adapters by adding the logical channel to the end of the adapter class name.

Algorithm Used to Calculate Channel

Channels are calculated based on Business object ID(BOID) found in the RibMessages <id> tag. The algorithm used to calculate is as follows.

MOD(MD5(family + ":" + businessObjectId)%maxChannelNumber) + 1
  • First the algorithm calculates the message digest of the string family+":"+businessObjectId which produces a unique number.

  • Then this number is divided by the maxChannelNumber, which is calculated by the number of configured channels for that message family.

  • A 1 is added to the result so that the channel number is always greater than 0.

For example:

Family = Alloc
BusinessObjectID (BOID) = 10202123
MaxChannelNumber = 7 (Total number of channels configured for the Alloc family)
Then the channel number for the BOID is calculated as
sMOD(MD5(Alloc + ":" + 10202123)%7) + 1 = 4
which means that all the messages that have BusinessObjectID of 10202123
are ALWAYS sent through channel 4 (Alloc_pub_4).

Note:

The channels have to be configured throughout the integration flow using the rib-app builder tool.

Example of a Message Family Flow with a TAFR:

Alloc_pub_1

Alloc_tafr_1

StockOrder_sub_1

How to Configure a Multi-Channel Flow

Generalized Process

  1. Determine the Family to multi-channel

  2. Examine the rib-integration-flows.xml to identify all participants in the full flow.

  3. In the rib-home modify the appropriate configuration files for each of the rib-<apps>.

    1. rib-<app>-adapters.xml

    2. rib-<app>-adapter-resources.properties

  4. For PL/SQL Application edit the RIB_SETTINGS table.

  5. Compile and deploy.

Example

This example is to configure the Alloc message flow with five channels. Alloc is a complex flow in that it has multiple Oracle Retail application subscribers and a TAFR that transforms the messages from one family to another; Alloc to StockOrder.

Backup the following files.

  • "rib-home/application-assembly-home/rib-rms/rib-rms-adapters.xml

  • rib-home/application-assembly-home/rib-rms/rib-rms-resources.properties.

The following is the message flow for the Alloc Family from rib-integration-flows.xml that this example uses.

  <message-flow id="1">
                 <node id="rib-rms.Alloc_pub" app-name="rib-rms" adapter-class-def="Alloc_pub"
 type="DbToJms">
                          <in-db>default</in-db>
                          <out-topic>etAllocFromRMS</out-topic>
                  </node>
                 <node id="rib-tafr.Alloc_tafr" app-name="rib-tafr" adapter-class-def="Alloc_tafr" type="JmsToJms">
                          <in-topic>etAllocFromRMS</in-topic>
                          <out-topic name="topic-name-key-iso">etStockOrdersISO</out-topic>
                          <out-topic name="topic-name-key-wh">etStkOrdersFromRIBToWH{*}</out-topic>             </node>
                 <node id="rib-sim.StockOrder_sub" app-name="rib-sim"
 adapter-class-def="StockOrder_sub" type="JmsToDb">
                          <in-topic>etStockOrdersISO</in-topic>
                          <out-db>default</out-db>
                  </node>
                 <node id="rib-rwms.StockOrder_sub" app-name="rib-rwms"
 adapter-class-def="StockOrder_sub" type="JmsToDb">
                          <in-topic>etStkOrdersFromRIBToWH1</in-topic>
                          <out-db>default</out-db>
                  </node>
        </message-flow>

RIB-RMS

  1. Modify rib-rms-adapters.xml to add multiple channels.

    Following is a portion of rib-rms-adapters.xml

       <publishers>
                 <timer-driven id="Alloc_pub_1" initialState="running" timeDelay="10">
                       <timer-task>
                            <class name="com.retek.rib.app.getnext.impl.GetNextTimerTaskImpl"/>
                                  <property name="maxChannelNumber" value="5" />
                       </timer-task>
                 </timer-driven>
                 <timer-driven id="Alloc_pub_2" initialState="running" timeDelay="10">
                       <timer-task>
                            <class name="com.retek.rib.app.getnext.impl.GetNextTimerTaskImpl"/>
                                  <property name="maxChannelNumber" value="5" />                   </timer-task>
                 </timer-driven>
                 <timer-driven id="Alloc_pub_3" initialState="running" timeDelay="10">
                       <timer-task>
                            <class name="com.retek.rib.app.getnext.impl.GetNextTimerTaskImpl"/>
                                  <property name="maxChannelNumber" value="5" />
                       </timer-task>
                 </timer-driven>
                 <timer-driven id="Alloc_pub_4" initialState="running" timeDelay="10">
                       <timer-task>
                            <class name="com.retek.rib.app.getnext.impl.GetNextTimerTaskImpl"/>
                                  <property name="maxChannelNumber" value="5" />
                       </timer-task>
                 </timer-driven>
                 <timer-driven id="Alloc_pub_5" initialState="running" timeDelay="10">
                       <timer-task>
                            <class name="com.retek.rib.app.getnext.impl.GetNextTimerTaskImpl"/>
                                  <property name="maxChannelNumber" value="5" />
                       </timer-task>
                 </timer-driven>
    
  2. Modify rib-rms-adapter-resources.properties.

      Alloc_pub_1.name=Alloc Publisher, channel 1
      Alloc_pub_1.desc=Publisher for the Alloc family through channel 1.
    
      Alloc_pub_2.name=Alloc Publisher, channel 2
      Alloc_pub_2.desc=Publisher for the Alloc family through channel 2.
    
      Alloc_pub_3.name=Alloc Publisher, channel 3
      Alloc_pub_3.desc=Publisher for the Alloc family through channel 3.
    
      Alloc_pub_4.name=Alloc Publisher, channel 4
      Alloc_pub_4.desc=Publisher for the Alloc family through channel 4.
    
      Alloc_pub_5.name=Alloc Publisher, channel 5
      Alloc_pub_5.desc=Publisher for the Alloc family through channel 5.
    

RIB-TAFR

  1. Modify rib-tafr--adapters.xml to add channels for a family.

    <tafrs>
           <message-driven id="Alloc_tafr_1" initialState="running"
    tafr-business-impl="com.retek.rib.domain.tafr.bo.impl.AllocToStockOrderFromRibBOImpl" />
           <message-driven id="Alloc_tafr_2" initialState="running"
    tafr-business-impl="com.retek.rib.domain.tafr.bo.impl.AllocToStockOrderFromRibBOImpl" />
           <message-driven id="Alloc_tafr_3" initialState="running"
    tafr-business-impl="com.retek.rib.domain.tafr.bo.impl.AllocToStockOrderFromRibBOImpl" />
           <message-driven id="Alloc_tafr_4" initialState="running"
    tafr-business-impl="com.retek.rib.domain.tafr.bo.impl.AllocToStockOrderFromRibBOImpl" />
           <message-driven id="Alloc_tafr_5" initialState="running"
    tafr-business-impl="com.retek.rib.domain.tafr.bo.impl.AllocToStockOrderFromRibBOImpl" />
    
  2. Modify rib-tafr-adapters-resources.properties.

    Alloc_tafr_1.name=AllocToStockOrder TAFR, channel 1
    Alloc_tafr_1.desc=TAFR for converting Allocation messages to StockOrders and routing them to the correct warehouse or store system
    Alloc_tafr_2.name=AllocToStockOrder TAFR, channel 2
    Alloc_tafr_2.desc=TAFR for converting Allocation messages to StockOrders and routing them to the correct warehouse or store system
    Alloc_tafr_3.name=AllocToStockOrder TAFR, channel 3
    Alloc_tafr_3.desc=TAFR for converting Allocation messages to StockOrders and routing them to the correct warehouse or store system
    Alloc_tafr_4.name=AllocToStockOrder TAFR, channel 4
    Alloc_tafr_4.desc=TAFR for converting Allocation messages to StockOrders and routing them to the correct warehouse or store system
    Alloc_tafr_5.name=AllocToStockOrder TAFR, channel 5
    Alloc_tafr_5.desc=TAFR for converting Allocation messages to StockOrders and routing them to the correct warehouse or store system
    

RIB-SIM

  1. Modify rib-sim-adapters.xml to add channels for a family.

     <subscribers>
          <message-driven id="StockOrder_sub_1" initialState="running"/>
          <message-driven id="StockOrder_sub_2" initialState="running"/>
          <message-driven id="StockOrder_sub_3" initialState="running"/>
          <message-driven id="StockOrder_sub_4" initialState="running"/>
          <message-driven id="StockOrder_sub_5" initialState="running"/>
    
  2. Modify rib-sim-adapters-properties.properties.

    StockOrder_sub_1.name=StockOrder Subscriber, channel 1
    StockOrder_sub_1.desc=Subscriber for the StockOrder family through channel 1.
    
    StockOrder_sub_2.name=StockOrder Subscriber, channel 2
    StockOrder_sub_2.desc=Subscriber for the StockOrder family through channel 2.
    
    StockOrder_sub_3.name=StockOrder Subscriber, channel 3
    StockOrder_sub_3.desc=Subscriber for the StockOrder family through channel 3.
    
    StockOrder_sub_4.name=StockOrder Subscriber, channel 4
    StockOrder_sub_4.desc=Subscriber for the StockOrder family through channel 4.
    
    StockOrder_sub_5.name=StockOrder Subscriber, channel 5
    StockOrder_sub_5.desc=Subscriber for the StockOrder family through channel 5.
    

RIB-RWMS

  1. Modify rib-rwms-adapters.xml to add channels for a family.

     <subscribers>
        <message-driven id="StockOrder_sub_1" initialState="running"/>
        <message-driven id="StockOrder_sub_2" initialState="running"/>
        <message-driven id="StockOrder_sub_3" initialState="running"/>
        <message-driven id="StockOrder_sub_4" initialState="running"/>
        <message-driven id="StockOrder_sub_5" initialState="running"/>
    
  2. Modify rib-rwms-adapters-properties.properties.

    StockOrder_sub_1.name=StockOrder Subscriber, channel 1
    StockOrder_sub_1.desc=Subscriber for the stockorder family through channel 1.
    
    StockOrder_sub_2.name=StockOrder Subscriber, channel 2
    StockOrder_sub_2.desc=Subscriber for the stockorder family through channel 2.
    
    StockOrder_sub_3.name=StockOrder Subscriber, channel 3
    StockOrder_sub_3.desc=Subscriber for the stockorder family through channel 3.
    
    StockOrder_sub_4.name=StockOrder Subscriber, channel 4
    StockOrder_sub_4.desc=Subscriber for the stockorder family through channel 4.
    
    StockOrder_sub_5.name=StockOrder Subscriber, channel 5
    StockOrder_sub_5.desc=Subscriber for the stockorder family through channel 5.
    

Edit the RIB_SETTINGS table

When a PL/SQL Publishing adapter is multi-channeled, the application code needs to designate the message to a specific thread. In order to do this, a change needs to be made in the RIB_SETTINGS table.

Find the Family of messages that is being multi-channeled, and adjust the column NUM_THREADS to the appropriate number. In this example, the number will be set to 4 for the Alloc Family.

Compile and Deploy

Using the RIB Installer or the RIB App Builder command line tools, compile and deploy the new rib-<app>.ears.

Message Aggregation

To improve message publication throughput within the integration system, the RIB provides multiple capabilities. The most efficient way to increase throughput of any system is to start working on the collection of data units instead of single data units. Using that philosophy, RIB provides capabilities to process the collection of multiple detail payloads in one transaction. To control the number of details (payload details) per payload header, the user must update the RIB_SETTING.MAX_DETAILS_TO_PUBLISH column in the PL/SQL retail applications database schema. This configuration allows users to control the size of the payload published within the RIB system.

Users also may aggregate messages in a transaction by bundlibg multiple payloads within a single message published to the JMS server, for example. Through message aggregation (<family>.maxNodesPerMessages), users can control the number of ribMessage nodes bundled into a single RibMessages message. Different families can have different nodes per message, so this property is qualified (prefixed) by the family name. This property allows control of the overall size of the RibMessages XML message.

RIB also allows users to optimize/minimize XA transaction overhead by allowing the system to commit multiple RibMessages to the JMS server in a single, two-phase XA commit. The number of messages committed to the JMS server in a single XA commit is controlled by the property named <family>.messagePerCommit. Different families may need different RibMessages per commit, so this property is qualified (prefixed) by the family name.

The configurable properties (<family>.maxNodesPerMessages and <family>.messagePerCommit) applies to each individual rib-<app>. To update the property and propagate the configuration to the app server, edit the corresponding rib-<app>.properties in rib-home and redeploy the updated rib-<app>.

Keep in mind the bigger the payload size, the bigger the memory requirement. A process (JVM) gets limited amounts of operating system memory. If the size is too large, memory will run out, resulting in OutOfMemoryError.

If numerous ribMessageNodes are bundled into the same RibMessages message, a single failure in one of the ribMessages will roll back the full transaction. which will result in the following: The error hospital table will fill up and throughput will decrease by many factors, because now it has to go through the retry process.

The general best practice is to not prematurely optimize. Test with business data and only if the default values are not meeting business needs. Think about optimization by updating these properties.

How to Configure Message Aggregate

  1. Edit the following file in rib-home:

    rib-home/application-assembly-home/rib-<app>/rib-<app>.properties

  2. Add the following properties:

    • <family>.maxNodesPerMessages=<your value>

    • <family>.MessagePerCommit=<your value>

  3. Using the app-builder tool compile/deploy the application.

    • rib-app-compile.sh

    • rib-app-deployer.sh -deploy-rib-app-ear rib-<app>

Aggregation Example

Suppose there are 1,300 payload details waiting to be published for a family. Suppose the following configuration in RIB:

MAX_DETAILS_TO_PUBLISH=100 maxNodesPerMessagess=5 MessagePerCommit=2

The diagram below explains the message aggregation in play in the RIB system. All 1,300 payload details will be published in three RibMessages within only two XA transaction commits. Each of the first two RibMessages will have five ribMessage nodes, and each of the ribMessage nodes will have a payload with 100 payload details. The example shows 1,300 payload details; the third RibMessages XML will have only three ribMessage nodes, each with 100 payload details.

XA transaction 1 = (RibMessages1 + RibMessages2) RibMessages1 = ribMessage1 + ribMessage2 + ribMessage3 + ribMessage4 + ribMessage5. ribMessage1 = PayloadHeader + 100 * PayloadDetail ribMessage2 = PayloadHeader + 100 * PayloadDetail ….. ribMessage5 = PayloadHeader + 100 * PayloadDetail

RibMessages2 equivalent to RibMessages1

XA Transaction 2 = RibMessages3 RibMessages3 = ribMessage1 + ribMessage2 + ribMessage3

Total = (XA Transaction 1 + XA Transaction 2) 100*5 + 100*5 + 100*3 = 1300

The following is an illustration of RIB Message Aggregation.

RIB Message Aggregation

Multiple Hospital Retry

This section explains the multiple hospital retry process.

Family Specific Hospital Retry Adapters

The RIB supports configuration of hospital retry adapters specific to message families. The family based adapters are configured to address performance issues when the error hospital gets very large--and a single retry adapter cannot handle the load.

How Family Specific Hospital Retry Works

Errors during processing result in messages in the error hospital. Reasons for errors include the following:

  • Incomplete or partial data from RMS: In this case, the messages are inserted into the error hospital with a reason code of PUB.

  • JMS related publication error conditions: (For example, the JMS server is down or not available due to network failures.) In this case, the messages are inserted into the error hospital with a reason code of JMS.

  • The subscriber application is not able to consume the message: In this case, the messages are inserted into the error hospital with a reason code of SUB.

By default, there are three kinds of hospital adapters, as listed below:

  • Sub retry adapter

  • JMS retry adapter

  • Pub retry adapter (RMS is the only application for which the Pub retry adapter is required.)

The sub retry adapter retries only those messages with a reason code of SUB. Similarly, the JMS retry adapter and the Pub retry adapter retry messages with reason codes of JMS and PUB, respectively.


Note:

For more information about the hospital retry mechanism, see "RIB Hospital Retry" in the Oracle RIB Integration Bus Implementation Guide.

Each message in the error hospital belongs to a particular message family. When the error hospital has a large number of messages from different families, the retry process becomes a performance bottleneck, as the default retry adapters retry the messages one by one (first in, first out), irrespective of message family.

To alleviate a bottleneck situation, retry adapters can be configured for a specific family and reason code. A family retry adapter can coexist with the default retry adapters. However, the default retry adapters will not retry those messages for which family retry adapters have been configured.

A family based retry adapter retries messages only for the family and reason code for which it is configured. For example, if a retry adapter is configured for the Order family and the SUB reason code, it retries only those messages from the Order family that failed with a reason code of SUB.

For each message family, a maximum of three family retry adapters can be configured--one for each reason code (PUB, SUB, and JMS).

How to Configure a Family Specific Retry Adapter

Process Overview:

  1. Determine the rib-<apps> where the family specific hospital retry adapter is to be configured.

  2. Determine the family for which the retry adapter should be configured.

  3. Determine the reason code (for example, PUB, SUB, or JMS) for the family retry adapter.

  4. In the rib-home, modify the appropriate configuration files for the rib-<apps>:

    1. rib-<app>-adapters.xml

    2. rib-<app>-adapter-resources.properties

  5. Compile and deploy.

Example:

To configure a family specific adapter for the Order family, where reason code = SUB and application = rib-rms, complete the following steps:

  1. Backup the following files:

    • rib-home/application-assembly-home/rib-rms/rib-rms-adapters.xml

    • rib-home/application-assembly-home/rib-rms-resources.properties

  2. Modify rib-rms-adapters.xml to add the family specific hospital retry adapter. The following is a portion of rib-rms-adapters.xml:

       <hospitals>
                     <timer-driven id="Order_familysubhosp_0" initialState="stopped" timeDelay="10" >
                       <timer-task>
                               <class name="com.retek.rib.j2ee.ErrorHospitalRegryTimerTask"/>
                                  </timer-task>
              </timer-driven/>         
       <hospitals>
    
  3. Modify rib-rms-adapter-resources.properties as follows:

    • Order_familysubhosp_0.name=Order SUB Hospital Retry

    • Order_familysubhosp_0.desc=Inject messages into JMS from Error Hospital


    Note:

    Only one instance of family retry adapter can be configured per family and per reason code.

  4. Compile and deploy:

    Using the RIB Installer or the RIB App Builder command line tools, compile and deploy the new rib-<app>.ears.