cancel
Showing results for 
Search instead for 
Did you mean: 

REST receiver add custom HTTP header

rasjoshi
Active Contributor
0 Kudos

Hi All,

I am getting access token value from UDF - Lookup, I want to add this value to REST receiver custom HTTP header value.

However, as per my understanding, we need to have xml structure from where we can add xpath expression and pass the value.

As this access_token is coming via lookup, I am not having any xpath expression for this.

How can I pass this value to my HTTP header?

BR,

Rashmi

Accepted Solutions (1)

Accepted Solutions (1)

vadimklimov
Active Contributor

Hello Rashmi,

You may use adapter specific message attribute: from within the UDF, add dynamic attribute and assign it a value of the acquired access token, then in the REST receiver channel, you can make use of it (in the tab 'REST URL', inspect value source option 'Adapter-Specific Attribute'). Note that attribute's namespace shall be 'http://sap.com/xi/XI/System/REST' for REST adapter (refer to the blog for details), and the attribute name used in the communication channel and in the UDF, shall be exactly the same. The rest of configuration in the communication channel in part of adding custom HTTP header will not be different from the option if you would have acquired the value from the message using XPath.

Regards,

Vadim

rasjoshi
Active Contributor
0 Kudos

Hi Vadim Klimov

Thanks for your reply, I am not good with JAVA... Could you check my UDF and suggest me some required modifications please?

UDF Dynamic Configuration -

...........

getTrace().addDebugMessage("Response: "+sb);

int i =sb.indexOf("\"access_token\":\"")+16;

int j = sb.indexOf("\"instance_url\"");

token = sb.substring(i,j - 2);

getTrace().addInfo("Token: "+token); }

catch (Exception e){ e.printStackTrace(); }

finally{

// 5. close the accessor in order to free resources.

if (accessor!=null) accessor.close(); }

return token;

//Dynamic Configuration

DynamicConfiguration dynConf = DynamicConfiguration)all.get(StreamTransformationConstants.DYNAMIC_CONFIGURATION);

DynamicConfigurationKey key = DynamicConfigurationKey.create( "http://sap.com/xi/XI/System/REST", token);

String value = dynConf.get(key);

return value;

REST Receiver Channel -

after testing interface using SOAPUI, I am getting below error -

<text>com.sap.engine.interfaces.messaging.api.exception.MessagingException: com.sap.aii.af.service.mapping.MappingException: Mapping failed in runtimeRuntime Exception when executing application mapping program com/sap/xi/tf/_MM_SFDC_RESTAPI_QUOTE_STATUS_UPSERT_REQ_V1_; Details: com.sap.aii.mappingtool.tf7.MessageMappingException; Runtime exception when processing target-field mapping /requestwraper; root message: Exception:[java.lang.IllegalArgumentException: Name is too long (112/50): 00D2F000000CqGE!ARwAQJMZknn3ZoGjrd44LLqxPqtYEA8namitYqQ6kXG.jYkT.GePn4e1Mky8siyu0Jh0N6MSCbyhinD6.3PLaif0_1qqQ3ck] in class com.sap.xi.tf._MM_SFDC_RESTAPI_QUOTE_STATUS_UPSERT_REQ_V1_ method getAccessToken[com.sap.aii.mappingtool.tf7.rt.Context@29f1cac5] at com.sap.aii.adapter.soap.web.SOAPHandler.processSOAPtoXMB(SOAPHandler.java:772)

BR,

Rashmi

manoj_khavatkopp
Active Contributor

Hi Rashmi,

The UDF in the Blog defines to read the ASMA parameters from Sender Channel but in your case you need to set ASMA parameter for receiver hence you need to modify the part of dynamic config to set the ASMA a sample wrt to what you have provided would look like :

DynamicConfiguration dynConf = DynamicConfiguration)all.get(StreamTransformationConstants.DYNAMIC_CONFIGURATION);
DynamicConfigurationKey key = DynamicConfigurationKey.create( "http://sap.com/xi/XI/System/REST","value");
dynConf.get(key,token);
return "";

Additionally you don't need 2 return statements .embed this dynamic udf in your lookup code only once you have the token then later you add this code . I remember you had raised similar thread on soap lookup and setting up the url dynamic it is similar like that once instead of reading soap envelope you are reading json and instead of setting soap url you are setting up dynamic header with REST adapter parameters.

