With SAP NetWeaver Process Orchestration (SAP NetWeaver PO) you have several options at your disposal for implementing particular integration scenarios. The key question is: How do you separate the work between SAP NetWeaver Business Process Management (BPM) and SAP NetWeaver Process Integration (PI) (both of which are actually part of SAP NetWeaver PO)? The answer is: Assign the respective tasks to the tool or framework that is best suited for it! See how to apply this rule for a concrete scenario.
Key Concept
The graphical mapper is a new enhancement for the Enterprise Services Repository perspective of the SAP NetWeaver Developer Studio. It allows you to conveniently map fields to each other by dragging and dropping, including the addition of complex mapping logic and the assignment of fields on different nesting levels by means of a context switch. SAP NetWeaver Process Orchestration (SAP NetWeaver PO) allows you to model and run all kinds of processes: Interactive human-centric business processes, stateful integration processes, and stateless message handling processes. However, users who worked with the SAP NetWeaver Process Integration (PI) double-stack version (ABAP/Java) before and want to benefit from the new capabilities SAP NetWeaver PO is offering have to remodel their integration processes using the graphical modeling standard Business Process Model and Notation (BPMN).
I explain how to separate work between the business process parts on the one hand and the integration parts on the other, and provide guidelines to help you decide which tool to use to achieve your goals.
In my previous article about remodeling existing ccBPM-based processes using BPMN (“Properly Convert Existing ccBPM based Integration Processes to SAP NetWeaver Process Orchestration”), I discussed one possible solution for moving the well-known flight-booking-coordination process to SAP NetWeaver PO (Figure 1).

Figure 1
ccBPM process for coordinating multiple flights
The process handles several connecting flights requested by a travel agency. It sends messages to the respective airlines to book seats. Either all airlines confirm the request and the whole journey is booked and confirmed back to the travel agency, or at least one flight is rejected with the consequence that all already-confirmed flights have to be canceled. In the latter case, the travel agency also receives a negative response indicating the failed attempt to book all seats.
Unfortunately there is no generic approach to move ccBPM-based processes (which, in the end, rely on the Business Process Execution Language [BPEL]) to BPMN. In order to redesign processes suited to run on BPM, you have to look at concrete scenarios and the options BPMN has to offer. In my previous article I solved the problem with the BPMN models depicted in Figures 2 and 3, respectively.

Figure 2
Flight coordination main process

Figure 3
Flight coordination subprocess
In essence, the solution relied on the combination of a main process (Figure 2) coordinating the overall process logic, and one helper subprocess (Figure 3) taking care of sending individual messages to the respective airlines and receiving their responses. I made extensive use of the multiple-instance marker (
) in the main process to indicate the execution of the affected subprocess (i.e., Send requests to airlines and receive status) and service task (i.e., Send Cancel Msgs. to Airlines) in a loop. They were executed as many times as the associated data objects contain entries in their lists (e.g., the RequestedFlights data object for the subprocess shape [Figure 2]). (For more details about this particular implementation option refer back to my other article.)
However, this solution obviously raises some questions such as:
- Is the proposed solution the only way to implement the given scenario?
- What are the performance implications of this implementation?
- What is the best way to divide the work between BPM and PI?
Let’s take a closer look at the solution above. The key problem is the use of the multiple-instance marker. Although this is a powerful means to achieve highly compact and easy-to-read as well as easy-to-maintain BPMN models, it has severe consequences for runtime. Assume the list contains not only a few, but several hundreds or thousands of entries. Maybe this is an unrealistic assumption in the flight coordination scenario, but it could certainly be the case for orders with hundreds of line items. In the latter case the subprocess would be instantiated and the service task would be called hundreds of times, with an end result of creating additional overhead caused by invoking subprocesses or tasks.
In these kinds of scenarios, you should keep in mind the three questions listed above. The last question is especially important as it leads directly to an alternative solution. Because you have to ask: Is it really optimal to let the integration process split the large message in smaller pieces and send individual messages to the respective airlines? The answer is (and this should be your general guideline if it comes to remodeling of ccBPM processes using BPM): Let the tool or framework take over tasks for which it is optimally suited. This means for these two environments:
- Let SAP NetWeaver BPM take care of all stateful coordination activities
- Let PI be responsible for all stateless message handling tasks, such as:
- Interface determinations
- Receiver determinations (routing)
- Message splits
- Mappings
- Technical connectivities
These are the tasks for which PI was developed and optimized. Therefore, in my scenario let it also take care of the message split.
BPM Process
As a consequence of this decision to divide these tasks, the BPM process can be remodeled as is depicted in Figure 4.

