Recoverable BAPI Transactions Part 1: Auto-Commit

This post has been republished via RSS; it originally appeared at: New blog articles in Microsoft Tech Community.

 

Introduction

 

A long-awaited improvement to the WCF-SAP adapter was recently introduced in BizTalk Server 2020 CU3: Support for custom grouping of BAPI transactions in the WCF-SAP adapter. It means that BAPI transaction messages can be now mapped arbitrarily to the same Logical Unit of Work (LUW) on the SAP server based on the value of the new property, Microsoft.Adapters.SAP.BiztalkPropertySchema.BAPIContextId. Previously, the grouping of BAPI transactions in the same context was always based on the message interchange id (which is still the default behavior).

 

Custom grouping can greatly simplify the implementation of some complex scenarios. In this first of two posts on the topic, we pick up where Recovering SAP BAPI Transactions with Custom Pipelines left off and look at how to support Recoverable Interchange Processing (RIP) with BAPI transactions when the "one-fails/all-fail" behavior could be cost-prohibitive. For instance, when a batch contains hundreds of transactions, if the BAPI transactions are unrelated and can be processed independently, it should be possible to keep the processing going rather than letting all messages/orchestration instances be suspended for some invalid field in one out of many transactions. As demonstrated in Handling Errors in SAP BAPI Transactions, it is complicated to achieve. Thanks to the new property BAPIContextId though, there is a simpler way to add recoverability to batches of BAPI transactions, by splitting them into independent "auto-commit" transactions. It is like reintroducing the "COMMIT WORK" to the BAPI Transaction Model (Without Commit).

 

All implementation artifacts and code are provided in the attached archive.

 

1. Scenario

 

Prerequisites: Section 1 of Recovering SAP BAPI Transactions with Custom Pipelines, which presents BAPI Operations and envelope schemas. The same info has been reproduced in the appendix sections at the end of this post. 

 

A receive location splits sales orders received under the form of XML documents and then maps each order to a BAPI Sales Order (BUS2032) creation transaction BUS2032.CREATEFROMDAT2 (shortened to CREATEFROMDAT2 in the rest of this article). BAPI schemas are created as shown in Appendix A. Orders is an envelope schema created by following the steps presented in Appendix B.

 

Received documents are disassembled... and then mapped to CREATEFROMDAT2
Debatching.png Map.png

 

The overall message flow is depicted below.

 

Message FlowMessage Flow

The various stages consist of the following, in chronological order:

 

Receive locations (steps 1, 2):

  • Orders are split into single Order messages.
  • A unique value for the built-in BAPIContextId property is assigned to each Order by a custom pipeline component.
  • Order messages are mapped to CREATEFROMDAT2, with the BAPIContextId property transferred to the message context.
  • CREATEFROMDAT2 messages are published to the message box.

Orchestration instances (steps 3, 4)

The orchestration's purpose is to turn each BAPI transaction into an "auto commit" transaction. For each published message, an orchestration instance takes care of the following:

  • Forward published CREATEDAT2 message to WCF-SAP send port.
  • Create and publish a BAPI_TRANSACTION_COMMIT. 

Finally, the send port (steps 5, 6) sends the BAPI transactions to the SAP server. We look at the details of each of the steps next.

 

2. Receive Location

 

2.1 Pipeline Component Code

 

Most of the implementation complexity resides in the custom pipeline component code, whose main purpose is to assign a unique BAPIContextId to each disassembled message.  The pipeline code is based on a reusable pattern introduced in the WCF LOB Adapter SDK. A class called NotifyingStream designed as a decorator of the Stream class, is used to invoke callbacks for specific events corresponding to when the stream is read. In our case, the custom pipeline component receives a notification when the entire stream has been read, thereby guaranteeing that all promoted properties from the message have been populated to the message context. 

 

Pipeline code to set message propertiesPipeline code to set message properties

The following code sets the BAPIContextId value to a unique value (interchange id + interchange sequence number). Separately, the property SuspendMessageOnMappingFailure is set to add RIP behavior to the subsequent mapping phase in the receive port, as documented in Mapping Phase (Recoverable Interchange Processing).

 

string interchangeId = (string)mBaseMessage.Context.Read("InterchangeID",

    "http://schemas.microsoft.com/BizTalk/2003/system-properties ");
