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: 
quovadis
Product and Topic Expert
Product and Topic Expert














Serverless architecture This brief is to demonstrate how one can leverage selected SAP BTP Kyma runtime serverless features, namely

  • how to use standard sap libraries to access secrets mounted as volumes

  • how to use SAP HANA Cloud with functions using @sap/hana-client library and other standard SAP libraries


Previously demonstrated topic was:









Requirements and Disclaimers:







Sample code:




Putting it all together.


SAP BTP, Kyma runtime is SAP's fully managed commercial kubernetes offering, part of SAP Business Technology Platform. It is often bundled with SAP Commerce Cloud and nowadays is becoming an extensibility runtime of choice.

Kyma brings a collection of additional modules on top of a kubernetes cluster. And serverless manager is one of them.

Serverless Architecture


The previous instalment demonstrated how to override a base function image.

Another cool and strategic feature with Kyma serverless CRD is the ability to mount secrets as volumes.

Secrets mounted as Volumes


Secrets mounted as Volume is a new feature introduced with the latest kyma release.


This is really useful when using the standard SAP libraries of the likes of xsenv, xssec and others with the BTP services provisioned with the btp service operator. and really essential when it comes to implementing portable, multi-environment services with one single code line.

Let's have a look at a snippet of a template of a function definition with the secretMounts.

The secretMounts allow to map values of the kubernetes secrets into a function's volume mount paths. The mounts paths are like the base directories in a folder structure and, combined with the secrets keys names, they become the data paths.

Thus, a function code can easily read secrets keys values from these data paths as if they were files.
apiVersion: serverless.kyma-project.io/v1alpha2
kind: Function
metadata:
name: {{ .Values.services.srv.name }}
labels:
{{- include "app.labels" . | nindent 4 }}
app: {{ .Values.services.srv.name }}
spec:
runtime: {{ .Values.services.srv.runtime }}

env:
- name: SERVICE_BINDING_ROOT
value: /bindings

secretMounts:
- secretName: {{ .Values.services.uaa.bindingSecretName }}
mountPath: "/bindings/fun-uaa"
- secretName: {{ .Values.services.dest.bindingSecretNamex509 }}
mountPath: "/bindings/fun-dest-x509"
- secretName: {{ .Values.services.hdi.bindingSecretName }}
mountPath: "/bindings/fun-hdi"
source:
gitRepository:

Eventually, this is how this works with most of the commonly used SAP libraries. We are using the SERVICE_BINDING_ROOT env variable to define the binding directory root folder (here called binding) to expose the mounted SAP BTP services binding secrets to SAP libraries that may be used in the function code.

This way any code relying on SAP libraries to manipulate the secrets can be used across runtime environments without modifications.

Using standard SAP libraries with mounted secrets


Let's see how to use SAP HANA Cloud with functions using @sap/hana-client  and other SAP libraries.

The below code snippet demonstrates the most commonly used SAP libraries:

const xsenv = require('@sap/xsenv');
const services = xsenv.getServices({
uaa: { label: 'xsuaa' }
,
hana: { label: 'hana' }
});

const util = require('util');
const xssec = require('@sap/xssec');
const createSecurityContext = util.promisify(xssec.createSecurityContext);

const hana = require('@sap/hana-client');
services.hana.sslValidateCertificate = true;
services.hana.ssltruststore = services.hana.certificate;
const hanaConn = hana.createConnection();

async function queryDB(sql, procedure, param) {
try {
await hanaConn.connect(services.hana);
} catch (err) {
debug('queryDB connect', err.message, err.stack);
results = err.message;
}
try {
await hanaConn.exec('SET SCHEMA ' + services.hana.schema);
if (procedure === undefined) {
results = await hanaConn.exec(sql);
}
else {
let hanaStmt = await hanaConn.prepare(procedure);
results = hanaStmt.exec(param);
}
} catch (err) {
debug('queryDB exec', err.message, err.stack);
results = err.message;
}
try {
await hanaConn.disconnect();
} catch (err) {
debug('queryDB disconnect', err.message, err.stack);
results = err.message;
}
return results;
}

and here goes a couple of simple calls against a SAP HANA Cloud database instance:
const session = await queryDB(`SELECT * FROM M_SESSION_CONTEXT`);
const db = await queryDB(`SELECT SYSTEM_ID, DATABASE_NAME, HOST, VERSION, USAGE FROM M_DATABASE`);
const connections = await queryDB(`SELECT TOP 10 USER_NAME, CLIENT_IP, CLIENT_HOST, START_TIME FROM M_CONNECTIONS WHERE OWN='TRUE' ORDER BY START_TIME DESC`);

 

Conclusion


This concludes a short excursion into the land of kyma serverless. To help you get started please refer to our Power of serverless with SAP BTP, Kyma runtime code samples here.

Good to know:



Last but not least, I hope you have enjoyed reading the blog post. Feel free to provide feedback in the comments section below.

 




SAP Community: https://community.sap.com/

SAP Community Topic Page link: https://community.sap.com/topics/kyma

SAP Community Q&A Tags:
Kyma Open Source: https://answers.sap.com/tags/2936b97d-6a90-4cd8-b635-0e51441611eb
SAP BTP, Kyma runtime: https://answers.sap.com/tags/73554900100800003012

Follow me in SAP Community: piotr.tesny