Figure 4
Flight coordination process without multiple-instance markers
Obviously no multiple-instance markers and no subprocesses are necessary any longer to implement exactly the same logic as before. Let’s take a closer look at the differences.
- The subprocess for sending requests to airlines and receiving their status (Figure 2) doesn’t exist anymore. It was replaced by a simple service task called Send requests to airlines (Figure 4).
- The Send requests to airlines service task simply forwards one message comprising all flights to PI. It doesn’t care about splitting the message into individual requests and forwarding them one by one to PI as this shouldn’t be the main focus of the integration-centric stateful process. (How PI handles this message is shown later.)
- Figure 4 depicts an explicitly modeled loop for collecting the responses. The loop consists of the intermediate message event Wait 4 Reply, the mapping task Increment Counter, and the gateway All Received?. The logic covered by this loop is a typical task of a stateful process: It has to store the replies from the airlines until all messages have arrived. The received messages make up the state of the process, a functionality that cannot be covered by PI.
- The Send Cancel Msgs. To Airlines service task is no longer marked with the multiple-instance symbol. Again you are not sending individual messages. Instead, one message containing all confirmed flights (see the association from the ConfirmedFlights data object to the Send Cancel Msgs. To Airlines task) is handed over to PI,which is then in charge of splitting the message and forwarding the individual cancel messages to the target systems.
With these main differences in mind, I can now analyze the other settings further to understand how to implement the scenario without applying multiple-instance markers.
- The Send requests to airlines step is just connected to an asynchronous outbound interface that has been imported from the Enterprise Services Repository (ESR). The operation consists of just one message containing customer information and the whole journey (the customer and flights fields Figure 5).

Figure 5
The Journey_DT data type
- The intermediate message event takes care of receiving the individual response messages from the airlines and maps them generally to the StatusAllFlights list, but only in the case where it is approved to the ConfirmedFlights data object. In my new process model the behavior is significantly different from the first implementation. In the first implementation, I had as many intermediate message events with their associated correlation conditions active at the same time as I had flights to confirm. In my new implementation there is only one intermediate message event and with that only one correlation condition is active, saving valuable resources. In addition, it also saves the engine time and effort to identify the right correlation condition during runtime. Even the correlation condition itself is much simpler. In the first implementation I had to make sure that the BPM engine could uniquely identify the right subprocess instance for the incoming message. Hence, the correlation condition was quite complex because it had to compare several fields of the returned message (e.g., customerNo, airline, from, to, date) with those in the process context. In my new solution only the customerNo is of relevance as I am collecting all messages for that particular customer independent of the individual flights. Therefore the correlation condition might now look like this:
string-equal
(FlightStatus_MT/customer/customerNo,FlightRequest/customer/customerNo)
- Mapping steps in general are necessary to map data between process context fields (Figure 6). In my example the Increment Counter mapping step is used for the Counter data object that holds the number of received messages (Figure 4). Finishing the intermediate message event always indicates the successful reception of a message. Hence, the counter can be incremented (Figure 7). Unfortunately this cannot be done during the output mapping of the intermediate message event. For intermediate message events the framework allows only the mapping from the fields representing the received message to the process context. Obviously the Counter field is not part of the received message, leading to an additional mapping step after the event.

Figure 6
Mapping step in detail

Figure 7
Incrementing the counter process context field
- The All Received? gateway checks the end criterion for the loop. Only if the process has received as many replies as there are flights in the initially received journey message does it continue the process flow downstream to the All Confirmed? gateway. Otherwise it jumps back to the intermediate message event to receive more response messages.
Note
The BPMN standard supports an alternative shape for receiving messages. It is called Receive Task and is depicted in
Figure 8.

