Overview:-
We use DynamicConfigurationBean bean to edit the message header for adapter-specific message attributes also to add, delete attributes from message headers. We usually use this when we develop pass-through interface using File and SFTP adapter, recently I came across a situation where I need to send (just pass-through) file from SFTP server to REST api and the receiver was expecting filename in the HTTP Headers. we can do this by using java UDF (creating REST adapter context objects) in graphical mapping or java mapping but this involves development on ESR which I wanted to avoid.
Also Read: SAP PO Certification Preparation Guide
Today we will be working on acknowledgement for both success and failure file transfer. to do this i have done below development
- Generic SAP PO interface which will receive acknowledgement from API
- Used JavaScript within API policy to create custom payload which will be sent to above interface
- used serviceCallout policy to call SAP PO generic interface.
Solution
1. Create an API in SAP API management and within API policy introduce erify API key under PreFlow to restrict unauthorized access, since we will be passing API key in the HTTP headers i have provided reference as <APIKey ref=’request.header.APIKey’/>
2. Once request(file sent from SAP) reaches target endpoint, receiver will respond. in our case receiver was sending “File successfully processed” and “Failed to process” along with appropriate HTTP status code(200 and 400)
3. Now with the response received we will be creating an acknowledgement by using JavaScript (policy name = cust) in PostFlow outgoing request.
4. Once created, JavaScript will be visible in the policy, within JavaScript we need to enter the script file name which we will be creating on our next step.
5. Let’s jump on JavaScript now, we can either import or create them manually in API management. In the policy Editor click over add and a new popup will appear enter the script name we maintained in our previous step and hit Add button
6. Inside script file use below JavaScript code which will create payload for us to send it out to SAP PO generic interface
var request1 = JSON.parse(context.getVariable("request.content"));
var response1 = context.getVariable("response.content");
var filename = context.getVariable("request.header.file");
var custresp;
switch(context.getVariable("response.status.code")) {
case 200:
custresp = { ResponseReceived: {ApplArea : "SD", "Module" :"Sales" , "InterfaceName" : "EDI" , "FileName" : filename , "RespBody" : response1 , "Status" : "OK" } } ;
break;
default:
custresp = { ResponseReceived: {ApplArea : "SD", "Module" :"Sales" , "InterfaceName" : "EDI" , "FileName" : filename , "RespBody" : response1 , "Status" : "ERROR" } } ;
}
//context.setVariable("response.content",JSON.stringify(custresp));
context.setVariable("cust",JSON.stringify(custresp));
As we know SAP API management is using apigee engine in the background i referred to apigee website to understand Flow variable and used them in my javaScript code above
Flow variables reference
- In the JavaScript program request1 and response1 variable are holding request and response payload
- file is accessed from the HTTP header(remember we added using DynamicConfigurationBean) and stored in a variable filename
- custresp is used for holding custom payload we will be sending out to SAP PO generic interface
- switch is used to create custom payload based on response HTTP status code, if 200 then success will be sent else status ERROR will be sent along with the payload
- a new variable cust is created and custresp is stored in it which we will be using in serviceCallout policy
7. Now it’s time to create serviceCallout policy to call external PO service and send an acknowledgement.
8. Within serviceCallout policy i have set below content to send out external request.
<!-- this policy lets you call to an external service from your API flow -->
<ServiceCallout async="true" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
<!-- The request that gets sent from the API proxy flow to the external service -->
<Request variable="myRequest">
<Set>
<Headers/>
<Payload contentType="*" variablePrefix="@" variableSuffix="#">@cust#</Payload>
<Verb>POST</Verb>
<StatusCode>200</StatusCode>
<ReasonPhrase>Success</ReasonPhrase>
</Set>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
</Request>
<!-- The time in milliseconds that the Service Callout policy will wait for a response from the target before exiting. Default value is 120000 ms -->
<Timeout>30000</Timeout>
<HTTPTargetConnection>
<!-- The URL to the service being called -->
<URL>https:xxxxxxxxxx/filepush</URL>
</HTTPTargetConnection>
</ServiceCallout>
In the above policy i am calling my PO generic interface along with the acknowledgment
- serviceCallout continueOnError attribute is used to return exception to the sender when set false, enabled attribute is used as a switch either to use policy or not even if policy is attached to the flow.
- <Request>tag contains request element which will be sent to the service. Request has got 4 sub-elements <Remove>, <Copy>, <Add>, and <Set> in my example i am using SET to assign newly created custom acknowledgement to the payload.
- SET has got 9 more sub-elements which can be checked in apigee website.
- Payload has got 3 attributes contentType, variablePrefix and variableSuffix. prefix and suffix variable is used to assign any existing variable to the payload. in my case i had created cust variable which has got custom payload created in step 6. i am using the same along with prefix and suffix variable ie. @cust#
- Verb is operation, i have created POST operation in REST api so i have hard coded POST
- statusCode is HTTP status code(Response status code) i have hard-coded because my generic interface in SAP PO(REST sender adapter) will throw error if we supply status code dynamically, i want acknowledgement for all the request so 200 fits best for me.
- ReasonPhrase is HTTP status code text.
- Finally i am calling my generic REST api under HTTPTargetConnection tab.
9. We are done with the API development now, policy will look like this when done.
SAP PO Configuration
In SAP PO we will be using REST sender adapter and SOAP(3.0) receiver adapter, acknowledgment will be stored in ECC table and also email will be sent.
1. Develop a REST sender adapter and set QoS as Exactly Once(because we don’t have to send response).
2. Develop a SOAP receiver adapter.(Not described)
3. In ESR develop Message Type and Message Mapping.
4. Create an Asynchronous Service Interface, operational mapping and import message mapping.
5. Generate Service Provider proxy in ECC so that we can later use in program and store acknowledgement in a table.(not described)
Testing
Now let us send a file and see if ECC has got acknowledgement or not.
our xml file was successfully picked up and the api which we developed has accepted request.
The generic SAP PO API has been called by SAP APIM serviceCallout policy successfully along with the custom payload.
since receiver is our ECC(for acknowledgement) message can be viewed in SXI_MONITOR
And finally the whole scenario was to store acknowledgment in ECC in a custom table which we have achieved. the below table has got filename and other parameters in it. the ABAP program which i developed for this has better control over log(we can define when to email and whom to email)