Skip to Content
0

REST receiver add custom HTTP header

Sep 04, 2017 at 11:46 AM

699

avatar image

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

10 |10000 characters needed characters left characters exceeded
* Please Login or Register to Answer, Follow or Comment.

3 Answers

Best Answer
Vadim Klimov Sep 04, 2017 at 01:32 PM
3

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

Show 8 Share
10 |10000 characters needed characters left characters exceeded

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

rest-url.png (15.2 kB)
http-header.png (6.9 kB)
0

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

1

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

1

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

rest-url1.png (15.0 kB)
http-header1.png (6.5 kB)
0

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

0

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

0

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

dynamconfi.png (22.0 kB)
messagelog.png (21.8 kB)
0

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

0
Rashmi Joshi Sep 05, 2017 at 02:37 PM
0

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

Share
10 |10000 characters needed characters left characters exceeded
Ritesh Kayal Sep 11, 2017 at 07:18 AM
0

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

Show 1 Share
10 |10000 characters needed characters left characters exceeded

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"?>

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

0