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: 
thomas_jung
Developer Advocate
Developer Advocate
26,156

This blog is part of the larger series on all new developer features in SAP HANA SPS 11: SAP HANA SPS 11: New Developer Features

XS Evolves Into XS Advanced

Requirements change over time and so too has XS within SAP HANA. SAP HANA extended application services in SPS 11 represents an evolution of the application server architecture building upon the previous strengths while expanding the technical scope.

Figure 1: Architecture as of SAP HANA SPS 11

We will use standard Cloud Foundry build packs as the basis of the XS language support. Therefore starting with SAP HANA SPS 11, XS Advanced will be delivered with and fully support both Apache TomEE Java and Google V8 JavaScript/Node.js.  In both of these runtimes, you will find a pure delivery of the standard runtimes; not an SAP branched or modified version. This greatly supports the easier porting of existing applications onto SAP HANA.

From Mozilla SpiderMonkey to Google V8

JavaScript has always been the foundation of SAP HANA XS.  In XS Classic we use the Mozilla SpiderMonkey virtual machine - the same JavaScript engine which runs the FireFox browser. In today's XS environment we have a single operating system process called XSEngine.  Within this process we create a pool of JavaScript Virtual Machines. The are clones of a single runtime version. Therefore there are no options to control which version of JavaScript your application runs against. There are some limited configuration parameters that apply to the entire pool of JavaScript VMs, but no way to configure memory or other scaling parameters per application. Finally as all the VMs live within a single operating system process, if anything goes wrong there is the potential to crash the entire XSEngine process.  We also extend the current JavaScript programming model with our $ APIs via JavaScript function wrappers around C/C++ libraries and other JavaScript functions. This creates a situation where there is a deep coupling between the JavaScript VM and the XSEngine codebase.


In the new Cloud Foundry based architecture of XS Advanced, things work very differently. First when you deploy an application or service a copy of the entire Java or Node.js runtime goes with.  This way each service is isolated and locked into their version. Even if you upgrade the entire HANA/XS system, already deployed services continue to run with their existing runtime providing better stability over time. It isn't until you would deploy the service again that you could pick up a newer version of the specific runtime. This allows single services to target different runtime versions in parallel.

At the operating system level, we also no longer have one monolithic process hosting all the runtimes. Each runtime instance has its own operating system process. This allows for much better process isolation ensuring that a single poorly written or behaving service can't disrupt other services/applications.

We also will now extend the JavaScript runtime via the standard concept of Node.js modules.  In fact even the $ APIs of XSJS are re implemented within Node.js (but more on that later in this blog).

The biggest change for developers however is the change from Mozilla SpiderMonkey to Google V8 as the underlying JavaScript VM.  Now you might think that two JavaScript VMs can't be all that different. From a purely JavaScript language aspect, that is certainly true.  However with Google V8 we also gain support for Node.js. Node.js has quickly become the defacto standard for server side JavaScript thanks to its Asynchronous / Non-Blocking I/O programming model and the easy of which you can access and manage reusable, open source modules. So for the remainder of this blog we will look at the basics of Node.js development and how SAP will be supplying XS and HANA functionality into the Node.js environment.

But Node.js is hardly an SAP specific technology.  It already has a strong community and many excellent resources.  So if you want to expand your knowledge of Node.js in general, here are some resources we would recommend:

Node.js Hello World

Even if you don't have access to SAP HANA SPS 11 yet, its easy to get started learning Node.js.  You can simply download the Node.js runtime from Download | Node.js and begin writing and executing Node.js applications.  Because we use a nearly standard Node.js within XS Advanced (only adding some supportability features), whatever you learn in this local version will prepare you well for developing in XS Advanced in the future. In fact at SAP TechEd 2015 we wanted hands-on exercises to teach people the Node.js programming model and introduce XS Advanced concepts but the actual SPS 11 software wasn't ready yet to be used.  Therefore we designed and delivered these hands-on sessions based solely on a local installation of Node.js alone.

The main thing to keep in mind that when you use this local Node.js installation you will be running the Node JavaScript files manually via the command line interface. However once you have SAP HANA XS Advanced you will have to deploy these files to the server and run them as services.

To being with a simple Hello World Node.js application you can simply create a .js file on your local file system and add this code:

console.log("Hello World");

