Recently i was requested to create simply idoc monitor on PI. Overall purpose of this solution should be like that. Some external system sends message to PI using adapter that support synchronic call. Data send in request message is transferred into idoc structure and sends to ERP. In response to request send form external system to sap pi there is necessary to return id of newly created idoc with has been sent to erp. The returned idoc’s id will be used later to display basic information about status in webdynpro application.
So first of all I thought it’s so simple
At the beginning I will receive message then start new integration process. In this integration process I will create sync to async bridge and use message id parameter in mapping to read id of newly created idoc. But I was wrong. Why? Let me show you the solution
I use four abstract interfaces.
- request – receive message from external system
- respond – send result as response to request to external system
- idoc – to send idoc to erp
- m_id – to read idoc message id.
Integration process consist of following steps
- Receive request message and also open sync to async bridge
- Transformation from receive to idoc and m_id.
- Send idoc message
- Transformation from m_id to respond
- Send respond and close sync to async bridge
One important thing is to check in second transformation ‘Create new transaction’. This check makes a commit to all steps executed before it. If I do not check it idoc will be recorded to be send, until next commit or at last end of integration process.
What has become the biggest problem is behavior of BPE. If i use in my message mapping udf like that (typical custom function to read parameter)
to read message id in second transformation, after idoc has been sent, i will receive id of idoc abstract interface, not id of message send to erp witch I was expected to receive. First screen presents result from IDX5 transaction
And second from sxmb_moni_bpe where we can trace integration process instance execution.
As you can see idoc (abstract interface) message id is different than message id in idx5 tcode.
To receive value from idx5 we need to use some trick.
My first idea was to create in second transformation message mapping of type abap, and read last entry from idxrcvpor table that store all sent idoc. But if two or more messages come in short time of period select can return wrong message id.
My second idea (this time good one) was to read data from SXMB_MONI_BPE tcode or more preciously table used by this transaction.
In abap mapping related to second transformation in integration process, required data that means message id of request abstract interface is passed in abstract interface m_id. The value is extracted from m_id message to field mid. Then I can use code that looks like that to receive proper message id of idoc.
data wa_workid type SWW_WIID.
data i_id type USERINFO_GUID.
select single wi_id into wa_workid
where msg_id = mid.
select single msg_id into i_id
where wi_id = wa_workid AND
msgprocrel = ‘A’.
select single idocnumber into idoc_id
where guid = i_id.
First select reads workflow id from SWFXIPROCMSGRE table, related to our request message. Second select reads message id also from the same table, for conditions workflow id and constant value A for Message Sent Asynchronously. Last single read idoc id from table used in idx5 tcode.
Rest what I need to do is put result to my respond message.