Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
vjimenez
Explorer
6,572
Hello,

As a Software Engineer I needed to create an interface between an SAP System and a third party API using XML as request and response but calling the API through REST adapter. After reading some blogs about creating a Lookup service within a UDF and how to use the REST adapter I have developed this implementation.

Requirement


I need to call an API which a dynamic token given by the same service must be included in the header parameters.

Request and Response must be XML format.

Using the API itself


Getting the Token

Request:
Method: POST
Endpoint: https://<hostname>;
Resource: /api/v1.3/auth/token
Parameters: ?user_name=<user_name>&password=<password>&auth_type=password
Body: None

Response:
{
"authToken": "<authToken>",
"issuedAt": <issuedAt>,
"endPoint": "<endPoint>"
}

Using the Token in a second request

In these example I'm retreiving my account information
Method: GET
Endpoint: https://<hostname>;
Resource: /api/v1.3/user/info
Parameters: None
Body: None

Headers:
Authorization: <authToken> //retrieved in previous request

Response:

{
"accountName": "<accountName>",
"userName": "<userName>",
"userEmail": "<userEmail>"
}

Implementation in SAP PI


ESR Objects

I used the UDF within the request Message Mapping. Since there is no body, I just needed the Token as an input:


The response Message Mapping is all one to one element


Code for the UDF

The inputs are the communication component and communication channel names. I'm using global variables in the UDF since I'm using it in many interfaces but you can set these values by parameters from the configuration side.


//Imports:
javax.xml.parsers.*;
org.w3c.dom.*;

public String getToken(String commComp, String commChann, Container container) throws StreamTransformationException{
Channel channel= LookupService.getChannel(commComp,commChann);
SystemAccessor accessor = LookupService. getSystemAccessor(channel);
StringBuffer sb = new StringBuffer();
String token = "";
try{
InputStream inputStream;
String reqString ="."; //This is to avoid XMLPayload is empty Exception
inputStream = (InputStream) new ByteArrayInputStream(reqString.getBytes());
Payload payload = LookupService.getXmlPayload(inputStream);
Payload RESTOutPayload = accessor.call(payload);
InputStream inpStr = RESTOutPayload.getContent();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(inpStr);
NodeList list = document.getElementsByTagName("authToken");
Node node = list.item(0);
if(node !=null) {
node = node.getFirstChild();
if (node !=null) {
token = node.getNodeValue();
}
}
}
catch (Exception e){
e.printStackTrace();
}
finally {
if (accessor!=null) accessor.close();
}
return token;
}

ID Objects

Receiver Channel used in the UDF

You can also send the user and password from de Message Mapping but I rather to set this data in the configuration side:


Request and Response format must be JSON since it's the format used by the API. I'm converting the response to XML so I can get the value by tag name in the UDF:


For this scenario I'm using XML as request and response but you can use JSON either on request or response.

Sender Channel

Since this is a synchronous scenario I just need to set the QoS to Best Effort


Receiver Channel

I get the dynamic token value from the target of the request Message Mapping


Request and Response must be JSON format since it's the format used by the API. I'm converting from and to XML in both request and response since that's my scenario. You can use same JSON either on request or response depending on your scenario.

I need to wrap the response to the MT used in the response Message Mapping.


The Token value is included in Headers tab


That's it, now the dynamic token is included in the header of the request and I'm able to retrieve the information in a single request from PI:


I hope this blog is helpful for you.

Feel free to share any feedback or thoughts.

Reference Blog posts:

REST Look Up using UDF in SAP PO | SAP Blogs

OAuth 2.0 authentication within a UDF mapping to be included in REST receiver channel | SAP Blogs
4 Comments
PRAGSMATIC
Participant
0 Kudos
How did you make the token cacheable so that you don't call it for every request?
vjimenez
Explorer
0 Kudos
Hello,

We need to get the token in every request.
Sven
Participant
0 Kudos
Hi, this works, thanks. My API responds with a token in the response header, not in the payload. I can see it in XPI_inspector trace of "commChann". I tried using DynamicConfiguration without success. How to get it in getToken UDF?
former_member430489
Discoverer
0 Kudos
Hi There,

can we send basic authentication dynamically ?

Regards,

Chaitanya.
Labels in this area