Technical Articles
How to create a SAP PO loopback interface (without receiver)
In today’s blog we want to take a look at how to implement a loopback interface on the SAP PI / PO. Before we start with the implementation, let’s take a look at what distinguishes a loopback interface and what its uses are.
Table of contents
- What is a loopback interface?
- When to use a loopback interface?
- How to build a loopback interface
- Enterprise Service Repository Objects
- Integration Directory Objects
- Loopback Module configuration (this is where the magic happens!)
- Conclusion
What is a loopback interface?
By a loopback interface I mean an interface that does not have a receiver system, but instead transmits the sent (and optionally transformed) message back to the sender.
In the past I’ve seen only solutions which involved a receiver system with a small dummy server, that responded with the request sent to it. In opposite to this, our loopback interface will work without any receiver system and thus keep its footprint as small as possible.
When to use a loopback interface?
I basically see two uses for a loopback interface:
- Implementation of a mapping-only service.
If you want to carry out a complicated data transformation and at the same time want to maintain flexibility, you can outsource the mapping to a loopback interface and call it up from your application using a “lookup”. - Implementation of a service / monitoring interface.
For example, if you want to provide system parameters such as CPU, hard disk space or database consumption (or whatever you read out using Java mapping / UDF) via an interface as an API.
If you recognize more / other use cases, please write a comment below this blog.
How to build a loopback interface
First let us setup Enterprise Service Repository (ESR) content: Data- and message types, service interfaces and message- and operation mapping.
At first let’s create the request and response data types. For our example we build two minimalistic datatypes with just one string field.
Enterprise Service Repository Objects
Next create two message types and connect them with the data types created right before.
Now we can create the Service Interfaces. Since we expect a result from our loopback interface, we will create them as “synchronous” interfaces.
Attention: For the outbound interface we use our request message type as request and the response message type as response. For the inbound interface we use the response message type as request and response! (That’s because we just want to return the message after we mapped it once.)
In the next step, we will create the Operation Mapping as also the Message Mapping. Use the Service Interfaces created one step before to define the Operation Mapping. Then add a new Message Mapping as “Request Mapping”.
For the Message Mapping, we implement a small “Hello X”-logic. It’s nothing special but should be enough to show in the later tests, that our interface works.
Save and activate all objects you’ve newly created. Then open the Integration Builder.
Integration Directory Objects
Let’s start with the communication channels. Create two SOAP channels – a sender and a receiver one. The sender channel is a regular SOAP sender channel. For now you just have to ensure, that its “Quality of Service” is set to “Best effort” (synchronous mode).
For the receiver channel we play the same game. Just create a standard SOAP receiver channel. Since we have no real receiver system, but have to provide a target url, we enter “http://nowhere.de” as url.
Create a new Integration Configuration now by using the Service Interfaces, Operation Mapping and Communication Channels we created in this tutorial. (Click image to enlarge!)
Save and activate the Integrated Configuration.
Loopback Module configuration
Now let’s go back to the communication channels. So far we have created an interface, which is not guaranteed to work. Finally, a “receiver system” is still missing in the receiver channel. Or not?
Through the targeted use of various adapter modules, we will teach SAP PI that as soon as a message arrives at the receiver channel, it is immediately sent back to the sender. In principle, we configure a kind of “sync async bridge” (as described here, for example), only that we work without a receiver system. So we are building a “sync nobody bridge”.
Let’s start with the sender channel. Open the channel object and switch to the “Module” tab. Then add three new module (in the order as shown in the screenshot below).
- AF_Modules/RequestOnewayBean
- AF_Modules/DynamicConfigurationBean
- AF_Modules/WaitResponseBean
The modules itself shall be configured as shown in the following table:
Module Key | Parameter Name | Parameter Value |
dynConf | key.0 | read http://sap.com/xi/XI/System/Messaging messageId |
dynConf | value.0 | message.messageId |
rob | passThrough | true |
wrb | timeout | 30000 |
The most important point here is the DynamicConfigurationBean, which we use to remember the message id of the incoming message. (We need this in the receiver channel right away.)
Save and activate the sender channel and open the receiver channel. In the receiver channel we will remove the main module of the adapter itself and add two new modules instead.
- AF_Modules/DynamicConfigurationBean
- AF_Modules/NotifyResponseBean
By removing the channels own module (“sap.com/com.sap.aii.af.soapadapter/XISOAPAdapterBean”) we prevent the channel from running (and trying to send the message to …nowhere.de).
The modules itself shall be configured as shown in the following table:
Module Key | Parameter Name | Parameter Value |
dynConf | key.1 | write http://sap.com/xi/XI/System/Messaging messageId |
dynConf | value.1 | message.correlationId |
nrb | timeout | 30000 |
As first thing we read back the recorded own message id and set it as correlation id. (Clear text: We claim that the message correlates to itself.) Then the NotifyResponseBean is called. This bean looks for the message matching the correlationId and setting to “waiting” state (via WaitResponseBean). And what does it find? Our request message, we set to waiting state in the sender channel.
That way we created a loopback interface which works fully without any target system/server. A quick test in SoapUI approves the functionality of our interface.
Conclusion
Due to the many pictures, the article looks longer than it actually is. I’m saying it, because to build a loopback interface, all you need is a few simple steps and cleverly used adapter modules. It’s not that hard than it may look like.
Finally, I have two questions for you:
- Have you already built a loopback interface? (And if so, how did you implement it?)
- What uses do you see for loopback interfaces? (Or do you think it’s completely unnecessary?)
I look forward to your comments and a lively discussion. And now – have fun building it!
Hi Raffael,
We had a similar case before: https://blogs.sap.com/2015/10/08/sync-async-soap2idoc-with-sap-pro-wout-bpm/
My understanding of loopback so far was that PI calls itself (ICO1->ICO2) on the same machine (using SOAP 1.1), however I am not sure this terminology is so well defined.
Nevertheless, using the Beans to switch from sync to async and back to the waiting process is quite handy.
Best regards,
Adam
Hi Adam,
Thanks for the feedback. Yes, I also heard the terminology of Loobpack in context of SAP PI self-calling interfaces. But to be honest, I couldn't think of a better name for the pattern shown above. Maybe the community has a better/more matching name for this kind of interfaces.
Best regards
Hi Raffael!
I’ve been using described approach to send synchronous response back to sender system in case of asynchronous receiver system. Using “Maintain Order at Runtime” option gives the possibility to send response only in case the main operation is completed successfully.
By the way, NotifyResponseBean module puts the message to Synchronizer internal object, while WaitResponseBean queries that object using request message ID as key during period, not exceeding default or specified timeout interval.
Regards, Evgeniy.
P.S. Raffael, please feel free to mention this use-case in your blog. And thanks for sharing this detailed explanation since there have been lots of questions before on requirements that could be fulfilled using this approach.
Hi Raffel,
Thanks for the wonderful blog-i have a question for you.
Can we use this approach for synchronous message split?
Regards,
Bhaskar.
Hi Bhaskar,
Yes and no. If you get an outbound synchronous call and split it you have two inbound messages. Then with the above method you could configure the receiver channel of one of the split messages to send back the response. But for the second inbound message you then had to use another bean to turn this message to an asynchronous one, because you can send only one response back to the synchronous caller.
Best regards
Hi Raffael,
Great article! This is situation we have all be in, and this is a very elegant solution to solve it!
however solving it with bpm or bpmn (SAP BPM) is also possible, but it a really big hassle.
But in CPI we BPMN “built” in and what an ease this is to solve this issue.
I dare you how easy it?
I bow myself into the dust, you are a pioneer with the CPI Dashboard.
But I really what to advocate for CPI. I now that is not right for all. And it can be big hurdle to overcome. However a hybrid architecture is really the way forward for most.
/Jesper
Hi Jesper,
thanks for your feedback. Yes, in CPI interface like this are much easier to build. But as you mentioned, CPI doesn't fit to every customers landscape. So that's the reason, why I wanted to show how to solve this integration task in SAP PI.
Best regards,
Raffael
Hello,
Once I asked this question here :
https://answers.sap.com/questions/12394125/abap-proxy-sync-to-pi-and-response-back-without-a-.html
Because of no proper answers, I had to develop my own loopback adapter from scratch in PI 7.1 and then in PO 7.5.
Nice idea.
BR
Hello Raphael.
Great Job! Excelent article. I have a question ? Can I put another mapping in response section?.
Hi Soporte,
if you build a loopback interface as shown in the article above, then you can't configure a "response" mapping, because as soon as the message arrives at the receiver channel it will be thrown back to the sender/sender channel. But for what reason do you want to configure a "response" mapping. Since no real receiver is called, there can't be a response which could need a mapping. The message will be returned to the sender as you mapped it in the "request" mapping. Thus, you should do all the mappings inside the request mapping.
Hi Raffael.
Thanks for your response. Well I'm on migration from 7.1 to 7.5 single stack and one scenario is with ccBPM.
RFC (Request) -- > Mapping --> RFC (Response) Both are the same RFC. I know in ccBPM is posible that , it's not necesary a receiver also I need to write a Log one in request and response.
This is an excellent blog, I was looking for a similar requirement from SAP ECC to SAP PI . I have followed the steps in this blog but Im getting an error when I execute the proxy call from ECC.
INTERNAL.ATTRIBUTE_UNEXPECTED_VALUE Attribute
MessageId has the unexpected value
<SAP:Code area="INTERNAL">ATTRIBUTE_UNEXPECTED_VALUE</SAP:Code>
<SAP:P1>MessageId</SAP:P1>
<SAP:P2>005056AA25CB1EDAAD9B861895EB2E18</SAP:P2>
<SAP:P3>NewMessageId</SAP:P3>
<SAP:P4/>
<SAP:AdditionalText/>
<SAP:Stack>Attribute MessageId has the unexpected value 005056AA25CB1EDAAD9B861895EB2E18; NewMessageId was expected </SAP:Stack>
I have followed the exact steps except the sender and receiver is SAP ECC proxy call and SOAP Channel message protocol is XI.
Any suggestions?
I'm gettting the same issue,have you found any solution?
I got the same error after how can we fix this and how can we get response back to ECC.. any pointers are greatly appreciated
Hello all,
got same error. The problem is indeed in ProxyFramework, which expects response with different MessageId GUID than was sent in the request.
I made some deep digging in SAP modules and tuned above blog content for XI sender channel. It might be handy for others so here it is:
And that's it. One note to be mentioned - apart from primary XI sender channel for SAP ECC system, you need to have separate XI sender channel for the loopback, which will be used in loopback scenario. The reason is obvious...
Happy hacking.
P.S. another way is to develop simple CC module, where you rewrite message id with new GUID.
Excellent Tomas, thank you very much for your contribution.
Thank you Tomas. That's exactly what I needed.
Hi Raffael,
Thanks for a wonderful blog.
I have exactly the same requirement and my SI's were already defined as yours in the blog. The blog is written beautifully with all the required images and key values to copy.
Only difference my SOAP sender uses XI protocol and I have a 1 line response to be given back to ECC and I have done all required mapping in my MM.
Only issue I am getting an error like :- "Exception: com.sap.engine.interfaces.messaging.api.exception.MessagingException: found no correlation ID"
Immediate reply is highly appreciated.
Hello Taranpreet Kaur,
Were you able to find a way out for the issue you mentioned above.
Thanks in advance.
Hi Raffael, Tomas and Others,
Thanks Raffael for a great post. I have used this approach in my project.
I still have one small problem. When in java mapping I throw an exception (StreamTransformationException) I get another type of error in the SXI_MONITOR in SAP. This exception is not related to the error thrown in mapping program.
Do you perhaps know how to get an error from mapping?
Best Regards,
Tobiasz
Hello Raffael Herrmann / All,
Thank you for such a detail blog, i tried to implement the same at my end as well with all the steps followed but i am ending up with an error when ever i test this interface , below is the error details :
com.sap.engine.interfaces.messaging.api.exception.MessagingException: found no correlation ID
We are using PO 7.5
Any help would be much appreciated. thanks in advance.
Hi Bharath,
I guess the error "found no correlation ID" means that the NotifyResponseBean hasn't found a matching message id for notification. Please check again sender as also receiver channels for correct setup. (Ideally compare them with the screenshots from the article above. It's important that not only all modules/paramters have been setup, but also that they are setup in the correct order! Maybe you have stacked the module configuration in a wrong order or maybe there's a typo in the parameter values?)