From the command line we can invoke the node.js runtime by issuing the command node. The parameter after the node command tells what JavaScript file to execute.

Therefore issue: node hello.js to run your first exercise.

Figure 2: Execute node hello.js from the command line


Now you can adapt your helloWorld to respond as a Web Server instead of to the console. Node.js has a built-in web server; therefore you can directly interact with the HTTP Request or Response objects. In this exercise create a small service that returns the Hello World text in a web browser. Node.js uses the syntax require to load a dependent library file. Require the built-in http library. Use the createServer API to start an HTTP server and then listen on port 3000 of your localhost (IP 127.0.0.1). The createServer API passes in the request and response objects as parameters. Use res.end to write the body of the response object.



var http = require('http');

http.createServer(function (req, res) {
res.end('Hello World\n');
}).listen(3000, '127.0.0.1');
console.log('Server running at http://127.0.0.1:3000/');









From the node.js command prompt execute the helloWeb.js you just created. Unlike the earlier example, it doesn’t immediately return control to the DOS prompt. Node continues to run because it’s listening for HTTP requests. Open a web browser and navigate to your node.js application which is running on http://localhost:3000. You should see the text of the message you passed back in the response object.


Here is a video detailing the steps of both the console and web based hello world in Node.js:


Reusable Modules

In the previous example, we created a hello world that runs from the web, but you had to manually open the web browser. Wouldn’t it be nice if the application opened the browser for you? Luckily there are many open source libraries available for Node.js and they are very easy to use and install. We will use one such library to extend the previous exercise to open a web browser for you.


Add the following line of code at the beginning of this file. This require statement gives us access to the opn library. Unlike the http library we used earlier, this isn’t built into node.js and has to be installed in a later step.


var opn = require('opn');

Add this line of code to the end of the file. This will trigger the opening of the default web browser to the web page where our application is listening.


opn('http://127.0.0.1:3000/');

From the node.js command prompt we can install the opn library using the npm tool. First make sure you are in the Exercise2 directory. Then issue the command npm install opn to install the opn library.

Figure 3: NPM Install


NPM is a powerful tool and a strong part of the Node.js's popularity. It makes the installation of external modules very easy. More importantly it manages the dependencies between modules well. When you install a module, all the depend modules are also automatically installed. We've built NPM into the deployment process of XS Advanced.  So as you are deploying a new service/application to XS Advanced, NPM is automatically called to also download any dependent modules.


One of the most common tasks in node.js is acting as a web server and handling http requests/responses. express is an open source module that wraps the low level http library and provides many additional services. Therefore it is widely used in Node.js projects in general and more specifically within new XS Advanced applications. We will now adapt our helloWeb to use express instead of the built  in http library.


Replace the require statement for the http library with one for the express library.


var express = require('express');


We also want to get a little more sophisticated with our HTTP port assignment. Instead of hard coding an HTTP port, use the built-in object called process to query the PORT which node.js is running under. If none is found fall back to port 3000. This is useful in the XS environment because the controller framework in XS will assign and pass in a distinct port to each application.


var PORT = process.env.PORT || 3000;


Replace the rest of the code in your application with this code. It will create an instance of express and setup a route. Routes are code handlers for certain HTTP URL paths. In our case we will now only respond to GET requests to the /hello path.



var app = express();
//Hello Router

app.route('/hello')
  .get(function(req, res) {
    res.send('Hello World');
  })
// Start the server
var server = app.listen(PORT, function() {
  console.log('Listening on http://localhost:'+ PORT +'/hello');
  opn('http://localhost:'+ PORT + '/hello');
});






As we get more and more libraries in our node.js applications, we don’t want to have to rely upon someone always manually using the npm install command to include them all. Instead we can create a package.json file that lists all the dependencies and their particular versions.

Figure 4: package.json example


You can now issue the command npm install. This will read the package.json and install all libraries listed in the dependencies section. Express is much larger library; so many more dependencies were installed as well.

One of the additional features of express is that it makes it easy to serve out static HTML content alongside your dynamic services. We can also add a static resource route for the root of our application. Add a line of code before the hello route to redirect requests from the root of the URL to static content in the html sub-directory.



//Home Router
app.use('/', express.static(__dirname + '/html'));





