Skip to Content
Author's profile photo Ramya Vasanth

Operations needing session key to be be passed in odata request

When session key has to be passed for every soap operation, the following can be done in order to achieve this.

The first step would be to get the session key from a login operation.

The user must provide the credentials as input to login soap operation. This will return session key if login is successful.

The input parameters (username/password) to login operation can be passed via custom script

This session key is passed as odata request header which can be fetched in custom script and set to exchange header or the cxf payload

Steps from Design Time tool

  1. Create an OData Service Implementation Project
  2. Create an OData Model for login operation, which can have property SessionKey

Img00.jpg

    3. Right click on odatasvc and choose Select data source

    4. Select the entity set and choose the query CRUD operation. Select the data source SOAP Service.

Img01.jpg

          5. Specify the wsdl file and choose the login operation from the list of soap operations and click on finish

Img1.jpg

       6. Right click on Query and select Define Custom Code

Img11.jpg

Select the script type

Img12.jpg

           7. Create a hashMap specifying username and password in the custom script’s processRequestData function


function processRequestData(message) {
  importPackage(java.util);
  importPackage(org.apache.olingo.odata2.api.processor);
  importPackage(com.sap.gateway.ip.core.customdev.logging);
  var context = message.getHeaders().get("odatacontext");
  var username = context.getRequestHeaders().get("username").get(0); // Read the parameters from odata header request
  var password = context.getRequestHeaders().get("password").get(0);
  childMap = new LinkedHashMap();
  childMap.put("username", username);
  childMap.put("password", password);
  message.setBody(childMap);
 return message;
}




f the odata request is https://localhost:8083/gateway/odata/SAP/SAMPLE;v=1/LoginSet,

Then the request payload looks like

   <soapenv:Body>
      <aut:LogIn>
         <UserName><username></UserName>
         <Password><password></Password>
      </aut:LogIn>
   </soapenv:Body>

       8. Right click on Query and select Define Response Mapping

Img14.jpg

      9. Do the mapping as below

Img15.jpg

     10. Right Click on Project and select Generate and Deploy Integration Content. This will deploy the bundle.

Now fire an OData Request https://localhost:8083/gateway/odata/SAP/SAMPLE;v=1/LoginSet on the browser and response will give a session key.

     11. Modify the same project created above. Add another entity type in odata model

Img10.jpg

    12. Right click on odatasrv and Select Data source

    13. Select the newly added entity set and choose any CRUD operation

Img16.jpg

     14. Select the wsdl and operation

Img2.jpg

   15. Right Click on CRUD operation and select Define custom Code like done before

   16. The custom code must fetch the session key obtained in previous login operation from the request header and set this to exchange header.

The odata request header looks like


function processRequestData(message) {
importPackage(org.apache.olingo.odata2.api.processor);
var context = message.getHeaders().get("odatacontext");
var sessionId = context.getRequestHeaders().get("TargetSession"); // TargetSession is the header name sent in  request
var id = "JSESSIONID="+sessionId.get(0);
message.setHeader("Cookie",id);
return message;
}




Note: Some web services need session Key to be part of cxfPayload header.Then the function processRequestXML in the custom script must have the below code


function processRequestXML(message) {
importPackage(org.apache.olingo.odata2.api.processor);
var context = message.getHeaders().get("odatacontext");
var sessionId = context.getRequestHeaders().get("TargetSession"); // Target session is the header name sent in odata request
importPackage(org.apache.camel.component.cxf);
importPackage(java.util);
importPackage(org.apache.cxf.helpers);
importPackage(java.io);
importPackage(javax.xml.soap);
importPackage(javax.xml.namespace);
importPackage(java.lang);
importPackage(org.apache.cxf.binding.soap);
importPackage(org.w3c.dom);
rootElement = DOMUtils.readXml(new ByteArrayInputStream(new StringBuilder()).
                         append("<tns:sessionKey xmlns:tns=\"http://namespace\">").
                         append(sessionId).append("</tns:sessionKey>").
                         toString().getBytes())).getDocumentElement();
var payload = message.getBody(CxfPayload);
payload.getHeaders().add(new SoapHeader(new javax.xml.namespace.QName("http://namespace",
"sessionKey"), rootElement));message.setBody(payload);
return message;
}




