Intro

Welcome to the final post in my first blogging series about calling outbound https services with server side Java Script using the HANA XS engine. In the first post you learned about setting up your HANA box to use SSL/TLS. The second part explained how to configure the trust relations. Now we are going to use the SSL configuration and the prepared trust store in an actual XS application.

This is the list of all three posts:

Prerequisites

You may have come to this post directly without going through the first two. If so, I don’t want to push you to read the other ones, although I’d be happy if you did 😉 .

So I’ll just summarize, what should have been done so far:

  • Your HANA box has got a running https configuration
  • The target service certificate has been exported
  • That certificate has been imported into an XS trust store (via the XS admin web tool)

In my example I am going to use https://api.github.com as the target service. Of course any other https service endpoint will do as well.

I prefer to use lightweight tools, so I am not going to use the HANA Studio to create and deploy the application.

I’d rather go for the XS Web IDE. It is delivered as non automated content and needs to be manually deployed. This can be done via

  • Studio->Quick launch->Import DU->Server …. IDE/Editor

Just let me know if you need any additional support here.

Create and use the https destination

To call the external https service we are going to set up an XS http destination (xshttpdest), link our trust store to that destination and finally call the service in a server side JavaScript (xsjs) file.

Create a new application

If you just want to play or you do not already have an XS application follow these steps:

Project->Project Templates->Create Empty Project

  • For the ‘Absolute Projectname’ (aka name of the package) you could provide: ‘/github

This will result in an empty project, meaning that you have created a package/folder, which contains two files: .xsaccess and .xsapp.

Create the .xshttpdest

The XS http destination file is the configuration description of the service you want to use. So it represents some meta data in which you can set several parameters like destination host, proxy configuration and (of course most importantly) whether to use SSL or not.

For a detailed reference of the parameters please check the HANA Developer Guide at section 3.7.

The destination is created via:

  • Right clicking the package which will contain the files;
  • Selecting the entry ‘new file’;
  • Providing /github/github.xshttpdest as the file name;

          (It is important to remember the file’s name, as that name is going to be used it in our xsjs.)

  • The content should be similar to the following code snippet:

github.xshttpdest

description = "github api httpS connection";
host = "api.github.com";
port = 443;
useProxy = true;
proxyHost = "proxy";
proxyPort = 8080;
authType = none;
useSSL = true;
timeout = 0;

  • Finally, save and activate this file.

Link the destination to the Trust Store