Modules don’t all have to come from central repositories. They can also be a way of modularizing your own code (similar to XSJSLIB files). Let’s now add another route but have the handler for it be contained in a module. Toward the beginning of your file add a require statement that points to a library named myModule which we will create locally in just a few steps.


var myModule = require('./myModule');


Add another route handler for the URL path /module that calls the helloModule function in the myModule library.



//Module Router
app.route('/module')
.get(function(req, res) {
res.send(myModule.helloModule());
  })





The myModule.js uses the syntax module.exports. Any function declarations within this block are exposed to the outside. This is all you really need to create such reusable modules.

Here is a video detailing the previous steps:



Asynchronous / Non-Block I/O

One of the major differences from Node.js and client side JavaScript or even XSJS is its asynchronous nature. This asynchronous capability allows for non-blocking input and output. This technique is one of the basic things that makes node.js development different from other JavaScript development and also creates one of the reasons for its growing popularity. We will see how these techniques are applied to common operations like HTTP web service calls or even SAP HANA database access.


We want first to look a very simple example that shows the asynchronous nature of node.js. Begin by creating a file named async.js. In this code we will output a start message to the console, then set a timer which will issue a message after 3 seconds. Finally we will issue an ending message to the console.



console.log('Start');
setTimeout(function(){
            console.log('Wait Timer Over');
}, 3000);
console.log('End');





What do you expect this code will output? From many other programming languages we would expect sequential processing and therefore the End output wouldn’t come until after the timer expired. However part of the power of node.js is asynchronous non-blocking execution of many core elements. Run the async.js from the command prompt to see the results. You should see the End output is issued before the Wait Timer Over.


Perhaps a timer seemed like an obvious asynchronous operation. However this asynchronous nature of node.js is often used when programs must wait on input or output. When asynchronous processing is applied to these operations, we can keep from blocking execution of other logic while we wait on things like file access, http requests or even database query execution. Let’s first look at the difference between synchronous and asynchronous file operations. Create two text files named file.txt and file2.txt. Place a little text in each file. The actual content isn’t that important.  Now create a file named fileSync.js. Using the fs library and the function readFileSync, read each of the text files. Output the content of each file to the console. After each read operation output a console message.



var fs = require('fs');
var text = fs.readFileSync('file.txt','utf8');

console.log(text);

console.log("After First Read\n");
text = fs.readFileSync('file2.txt','utf8');

console.log(text);
console.log("After Second Read\n");




Test your fileSync.js from the node.js command prompt. As you might expect, everything is output in exactly the same order as the lines of code were listed in the application because all operations were synchronous. Program execution didn’t continue until each read operation had completely finished.


Create an additional file named fileAsync.js or copy from the fileSync.js in the previous step. Adjust the logic to use the fs.readFile function. Notice that the console.log(text) now is embedded as an in-line callback function. It doesn’t get executed until the read operation is complete, but the rest of the program flow continues and isn’t blocked by the file operation.



var fs = require('fs');

fs.readFile('file.txt','utf8', function(error, text){
            console.log(text);
});

console.log("After First Read\n");

fs.readFile('file2.txt','utf8', function(error, text){
            console.log(text);
});
console.log("After Second Read\n");




Now run fileAsync.js from the node.js command prompt. The output of this exercise gives us very different results. Both after comments are output before either of the file contents.  Also if the first file had been significantly larger than the second, it’s possible that the second might have finished and output first. This has powerful implications to how we code applications.


Similar to file operations, HTTP requests are another area where our programs must often wait on an external response. In this example let’s see how node.js also makes calling external HTTP services non-blocking. Create a file named httpClient.js. The http library we used in earlier exercises can also be used to make HTTP requests. Use the get function of the http library to call to http://www.loc.gov/pictures/search/?fo=json&q=SAP. This will call the US Library of Congress Image Search (a REST API which requires no authentication or API Key to keep the exercise simple). Issue a console message before and after the HTTP request.



var http = require('http')

console.log("Before HTTP Call\n");
http.get(
            {path: "http://www.loc.gov/pictures/search/?fo=json&q=SAP",
     host: "proxy.fair.sap.corp",
     port: "8080",
     headers: {
            host: "www.loc.gov"
     }},
function (response) {
response.setEncoding('utf8');
response.on('data', function(data){console.log(data.substring(0,100))});
response.on('error', console.error);
});
console.log("After HTTP Call\n");