int interchangeSequenceNumber = (int)mBaseMessage.Context.Read("InterchangeSequenceNumber",

    "http://schemas.microsoft.com/BizTalk/2003/system-properties ");
mBaseMessage.Context.Write("BAPIContextId",

    "http://Microsoft.LobServices.Sap/2007/03/SapSendContextProperties ", interchangeId + interchangeSequenceNumber);

mBaseMessage.Context.Write("SuspendMessageOnMappingFailure", "http://schemas.microsoft.com/BizTalk/2003/system-properties ", true);

 

2.2 Installing the pipeline component

 

In order to use it in the pipeline designer, the custom component was installed according to Deploying Custom Pipeline Components, illustrated below.

 

Pipeline Component InstallationPipeline Component Installation

The new component can then be selected from the pipeline designer toolbox.

 

2.3 Creating the custom pipeline in the BizTalk solution

 

The custom pipeline, created in the pipeline designer hosted in Visual Studio, comprises the default XML disassembler and validator. The new pipeline component from the previous section is inserted after the default validator. RIP is set in the configuration of XML disassembler and validator in order to allow processing to go on if some messages within a batch fail any validation. Schemas and envelope schemas are left blank, since BizTalk automatically resolves the envelope and inner schemas from the messages. Note that BAPIContextId will provide RIP later on, in the orchestration stage.

 

The process is identical to the one presented in Recovering SAP BAPI Transactions with Custom Pipelines:

 

Custom Pipeline CreationCustom Pipeline Creation

Once the BizTalk application is deployed, the pipeline is ready to be used in the receive location settings as receiving pipeline.

 

2.4 Transformation of Order to CREATEFROMDAT2 in the receive location

 

The following map is created in the BizTalk solution and added to the receive port properties.

 

Execute transform in receive portExecute transform in receive port

 

3. Orchestration

 

The main purpose of the orchestration is to send a BAPI_TRANSACTION_COMMIT after each CREATEFROMDAT2 message.

The bulk of the work being done in the receive location, the orchestration implementation is pretty minimal, as shown below.

 

Orchestration DetailsOrchestration Details

 

There is one orchestration instance per CREATEFROMDAT2 message, and messages are processed independently, in parallel. So, orchestration instances can be suspended without affecting other messages.

 

4. Concluding Remarks

 

We can control which BAPI transactions go together by setting the new built-in context property BAPIContextId*. So far, we have seen the two ends of the spectrum in terms of batch processing:

  • Default processing (BAPIContextId not set).
  • Unique BAPIContextId for each message.

In part 2 we will cover the middle ground: groups of transactions within batches.

 

* Up to a certain point. BAPI transactions are still required to be sent by the same port.

 

Appendix A: BAPI Operations and Schemas

 

Schemas and metadata for BAPI transactions are downloaded from the SAP server by using the "Consume Adapter Service" in Visual Studio, as explained in this section of the SAP Adapter documentation.

 

The figure below, taken from SAP BAPI Transactions Walkthrough, depicts the process to generate schemas for the BAPI methods BUS2032.CREATEFROMDAT2 (shortened to CREATEFROMDAT2 in the rest of this article) and BAPI_TRANSACTION_COMMIT, used in the demo scenario. 

 

Article1ConsumeAdapterServiceRedux.png

 

Appendix B: Envelope Schemas

 

The figure below, taken from Recovering SAP BAPI Transactions with Custom Pipelines, shows the non-trivial process for creating an Orders envelope schema after creating the Order schema.

 

 

CreateEnvelopeSchemaREDUX.png

 

References

 

BizTalk Server 2020 CU3

Improvement: Support for custom grouping of BAPI transactions in the WCF-SAP adapter

SAP BAPI Transactions Walkthrough

Recovering SAP BAPI Transactions with Custom Pipelines

Handling Errors in SAP BAPI Transactions

 

BAPI in BizTalk

Operations on BAPIs in SAP

Run BAPI Transactions in SAP using BizTalk Server

Get Metadata for SAP Operations in Visual Studio

Browse, search, and retrieve metadata from SAP for BAPI operations

Message Schemas for BAPI Operations

 

Pipelines

Deploying Custom Pipeline Components

Recoverable Interchange Processing

Mapping Phase (Recoverable Interchange Processing)

 

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.