Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 

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

    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.

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

       6. Right click on Query and select Define Custom Code

Select the script type

           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

      9. Do the mapping as below

     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

    12. Right click on odatasrv and Select Data source

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

     14. Select the wsdl and operation

   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;
}

4 Comments