Test your httpClient.js from the node.js command prompt. Similar to the earlier file exercise, the after http call console message is output before the response from the HTTP request.


Perhaps most interesting to us is that this non-blocking concept can also be extended to database access. This allows us to issue multiple requests to the underlying HANA database in parallel and without stopping the processing flow of the JavaScript application logic. In the next section of this blog we will learn more about making database access to HANA. For this demo we’ve already coded the database requests in a reusable module, so you can concentrate on the asynchronous flow. Create a new file named databaseAsync.js. Issue a message to the console, then call two functions (callHANA1 and callHANA2), then issue another message to the console. This will execute two different queries in the HANA database.



var hana = require('./database');
console.log('Before Database Call');
hana.callHANA1(console.log);
hana.callHANA2(console.log);
console.log("After Database Call");



Test your databaseAsync.js from the node.js command prompt. As you are hopefully learning to expect, the messages you issued after the database requests are actually output first. Only then are the database query results returned. There is also no guarantee that query 1 will finish before query 2.

Figure 5: HANA Database Non-Blocking Access


But what if you want more control over the flow of program execution. Maybe you want several database operations to happen in parallel, but then some logic to execute only after all queries are complete. This is one of things the async module in node.js can make easier. Copy the databaseAsync.js to databaseAsync2.js. Adjust the logic to use the async.parallel function. This allows some of the commands to execute in parallel as before, but then have a sync point once all operations are complete to allow further processing.  We will output one final message after everything is done.



var hana = require('./database');
var async = require("async");
async.parallel([
            function(cb){console.log('Before Database Call'); cb()},
            function(cb){hana.callHANA1(cb, console.log); },
            function(cb){hana.callHANA2(cb, console.log); },
            function(cb){console.log("After Database Call"); cb();}
],          function(err){
                        setTimeout(function() {
                        console.log("---Everything's Really Done Now. Go Home!---");
                        process.exit();          
                        }, 100);
});



Test your databaseAsync2.js from the node.js command prompt. The execution is similar to before, but now we have the final message after all queries are complete. Notice that we don’t have to manually kill the service with Ctrl+C this time either. Because we have a sync point after all parallel execution is complete, we can exit the process safely. Note: We did have to use a timer with a delay of 1/10 of a second otherwise the process would close before the last query console log was done being output making the results look odd.


Here is a video detailing the previous steps:


SAP XS Specific Capabilities For Node.js

In this example we will look at how to use the HANA database access library to send queries to the database. The function readTables contains all the most interesting code. We create the HANA client and pass in connection details. These details are read from the default-services.json file. In the final version of XS with node.js integrated; these settings can also be configured centrally in a service broker instead.

The actual database code is very similar to JDBC or XSJS coding. There is a connection, prepared statement and query execution. The result set which is return is a JSON object (just like XSJS $.hdb interface). The major difference is the structure of callbacks for the steps described above due to the asynchronous nature of node.js.



function readTables(cb) {
    console.log("starting partner read query ...");
    var client = hdb.createClient({
        host: options.hana.host,
        port: options.hana.port,
        user: options.hana.user,
        password: options.hana.password
    });
    client.connect(function(err) {
    client.prepare('select * from "SAP_HANA_EPM_NEXT"."sap.hana.democontent.epmNext.data::MD.BusinessPartner" where PARTNERROLE = ?',
    function (err, statement){
    statement.exec(['01'],
    function (err, res) {
                if (err)
                    return cb("ERROR: " + err);
                result = JSON.stringify({ PARTNERS: res });
                cb(result);
                }
    )}
    )
    });
}


One of the most exciting features of node.js on XS is the XSJS backward compatibility. We have the ability to run most XSJS applications without any changes directly from within node.js. We will create a new file called xsjs.js. This will be the node.js starting point that initializes the xsjs library and gives us an access point to then call through to the specific xsjs artifacts. Add the following logic. It brings in the necessary base modules and SAP specific modules that we need.  Then we start the XSJS service handler directing it to look in the src folder for our XSJS content. We also set index.xsjs as our default target if nothing is specified by the user.  The rest of the code is similar to earlier exercises where we open the web browser for testing.



