This article is contributed. See the original author and article here.

Introduction


 


This article is the second installment of a series on the scenario used in SAP BAPI Transactions Walkthrough, which should be read before this blog post.


 


Here, instead of receiving a pre-determined number of BAPI transaction requests one at a time, the orchestration expects a single document containing a batch of requests, as well as the desired outcome (commit or rollback). Debatching of XML messages into single BAPI transaction requests is done inside the orchestration by calling the default XMLReceive pipeline. General documentation regarding this orchestration feature may be found at How to Use Expressions to Execute Pipelines


 


The choice of in-orchestration pipeline processing over direct processing in the receive port is mostly arbitrary. It allows us to keep this presentation focused on a single place where the different stages are integrated. The orchestration is well-suited for a workflow of multiple actions and custom error handling. There are pros and cons mentioned in the literature regarding both options and it would take another post to cover them in detail.


It is worth mentioning that with in-orchestration pipelines:


– Transforms can happen before debatching, which in some cases could be a hard requirement;


– It is possible to enumerate over messages of different types;


– Failures result in exceptions being thrown rather than messages being suspended by the pipeline (see for instance Error Handling for failure behavior in the pipeline stage). The thrown exceptions can be handled in a catch block within the calling orchestration, which could allow for graceful error handling with BAPI_TRANSACTION_ROLLBACK.


 


Debatching with Receive Pipeline


 


Pipeline processing of messages containing batches of orders can summarized as :


 


Article2PipelineMessageProcessing.PNG


 


Envelope Schema


 


The first step for using a debatching pipeline is to define an envelope schema to represent multiple orders. This is done according to the following process, initially documented in Calling a pipeline inside an orchestration.


 



  1. Add a new schema file to the project.

  2. Change the root node name to “Orders”.

  3. In the properties window for the <schema> treeview node: (a) change the Envelope property to Yes, and (b) import the Order schema.

  4. In the properties window for the “Orders” root node, set the Body XPath property to /*[local-name()=’Orders’ and namespace-uri()='<namespace of the schema here’

  5. Insert a child record under the root node.

  6. In the child record properties, set the data structure type field to Order. As a result, the Order definition will appear under Orders.


 


CreateEnvelopeSchemaREDUX.png


 


IsCommit is a promoted property which is used later on for deciding whether to commit or rollback the transaction batch. Orders corresponds to the envelope schema imported into RequestsInfo. The Orders element is extracted by a transform shape into a message called SalesOrders.


Note: the RequestsInfo schema could also be an envelope schema for Order, instead of the Orders schema.


 


Implementing the Pipeline


 


Before using the pipeline, the following dependencies must be added to the BizTalk project:



  • Microsoft.XLANGs.Pipeline.dll

  • Microsoft.BizTalk.Pipeline.dll


The pipeline must be inside a scope of type Atomic because it is of non-serializable type. As a result, the orchestration has to be of type “Long running”. Inside the atomic scope, the first expression starts the pipeline execution:


 

PipelineOutputMessageVar = Microsoft.XLANGs.Pipeline.XLANGPipelineManager.ExecuteReceivePipeline(typeof(Microsoft.BizTalk.DefaultPipelines.XMLReceive), SalesOrders);

 


where PipelineOutputMessageVar is a variable of type Microsoft.XLANGs.Pipeline.ReceivePipelineOutputMessages and is used to iterate in a loop shape with the expression:


 

PipelineOutputMessageVar.MoveNext()

 


Inside the loop shape, a message of type Order, CurrentOrder, is assigned as follows:


 

CurrentOrder = null;
PipelineOutputMessageVar.GetCurrent(CurrentOrder);

 


CurrentOrder is then mapped to a message (BAPIMessage) of type BUS2032.CREATEFROMDAT2.


 


The figure below shows the entire pipeline stage:


 


AnnotatedPipelineREDUX.png


 


Caching BAPIMessages


 


Ideally, the BAPIMessages should be sent to the SAP server from within the pipeline, by using the send-receive port connected to SAP. However, an atomic scope may not contain both the send and the corresponding receive (see a detailed explanation here); in our case, the SAP adapter port needs to be bidirectional because the orchestration needs the document id contained in the response and which is used later on to query the transactions status. To work around this limitation, BAPIMessages are saved in a list object to be used outside the pipeline scope:


 

TempXmlData = BAPIMessage;
BAPIOrders.AddFromXMLString(TempXmlData);

 


where TempXmlData is a variable of type XmlDocument, and BAPIOrders is of custom type BAPIOrderList added in a helper library.


 

namespace SapBAPITxClientDebatching
{
    [Serializable]
    public class BAPIOrdersList : List<CREATEFROMDAT2>
    {
        public BAPIOrdersList() { }

        public void AddFromXMLString(XmlDocument document)
        {
            MemoryStream stream = new MemoryStream();
            document.Save(stream);
            stream.Flush();
            stream.Position = 0;

            XmlSerializer reader = new System.Xml.Serialization.XmlSerializer(typeof(CREATEFROMDAT2));
            StreamReader st = new StreamReader(stream);
            this.Add((CREATEFROMDAT2)reader.Deserialize(st));
            st.Close();
        }

        public CREATEFROMDAT2 Get(int index)
        {
            return this[index];
        }

        public int OrdersCount()
        {
            return this.Count;
        }
    }
}

 


The helper library also contains C# classes corresponding to the BAPI transactions schemas generated by running the xsd.exe utility on the BAPI schemas generated in Visual Studio.


 


Processing the debatched BAPI Transactions


 


Once all Order elements have been debatched, the orchestration exits the pipeline atomic scope and iterates over the list of BAPI transaction messages to serialize and send to the send-receive port (LOBPort) connected to the SAP server. This stage is identical to Stage 2 in SAP BAPI Transactions Tutorial except that here, BAPI transaction requests are provided by the orchestration variable BAPIOrders.


 


DebatchingStage2AnnotatedREDUX.png


 


The Global Picture


 


Subsequent stages of the orchestration are presented in detail in SAP BAPI Transactions Tutorial. In Stage 3, the action to take (Commit/Rollback) is determined by the IsCommit promoted property mentioned earlier.


 


DebatchingOrchestrationREDUXS1.png


DebatchingOrchestrationREDUXS2.png


DebatchingOrchestrationREDUXS3.png


DebatchingOrchestrationREDUXS4.png


 


Concluding Remarks


 


The aim of this post was to extend the BAPI tutorial scenario by showing BAPI transactions working with known BizTalk patterns such as debatching. Another pattern to consider is Scatter-Gather, of which debatching is the first step. This will be the topic of another blog post.


 


All code used in this article is attached.


 


References


 


SAP BAPI Transactions Tutorial


Calling a pipeline inside an orchestration


Debatching in orchestration


Performance study of debatching within an orchestration


Different techniques of debatching in orchestration


How to Use Expressions to Execute Pipelines


Error Handling in Pipelines


 


For more general info on the SAP Adapter:


Operations on BAPIs in SAP


Run BAPI Transactions in SAP using BizTalk Server


Message Schemas for BAPI Operations


SAP Adapter documentation


Registry setting to enable BAPI transactions


Get Metadata for SAP Operations in Visual Studio


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


 

Brought to you by Dr. Ware, Microsoft Office 365 Silver Partner, Charleston SC.

AI Chatbot Avatar
Dr. Ware:
Hi! How can I help you?