Did I say we are done with the setup in the last post? Well, I guess I was not totally honest with you (sorry!), but I promise this really is the last thing you need to configure! So let’s get it done quickly.

  • Open the XS admin tool (remember? It is available at https://<host>:43<InstNo>/sap/hana/xs/admin/ )
  • Via the ‘XS applications’ tab
    • Choose your package
    • Select the http destination
    • Within the details area, you need to scroll down to the ‘Authentication’ section and set the following:
      • Authentication type: None;
      • Use SSL: YES;
      • Trust store select the trust store, which contains the target certificate:
        • In my example this is api github;
      • Trigger the ‘Save’ button.

Write server side JavaScript code using this destination

Now you finally have set up everything, and you should be able to call this service from anywhere in your application.

The default way to do it can be found in the reference, available at

There is just a small modification: Github’s API wants us to send a ‘User-Agent’. So we are going to send one, of course.

In this example it will look like the following:

issues.xsjs (also attached)

try {
    //readDestination(package, destination_name)
    var destination = $.net.http.readDestination("github", "github");
    var client = new $.net.http.Client();
   
     var request = new $.net.http.Request($.net.http.GET, "/users/SAP");
     // api.github.com wants a user agent, so we have to provide it
     request.headers.set('User-Agent', 'hana-xs-demo-app');
   
     var response = client.request(request, destination).getResponse();
     //The rest of the file (attached) is just a default forward of the response
  var myCookies = [], myHeader = [], myBody;
    //Cookies
    for(var c in response.cookies) {
        myCookies.push(response.cookies[c]);
    }
    //Headers
    for(var h in response.headers) {
         myHeader.push(response.headers[h]);
    }
    //Body
    if(response.body)
        try{
             myBody = JSON.parse(response.body.asString());
        }
        catch(e){
            myBody = response.body.asString();
        }
    $.response.contentType = "application/json";
    $.response.setBody(JSON.stringify({
        "status"    : response.status,
        "cookies"   : myCookies,
        "headers"   : myHeader,
        "body"      : myBody
        }));
}
catch (e) {
    $.response.setBody(e.message);
    $.response.status = $.net.http.INTERNAL_SERVER_ERROR;
}

Please mind the signature of the ‘readDestination’ method. It expects the package/folder, which contains the destination as the first and the actual name of the destination as a second parameter:

     readDestination(package, destination_name)

Once you’ve saved and activated this file, your package should look like:

and you should finally be able to call it. If this is what you see:

Then you’ve made it  – congratulations!


Video

Of course I also can show this interactively:

Outlook, conclusion and where to go from here

As HANA XS is a pretty young product you can look forward to more features coming your way soon. They are currently under development and I will try to keep you updated on their progress.

Anyway, you now have another powerful piece of technology right in your hand and can explore it by using, for example API sites like Programmable Web or API hub (you also may want to look at the API evangelist serving as a good introduction to APIs).

I hope these posts were useful and enjoyable to you.

I would also like to take the opportunity to send a big THANK YOU to Bjoern Friedmann(@BjoernFriedmann) for his support in helping me getting into those nitty-gritties of the technical complexities.

Stay tuned for more

Kai-Christoph

To report this post you need to login first.

27 Comments

You must be Logged on to comment or reply to a post.

  1. Harald Kopf

    Dear Kai-Christoph,

    first of all thanks a lot for your excellent blog. You addressed a problem were were just dealing with the past few days.

    I managed to do all the steps you described but when I execute the xsjs script at the end the browser tells me “HttpClient.request: request failed. The following error occured: unable to establish connection to proxy:8080 – internal error code: Secure store initialization failed“. Do you have any idea about the issue here? (Note that our Hana system is on SP6, maybe this feature only works with SP7?)

    Two more minor comments:

    – depending on the folder one has chosen earlier one might have to adapt line four:

                   var destination = $.net.http.readDestination(“github”, “github”); 

    in the issues.xsjs script. Maybe it is worthwile to state that explicitly.

    – in part one of yout blog some pics are not visible f.e. the ones under “using Firefox” and “using Chrome”. Maybe some links are broken here.

    Once again thanks a lot!

    Harald

    (0) 
    1. Kai-Christoph Mueller Post author

      Hi Harald

      thank you very much for the flowers!

      So I will of course go ahead and answer your questions 😉

      – The Blog was written using a SP6 system as well.

      — If there will be changes with SP7 I am going to extend / adapt where necessary

      – I also faced the issue (

      HttpClient.request: request failed. The following error occured: unable to establish connection to proxy:8080 – internal error code: Secure store initialization failed

      )

      often when getting things ready for the Blog.

      Most likely you forgot to create the sapcli.pse file (please mind the process needs to be restarted so the file can be loaded). Depending on the signing method you chose you can do this via:

      $DIR_SECURITY_LIB/sapgenpse gen_pse -p $SECUDIR/sapcli.pse -x ” “CN=${HOST}.${DOMAIN}, OU=${INSTANCE}, O=SAP, C=DE”

      or

      $DIR_SECURITY_LIB/sapgenpse gen_pse -p $SECUDIR/sapcli.pse -x ” “CN=${HOST}”

      Also thanks for your comments:

      Even though the signature of the readDestination method is listed in the code, it seems to be a good idea to point it out explicitly. So I did that.

      The picture issue somehow is related to Jive (SCN) as I can see them with Firefox, but not with IE. And to make it even more complicated: Sometimes only in ‘View’ mode and other time only in the ‘Edit’ mode… no idea what the issue actually was, but it seems like I could resolve it by uploading the pictures again.

      Best regards

      Kai-Christoph

      (0) 
    2. Meir Rotstein

      Hi Harald,

      I’m also facing the Secure store initialization failed issue – can you provide any tips how to resolve it? did it was the lack of sapcli.pse?

      Thanks in advance,

      Meir.

      (0) 
      1. Harald Kopf

        Hi Meir,

        I am not an administrator in the system I used, so I could not follow this tip. Step 1 of the blog was not relevant for us as the link https://<yourFQDN&gt;:43<InstNo>/sap/hana/xs/admin/ worked already and we could access the trust center without errors. 

        But we still want to get this running, so I am in contact with the admin of our system. For sure I publish all useful further info here

        Best regards,

        Harald

        (0) 
        1. Harald Kopf

          Hi Meir,

          we tried the same now in Hana Cloud Platform: there it works without problems: we consume now an A2X service of a ByD system.

          We only needed to follow parts 2 and 3 of the blog as the system was already set-up correctly. However what exactly is required for the correct set-up I have no clue…

          Best regards,

          Harald

          (0) 
  2. Liran Shani

    Hi Kai-Christoph,

    When i use the function :

    var dest = $.net.http.readDestination(“sap.idecision.infrastructure.communication”, “esp_wsp”);

    I get this error:

    “Error: User is not authorized to use destination (package: sap.idecision.infrastructure.communication, name: esp_wsp)”

    just to make sure, i added in security.users._system a role: HTTPDestAdmin…

    Best regards, Liran

    (0) 
    1. Meir Rotstein

      Hi Liran,

      This might have to do with the location of your destination file – make sure it’s located at the same level or below as the xsjslib that uses it.

      Good luck,

      Meir.

      (0) 
  3. Dzianis Lapanik

    On SP7 we are getting error message: “HttpClient.request: request failed. The following error occured: unable to establish connection to api.github.com:443 – internal error code: Secure store initialization failed”

    In hana log: “XsIpConnection   IPConnection.cpp(00072) : IPconnection can not initialize libsapcrypto. rc = -40”

    Any ideas what can be the root cause?

    Thanks,

    Denis.

    (0) 
    1. Kai-Christoph Mueller Post author

      Hi Denis,

      to get some more details on this, please do the following:

      1

      Go the ‘Trace configuration’ tab of that system (via Studio) and set the parameter

      sapkerneltrace to DEBUG in section XSENGINE

      (you may need to check box ‘show all components’ )

      Now execute the request again. In the tab ‘Diagnosis files’ you will now find the xsengine…trc file. This file contains the traced messages, which I need for further assistance.

      2

      Send a screenshot of your trust store configuration

      (Are you sure you have got the right certificate and the whole trust chain is available?)

      Hope that helps

      kc

      (0) 
        1. Avinash Raju

          Hi Dzianis,

          How did you resolve this

          HttpClient.request: request failed. The following error occured: unable to establish connection to api.github.com:443 – internal error code: Secure store initialization failed”

          Kindly help,

          -Avinash

          (0) 
  4. Andreas Kerner

    Hi Kai-Christoph,

    Excellent blog, thanks for that. It helped us a lot in a current issue we had.

    Keep up the good work and great entries.

    Thanks a lot

    Best regards

    Andreas

    (0) 
  5. Rachit Puri

    Hi,

    I want to do outbound POST service call.

    I tried the following,

    var jsonObj = ‘{….}’;

    var conn      = $.db.getConnection();

       

    var dest = $.net.http.readDestination(“services”, “CustomerRegistration”);

    var client = new $.net.http.Client();

    var req = new $.web.WebRequest($.net.http.POST, “”);

    client.request(req, dest);

    var myresponse = client.getResponse();

    But I don’t know how pass my payload (jsonObj)

    Can you please help me?

    Thanks & Regards,

    Rachit

    (0) 
    1. Kai-Christoph Mueller Post author

      Hi Rachit

      actually there is nothing special about whether you use https for your request or standard http.

      You will find plenty of examples out there in the net how this can be done.

      The way the XS engine handles this can be seen in the JS API documentation available at:

      JSDoc: Class: Request (method setBody())

      If you look at our demo application you will find some examples on how this has been done for the response object. Using it for the request object is pretty much the same.

      Best regards

      kc

      (0) 
    1. Kai-Christoph Mueller Post author

      Hi Manjunath,


      currently I also do not know about a straight forward way to do this.

      Before looking deeper into this:

      Could you please let me know your use case for this functionality?


      Best regards

      kc


      (0) 
      1. Manjunath Babu Rayampalli

        Hi KC,

        Mine is simple use case. I am trying to do Native HTTP calls using Destination file.

        Still i am able to access properties in Script using

        var dest = $.net.http.readDestination(“services”, “CustomerRegistration”);

        jasmine.log(dest.host);

        will requried info.

        But thanks for the Blog 🙂

        Regrads,

        Manju

        (0) 
        1. Kai-Christoph Mueller Post author

          Hi Manju

          you are welcome 🙂

          So if I get it right, you want to log some properties of the destination?

          This is possible for the following properties:

          dest.

               baseUrl

               description

               host

               pathPrefix

               port

               useSSL

             

          You can set a break point in the debugger and doing so, you will see all those.

          Best regards

          kc

          (0) 
  6. Avinash Raju

    Hi Kai,

    Great Blog !! 🙂 and thanks for sharing.

    After setting up.. I am facing the below error while executing my service. I have tried with the same github example which you have provided..


    “HttpClient.request: request failed. The following error occured: unable to establish connection to api.github.com:443 – internal error code: Secure store initialization failed”

    The SSL and trust store are also configured. It is anything to do with the port specified ?

    Kindly help

    -Avinash

    (0) 
    1. Kai-Christoph Mueller Post author

      Hi Avinash,

      thank you!

      This error message shows that there is something wrong with the SSL and trust store configuration. Did you follow all of the steps of the previous two posts? Is there anything erroneous showing up in the trust store / destination admin?

      You also may want to have a look into the trace files.

      Please check this and let me know more details.

      Best regards

      kc

      (0) 
  7. Hirak Bhowmick

    Hi Kai-Christoph Mueller,

    I have followed all the steps mentioned in your blog. But when I execute the xs js file I am getting an error :-   ”

    HttpClient.request: request failed: internal error occurred "Failed to send request to socket...rc = -1"
    
    Please note I am using hanatrial account. IS it mandatory to use a Production account ?
    
    Please help.
    
    Thanks and Regards.
    Hirak Bhowmick

     

    (0) 

Leave a Reply