'use strict';
var os = require('os');
var path = require('path');
var xsjs = require('xsjs');
var xsenv = require('xsenv');
var opn = require('opn');
var port = process.env.PORT || 3000;
var options = xsjs.extend({
  rootDir: path.join(__dirname, 'src'),
  redirectUrl: '/index.xsjs',
  port: port
}, xsenv.getServices());
xsjs(options).listen(port);

console.log('Using HANA on %s:%d', options.hana.host, options.hana.port);
console.log('Server running at http://' + os.hostname() + ':' + port);
opn('http://' + os.hostname() + ':' + port);


But the integration between XSJS and Node.js doesn't end there.  From XSJS we add a new $ API called $.require. This new API functions the same as the require keyword in Node.js and gives you full access to Node.js modules from XSJS. This allows you to move freely back and forth from XSJS's simplified synchronous programming mode and Node.js's powerful, but a bit more complex asynchronous/non-blocking programming model. It also means that you have ability to access any pre-built Node.js module managed via NPM from XSJS.

Figure 6: $.require


Here is a video detailing the previous steps:



Web Sockets

For the final example in this blog we will look at the Web Sockets functionality of Node.js. One of the often requested features of XS has been Web Sockets support. Luckily this is something that node.js comes with and the asynchronous programming is particularly well suited to the very idea of Web Sockets. In this example we will create a small chat application using Web Sockets.

Using what you’ve already learned, its easy to add code to the chatServer.js that will use express to serve the static content from the html directory on the process.env.PORT or 3000. The module for Web Sockets which we are going to use is ws. Require it and create a new instance of the WebSocketServer on port 3080 (that’s what our UI part is expecting). Then the remainder of the implementation of the Web Sockets functionality is just a few lines of code to both receive and send messages.



wss.broadcast = function (data) {
    for (var i in this.clients)
        this.clients[i].send(data);
    console.log('sent: %s', data);
};
wss.on('connection', function (ws) {
    ws.on('message', function (message) {
        console.log('received: %s', message);
        wss.broadcast(message);
    });
    ws.send(JSON.stringify({
        user: 'XS',
        text: 'Hello from Node.js XS Server'
    }));
});


From the client side, SAPUI5 has a library for Web Sockets communication.  In order to setup the Web Socket connection to our Node.js service we need the following code.



      jQuery.sap.require("sap.ui.core.ws.WebSocket");       // WS handling
      var connection = new sap.ui.core.ws.WebSocket('ws://localhost:3080');

We can then have event handlers on the client side for both sending and receiving message with this web socket server.


                // connection opened
                connection.attachOpen(function (oControlEvent) {
                                sap.m.MessageToast.show('connection opened');
                });
                // server messages
                connection.attachMessage(function (oControlEvent) {
                                var oModel = sap.ui.getCore().getModel('chatModel');
                                var result = oModel.getData();
                                var data = jQuery.parseJSON(oControlEvent.getParameter('data'));
                                msg = data.user + ': ' + data.text,
                                lastInfo = result.chat;
     
                                if (lastInfo.length > 0) lastInfo += "\r\n";
                                                oModel.setData({chat: lastInfo + msg}, true);
      
                                                // scroll to textarea bottom to show new messages
                                                $('#app--chatInfo-inner').scrollTop($('#app--chatInfo-inner')[0].scrollHeight);
                });


            // send message
                                sendMsg: function() {
                                                var oModel = sap.ui.getCore().getModel('chatModel');
                                                var result = oModel.getData();
                                                var msg = result.chat;
                                                if (msg.length > 0) {
                                                connection.send(JSON.stringify(
                                                                {user: result.user, text: result.message}
                                                ));
                    oModel.setData({message: ''}, true);
                                                }  
                                }



Here is a video detailing the previous steps


29 Comments
SergioG_TX
Active Contributor
0 Kudos

very intrigued in looking into web sockets - one of the cool features in nodejs

matt_steiner
Active Contributor

Happy to see HANA embracing Cloud Foundry build packs and the openness it brings!

 

Thanks for the detailled blog post Tom!

former_member81750
Active Participant
0 Kudos

This is so exciting. Can't wait to whip up some js code and do cf push. Thanks for sharing.

thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

Pankaj Kumar wrote:


 


This is so exciting. Can't wait to whip up some js code and do cf push. Thanks for sharing.


Actually in on premise HANA, the command would be xs push not cf push. But yes - its the same concept.