The request payload looks like

<soapenv:Header>
       <tns:sessionKey xmlns:tns="http://namespace">
              0xxffjjlki3456
       </tns:sessionKey>
</soapenv:Header>
<soapenv:Body>
     <objNamespace:getList xmlns:objNamespace=”http://objectNamespace”>
     </objNamespace:getList>
</soapenv:Body>

   17. Right click on CRUD operation and select Define response mapping and do the mapping like before

   18. Right click on Project and click on Generate and Deploy Integration Content

Now fire an OData Request https://localhost:8083/gateway/odata/SAP/SAMPLE;v=1/ListSet specifying the header

   19. Some web services may need to send username, password as part of exchange headers. In this case the username:password must be encoded and this value must be set to exchange header. The header name will be Authorization and value will be Basic <Encoded Text>

The request payload will be

   <soapenv:Body>
      <xyz:findListOfElements>
         <arg0>        
            <MaxResults/>
            <adjustDates></adjustDates>
         </arg0>
      </xyz:findListOfElements>
   </soapenv:Body>

The custom code script for the same is


function processRequestData(message) {
importPackage(java.util);
var parentMap = new HashMap();
var childMap = new HashMap();
childMap.put("MaxResults", "");
childMap.put("adjustDates", "");
parentMap.put(childMap);
message.setBody(parentMap);
message.setHeader("Authorization", "Basic <Encoded Text>");
return message;
}




Note: in the above script, header value is hardcoded. To avoid this username, password can sent as filter expressions in odata URI and value can be encoded in the script.

Or, encode the username/password and send the encoded value as a request header parameter, which can be fetched in the script file and set to message header.

20. Some web services require attributes to be added to the CxfPayload elements.

The request payload will be

   <soapenv:Body>
      <xyz:LoginCustomerRequest origin="SoapUI" traceNo="A123456789" repeat="false">
         <identification>+6287880946389</identification>        
           <credential>123123</credential>
           <identificationType>0</identificationType
         <credentialType>0</credentialType>
      </xyz:LoginCustomerRequest>
   </soapenv:Body>

The custom code script for the same is


function processRequestData(message) {
 importPackage(java.util);
 importPackage(org.apache.olingo.odata2.api.processor);
 var childMap = new LinkedHashMap();
childMap.put("identification", "+6281945554369");
 childMap.put("credential", "112233");
 childMap.put("identificationType", "0");
 childMap.put("credentialType", "0");
message.setBody(childMap);
return message;
}
function processRequestXML(message) {
importPackage(org.apache.camel.component.cxf);
importPackage(org.apache.cxf.helpers);
importPackage(java.io);
var str = message.getBody();
var rootElement = DOMUtils.readXml(new ByteArrayInputStream(str.getBytes())).
                              getDocumentElement();
var payload = (CxfPayload)(message.getBody(CxfPayload));
rootElement.setAttribute("origin", "SoapUI");
rootElement.setAttribute("traceNo", "UI6ot772");
rootElement.setAttribute("repeat", "false");
payload.getBody().remove(0);
payload.getBody().add(rootElement);
message.setBody(payload);
return message;
}

Assigned Tags

      4 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      Hi Ramya,

      Some of the images are not visible, could you insert it once again.

      Thanks

      -Stan

      Author's profile photo Former Member
      Former Member

      Hi ..

      For the above request I want to pass the origin and TraceNo dynamically..that means i don't want to keep statically please help me

      Author's profile photo Ramya Vasanth
      Ramya Vasanth
      Blog Post Author

      Hi,

      If you want to pass any parameter dynamically, you can pass it via headers or as an OData filter.

      You can read this value (if set as header) in the custom script using methods message.getHeaders() as described in the blog.

      If it is set as filter you can read the value as described in the blog

      http://scn.sap.com/community/developer-center/mobility-platform/blog/2014/10/29/how-to-handle-filters-in-soap-operations

      Regards,

      Ramya

      Author's profile photo Former Member
      Former Member

      Thanks a lot for this blog. It helped us a lot for passing SOAP Header parameters.