Figure 8
BPMN Receive Task
The main advantage of using a task instead of an intermediate message event lies in the use of markers. Markers can only be applied to tasks, not to events. Hence, you can benefit from this advantage by using the so-called sequential multiple-instance marker ( ) to indicate that the message reception is executed in a loop, that the loop is executed sequentially, and that the loop ends after the reception of a set number of messages.
By removing the intermediate message event, the mapping task, and the gateway altogether it would simplify the process model even further. All three steps could be replaced by just the Receive Task enhanced with the sequential multiple-instance marker. Unfortunately, SAP NetWeaver BPM doesn’t support this shape yet. Therefore you have to live with the solution shown in Figure 4. However, it is already an indicator for you explaining what is possible once the BPMN standard is implemented in all its beauty.
PI Messages, Mappings, and Integration Flows
This concludes the description of the BPM part of the solution. What is left is the explanation of the PI part. Fortunately the messages being sent to the BPM process didn’t change at all. So everything I discussed already in my previous article applies to the new implementation as well. You only have to analyze the messages from the stateful integration process to the airlines.
There are two of them: One contains the flight requests and the other the cancel messages in cases where not all of the flights have been confirmed. As both messages are logically handled the same way, it is sufficient to take a closer look at one message exchange as an example. In my example, I use the message that is sent by the Send requests to airlines service task in Figure 4. The content of this message is the customer information enhanced by all flights for the journey. The goal is to forward only those flights to the respective airline that it has to serve for this particular journey. Consequently, you have to filter the incoming message for the respective airlines. This filtering is done via mapping.
You can now define individual mappings for each airline. One mapping that filters the incoming message for flights served by Airline_1, a second mapping for Airline_2, and so forth, ending up in n mappings for n different airlines. However, the PI tooling allows you to define mappings using parameters, which can be set during the configuration of the scenario in the PI Designer. It makes sense to define just one mapping, which is dependent on one parameter representing the airline to which the mapping should be applied. Let’s see how this looks in the development environment. Figures 9 and 10 depict the signature of the message mapping and the field mapping, respectively.

Figure 9
Message mapping signature

Figure 10
Field mapping
First, from the signature (Figure 9) you derive that even the target message consists of a flight list as I am reusing the Journey_MT message type that actually wraps the data type Journey_DT. Journey_DT in turn consists of customer data and the flight list (compare to Figure 5). So I am not sending individual messages for each flight to the airlines. Instead I am sending the flights belonging to one airline in a bundle.
Second, you can identify the parameter I was talking about before in the Parameters section of Figure 9. Its name is airline and it serves as an import parameter for the mapping. The field mapping shown in Figure 10 reveals no surprises initially — the customer and the fields of the flights are mapped to each other. However, one mapping leads from the airline node on the left to the flights node on the right. Taking a closer look at this particular mapping in the new graphical mapper reveals the model depicted in Figure 11.

Figure 11
Field mapping for the flights list
Trying to translate this model into prose yields the following explanation: only create a new flights node (createIf) if the content of the airline field is equal (string compare function equalsS) to the name given as a constant. It is this Constant field where you apply the variable that was defined in the Parameters section before. Double-clicking the Constant box shows you the input field against which the value is compared (Figure 12).

Figure 12
Comparing against the parameter airline
The input field is obviously the airline parameter. If you set this parameter later in the PI Designer to, for example, Airline_1, only the flights whose airline field contains the exact string Airline_1 are filtered. Clearly this mapping has to be configured differently for the other airlines, but the idea behind using parameters becomes obvious. This technique saves you from having to define mappings for each individual airline.
However, there is still one important aspect to address. If you take a closer look at Figure 10 you see that the two connected fields airline (on the left) and flights (on the right) are on completely different nesting levels. The parent of the airline field (also called the context of the airline field) on the left is the flights node, whereas the parent of the flights node on the right, to which the airline node is mapped, is Journey_MT. The airline is one nesting level deeper than flights. Fortunately you can overcome this mismatch by lifting the airline node on the left up to the same level as the flights node on the right. To do this, right-click the airline node in your mapping for the flights field and raise it to the Journey_MT level by choosing Context > Journey_MT from the context menu (Figure 13). This context switch guarantees a new flight entry in the flights list (on the right) for every entry for that particular airline in the flights list (on the left).

Figure 13
Set the context of the source node to a higher level (context switch)
Let’s move on to the operation mapping, which is pretty straightforward now as it just more or less wraps the message mapping. As the message mapping requires a parameter, you have to define one for the operation mapping as well. The definition of the operation mapping operation looks like the one shown in Figure 14.

Figure 14
Operation definition of the operation mapping
The source and target operations just point to the services, which in the end refer to the Journey_MT message type shown in Figure 9. Note the Parameters section at the bottom with one entry named airline. This parameter is later bound to the parameter of the message mapping. If you switch to the Definition tab at the bottom of your operation mapping, you have to assign the previously defined message mapping to it (see Figure 15 for details).

Figure 15
Assigning message mapping to operation mapping
The Binding… button of the Assign Mapping Programs dialog box is important. By clicking this you can assign the parameter of the operation mapping and the parameter of the message mapping to each other. The assignment looks like the one shown in Figure 16.

Figure 16
Binding of parameters
Obviously the parameter of the message mapping (left column) is assigned to the airline parameter of the operation mapping. By this assignment you ensure the correct setting of the Constant field in the field mapping of Figure 11. With that, the definition of both the message as well as the operation mapping is complete. You can now proceed with the configuration of this scenario in the PI Designer. The integration flow for transmitting the message from the process to the airlines is shown in Figure 17.

