Outbound httpS with HANA XS (part 3) – call the https outbound service in XS server side JavaScript (xsjs)
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:
- Outbound httpS with HANA XS (part 1) – set up your HANA box to use SSL/TLS
- Outbound httpS with HANA XS (part 2) – set up the trust relation
- Outbound httpS with HANA XS (part 3) – call the https outbound service in XS server side JavaScript (xsjs)
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:
- Go to your web IDE ( https://<host>:43<InstNo>/sap/hana/xs/ide/ )
- Using the menu, select:
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
- http://help.sap.com/hana/SAP_HANA_XS_JavaScript_Reference_en/$.net.http.Client.html ;
- http://help.sap.com/hana/SAP_HANA_Developer_Guide_en.pdf ;
- Section 8.4
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
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
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
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.
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>: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
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
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
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.
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.
Hi Denis
it seems like your installation is not correct.
Did you follow Outbound httpS with HANA XS (part 1) - set up your HANA box to use SSL/TLS - especially the 'check the installation' section?
Merry Christmas
kc
Check passed successfully.
sapcli.pse file is present as well?
Yes
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
It is working now.
thanks.
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
thank you - works like a charm !
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
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
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
Hi Kai-Christoph,
Is there any way to access the properties of Destination file from XSJS ?
Regards,
Manjunath.
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
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
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
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
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
Hi Kai-Christoph,
I am facing below error
HttpClient.request: request failed: internal error occurred "Failed to send request to socket...rc = -1"
with this config
description = "******";
host = "***.apimanagement.hana.ondemand.com";
port = 443;
pathPrefix = "/****/***";
proxyType = http;
proxyHost = "proxy";
proxyPort = 8080;
authType = none;
useSSL = true;
timeout = 30000;
Kindly help.
Regards,
Rajesh Kannan K
Hi Avinash
Even I'm facing the same " Secure store initialization failed" where you able to resolve it? Do share the solution.
Thanks
Shashank K
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 :- Â "
Hi Bhowmick,
I have same issue. do you fix it ?
Thanks and Best Regards
Eric
Hi,
Facing Same Problem
any solution?
Hi Bayzidi,
Have you find any solution for this?
Regards,
Rajesh Kannan K
Hi Hirak,
Have you find any solution for this?
Regards,
Rajesh Kannan K
I am also facing same error, any help?
Â
HttpClient.request: request failed: internal error occurred "Failed to send request to socket...rc = -1"
Hi Siva,
Have you find any solution for this?
Regards,
Rajesh Kannan K
Hi Kai
I'm getting
ERROR HttpClient.request: request failed: unable to establish connection to <host>:443 - IPcon: connection to host <host>:443 failed!; $REASON$=ssl: internal error
Could you please help me?
Details on
https://answers.sap.com/questions/13524074/hana-xs-on-prem-httpclientrequestipcon-connection.html#