0 Kudos

Excellent article Thomas, thank you 😉

former_member185671
Participant
0 Kudos

Hi thomas.jung

 

Thank you for you informative article !

Can you please explain why node.js is needed ?

 

I've been using node.js to connect at the HCP Trial to insert data but it's still not very clear to me why is it needed.

 

BR,

Christoforos

thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

Node.js is our primary JavaScript runtime in XS now.  Its need to port over the XSJS and XSODATA artifacts that currently run in XS Classic. It also provides the primary application server programming and runtime layer for HANA moving forward.

htammen
Active Contributor
0 Kudos

Great blog, thank you. It was a good decision to move to node.js as JS runtime and to CloudFoundry as well.

If you now exchange your JS code by Typescript and use Promises instead of callbacks / async it would be perfect .

 

Best Regards

Helmut

0 Kudos

Hi Thomas,

 

This is the most useful piece of information that I managed to find about supporting nodejs in hana. Others were mainly about creating  "hello world" app in nodejs without any relation to hana or xsjs.

 

At the same time, I have some difficulties finding the relevant documentation about libraries/APIs that can/should be used in order to work with hana.  It looks like I cannot use the old XS JavaScript API from nodejs project directly to access database, jobs, destinations, security, etc. that xsjs provides? Or am I missing something?

 

For DB access should node-hdb be used?

 

Where can I find documentation for this modules:

  1. var xsjs = require('xsjs'); 
  2. var xsenv = require('xsenv'); 

 

We need to switch to nodejs because current XS synchronous model does not allow parallelism and does not scale well and using xs jobs is kind of pain.

 

Thank you.


thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

>At the same time, I have some difficulties finding the relevant documentation about libraries/APIs that can/should be used in order to work with hana.

 

You should use the ones which are shipped with HANA SPS 11. They are in the installation media (DATA_UNITS/XSA_CLIENT_10) in a zip file named xs_javascript*

 

>For DB access should node-hdb be used?

No sap-hdb-connection should be used.

 

I've published some examples here that might help:

I809764/DEV162A · GitHub

I809764/DEV602 · GitHub

I809764/xsa-workshop · GitHub

 

>Where can I find documentation for this modules:

You will find documentation in the readme.md file inside each model folder in the above mentioned zip.

 

former_member185671
Participant
0 Kudos

Hi Thomas and Happy new year !

 

Do you think it would be possible to use the SMTP mail sending function with the xsjs engine, inside a .js program ?

 

I thinking about writing a .js script that would send emails.

Could this be done with an .xsjs script ?

 

Best,

.CV

thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

Yes the XSJS $.net API is supported for SMTP with the following limitations:

 

Mail, SMTPConnection

  • proxy support and Digest-MD5 authentication method are not supported
former_member185671
Participant
0 Kudos

Hi Thomas and thanks for your quick reply,

 

But is it possible to "connect" it with a node.js script ?

 

What I now have is a node.js script that connects to the database (HCP) to write records.

And I want to be able to send emails with that very content while the node.js script is running.

 

Do you think that it might be possible ?

 

Or the option is to stop the node.js script, and then send the email ?

 

 

Best,

.CV

thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

XSJS runs within node.js. You start your service in node.js and it has the XSJS bootstrap that listens on the port. From XSJS you can branch back into node.js using the $.require API to run a node module from XSJS.

0 Kudos

Hi Thomas,

Is XSA available(or are there plans to make it available) within any trial environments on HCP or CAL? If so, is the XSA client available from anywhere other than the HANA installation media?

 

Thanks!

thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

No the SPS 11 version isn't available in HCP or the HANA Developer Edition yet. As is usual, the trial versions lag a bit behind the product release. I don't have any influence or control over the trial edition timings, so I couldn't really say when the SPS 11 version will be available there.

former_member185511
Active Participant
0 Kudos

Hi Thomas,

Thank you first of all, i am so excited.

Version control for the packages delivered by sap will be done by GitHub ?

Can we install any packages via NPM or we are limited by sap-delivery packages only

Lets assume can we build an application by using NodeJS, React with Flux architecture ?

thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

>Version control for the packages delivered by sap will be done by GitHub ?

No.  SAP delivers installable archives; not the source code.  SAP's original sources aren't delivered into your Git instance.

 