Br,

Manoj

vadimklimov
Active Contributor

Rashmi,

To create dynamic attribute and assign it value in UDF, you may use following sample:

Map map = container.getTransformationParameters();
DynamicConfiguration conf = (DynamicConfiguration) map.get(StreamTransformationConstants.DYNAMIC_CONFIGURATION);
DynamicConfigurationKey confKey = DynamicConfigurationKey.create(namespace, attribute);
conf.put(confKey, value);

where in your specific case,

  • namespace - attribute namespace, here http://sap.com/xi/XI/System/REST
  • attribute - attribute name that will be used further in communication channel in the field 'Attribute Name'
  • value - attribute value, here value of the obtained access token (assigned to a variable 'token' from your code).

In your code, you made an attempt to create an attribute with the name that is equal to the token value, which is too long String value exceeding allowed maximum length of the attribute name. Note that attribute name IS NOT its value, but can be thought as a named alias that is used to access the value.

When configuring the communication channel and accessing dynamic attribute value, there is no need to use double slash before the attribute name (as highlighted in your screenshot, configuration parameter 'Attribute Name') - instead, only specify pure attribute name there.

I would also suggest you renaming the attribute name to somewhat different from 'value', as 'value' is too generic naming. As an example, you could name it somewhat reflecting nature of the contained value - for example, 'AccessToken'.

Regards,

Vadim

rasjoshi
Active Contributor
0 Kudos

Hi Vadim Klimov,

Modified UDF as per your suggestion, but I am getting below error now.

UDF -

token = sb.substring(i,j - 2);

getTrace().addInfo("Token: "+token); }

catch (Exception e){ e.printStackTrace(); }

finally{

// 5. close the accessor in order to free resources.

if (accessor!=null) accessor.close(); }

//return token;

//Dynamic Configuration

String namespace = "http://sap.com/xi/XI/System/REST";

String Access_Token = "";

Map map = container.getTransformationParameters();

DynamicConfiguration conf = (DynamicConfiguration) map.get(StreamTransformationConstants.DYNAMIC_CONFIGURATION);

DynamicConfigurationKey confKey = DynamicConfigurationKey.create(namespace, Access_Token);

conf.put(confKey, token);

return "";

Below is the error I am getting while trying to test in Message Mapping tab -

Runtime exception when processing target-field mapping /requestwraper; root message: Exception:[java.lang.NullPointerException: while trying to invoke the method com.sap.aii.mapping.api.DynamicConfiguration.put(com.sap.aii.mapping.api.DynamicConfigurationKey, java.lang.String) of a null object loaded from a local variable at slot 11] in class com.sap.xi.tf._MM_SFDC_RESTAPI_QUOTE_STATUS_UPSERT_REQ_V1_ method newAccessToken[com.sap.aii.mappingtool.tf7.rt.Context@5b9fa57b] See error logs for details

Whereas as per trace, I am getting value in token -

Mapping Trace -

Parameters for Token Lookup - Channel: CC_RCVR_SFDC_REST_LOOKUP (Party: , Service: BC_SFDC, Object ID: 25f71318dbba3381bcf077849c698519) Token: 00D2F000000CqGE!ARwAQMsEqv99TfXVbWg3TTGzXNHsfQZG8.vM51FYZqsd.g53qKAbE87LaybDfDIw40zIo4mVT773jMiEgPa1_21kGqj_0zFS

SOAP UI test error -

com.sap.aii.adapter.rest.ejb.receiver.PlaceholderMissingException: URL placeholder token is not configured, or has an empty value

REST Channel -

Looks like token value is not getting assigned to attribute - Access_Token.

I am not getting this error...

BR,

Rashmi

rasjoshi
Active Contributor
0 Kudos

Not getting error at message mapping test after adding statement -

if (conf != null) {

DynamicConfigurationKey confKey = DynamicConfigurationKey.create(namespace, Access_Token); conf.put(confKey, token); }

But still not getting value passed to HTTP Header....

BR,

Rashmi

vadimklimov
Active Contributor
0 Kudos

Rashmi,