Figure 17
Integration flow from the integration process to the airlines
At first there seems to be only one obvious difference compared to the integration flow shown in my other article: for each of the airlines a mapping step has been added. This comes as no surprise as you need the mapping for filtering out the flights for the respective airline. However, there are two other subtle differences:
- The sender interface is no longer a single flight. It is now the service interface pointing to the Journey_MT (Figure 9) comprising customer information as well as all flights.
- Due to this change the conditions for the content-based router Recipient List look like what you see in Figure 18.

Figure 18
Defining the conditions for the content-based routing
You don’t have to define any loop over all entries of the flights list to check the associated airline field. This is done automatically for you as you are referring to a field of the flights list. Consequently the airline field of all flight entries is checked. As soon as one entry contains the respective airline string the whole message is forwarded accordingly.
- Finally the flights list of my message has to be filtered for the respective airline to which it is dispatched. This is done by operation mapping. If you select one of the mapping steps in Figure 17 (e.g., the upper mapping for airline 1) you can configure the following settings (Figure 19).

Figure 19
Settings of the operation mapping
There are essentially two important settings. First, you have to select the operation mapping itself via the Browse… button of the Name field. Obviously I’ve chosen the mapping shown in Figure 14. As I defined a parameter named airline for this particular mapping, now it’s time to assign a concrete value to it. As I want to filter the message for all flights dedicated to airline 1, I set the parameter’s value to Airline_1 (compare the Value column of the Parameters section in Figure 19), because this is the string you expect in the airline field of the incoming message. Accordingly the parameterization of the mappings for the other airlines is identical. Only the value of the airline parameter has to be changed to either Airline_2 or Airline_3, respectively.
With that you have mastered all the configuration steps required to make the new solution executable. However, there is one drawback of the presented result. Although from a development perspective this is certainly one of the best options, you also have to consider the monitoring aspects of such scenarios. With the subprocess variant presented in my previous article, you get a perfect overview of the status of the main process as well as of all the subprocesses it has kicked off in SAP’s process monitoring view (which is part of the SAP NetWeaver Administrator) as shown in Figure 20.

Figure 20
Monitoring of subprocesses
Figure 20 nicely depicts the flight coordination process at the top and all the subprocesses it has spawned. They are listed as child nodes beneath the parent node. Three messages have been forwarded to the airlines, and one subprocess has already been completed. In essence you get an immediate overview of the communication status with the airlines – each request-reply-pair can be monitored individually. You could easily drill down into each of the subprocesses to find out which response is still missing, and you would find out all the details about the affected airline and flight.
The same convenience cannot be achieved with the approach presented in this article. Yes, you can derive the same information but it is a little bit more cumbersome. This is due to the fact that you get only one entry in the Manage Processes table representing the main process. If you would like to find out missing replies in this case, for instance, you would have to compare the contents of the RequestedFlights data object in Figure 4 with the list of already received replies collected in the StatusAllFlights data object. Especially if you have to deal with hundreds of list entries, this certainly becomes tedious, so also be aware of the consequences in regards to monitoring your scenario.
This concludes my description of an alternative way to model the flight booking coordination process. In this case, each tool took over the parts for which it was developed: BPM coordinating only the stateful message flow and PI taking care of the stateless message handling tasks including message split and content-based routing. By combining the techniques covered in both of my articles you are now ready to master your own ccBPM-to-BPMN remodeling projects.
Note
I’d like to thank my colleagues William Li, Alexander Bundschuh, and Venugopal Chembrakalathil for their support and feedback on this article.

Dr. Volker Stiehl
Prof. Dr. Volker Stiehl studied computer science at the Friedrich-Alexander-University of Erlangen-Nuremberg. After 12 years as a developer and senior system architect at Siemens, he joined SAP in 2004. As chief product expert, Volker was responsible for the success of the products SAP Process Orchestration, SAP Process Integration, and SAP HANA Cloud Integration (now SAP HANA Cloud Platform, integration service). He left SAP in 2016 and accepted a position as professor at the Ingolstadt Technical University of Applied Sciences where he is currently teaching business information systems. In September 2011, Volker received his Ph.D. degree from the University of Technology Darmstadt. His thesis was on the systematic design and implementation of applications using BPMN. Volker is also the author of Process-Driven Applications with BPMN as well as the co-author of SAP HANA Cloud Integration and a regular speaker at various national and international conferences.
You may contact the author at editor@SAPpro.com.
If you have comments about this article or publication, or would like to submit an article idea, please contact the editor.