>Can we install any packages via NPM or we are limited by sap-delivery packages only

You can install any package you want; but you take responsibility for the security, quality, and support for any package which didn't originate from SAP.

Former Member
0 Kudos

Hi Thomas,

 

How does the $.require works?

I'm used to install modules via npm install with the option to save it to the package.json. But in this case, when watching the videos i didnt noticed any package.json there so i'm wondering how does it knows which version of the module is to be used?

thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

It works exactly as it does in standard Node.js.  Yes there is a package.json in XSA Node.js projects. NPM is called automatically during a Build/Run from the SAP Web IDE for SAP HANA or whenever you perform an XS PUSH, DEPLOY, or INSTALL.

Former Member
0 Kudos
Hi,

I am not sure it this is the right place to ask questions or not.

Downloaded the apps from following link Git Repo and tried deploying it to HANA Express (1.00.122.01.1470046197).

Web apps works fine but some how on redirect to xsjs app, always hit following error.
10/24/16 5:07:32.703 PM [APP/1756-1] ERR        at Function.Module._load (module.js:300:12)
10/24/16 5:07:32.703 PM [APP/1756-1] ERR at Module.require (module.js:353:17)
10/24/16 5:07:32.703 PM [APP/1756-1] ERR at require (internal/module.js:12:17)
10/24/16 5:07:32.703 PM [APP/1756-1] ERR at Object.<anonymous> (/hana/shared/HXE/xs/ea_data/hxehost/executionroot/bed3ef82-a28b-4211-8b8c-c400af3c3617/app/node_modules/sap-xsjs/node_modules/sap-fibrous/lib/fibrous.js:6:11)
10/24/16 5:07:32.703 PM [APP/1756-1] ERR at Object.<anonymous> (/hana/shared/HXE/xs/ea_data/hxehost/executionroot/bed3ef82-a28b-4211-8b8c-c400af3c3617/app/node_modules/sap-xsjs/node_modules/sap-fibrous/lib/fibrous.js:192:4)
10/24/16 5:07:32.703 PM [APP/1756-1] ERR at Module._compile (module.js:409:26)
10/24/16 5:08:00.325 PM [API] ERR Number of running instances for application "myapp1-xsjs" is 0 but should be 1. Trying to adapt number of running instances...
10/24/16 5:08:00.353 PM [API] OUT Cleared instance '1f7c001f-da30-4aae-ae35-a7c08b5f8fa0' of application "myapp1-xsjs" (port 50020, pid 17855).
10/24/16 5:08:09.357 PM [API] OUT Starting new instance '803fa4dc-a118-4b8f-ba83-de49a7af9b35' of application "myapp1-xsjs" (port 50025, index 2).
10/24/16 5:08:12.125 PM [APP/1756-2] ERR /hana/shared/HXE/xs/ea_data/hxehost/executionroot/803fa4dc-a118-4b8f-ba83-de49a7af9b35/app/node_modules/sap-xsjs/node_modules/sap-fibers/fibers.js:16
10/24/16 5:08:12.133 PM [APP/1756-2] ERR throw new Error('`'+ modPath+ '.node` is missing. Try reinstalling `node-fibers`?');
10/24/16 5:08:12.133 PM [APP/1756-2] ERR ^
10/24/16 5:08:12.133 PM [APP/1756-2] ERR
10/24/16 5:08:12.133 PM [APP/1756-2] ERR Error: `/hana/shared/HXE/xs/ea_data/hxehost/executionroot/803fa4dc-a118-4b8f-ba83-de49a7af9b35/app/node_modules/sap-xsjs/node_modules/sap-fibers/bin/linux-x64-v8-4.5/fibers.node` is missing. Try reinstalling `node-fibers`?
10/24/16 5:08:12.133 PM [APP/1756-2] ERR at Object.<anonymous> (/hana/shared/HXE/xs/ea_data/hxehost/executionroot/803fa4dc-a118-4b8f-ba83-de49a7af9b35/app/node_modules/sap-xsjs/node_modules/sap-fibers/fibers.js:16:8)
10/24/16 5:08:12.133 PM [APP/1756-2] ERR at Module._compile (module.js:409:26)
10/24/16 5:08:12.133 PM [APP/1756-2] ERR at Object.Module._extensions..js (module.js:416:10)
10/24/16 5:08:12.133 PM [APP/1756-2] ERR at Module.load (module.js:343:32)
10/24/16 5:08:12.133 PM [APP/1756-2] ERR at Function.Module._load (module.js:300:12)
10/24/16 5:08:12.133 PM [APP/1756-2] ERR at Module.require (module.js:353:17)
10/24/16 5:08:12.133 PM [APP/1756-2] ERR at require (internal/module.js:12:17)
10/24/16 5:08:12.133 PM [APP/1756-2] ERR at Object.<anonymous> (/hana/shared/HXE/xs/ea_data/hxehost/executionroot/803fa4dc-a118-4b8f-ba83-de49a7af9b35/app/node_modules/sap-xsjs/node_modules/sap-fibrous/lib/fibrous.js:6:11)
10/24/16 5:08:12.133 PM [APP/1756-2] ERR at Object.<anonymous> (/hana/shared/HXE/xs/ea_data/hxehost/executionroot/803fa4dc-a118-4b8f-ba83-de49a7af9b35/app/node_modules/sap-xsjs/node_modules/sap-fibrous/lib/fibrous.js:192:4)
10/24/16 5:08:12.133 PM [APP/1756-2] ERR at Module._compile (module.js:409:26)
10/24/16 5:08:30.353 PM [API] OUT Cleared instance 'ab1fc51a-cb30-4f8f-b3aa-3f9c2be29dc8' of application "myapp1-xsjs" (port 50021, pid 17900).

