SOA 11g & SAP – Single Channel/Program ID for Multiple IDOCs
By Greg Mally on Mar 09, 2012
When faced with integrating SOA Suite 11g with SAP R/3 the recommended approach is using the Oracle Application Adapter for SAP R/3 (SAP JCo 3.0). This adapter has been used in many enterprises very successfully for integrating with SAP outbound (calls from the adapter to SAP) and inbound (events from SAP to the adapter). However, with any type of product there are edge cases where the features may fall short or require some creativity to work with those edge cases. One of those edge cases for the SAP adapter is the ability leverage a feature of SAP where multiple IDOCs can share the same Program ID. The standard case for SAP to send an IDOC to the SAP adapter is via a Channel configuration done in the Application Explorer (a utility provided with the Oracle Application Adapters). If you notice when you are generating the artifacts for JDeveloper via Application Explorer, the window clearly states in red “* You must create a separate channel for each inbound service”:
The reason for the channel definition in the Application Explorer is to provide a correlation between the adapter and a Program ID defined in the SAP system. Basically, when an IDOC is released it is associated with a Program ID that is used to locate a hostname and port (i.e., channel) to send the IDOC to. When the adapter receives the IDOC, it will then determine which partnerlink to send the IDOC to resulting in some SOA component instance being created. One of the limitations of the adapter is that when you export the artifacts from the Application Explorer for different IDOCs but select the same channel, all partnerlinks that are created from the generated artifacts will receive copies of all IDOCs that flow on the same channel/Program ID. For example, let's say artifacts for DEBMAS06 and MATMAS05 are generated using the same channel and two partnerlinks are created for DEBMAS06 and MATMAS05. Now if two BPEL processes are created and one is wired to DEBMAS06 partnerlink and the other is wired to MATMAS05 partnerlink, both BPEL processes will get instantiated regardless of the IDOC that has been released from SAP on the common channel/Program ID.
This fan-out behavior of the adapter presents issues for companies that have a large number of IDOCs flowing and don't want the administrative hassles of defining a channel/Program ID for every IDOC type. Luckily, there is hope for this scenario but requires the introduction of either a Mediator component or Oracle Service Bus (OSB). This write-up will focus on the Mediator solution where details of the OSB solution can be found at: [link to Single Channel/Program ID with Multiple IDOCs via OSB is coming soon :)]
The basics behind controlling the fan-out of IDOCs from the adapter are fairly straightforward:
- Use the generated artifacts from the Application Explorer for one and only one of the IDOCs that will flow on the common channel to create the partnerlink (see Configuring a Mediator Inbound Process).
- Create a Mediator Component using the generated WSDL specified in the partnerlink.
- Wire the adapter partnerlink to the Mediator and from the Mediator to the components that are capable of handing the various IDOCs that will be flowing down the common channel.
It is important to remember that every IDOC type on the channel will flow to the configured IDOC partnerlink regardless of the associated WSDL, XSD, and JCA file. The BPEL processes in the diagram have been created with a one-way interface that accepts a specific IDOC type (i.e., the xsd generated from the Application Explorer for each IDOC).
- Add a filter expression for each static routing in the Mediator based on the XML document root element name (e.g, name($in.event_DEBMAS06/*) = 'DEBMAS06').
- Save and deploy your composite application.
The filter expression for each static routing in the Mediator looks a bit strange because it appears like it is evaluating the payload of the IDOC that was used to create the partnerlink (e.g, name($in.event_DEBMAS06/*) = 'MATMAS05'). The filter expression will evaluate to the root element of the payload and the name() function will retrieve the root element name where that is compared to a string containing the name of the IDOC. Each IDOC from the adapter contains a root element with the name of the IDOC type, therefore we can route the document accordingly. As new IDOCs are added to the channel/Program ID all that is required is a new static routing in the Mediator based on the IDOC name.