ABAP RFC connectivity from BTP to ABAP systems is supported by SAP Cloud Connector, for BTP Java runtime only. This blog describes the RFC connectivity configuration for BTP Node.JS runtime, so that Node.JS BTP applications can consume ABAP RFCs, as described in Deployment options section of Powerful web applications with old and new ABAP systems and related blogs.
Our “hello world” example is BTP Node.JS buildpack, with Express server, SAP/node-rfc and SAP NW RFC SDK.
The example source code: SAP-samples/node-rfc-samples//integration/noderfc_with_nwrfcsdk
ABAP RFC connectivity from Node.JS is provided by SAP/node-rfc open source, which provides interface to SAP proprietary SAP NW RFC SDK
SAP NW RFC SDK
SAP NW RFC SDK is not included in SAP/node-rfc because the license is different. SAP Support Portal is the only allowed public distribution channel for SAP NW RFC SDK.
Shared SO libraries are required in runtime and must be registered at operating system level, using LD_LIBRARY_PATH env variable on Linux systems for example. Include files and shared libraries are both required for SAP/node-rfc build and re-build. The node-rfc rebuild can be triggered during BTP deployment, as for other native Node.JS modules.
Express and SAP/node-rfc are standard NPM packages and BTP deployment is straightforward.
One possibility for SAP NW RFC SDK deployment is using standard SAP/node-rfc and custom buildpack, with SAP NW RFC SDK included. It requires a bit more efforts and eventually re-work in case of buildpack upgrades. Another possibility is using standard buildpack and modified SAP/node-rfc , with SAP NW RFC SDK added there.
The first approach is described in CF documentation [Creating custom buildpacks for Cloud Foundry](https://docs.cloudfoundry.org/buildpacks/custom.html) and this blog covers the second approach. Modified SAP/node-rfc , with SAP NW RFC SDK included, can be also used with other server frameworks.
We use this cflinuxfs4 docker container, with SAP NW RFC SDK copied in /usr/local/sap folder and we use the standard buildpack structure, with application in app folder.
Now let prepare SAP/node-rfc for BTP deployment.
First copy SAP NW RFC SDK for Linux 64 to app folder and clone SAP/node-rfc in that same app folder.
$ cd buildpack/app
$ # copy SAP NW RFC SDK here
$ git clone https://github.com/sap/node-rfc
After both steps done, the buildpack looks like
Buildpack
To make SAP NW RFC SDK available for SAP/node-rfc (re)build, it shall be added as SAP/node-rfc dependency. Using new created package.json in nwrfcsdk folder, the SDK is therefore “promoted” to local NPM package:
{
"name": "nwrfcsdk",
"version": "1.0.0",
"description": "SAP NW RFC SDK",
"files": [
"nwrfcsdk"
],
"author": "",
"license": "SAP Developer License"
}
and then added to node-rfc dependencies in node-rfc package.json
"dependencies": {
"bluebird": "^3.7.2",
"decimal.js": "^10.4.3",
"node-addon-api": "^6.1.0",
"node-gyp-build": "^4.6.0",
"nwrfcsdk": "file:../nwrfcsdk"
}
The cloned node-rfc does not have any prebuilds yet and can be now prepared for use. The SAPNWRFC_HOME env variable must point either to app/nwrfcsdk folder full path, or to another folder with SAP NW RFC SDK:
$ export SAPNWRFC_HOME=/home/btp-developer/.../buildpack/app/nwrfcsdk
$ cd node-rfc
$ npm install
$ npm run build
The application dependencies are only express and node-rfc:
"dependencies": {
"express": "^4.18.2",
"node-rfc": "file:node-rfc"
},
When node-rfc is installed on BTP, the nwrfcsdk package will be pulled as a dependency and added to application node modules. The RFC SDK shared libraries from that location shall be therefore registered for buildpack and application runtime, using LD_LIBRARY_PATH env variable in application manifest.yaml:
---
applications:
- name: rfcapp
stack: cflinuxfs4
env:
SAPNWRFC_HOME: /home/vcap/app/node_modules/nwrfcsdk
LD_LIBRARY_PATH: /home/vcap/app/node_modules/nwrfcsdk/lib
During deployment, native NPM modules like node-rfc may be or must be rebuilt. The re-build process will first install nwrfcsdk and other dependencies and must be able to locate RFC includes and shared libraries. The standard node-rfc uses SAPNWRFC_HOME env variable for that purpose, which is not available during deployment.
The node-rfc/binding.gyp is therefore modified, to point to nwrfcsdk package location during deployment, which is temporary node_modules folder on BTP. The node-rfc/binding.gyp is therefore modified as follows
'variables': {
#'nwrfcsdk_dir': '<!(echo $SAPNWRFC_HOME)',
'nwrfcsdk_dir': '/tmp/app/node_modules/nwrfcsdk',
Now the app can be tested locally:
$ cd buildpack/app
$ export SAPNWRFC_HOME=`pwd`/nwrfcsdk
$ export LD_LIBRARY_PATH=$SAPNWRFC_HOME/lib
$ npm install
$ node .
node .
HOME
/home/www-admin
SAPNWRFC_HOME
/home/www-admin/src/sap/node-rfc-samples/integration/noderfc_with_nwrfcsdk/buildpack/app/nwrfcsdk
SAPNWRFC_HOME files:
["include","lib","package.json"]
LD_LIBRARY_PATH
node-rfc
{
"platform": {
"name": "linux",
"arch": "x64",
"release": "6.4.16-linuxkit"
},
"env": {
"SAPNWRFC_HOME": "/home/www-admin/src/sap/node-rfc-samples/integration/noderfc_with_nwrfcsdk/buildpack/app/nwrfcsdk",
"RFC_INI": ""
},
"versions": {
"node": "18.18.2",
"acorn": "8.10.0",
"ada": "2.6.0",
"ares": "1.19.1",
"brotli": "1.0.9",
"cldr": "43.1",
"icu": "73.2",
"llhttp": "6.0.11",
"modules": "108",
"napi": "9",
"nghttp2": "1.57.0",
"nghttp3": "0.7.0",
"ngtcp2": "0.8.1",
"openssl": "3.0.10+quic",
"simdutf": "3.2.14",
"tz": "2023c",
"undici": "5.26.3",
"unicode": "15.0",
"uv": "1.44.2",
"uvwasi": "0.0.18",
"v8": "10.2.154.26-node.26",
"zlib": "1.2.13.1-motley"
},
"noderfc": {
"version": "3.3.0",
"nwrfcsdk": {
"major": 7500,
"minor": 0,
"patchLevel": 12
}
}
}
When all works fine, let deploy
$ cd buildpack
$ cf push
Pushing app rfcapp to ...
Uploading files...
Instances starting....
Instances starting...
name: rfcapp
requested state: started
routes: rfcapp.cfapps.eu10.hana.ondemand.com
last uploaded: Thu 26 Oct 15:46:54 CEST 2023
stack: cflinuxfs4
buildpacks:
name version detect output buildpack name
https://github.com/cloudfoundry/nodejs-buildpack#v1.8.18 1.8.18 nodejs nodejs
type: web
sidecars:
instances: 1/1
memory usage: 128M
start command: npm run start:btp
state since cpu memory disk logging details
#0 running 2023-10-26T13:47:09Z 0.0% 54.9M of 128M 231.8M of 1G 0/s of unlimited
The app test route https://rfcapp.cfapps.eu10.hana.ondemand.com/ shows the same result as on premise test:
HOME /home/vcap/app SAPNWRFC_HOME /home/vcap/app/node_modules/nwrfcsdk
SAPNWRFC_HOME files: ["include","lib","package.json"]
LD_LIBRARY_PATH /home/vcap/app/node_modules/nwrfcsdk/lib
node-rfc { "platform": { "name": "linux", "arch": "x64", "release": "6.2.0-33-generic" }, "env": { "SAPNWRFC_HOME": "/home/vcap/app/node_modules/nwrfcsdk", "RFC_INI": "" }, "versions": { "node": "18.18.2", "acorn": "8.10.0", "ada": "2.6.0", "ares": "1.19.1", "brotli": "1.0.9", "cldr": "43.1", "icu": "73.2", "llhttp": "6.0.11", "modules": "108", "napi": "9", "nghttp2": "1.57.0", "nghttp3": "0.7.0", "ngtcp2": "0.8.1", "openssl": "3.0.10+quic", "simdutf": "3.2.14", "tz": "2023c", "undici": "5.26.3", "unicode": "15.0", "uv": "1.44.2", "uvwasi": "0.0.18", "v8": "10.2.154.26-node.26", "zlib": "1.2.13.1-motley" }, "noderfc": { "version": "3.3.0", "nwrfcsdk": { "major": 7500, "minor": 0, "patchLevel": 12 } } }
With RFC connectivity enabled in Node.JS on BTP, WS-RFC connection parameters and SAP Business Connector can be used for RFC connections to ABAP systems.
The configuration could be simplified, if SAPNWRFC_HOME env variable could be set in buildpack deployment phase but I did not find a possibility for that. In that case, the node-rfc modification could be avoided.