Is this a known issue with npm packages or related to version of node instelled in the HANA Express. Steps to install the app have been mention in HANA Academy youtube channel

Thanks
-A
0 Kudos
Hi Christoforos,

I also want to connect my node.js script to my HANA (HCP) and don't know how to deliver the login credentials.
I think I have to add Account name and Database name to the list of credentials - but don't know the correct format.
Could you send me a snap of your code?


BR,
Felix
former_member185671
Participant
0 Kudos
Hi Felix,

I cannot find that code in the moment, but you should take these credentials when opening that db tunnel.

The user and the password are displayed there.

BR,
.CV
Former Member
0 Kudos
Hello,

I think that I have the same problem than Felix : I want to connect my node.js application to my HANA database on my HCP trial (SCP now).

Locally, no problem :

  • Open a tunnel : neo open-db-tunnel -h hanatrial.ondemand.com -i hello2 -a sZZZZZZZZtrial -u sZZZZZZZZ

  • In my js code : var hdb = Hdb.createClient({
    host: 'localhost',
    port: '30015',
    user: 'XXXX',
    password: 'YYYY'
    });

  • All runs perfect


But, when my node application is deployed on the Cloud, the Cloud Foundry in fact, after a "cf push", I have no idea about the options I have to pass to the createClient...

host : hanatrial.ondemand.com ?

databaseName : hello2

user : XXXX or sZZZZZZZZ or sZZZZZZZZtrial ?

password : YYYY ?

port : 30015 ? 30013 ?

Somebody have an idea to help me please ?

Thank you

 

Frédéric
Eliramy
Explorer
0 Kudos
What's the difference between using ABAP System include SAP Gateway VS. XSJS Application to get data from SAP Hana ? ?
thomas_jung
Developer Advocate
Developer Advocate
Well of course both can create OData V2 services with the same basic capabilities.  So from the consumption side there is little difference.  The primary difference is right there in the question - one is ABAP AS based and the other XS. I'm not being flippant - the difference really comes from the environment of the surrounding Application Service.  This means different security models, license models, and programming languages used.  Of course not everyone who uses HANA has an ABAP AS.  There are applications which use the HANA DB which aren't ABAP based.
Eliramy
Explorer
0 Kudos
Thomas, Thanks about the explain !

One more Question, what is the difference between XSJS Application Vs. Node.JS ?
Also, what are the pros & cons of each one.

 
thomas_jung
Developer Advocate
Developer Advocate
0 Kudos
I would suggest reading the From Mozilla SpiderMonkey to Google V8 section of this blog.  It describes some of the technical differences and then also has links to external content describing the unique features of Node.js.
Former Member
0 Kudos

Hi Thomos, This is Venkat  do u had any idea to communication from Node Red to Kepware and

also SAP Hana to Node Red