In the channel configuration, you attempt reading value of the dynamic attribute 'Access_Token', but in UDF code, no such attribute is created (you defined similarly named variable name, but this doesn't get promoted to the attribute with the same name). Hence, in the UDF code, change so that:

  • Replace String Access_Token = ""; with String attrAccessToken = "AccessToken";
  • Replace DynamicConfigurationKey confKey = DynamicConfigurationKey.create(namespace, Access_Token); with DynamicConfigurationKey confKey = DynamicConfigurationKey.create(namespace, attrAccessToken);

After that, in the communication channel, change value of parameter 'Attribute Name' from Access_Token to AccessToken.

Regards,

Vadim

rasjoshi
Active Contributor
0 Kudos

Hi Vadim Klimov,

I can see access_token value in PIMON -- Message Content tab but when I check logs, I dont see HTTP Header getting added by rest adapter... please check below screen shots -

BR,

Rashmi

vadimklimov
Active Contributor
0 Kudos

Hi Rashmi,

From the message log, I can see many other HTTP headers are not set as well (or not reflected in the log). Can you make a trace (XPI Inspector trace including HTTP trace) of the receiver channel and see if there is any indication of successful processing of the retrieved adapter specific message attribute, as well as setting of other extra HTTP headers that you configured with fixed values?

Regards,

Vadim

vadimklimov
Active Contributor
0 Kudos

Yes, in REST receiver channel configuration, in tab 'Data Format', you can enable logging of the message before REST adapter converts received response JSON message into XML message - checkbox 'Log JSON message' becomes available for you when you specify response data format as JSON and enable conversion to XML.

Besides REST adapter specific logging of the JSON representation of the message, you can also log messages on Messaging System level (see examples in the blog) - for example, here verification of processed response XML message would be helpful to figure out which source fields were not populated / were missing, that caused the exception you got during response mapping execution.

Regards,

Vadim

Answers (2)

Answers (2)

0 Kudos

Hi Rashmi,

You can test the SFDC REST API using POSTMAN to check the response JSON format.

Then you can design your structure in SAP PO and convert the JSON response in the REST receiver channel so that your response mapping doesn't fail.

Thanks,

Ritesh K

rasjoshi
Active Contributor
0 Kudos

Hi Ritesh Kayal,

I checked response message from SOAPUI, below is the response I am getting -

{ "access_token": "xxxxxxxxxxxxxxxx.b.62jco7n_Juvd",

"instance_url": "https://xxxxxxx.my.salesforce.com",

"id": "https://test.salesforce.com/id/xxxxxxx4",

"token_type": "Bearer",

"issued_at": "xxxxxxxx",

"signature": "xxxxxxxxxxxxxxx+zg=" }

And below is my structure defined in PI -

<?xml version="1.0" encoding="UTF-8"?>

<ns0:MT_RESP_TOKEN xmlns:ns0="urn:ca.com:OT_QUOTE_STATUS_UPSERT">

<access_token/>

<instance_url/>

<id/> <token_type/>

<issued_at/>

<signature/>

</ns0:MT_RESP_TOKEN>

In rest receiver channel, for response message I have kept format as JSON...

But below is the error I am getting for response mapping -

How should I deal with it?

BR,

Rashmi

rasjoshi
Active Contributor
0 Kudos

Thank you so much Vadim Klimov...

Restarting PI system fixed this issue....

However, getting new issue at response mapping.. I am not able to see what SFDC is sending in response...

Is there any way to log these messages in REST adapter?

error -

Server returned code: 20009/05/2017 09:40:56.689InformationProcessing result09/05/2017 09:40:56.769InformationREST call finished09/05/2017 09:40:56.961ErrorTransmitting the message using connection SOAP_http://sap.com/xi/XI/System failed, due to: com.sap.engine.interfaces.messaging.api.exception.MessagingException: Error encountered while executing mapping: com.sap.aii.af.service.mapping.MappingException: Mapping failed in runtimeRuntime Exception when executing application mapping program com/sap/xi/tf/_MM_SFDC_RESTAPI_QUOTE_STATUS_UPSERT_RESP_V1_; Details: com.sap.aii.mappingtool.tf7.IllegalInstanceException; Cannot create target element /Log_Messages/DT_SFDC_QUOTE_STATUS_RESP/item. Values missing in queue context. Target XSD requires a value for this element, but the target-field mapping does not create one. Check whether the XML instance is valid for the source XSD, and whether the target-field mapping fulfils the requirement of the target XSD

BR,

Rashmi