PackagePackagetypeA library you install and call yourself.See every one →What this type is →by SAPby SAPoriginPublished by SAP itself. A visible facet, never an input to a reading — a dormant official plugin reads exactly like a dormant independent one.See every one →

@sap/hdi-deploy

The Node.js deployer for SAP HANA Deployment Infrastructure: it writes a database module's design-time files into an HDI container as a delta, and it is what cds deploy runs for SAP HANA.

A Node.js module that deploys a database module's design-time files, the src/ folder and an optional cfg/ folder, into an SAP HANA Deployment Infrastructure (HDI) container. It finds the container among the services bound in VCAP_SERVICES, or for a local run in default-env.json or .env, and TARGET_CONTAINER names the one to use when several are bound. Each run works out which files were added, modified and deleted, and schedules the added and modified ones. Deleted files are not undeployed unless undeploy.json lists them or the run is given --auto-undeploy, so an object whose file is gone stays in the container until someone asks for its removal. Reusable database modules found in node_modules/ are folded into the same deployment. It reads HDI artifacts, not CDS: in a CAP project cds build from @sap/cds-dk generates them from the model, and cds deploy --to hana starts this package locally against them. It does not create the container either; on Cloud Foundry that is the hdi-shared service instance. The README describes it running on Cloud Foundry and XS Advanced, pushed as an app or run as a task, and locally with npm run start -- --exit; since 4.3.1 it also reads credentials from a Kubernetes secret volume.

Facts

Latestv5.7.0ReleasedLicenceSAP DEVELOPER LICENSE AGREEMENT 3.2

Where it sits

Lives in
Provides
Schema evolutionCAPSchema evolutioncapabilityGetting a model change into a database that already holds data, in every tenant, without losing any of it. Generating the initial schema and migrating one that already holds data are often treated as the same step.Native SAP HANA artifactsCAPNative SAP HANA artifactscapabilityUsing native SAP HANA database objects alongside an application’s generated data model, including objects and database features the modelling layer cannot express. Choosing a database is [database connectors](capability:database-connectors); changing an existing schema is [schema evolution](capability:schema-evolution).
Flavors
Node.jsfrom its runtime
Runs
Cloud Foundrylocal
Requires
SAP HANA CloudSAP HANA CloudartifactThe target: an HDI container, which on Cloud Foundry is an hdi-shared service instance. The README names SAP HANA 1 SPS11/SPS12 and SAP HANA 2 as supported; SAP HANA Cloud appears in the changelog, which added its tenant credential format in 5.4.0.

What it declares

Every artifact

Type
Package
Origin
By SAP
Runtime
Node.js
Runs on
Cloud Foundrylocal

As a package

Where it runs
does not say
Distributed through
does not say

Connections4

@sap/hdi-deploy connections@sap/hdi-deployPROVIDES→ provides2provides stated Deploys the design-time files of a database module, generated and native alike, into the HDI container, as the delta of added and modified files. @sap/hdi-deploy — README: https://unpkg.com/@sap/hdi-deploy@5.7.0/README.mdNative SAP HANA artifactsprovides stated Brings an HDI container up to the current design-time files as a delta: added and modified files are deployed, deleted ones only when `undeploy.json` or `--auto-undeploy` asks for it. For SAP HANA it is what cds deploy runs. @sap/hdi-deploy 5.7.0 — README, Delta Deployment and Undeploy Allowlist: https://unpkg.com/@sap/hdi-deploy@5.7.0/README.md Using SAP HANA Cloud for Production — capire: https://cap.cloud.sap/docs/guides/databases/hanaSchema evolutionUSED BY← optionally used by1optionally used by derived If: the deployments are done with the HDI Deployer module; the guide names an MTA deployment as the alternative. deploying the rename procedure, the access role and the CAP db module into the HDI container. Through: inverted from its requires edge SAP-samples/xsa-cap-migration — README, Requirements: https://github.com/SAP-samples/xsa-cap-migrationxsa-cap-migrationifNEEDS→ needs1needs stated The target: an HDI container, which on Cloud Foundry is an `hdi-shared` service instance. The README names SAP HANA 1 SPS11/SPS12 and SAP HANA 2 as supported; SAP HANA Cloud appears in the changelog, which added its tenant credential format in 5.4.0. @sap/hdi-deploy 5.7.0 — README: https://unpkg.com/@sap/hdi-deploy@5.7.0/README.md @sap/hdi-deploy — CHANGELOG, 5.4.0: https://unpkg.com/@sap/hdi-deploy@5.7.0/CHANGELOG.md Using SAP HANA Cloud for Production — capire: https://cap.cloud.sap/docs/guides/databases/hanaSAP HANA Cloud

Install

npm add @sap/hdi-deploy
The config you actually write
{
  "name": "deploy",
  "dependencies": {
    "@sap/hdi-deploy": "5.7.0",
    "@sap/hana-client": "2.27.19",
    "hdb": "2.26.4"
  },
  "scripts": {
    "start": "node node_modules/@sap/hdi-deploy/"
  }
}
Minimal example
# in the db module's folder, with default-env.json holding the service bindings and TARGET_CONTAINER
npm install
npm run start -- --exit
  • Deleted files in src/ and cfg/ are not undeployed. They must be listed in undeploy.json, or the run given --auto-undeploy, which ignores undeploy.json and undeploys every deleted file.
  • Binding more than one HDI Deployer instance to the same target container is not supported and results in undefined behaviour.
  • Reusable database modules cannot include other reusable database modules recursively.

Copied from @sap/hdi-deploy 5.7.0 — README, read . Not run by the atlas.

Where it sits in your app

Download
Your CAP applicationYour SAP BTP subaccountdocumentedrequires@sap/hdi-deploy, module@sap/hdi-deploySAP HANA Cloud, service instanceSAP HANA Cloud
SAPnot SAP's, or the project's owndocumented only

README

quoted from @sap/hdi-deploy@5.7.0 under SEE LICENSE IN LICENSE, read
@sap/hdi-deploy@5.7.0/README.mdOn npm

@sap/hdi-deploy

@sap/hdi-deploy is a Node.js-based deployment module for SAP HANA DI (HDI)-based persistence models, HDI Deployer for short. The HDI Deployer can be used in XS Advanced (XSA) and in SAP Business Technology Platform (SAP BTP)/Cloud Foundry (CF), and it is also used by the SAP Web IDE for interactive development scenarios. It can also be used in scenarios without XSA (or SAP BTP), e.g. for deploying HDI persistence models into a SAP HANA database where no XSA is installed.

For more information about SAP HANA DI, please check the SAP HANA Developer Guide and the SAP HANA Administration Guide.

Usually, the HDI Deployer is packaged into a database module, a db module, as part of a Multi-Target Application (MTA) and is used to deploy HDI design-time artifacts of the db module to the respective HDI container. When an MTA is deployed via the Deploy Service, the db module is pushed first so that it can "prepare" the SAP HANA persistence; by the time defined services are started, the HDI container is ready for use.

The HDI Deployer can also be used without the Deploy Service and MTAs, without XSA, and also for interactive scenarios or automation scripts.

For an MTA with different modules, e.g. a db module, a Node.js module, etc., this looks as follows:

  +-----------------+    +-----------------+    +-----------------+
  | db module       |    | Node.js module  |    | ... module      |
  | w/ HDI Deployer |    |                 |    |                 |
  +-----------------+    +-----------------+    +-----------------+

           |                      |                      |
           |                      |                      |
 \/ deploy persistence       \/ read/write/extend persistence      
           |                      |                      |
           |                      |                      |

  +---------------------------------------------------------------+
  | HDI container                                                 |
  |                                                               |
  +---------------------------------------------------------------+

In an SAP HANA-Service-Broker-based HDI setup, each module of the MTA is equipped with it's own technical database user for accessing the runtime schema of the HDI container.

The following diagram illustrates the different users who are involved in this setup with regard to privileges: the application users user1 and user2 who are bound to one of the modules each, and the HDI container's object owner (the #OO user) who is the owner of the objects in the database persistence of the MTA which are managed by HDI:

  +-----------------+    +-----------------+    +-----------------+
  | db module       |    | Node.js module  |    | ... module      |
  | w/ HDI Deployer |    |                 |    |                 |
  +-----------------+    +-----------------+    +-----------------+

                                  |                      |            o
                                  | --------------------------------- X application user user1
                                  |                      |       o
                                  |                      | ----- X application user user2
                                  |                      |

  +---------------------------------------------------------------+
  | HDI container                                                 |
  |                              db object 1      db object 2     |
  +-------------------------------------\-------------/-----------+
                                         \           /
                                      o   \         /
                                      X object owner (#OO user)

The HDI Deployer is packaged into the db module of the MTA. So, in order to use a new HDI Deployer, you need to reference a new version of the HDI Deployer in the db module's package.json file.

The HDI Deployer supports SAP HANA 1 SPS11/SPS12 and SAP HANA 2. The HDI Deployer assumes that for newer versions of SAP HANA, a corresponding version of the SAP HANA Service Broker is used to create the CF/XSA service bindings.

Note: The HDI Deployer assumes ownership of the src/, cfg/, and lib/ folders in the bound target HDI container. Binding more than 1 instance of the HDI Deployer to the same HDI container as the target container, e.g. the db modules of 2 MTAs or 2 applications are bound to the same HDI container as the target container, is not supported and results in undefined behavior.

README.md

Installation:

The Database Module:

Configuration and Reconfiguration:

Dynamic Deployment:

Library Usage:

Integration into a Database Module

Usually, @sap/hdi-deploy gets installed via a package.json-based dependency inside your application's db module:

db/package.json:

{
  "name": "deploy",
  "dependencies": {
    "@sap/hdi-deploy": "5.7.0",
    "@sap/hana-client": "2.27.19",
    "hdb": "2.26.4"
  },
  "scripts": {
    "start": "node node_modules/@sap/hdi-deploy/"
  }
}

SAP HANA Client

As of version 5.0.0 @sap/hdi-deploy does not contain @sap/hana-client and hdb as dependencies. This was done due to the large size of in some cases unnecessary '@sap/hana-client' dependency. To use @sap/hdi-deploy 5.0.0 and higher you must install @sap/hana-client and/or hdb peer dependencies yourself.

To make use of the @sap/hana-client or hdb clients, simply install the desired client. If both clients are installed, the deployer will give priority to the @sap/hana-client client. Where as to use hdb use --use-hdb option in package.json file or set use_hdb to true in HDI_DEPLOY_OPTIONS. You can find detailed information on how to set --use-hdb option here (#options-for-interactive-scenarios).

Database Connection Details

Connection details for the database, e.g. host, port, credentials, certificates, hostname_in_certificate, encrypt and validate_certificate, are looked up by the HDI Deployer from the standard CF/XSA VCAP_SERVICES environment variable which contains the bound services.

Since version 4.3.1 of hdi-deploy supports reading credentials from a secret volume for Kubernetes.

Mutual Authentication Configuration

To use X.509 certificate-based authentication, you must provide a client certificate and private key. These can be supplied through your service binding in either of these two ways:

  1. Combined in a single password field: You can include both the private key and certificate in either the hdi_password or password field. In this case, the corresponding hdi_user or user field must be blank. The system will automatically extract and use both components.

  2. As separate credential properties:

    "credentials": {
     ...
      "client_authentication_private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
      "client_authentication_certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
    }

    client_authentication_private_key and client_authentication_certificate take precedence over private key and certificate from hdi_password or password. Older versions of hdb (before 2.26.1) do not support this feature.

For local testing, the HDI Deployer supports default configurations via the following configuration files:

  • default-env.json: a JSON file which contains a set of environment variables and their values
  • .env: a dot env file which contains a set of environment variables and their values. This file is used in the absence of default-env.json.
  • default-services.json: a JSON file which contains a set of service bindings

In addition, you can provide a path to a json file containing VCAP_SERVICES in json format. This is done using the VCAP_SERVICES_FILE_PATH environment variable. If the VCAP_SERVICES_FILE_PATH environment variable is set, the deployer will use it for obtaining the VCAP_SERVICES value. Read more about this in the VCAP_SERVICES section.

Details of a bound service from an SAP HANA-Service-Broker-based service binding in CF/XSA usually look as follows:

{
  "name" : "foo",
  "label" : "hana",
  "tags" : [ "hana", "database", "relational" ],
  "plan" : "hdi-shared",
  "credentials" : {
    "schema" : "FOO",
    "user" : "FOO_345999596729_RT",
    "password" : "<password>",
    "hdi_user" : "FOO_645927945801_DT",
    "hdi_password" : "<password>",
    "host" : "srv1234567.host.name",
    "port" : "30115",
    "db_hosts" : [ {
      "port" : 30115,
      "host" : "srv1234567.host.name"
    } ],
    "url" : "jdbc:sap://srv1234567.host.name:30115/?currentschema=FOO",
    "driver" : "com.sap.db.jdbc.Driver"
  }
}

Here, the credentials section contains all the data which is needed by the HDI Deployer for connecting to the database. The HDI Deployer uses the hdi_user/hdi_password credentials from a direct service binding. The hdi_user should be minimal, i.e. only have the privileges required to fulfill the deployment. In most cases, access to a container FOO's API in the FOO#DI schema is sufficient.

Splitting passwords across services

The password property and the hdi_password property can also be specified as a combination of passwords from other bound services. Consider the following service binding:

{
    "hana" : [],
    "user-provided" : [ 
      {
      "name" : "split_password_service",
      "label" : "user-provided",
      "tags" : [],
      "credentials" : {
        "user" : "user",
        "schema": "schema",
        "password": ["password_and_hdi_password_service", "password_only_service"],
        "hdi_password": ["password_and_hdi_password_service", "hdi_password_only_service"],
        "tags" : [ "hana" ]
      }
    },
    {
      "name" : "password_and_hdi_password_service",
      "label" : "user-provided",
      "tags" : [],
      "credentials" : {
        "password" : "PASSWORD",
        "hdi_password": "HDI_PASSWORD",
        "tags" : [ "password" ]
      }
    },
    {
      "name" : "hdi_password_only_service",
      "label" : "user-provided",
      "tags" : [],
      "credentials" : {
        "hdi_password": "123",
        "tags" : [ "password" ]
      }
    },
    {
      "name" : "password_only_service",
      "label" : "user-provided",
      "tags" : [],
      "credentials" : {
        "password" : "456",
        "tags" : [ "password" ]
      }
    } ]
  }

When the service shared_password_service is used, the services specified in password and/or hdi_password will be checked and their password and/or hdi_password will be concatenated. The services will be accessed in the order they are defined. The resulting shared_password_service would have the password "PASSWORD456" and the hdi_password "HDI_PASSWORD123".

0 to n services can be specified, specifying 0 services results in the password/hdi_password ''.

VCAP_SERVICES

Connection details for the database are stored in the following format in the VCAP_SERVICES environment variable:

VCAP_SERVICES:

{
  "hana" : [
    <hana-service-binding-1>,
    <hana-service-binding-2>,
    ...
    <hana-service-binding-n>
  ],
  "user-provided" : [
    <user-provided-service-binding-1>,
    <user-provided-service-binding-2>,
    ...
    <user-provided-service-binding-m>
  ]
}
'
default-env.json

A default-env.json file can contain a set of environment variables and their values. The HDI Deployer will pick up these settings on startup:

default-env.json:

{
  "TARGET_CONTAINER" : "<name-of-the-service-instance-to-use-as-deployment-target>",
  "VCAP_SERVICES" : {
    "hana" : [
      <hana-service-binding-1>,
      <hana-service-binding-2>,
      ...
      <hana-service-binding-n>
    ],
    "user-provided" : [
      <user-provided-service-binding-1>,
      <user-provided-service-binding-2>,
      ...
      <user-provided-service-binding-m>
    ]
  }
}

default-env.json example file with a target container binding and a user-provided service:

{
  "TARGET_CONTAINER" : "target-service",
  "VCAP_SERVICES" : {
    "hana" : [ {
     "name" : "target-service",
      "label" : "hana",
      "tags" : [ "hana", "database", "relational" ],
      "plan" : "hdi-shared",
      "credentials" : {
        "schema" : "SCHEMA",
        "hdi_user" : "USER_DT",
        "hdi_password" : "PASSWORD_DT",
        "certificate" : "-----BEGIN CERTIFICATE-----\nABCD...1234\n-----END CERTIFICATE-----\n",
        "host" : "host",
        "port" : "30015"
      }
    } ],
    "user-provided" : [ {
      "name" : "GRANTING_SERVICE",
      "label" : "user-provided",
      "tags" : [ ],
      "credentials" : {
        "schema" : "SYS",
        "user" : "GRANT_USER",
        "password" : "PASSWORD",
        "procedure_schema" : "PRIVILEGE_PROCEDURE_GRANTOR_DEFINER",
        "procedure" : "GRANT",
        "type" : "procedure",
        "tags" : [ "hana" ]
      }
    } ]
  }
}
.env

A .env file can contain a set of environment variables and their values. The HDI Deployer will pick up these settings on startup:

.env example file:


  VCAP_SERVICES='{"hana" : [ { "name" : "target-service", "label" : "hana", "tags" : [ "hana", "database", "relational" ], "plan" : "hdi-shared", "credentials" : { "schema" : "SCHEMA", "hdi_user" : "USER_DT", "hdi_password" : "PASSWORD_DT", "certificate" : "-----BEGIN CERTIFICATE-----\nABCD...1234\n-----END CERTIFICATE-----\n", "host" : "host", "port" : "30015" } } ] }'
  
VCAP_SERVICES_FILE_PATH

The VCAP_SERVICES can be read from a file. This is achieved with the VCAP_SERVICES_FILE_PATH variable. The variable is an absolute path to an existing file. The content of that file must be in json format.

Note: default-services.json does not take effect when used in combination with VCAP_SERVICES_FILE_PATH.

.env example file:


  VCAP_SERVICES_FILE_PATH='/tmp/vcap_services.json'

Deployment via Push and Tasks

There are two ways of using the HDI Deployer as an application:

  • Push the application with one instance. The application will then start and do the HDI deployment of the data model. After a successful deployment, the application will enter an idle loop and can be stopped.
  • Push the application with zero instances and then trigger a task on the application which does the HDI deployment of the data model. After deployment of the data model, the task will be completed. An instance of the application is only running while the task is being executed.

For both scenarios, ensure that the health-check-type in the manifest is set to process, instead of the default, port-based health check.

In order to push the application with zero instances, the application can either be pushed with the --no-start option or the number of instances can be set to zero in the manifest.yml file via instances: 0.

The deployment task can be started via xs run-task <app> deployment-task "npm run start -- --exit" --wait-for-completion on XSA. The task will run and the call will propagate the success/failure of the deployment task. On CF, the --wait-for-completion option is not available and the status of the task needs to be checked periodically.

Deployment via Local Run

An HDI deployment can also be triggered without using an application. In this case, the HDI Deployer will be run locally and directly connects to the database. This is possible in the following scenarios: the database is accessible locally from a network point of view or a network tunnel with a local endpoint was established, e.g. a cf ssh-based tunnel is set up in CF.

Apply the following steps to run the HDI Deployer locally: run npm install in the db module's folder to install the HDI Deployer module, then create a default-env.json file in the db module's folder which contains the required service bindings and the TARGET_CONTAINER setting, then run npm run start -- --exit in the db module's folder to trigger the deployment of the data model.

If the database uses SSL/TLS encryption, please ensure that the hostname_in_certificate value is set up correctly in the service bindings, because the network tunnel's local endpoint (e.g. localhost:9000) doesn't match the hostname in the SSL/TLS certificate.

A Database Module's File System Structure

The HDI Deployer expects the following file system structure for the HDI content in your db module:

  • src/: folder which contains your HDI source artifacts
  • cfg/: optional folder with HDI configuration artifacts
  • package.json: this file is used by npm (the Node.js package manager) to bootstrap and start the application

Other files in the root directory will be ignored by @sap/hdi-deploy.

Please note that the cfg/ folder also might need a .hdiconfig file, e.g. in case .hdbsynonymconfig files are placed there.

In combination with reusable database modules, the HDI Deployer will also consider database modules which are located in the node_modules/ folder and which will be mapped to a corresponding sub-folder hierarchy in the container's lib/ folder.

Note: The design-time files should be protected against unauthorized modifications to guard against unwanted undeployments or deployment of foreign objects. For applications running on XSA or Cloud Foundry, this is taken care of by the platform.

Delta Deployment and Undeploy Allowlist

The HDI Deployer implements a delta-based deployment strategy:

On startup, the HDI Deployer recursively scans the local src/ and cfg/ folders, processes config templates, looks at the HDI container at the server-side and calculates the set of added, modified, and deleted files based on the difference between the local file system state and the deployed file system state of the server-side HDI container.

In normal operation, the HDI Deployer will schedule only the set of added and modified files for deployment. The set of deleted files is not scheduled for undeployment.

In order to undeploy deleted files, an application needs to include an undeploy allowlist via an undeploy.json file in the root directory of the db module (right beside the src/ and cfg/ folders). The undeploy allowlist undeploy.json file is a JSON document with a top-level array of file names. "real" paths, path patterns and path negations are supported.

undeploy.json:

[
    "src/Table.hdbcds",
    "src/Procedure.hdbprocedure",
    "src/*.hdbtable",
    "**/*.hdbtable",
    "!**/temp/*.hdbtable"
]

The file must list all artifacts which should be undeployed. The file path of the artifacts must be relative to the root directory of the db module, must use the HDI file path delimiter '/', and must be based on the HDI server-side folder structure. In case of reusable database modules, the server-side top-level folder lib/ needs to be used instead of the local folder node_modules/.

For interactive scenarios, it's possible to pass the auto-undeploy option to the HDI Deployer, e.g.

node deploy --auto-undeploy

In this case, the HDI Deployer will ignore the undeploy allowlist undeploy.json file and will schedule all deleted files in the src/ and cfg/ folders for undeployment.

The default_access_role Role

When an HDI container service instance is created by the SAP HANA Service Broker, for example, service instance foo with schema name FOO, the broker creates an HDI container named FOO (consisting of the run-time schema FOO , the HDI metadata and API schema FOO#DI , and the object owner FOO#OO) and, in addition, the following roles, which are assigned to the application user:

  • FOO::access_role A global access role that equips the application user with privileges on the run-time schema 'FOO'. This access role is assigned a set of default permissions for the run-time schema: SELECT, INSERT, UPDATE, DELETE, EXECUTE, CREATE TEMPORARY TABLE, and SELECT CDS METADATA on the run-time schema FOO.

  • FOO::external_privileges_role A role that grants the application user the privileges required to enable access to schemas and objects outside the HDI container, for example, the run-time container BAR. By default, external_privileges_role has no privileges assigned. If the application user requires access to external objects, a user with grant-option privileges on those external objects must first explicitly grant the required privileges to the external_privileges_role. Similarly, any explicitly assigned privileges must also be explicitly revoked.

Note : The roles exist as long as the HDI container exists; they are not lost when the application binding user changes. New binding users are automatically assigned these roles by the broker.

Every time the service instance is bound to an application, the service broker creates two new users that are specific to this binding. The first user is the application user who is named user in the instance's credentials. This user is used by the application to access the HDI container's run-time schema FOO. This user is assigned the service instance's global access role FOO::access_role and the role FOO::external_privileges_role. The second user is the HDI API user - named hdi_user in the credentials. This user is equipped with privileges for the container's APIs in the FOO#DI schema.

The following diagram illustrates the binding-specific application users and the role of the global access role (the HDI API users and the bindings for the HDI Deployer are not shown for simplicity):

  +-----------------+    +-----------------+    +-----------------+
  | db module       |    | Node.js module  |    | ... module      |
  | w/ HDI Deployer |    |                 |    |                 |
  +-----------------+    +-----------------+    +-----------------+

                                  |                      |            o
                                  | --------------------------------- X application user user1
                                  |                      |       o                        \
                                  |                      | ----- X application user user2  \
                                  |                      |                           \      \
                                                                                      \      \
  +---------------------------------------------------------------+           role FOO::access_role
  | HDI container FOO                                             |                   /
  |                                                               | SELECT/INSERT/... on schema FOO
  +---------------------------------------------------------------+

Exemplary service binding:

{
   "hana" : [ {
     "name" : "foo",
     "label" : "hana",
     "tags" : [ "hana", "database", "relational" ],
     "plan" : "hdi-shared",
     "credentials" : {
       "schema" : "FOO",
       "user" : "FOO_345999596729_RT",
       "password" : "<password>",
       "hdi_user" : "FOO_645927945801_DT,
       "hdi_password" : "<password>",
       "host" : "srv1234567.host.name",
       "port" : "30115",
       "db_hosts" : [ {
         "port" : 30115,
         "host" : "srv1234567.host.name"
       } ],
       "url" : "jdbc:sap://srv1234567.host.name:30115/?currentschema=FOO",
       "driver" : "com.sap.db.jdbc.Driver"
     }
   } ]
}

In order to assign roles from the HDI content to the application binding users (the user users), the HDI Deployer implements an automatic assignment of the default_access_role role if it is present in the deployed content:

If a role definition file exists at the path src/defaults/default_access_role.hdbrole, and this file defines a role named default_access_role, and this file is included in the deployment (e.g. not excluded via include-filter), then the HDI Deployer grants the deployed default_access_role role to the service instance's global access role (e.g. FOO::access_role). In addition, the HDI Deployer revokes all default permissions (e.g. SELECT, INSERT, UPDATE, DELETE, EXECUTE, CREATE TEMPORARY TABLE, and SELECT CDS METADATA (not on SAP HANA Cloud) on the runtime schema FOO) from the global access role. If the default_access_role is undeployed, the default permission set for the runtime schema will be restored.

Note: If you use a .hdinamespace file in src/ which defines a real namespace prefix for subfolders, then you need to put a .hdinamespace file with the empty namespace "name" : "" at src/defaults/ to ensure that the role can be named default_access_role.

The following diagram illustrates the binding-specific application users, the role of the global access role, and the container-specific default access role:

  +-----------------+    +-----------------+    +-----------------+
  | db module       |    | Node.js module  |    | ... module      |
  | w/ HDI Deployer |    |                 |    |                 |
  +-----------------+    +-----------------+    +-----------------+

                                  |                      |            o
                                  | --------------------------------- X application user user1
                                  |                      |       o                        \
                                  |                      | ----- X application user user2  \
                                  |                      |                           \      \
                                                                                      \      \
  +---------------------------------------------------------------+           role FOO::access_role
  | HDI container FOO                                             |                      /
  |                                role default_access_role ----------------------------+
  |                                       /         \             |
  |                                role role1     role role2      |
  |                                   /              /   \        |
  |                 structured privileges       DCL role 1 / 2    |   
  +---------------------------------------------------------------+

Note: The default_access_role is assumed to be an "umbrella" role which aggregates other roles.

A role with the default permission set which is granted by the SAP HANA Service Broker on container creation looks as follows:

default_permissions_role.hdbrole:

{
   "role":{
      "name":"default_permissions_role",
      "schema_privileges":[
         {
            "privileges":[
               "SELECT",
               "INSERT",
               "UPDATE",
               "DELETE",
               "EXECUTE",
               "CREATE TEMPORARY TABLE",
               "SELECT CDS METADATA"
            ]
         }
      ]
   }
}

On SAP HANA Cloud, "SELECT CDS METADATA" is not granted.

The development_debug_role Role

Similarly to the default_access_role, a development_debug_role can be used to add additional privileges to the access role. This is only intended for development and debugging, not for productive use!

If a role definition file exists at the path src/defaults/development_debug_role.hdbrole, and this file defines a role named development_debug_role, and this file is explicitly included in the deployment via the --deploy option, then the HDI Deployer grants the deployed development_debug_role role to the service instance's global access role (e.g. FOO::access_role).

In order to remove the privileges granted this way, the file has to be undeployed.

Reusable Database Modules

In order to allow that an application uses (parts of) the database persistence of a reusable component inside its own persistence model, the HDI Deployer allows to link/include the design-time files of reusable components in a consuming application in an automated way. This mechanism is based on the Node.js package management mechanism for defining, publishing, and consuming reusable database modules which also supports versioning based on the semantic versioning concepts (cf. http://semver.org).

A reusable database module is considered to have the same src/ and cfg/ folder structure as a normal database module. The src/.hdiconfig file is mandatory and used by the module mechanism as an indicator that the src/ and cfg/ folders belong to a consumable, reusable database module. In addition, the reusable database module needs to have a package.json file which defines the module's name, the module's version, etc.

A complete reusable database module looks as follows:

/
+-- src/
|   +-- .hdiconfig
|   +-- <source files ...>
+-- cfg/
|   +-- <optional configuration files ...>
+-- package.json

The package.json file contains the module’s name, description, version, repository URL, and the set of files which belong to the module:

package.json:

{
  "name": "module1",
  "description": "A set of reusable database objects",
  "version": "1.3.1",
  "repository": {
    "url": "git@your.gitserver:modules/module1.git"
  },
  "files": [
    "src",
    "cfg",
    "package.json"
  ]
}

The reusable database module should be published to a Node.js package management compliant object repository.

Consumption of a reusable database module is done by adding a dependency in the consuming module's package.json file, right beside the dependency to @sap/hdi-deploy:

{
  "name": "deploy",
  "dependencies": {
    "@sap/hdi-deploy": "5.7.0",
    "module1": "1.3.1",
    "module2": "1.7.0",

    "@sap/hana-client": "2.27.19",
    "hdb": "2.26.4"
  },
  "scripts": {
    "start": "node node_modules/@sap/hdi-deploy/"
  }
}

Here, the consuming module requires module1 in version 1.3.1 and module2 in version 1.7.0.

When running npm install to download and install the dependencies which are listed in the dependencies section of the package.json file, npm will also download the reusable database modules and places them into the node_modules/ folder of the consuming module. For each module a separate subfolder is created with the name of the module.

When the HDI Deployer is triggered to do the actual deployment of the (consuming) database module, it scans the node_modules/ folder and virtually integrates the src/ and cfg/ folders of found reusable database modules into the (consuming) database module’s lib/ folder. Reusable database modules are identified by the mandatory src/.hdiconfig file.

On successful deployment, the HDI container will contain the consumed modules below the root-level lib/ folder, e.g.

/
+-- src/
+-- cfg/
+-- lib/
|   +-- module1/
|   |   +-- src/
|   |   +-- cfg/
|   +-- module2/
|       +-- src/
|       +-- cfg/

For the time being, it’s not allowed to recursively include reusable database modules.

The cfg/ folders of reusable database modules are also subject to configuration file templating.

Configuration File Templating

The HDI Deployer implements a templating mechanism for HDI configuration files, e.g. configuration files for synonyms, projection views, etc., based on services which are bound to the db module application. By means of this templating mechanism, it is possible to configure synonyms, projection views, etc. to point to the right database schema without knowing the schema name at development time.

On startup, the HDI Deployer recursively scans the local cfg/ folder and picks up all files with a .*config suffix, e.g. all .hdbsynonymconfig, .hdbvirtualtableconfig, etc. files. For all collected files which contain .configure markers in their content, it applies the configuration templating and creates transient configuration files which are then deployed to the HDI container.

For a synonym configuration file cfg/LOCAL_TARGET.hdbsynonymconfig

{
    "LOCAL_TARGET" : {
        "target" : {
            "schema.configure"    : "logical-external-service/schema",
            "database.configure"  : "logical-external-service/database",
            "object"              : "TARGET"
        }
    }
}

the section

            "schema.configure"    : "logical-external-service/schema",
            "database.configure"  : "logical-external-service/database",
            "object"              : "TARGET"

will be transformed by the templating mechanism into

            "schema"              : "THE_SCHEMA",
            "database"            : "THE_DATABASE",
            "object"              : "TARGET"

where THE_SCHEMA and THE_DATABASE are the values for the schema and database fields of the bound service logical-external-service, which are denoted by the path expressionslogical-external-service/schema and logical-external-service/database.

If a field in the service is missing, it will not be configured and will be removed instead, e.g. database might be optional.

The names of the services are subject to the service replacements mechanism, which can be used to map a real service, e.g. real-external-service, to a logical service name which is used in the configuration files, e.g. logical-external-service.

It's not always applicable to use schema.configure, database.configure, etc. in the configuration template files. Therefore, the HDI Deployer provides a generic way of copying a set of properties from the bound service, e.g. schema, database, remote source, etc. if they are present, although the template file doesn't mention them.

For the configuration file cfg/LOCAL_TARGET.hdbsynonymconfig this could looks as follows:

{
    "LOCAL_TARGET" : {
        "target" : {
            "*.configure"         : "logical-external-service",
            "object"              : "TARGET"
        }
    }
}

When the HDI Deployer encounters a *.configure entry, it simply copies all well-known fields which are present in the bound service into the configuration file. The well-known fields are currently remote, database, and schema.

The HDI Deployer also supports old-style .hdbsynonymtemplate template files: If a .hdbsynonymtemplate file is found in the cfg/ or src/ folder, then it is processed as a configuration template file and a transient file with the suffix .hdbsynonymconfig is created. A field grantor is replaced with the schema value from the referenced service; so, a grantor field is equivalent to a "schema.configure" : "the-service/schema" entry in a configuration template file.

Permissions to Container-External Objects

An HDI container is by default equipped with nearly zero database privileges, e.g. the object owner (#OO user) is mainly equipped with the CREATE ANY privilege on the container's runtime schema (e.g. schema FOO for an HDI container FOO). Since SAP HANA 2 SPS00, the object owner is equipped with an additional restricted set of privileges for system views in the database's SYS schema, e.g. SYS.VIEWS or SYS.TABLES. These system views apply an additional row-level filter based on the object owner's other privileges, e.g. the object owner can only see metadata in SYS.VIEWS for views he has privileges on. So, without additional privileges, the object owner can only see metadata for the objects in his container schema.

In order to access database objects inside other database schemata or other HDI containers, and in order to deploy synonyms into the HDI container which point to these container-external objects, at least the object owner needs additional privileges, e.g. for an object object in schema X SELECT privileges on X.object:

  +---------------------------------------------------------------+      +------------------------+
  | HDI container FOO                                             |      | other schema X         |
  |                                                synonym ------------------------> object       |
  +---------------------------------------------------/-----------+      +-------------\----------+
                                                     /                                  \
                                      o             /                                    \
                                      X object owner FOO#OO -------------------- SELECT on X.object

Please also refer to the official Using Synonyms to Access External Schemas and Objects in XS Advanced guide.

.hdbrevokes Files

Starting with version 3.8, the deployer now allows revoking rights. Anything that can be granted via .hdbgrants can be revoked via .hdbrevokes. Both files, .hdbgrants and .hdbrevokes use the same structure. For more information on the structure of these files, see the section about .hdbgrants Files.

The .hdbrevokes file will be processed before the .hdbgrants file.

.hdbgrants Files

In order to automatically assign privileges to the object owner and/or the application binding users, the HDI Deployer provides .hdbgrants files with a syntax similar to .hdbrole files:

An .hdbgrants file has the following structure:

granting-service.hdbgrants:

{
  "granting-service": {
    "object_owner": {
      <privileges>
    },
    "application_user": {
      <privileges>
    }
  }
}

The top-level keys define the names of the bound services which "grant" the privileges, these are the "grantors", e.g. granting-service in the example. The next level defines to which users the privileges will be granted, these are the "grantees": object_owner is used for the HDI container's object owner, and application_user marks the application users which are bound to the application modules, e.g. the Node.js module. The third level defines the set of privileges in a .hdbrole-like structure.

On startup, the HDI Deployer looks for .hdbgrants files and processes them as follows: For each grantor in the file, the HDI Deployer looks up a bound service with the name (subject to service replacements), connects to the database with the service's credentials, and grants the specified privileges to the grantees. If the schema field is omitted for a privilege, then the grantor's schema property is used. If the name field in a global_object_privileges element of type REMOTE SOURCE is omitted, then the grantor's remote property is used.

For backwards compatibility, also the suffix .hdbsynonymgrantor is supported.

Example of a cfg/external-access.hdbgrants file with some privileges for the object owner:

{
  "external-access": {
    "object_owner": {
      "system_privileges" : [
        {
          "privileges" : [ "SYSTEM_PRIVILEGE_1" ],
          "privileges_with_admin_option" : [ "SYSTEM_PRIVILEGE_2", "SYSTEM_PRIVILEGE_3" ]
        }
      ],
      "global_roles" : [
        {
          "roles" : [ "GLOBAL_ROLE_1", "GLOBAL_ROLE_2" ],
          "roles_with_admin_option" : [ "GLOBAL_ROLE_3", "GLOBAL_ROLE_4" ]
        }
      ],
      "schema_privileges" : [
        {
          "privileges" : [ "INSERT", "UPDATE" ],
          "privileges_with_grant_option" : [ "SELECT" ]
        }
      ],
      "schema_roles" : [
        {
          "roles" : [ "SCHEMA_ROLE_1", "SCHEMA_ROLE_2" ],
          "roles_with_admin_option" : [ "SCHEMA_ROLE_3", "SCHEMA_ROLE_4" ]
        }
      ],
      "object_privileges" : [
        {
          "name": "AN_OBJECT",
          "privileges": [ "INSERT", "UPDATE" ],
          "privileges_with_grant_option" : [ "SELECT" ]
        }
      ],
      "global_object_privileges" : [
        {
          "name" : "A_REMOTE_SOURCE",
          "type" : "REMOTE SOURCE",
          "privileges" : [ "CREATE VIRTUAL TABLE" ],
          "privileges_with_grant_option" : [ "CREATE VIRTUAL PROCEDURE" ]
        }
      ]
    }
  }
}

The following elements and keys are supported for backwards compatibility or for compatibility with .hdbrole:

  • container_roles: grant roles from an HDI container; superseded by schema_roles which works for normal schemas and HDI containers
      "container_roles" : [ "SCHEMA_ROLE_1", "SCHEMA_ROLE_2" ]
  • roles: grant global roles; superseded by global_roles:
      "roles" : [ "GLOBAL_ROLE_1", "GLOBAL_ROLE_2" ]
  • string-array-style roles and names key (maps to the non-grant/admin-option variant):
      "global_roles" : [
        "GLOBAL_ROLE_1",
        {
          "roles" : [ "GLOBAL_ROLE_1", "GLOBAL_ROLE_2" ]
        },
        {
          "names" : [ "GLOBAL_ROLE_1", "GLOBAL_ROLE_2" ]
        },
        {
          "roles_with_admin_option" : [ "GLOBAL_ROLE_3", "GLOBAL_ROLE_4" ]
        },
        "GLOBAL_ROLE_2"
      ]

If any non-container privileges are used, then the object owner (#OO user) will need to be given these privileges WITH GRANT option by a user-defined granting-service. Otherwise it won't be able to grant these privileges to e.g. a role in the container.

Creating a Granting Service

The HDI Deployer supports the following types of granting-services:

  • sql: a technical database user with GRANT privileges for the required object privileges, roles, system privileges, etc.
  • hdi: an HDI container with access to the container's GRANT APIs. An HDI container can only grant roles from the container, without admin option.
  • procedure: a technical database user with EXECUTE privileges on a stored procedure which has GRANT privileges for the required object privileges, roles, system privileges, etc.
  • ignore: grants were already given at the database-level and the HDI Deployer will ignore the content of the .hdbgrants file.

For the HDI container case, the corresponding service can simply be bound to the db module application. The HDI Deployer recognizes the bound service by its hdi_user value in the credentials section and calls the container's API procedures to grant the privileges from the .hdbgrants file.

In case a technical database user is used, a 'user-defined service' must be created for this purpose in the same space as the container. The service needs to be set up with the permissions of a specified database user to connect to the database and to grant the privileges specified in the .hdbgrants files during application deployment.

Such a user-provided service can be created as follows:

  • Open a command shell and log on to XSA: xs login
  • Change to the target space where you want to create the user-defined service: xs target -s <SPACE>
  • Create the user-defined service (e.g. grantor-service): xs cups grantor-service -p '{ "host": "host.acme.com", "port": "30015", "certificate": "<myCertificate>", "user": "TARGET_USER", "password": "Grant_123", "schema": "TARGET_SCHEMA", "tags": [ "hana" ] }'
    • "host"/"port": Required for the connection to the database: port is the SQL port of the index server.
    • "certificate": If the database is configured to only accept secure connections, then the granting-service requires an SSL certificate that must be included in the user-provided service, for example, using the "certificate":"" parameter.
    • "user"/"password": Connection details for a database user that has grant permissions for the objects in the schema.
    • "schema": The database schema that contains the objects to which access is to be granted.
    • "type": The type of the grantor mechanism; valid values are "hdi", "sql", or "procedure". If the type is not specified, then the type is auto-sensed (see details below).
    • "tags": For the purposes of granting, create user-provided services that are tagged with the "hana" tag. E.g.: "tags": [ "hana" ] or "tags": "hana".
  • Use the command xs services to display a list of services available in the current space; the 'grantor-service' service should be visible.

For Cloud Foundry, use the corresponding cf commands.

Note: Starting with version 3.0.0 of the HDI Deployer, the "host", "port", and "certificate" parameters are no longer required since they can be obtained from the target container binding. In this case, you must only specify the "user", "password", and "schema" when creating the user-provided service, e.g. xs cups grantor-service -p '{ "user": "TARGET_USER", "password": "Grant_123", "schema": "TARGET_SCHEMA", "tags": [ "hana" ] }'.

If the "type" is not specified, then the type is selected based on the following rule: if the field hdi_user is present, then the type is auto-sensed as hdi; otherwise, the type is set to sql.

If the technical database user does not have GRANT privileges by its own, but only EXECUTE privileges on a stored procedure which can grant the privileges, then the following settings are required:

  • At the database, a GRANT procedure must exist (or be visible) in the schema which is used in the user-provided service; an example is shown below.
  • The technical database user must have EXECUTE privileges on the GRANT procedure.
  • The name of the GRANT procedure must be specified in the user-provided service in the "procedure" field, e.g. "procedure": "GRANT".
  • The scheme name of the GRANT procedure can be specified in the user-provided service in the "procedure_schema" field, e.g. "procedure_schema": "A_SCHEMA".
  • The user-provided service must contain a "type" field with the value "procedure".

For the different types of privileges, the following fields are passed to the GRANT procedure:

PRIVILEGE_TYPEPRIVILEGE_NAMEOBJECT_SCHEMAOBJECT_NAMEOBJECT_TYPEGRANTEE_SCHEMAGRANTEE_NAMEGRANTABLE
SCHEMA_OBJECT_PRIVILEGEprivilegeschemaobjectNULLNULLgranteeTRUE/FALSE
GLOBAL_OBJECT_PRIVILEGEprivilegeNULLobjecttypeNULLgranteeTRUE/FALSE
SCHEMA_ROLENULLschemaroleNULLNULLgranteeTRUE/FALSE
GLOBAL_ROLENULLNULLroleNULLNULLgranteeTRUE/FALSE
SCHEMA_PRIVILEGEprivilegeNULLschemaNULLNULLgranteeTRUE/FALSE
SYSTEM_PRIVILEGEprivilegeNULLNULLNULLNULLgranteeTRUE/FALSE

Note: This procedure does not work for SAP HANA1 SPS11, since REPLACE_REGEXPR is not supported. Please use the sample procedure provided with older releases of the deployer. The old sample procedure does not correctly handle component names of system privileges in .hdbgrants files.

Example of a GRANT procedure:

CREATE PROCEDURE GRANT(
  IN PRIVILEGES TABLE (
    PRIVILEGE_TYPE NVARCHAR(128), -- 'SCHEMA_OBJECT_PRIVILEGE'
                                  -- 'GLOBAL_OBJECT_PRIVILEGE'
                                  -- 'SCHEMA_ROLE'
                                  -- 'GLOBAL_ROLE'
                                  -- 'SCHEMA_PRIVILEGE'
                                  -- 'SYSTEM_PRIVILEGE'
    PRIVILEGE_NAME NVARCHAR(256), -- cf. SYS.PRIVILEGES
    OBJECT_SCHEMA NVARCHAR(256),  -- NULL or schema
    OBJECT_NAME NVARCHAR(256),
    OBJECT_TYPE NVARCHAR(128),    -- NULL or 'REMOTE SOURCE'
    GRANTEE_SCHEMA NVARCHAR(256), -- NULL or schema
    GRANTEE_NAME NVARCHAR(256),
    GRANTABLE NVARCHAR(5)         -- 'TRUE' or 'FALSE'
  )
)
LANGUAGE SQLSCRIPT
SQL SECURITY DEFINER
AS
BEGIN
  DECLARE ERROR CONDITION FOR SQL_ERROR_CODE 10000;
  DECLARE CURSOR PRIVILEGES_CURSOR FOR SELECT * FROM :PRIVILEGES;

  -- TODO: add checks for valid grantees, e.g. check with _SYS_DI#<group>.M_CONTAINER_SCHEMAS
  --       or with SYS.USERS and creator and grantee like '%#OO'
  -- TODO: keep only functionality that should be allowed, e.g. only allow to grant schema-local
  --       roles, but no object privileges, etc.

  FOR PRIVILEGE AS PRIVILEGES_CURSOR
  DO
    DECLARE TO_GRANTEE_CLAUSE NVARCHAR(512);
    DECLARE GRANTABLE_CLAUSE NVARCHAR(512) = '';

    IF PRIVILEGE.GRANTEE_SCHEMA IS NULL THEN
      TO_GRANTEE_CLAUSE = ' TO "' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.GRANTEE_NAME) || '"';
    ELSE
      TO_GRANTEE_CLAUSE = ' TO "' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.GRANTEE_SCHEMA)
                                  || '"."' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.GRANTEE_NAME) || '"';
    END IF;

    IF PRIVILEGE.GRANTABLE = 'TRUE' THEN
      IF PRIVILEGE.PRIVILEGE_TYPE = 'SYSTEM_PRIVILEGE' OR
         PRIVILEGE.PRIVILEGE_TYPE = 'GLOBAL_ROLE' OR
         PRIVILEGE.PRIVILEGE_TYPE = 'SCHEMA_ROLE' THEN
        GRANTABLE_CLAUSE = ' WITH ADMIN OPTION';
      ELSE
        GRANTABLE_CLAUSE = ' WITH GRANT OPTION';
      END IF;
    ELSEIF PRIVILEGE.GRANTABLE != 'FALSE' THEN
      SIGNAL ERROR SET MESSAGE_TEXT = 'unsupported value for GRANTABLE: '
                                      || PRIVILEGE.GRANTABLE;
    END IF;

    IF PRIVILEGE.PRIVILEGE_TYPE = 'SCHEMA_OBJECT_PRIVILEGE' THEN
      EXEC 'GRANT "' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.PRIVILEGE_NAME) || '"'
        || ' ON "' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.OBJECT_SCHEMA)
                   || '"."' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.OBJECT_NAME) || '" '
        || TO_GRANTEE_CLAUSE
        || GRANTABLE_CLAUSE;
    ELSEIF PRIVILEGE.PRIVILEGE_TYPE = 'GLOBAL_OBJECT_PRIVILEGE' THEN
      IF PRIVILEGE.OBJECT_TYPE = 'REMOTE SOURCE' THEN
        EXEC 'GRANT "' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.PRIVILEGE_NAME) || '"'
          || ' ON ' || PRIVILEGE.OBJECT_TYPE || ' "' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.OBJECT_NAME) || '" '
          || TO_GRANTEE_CLAUSE
          || GRANTABLE_CLAUSE;
      ELSE
        SIGNAL ERROR SET MESSAGE_TEXT = 'unsupported value for OBJECT_TYPE for GLOBAL_OBJECT_PRIVILEGE: '
                                        || PRIVILEGE.OBJECT_TYPE;
      END IF;
    ELSEIF PRIVILEGE.PRIVILEGE_TYPE = 'SCHEMA_ROLE' THEN
      EXEC 'GRANT "' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.OBJECT_SCHEMA)
                     || '"."' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.OBJECT_NAME) || '" '
        || TO_GRANTEE_CLAUSE
        || GRANTABLE_CLAUSE;
    ELSEIF PRIVILEGE.PRIVILEGE_TYPE = 'GLOBAL_ROLE' THEN
      EXEC 'GRANT "' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.OBJECT_NAME) || '" '
        || TO_GRANTEE_CLAUSE
        || GRANTABLE_CLAUSE;
    ELSEIF PRIVILEGE.PRIVILEGE_TYPE = 'SCHEMA_PRIVILEGE' THEN
      EXEC 'GRANT "' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.PRIVILEGE_NAME) || '"'
        || ' ON SCHEMA "' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.OBJECT_NAME) || '" '
        || TO_GRANTEE_CLAUSE
        || GRANTABLE_CLAUSE;
    ELSEIF PRIVILEGE.PRIVILEGE_TYPE = 'SYSTEM_PRIVILEGE' THEN
      EXEC 'GRANT "' || REPLACE_REGEXPR('\.' IN ESCAPE_DOUBLE_QUOTES(PRIVILEGE.PRIVILEGE_NAME) WITH '"."') || '"'
        || TO_GRANTEE_CLAUSE
        || GRANTABLE_CLAUSE;
    ELSE
      SIGNAL ERROR SET MESSAGE_TEXT = 'unsupported value for PRIVILEGE_TYPE: '
                                      || PRIVILEGE.PRIVILEGE_TYPE;
    END IF;
  END FOR;
END;
Defining the Granting Service in the mta[d].yaml

If the container needs a granting-service, then besides the service itself, the Application Development Descriptor mta.yaml needs to be adjusted for the deployer to be able to find the service. The mta.yaml must be modified to:

  1. The container of the db module needs to get a TARGET_CONTAINER property to mark the service that corresponds to the container
  2. A new entry in requires is added for the granting-service
  3. A new entry in resources is added for the granting-service

Example: mta.yaml:

schema-version: '2.0'
ID: granting-service-example
version: 0.0.1

modules:
  - name: db
    type: hdb
    path: db
    requires:
      - name: hdi-container
        properties:                                     # 1.
          TARGET_CONTAINER: ~{hdi-container-service}    # 1.
          
      - name: granting-service                          # 2.
          
resources:
  - name: hdi-container
    type: com.sap.xs.hdi-container
    properties:
      hdi-container-service: ${service-name}        

  - name: granting-service                              # 3.
    type: org.cloudfoundry.existing-service             # 3.

Environment Variables for Applications

@sap/hdi-deploy supports (re-)configuration via the following environment variables which are exposed to applications, e.g. via the CF/XSA manifest.yml or the MTA descriptor mta.yaml:

  • TARGET_CONTAINER: (optional) service name that specifies the HDI target container (needed, if more than one HDI service is bound to the HDI Deployer)
  • SERVICE_REPLACEMENTS: (optional) JSON-structured list of service replacements, e.g. [ { "key": "logical-service-name-1", "service":"real-service-name-1"}, { "key": "logical-service-name-2", "service":"real-service-name-2"} ], where the logical service names refer to the names in the HDI content and the real service names refer to the services which are bound to the HDI Deployer via VCAP_SERVICES; if the HDI content references a service name which is not listed in the replacements, then this name is used as a real service name

The structure of the SERVICE_REPLACEMENTS environment variable is based on the MTA specification in order to enable MTA group assignments.

Example manifest.yml:

applications:
- name: app-db
  path: db
  health-check-type: process
  services:
    - app-database
    - real-grantor-service
    - real-external-service
  env:
    TARGET_CONTAINER: app-database
    SERVICE_REPLACEMENTS: >
      [
        {
          "key"     : "logical-grantor-service",
          "service" : "real-grantor-service"
        },
        {
          "key"     : "logical-external-service",
          "service" : "real-external-service"
        }
      ]

Environment Variables for Infrastructure / Development Tools

@sap/hdi-deploy supports (re-)configuration via the following environment variables for infrastructure / development tools like the Deploy Service or internal build tools of the WEB IDE

  • EXIT: (optional) if set, the HDI Deployer will exit when the deployment is done; using the environment variable is equivalent to passing a --exit on the command line
  • DEPLOY_ID: (optional) if set, the given id will be written to the final application log entry (custom id, to support processes in parsing log output
  • HDI_DEPLOY_OPTIONS: (optional) JSON-structured set of options for the HDI Deployer, e.g. { "auto_undeploy" : true, "exit" : true }; command line options can be translated to HDI_DEPLOY_OPTIONS options by replacing the -s in the option names with _s; options which can accept multiple values require a JSON array with the values, e.g. path options like the include-filter option.

Example mta.yml:

_schema-version: "2.1"
ID: project
version: 0.0.1
modules:
- name: db
  type: hdb
  path: db
  requires:
  - name: hdi_db
    properties:
      TARGET_CONTAINER: ~{hdi-container-name}
      HDI_DEPLOY_OPTIONS: >
        {
          "validate_external_dependencies": false,
          "treat_unmodified_as_modified": true,
          "exit": true,
          "include_filter": ["src/", "cfg/"]
        }

        ...
  • APPLICATION_ID: (optional, fallback SAP_HDI) this will be used, in conjunction with the space_name and the organization_name of the VCAP_APPLICATION to set the session variable APPLICATION for all connections to the database. This setting may only be used by applications from SAP.
  • APPLICATION_VERSION_INFO: (optional) this will be logged to the command line, to allow logging of some additional information about the application.

Options from HDI_DEPLOY_OPTIONS and the command line are merged. HDI_DEPLOY_OPTIONS have priority over options from the command line.

Ignore List

The hdi deployer supports ignoring certain files via an .hdiignore file. The file has to be placed at the root of the project folder, just like the undeploy.json. The file has a structure similar to a .gitignore file, simply lines of texts specifying the paths to exclude. Both "real" paths and path patterns are supported.

src/table_1.hdbtable
src/*_2.hdbtable

The file works just like the --exclude-filter option and they can be used at the same time.

Options for Interactive Scenarios

@sap/hdi-deploy supports the following options for interactive deployment scenarios, e.g. for orchestration via the WEB IDE or for CI scripts:

  • --version: print version and exit
  • -t, --trace: enable tracing
  • --use-hdb: enable the "hdb" client to connect to the database instead of "@sap/hana-client"; by default "@sap/hana-client" is used
  • --hana-client-trace: enable tracing for the SAP HANA client; All interactions with the SAP HANA server will be traced which can lead to a large amount of trace information to be written
  • --hana-client-packet-trace: enable PACKET tracing for the SAP HANA client; Must only be used in combination with --hana-client-trace
  • --[no-]verbose: [don't] print detailed log messages to the console
  • --skipped-deleted-files-log <filepath> | local | stdout: [filepath] write skipped deleted files (that are not listed in undeploy.json) to the file indicated by the file path. The file must not exist; [local] create a new file called skippedDeletedFiles.json in the deployer working directory and write the deleted files into it. [stdout] write the deleted files to the standard output.
  • --structured-log <file>: write log messages as JSON objects into the given file; messages are appended if the file already exists
  • --[no-]exit: [don't] exit after deployment of artifacts
  • --[no-]lock-container: [don't] acquire the container lock while working with the container
  • --root <path>: use the given root path for artifacts
  • --working-set [<path> ..]: define the given paths (directories and files) as the working set; a non-default working set applies additional restrictions, e.g. other options might be disallowed
  • --include-filter [<path> ..]: only include the given paths (directories and files) during delta detection
  • --deploy [<file> ..]: explicitly schedule the given files for deploy; extends the include-filter for collecting local files. Instead of a real path, a path pattern like src/**/*.hdbtable can be used as well.
  • --[no-]treat-unmodified-as-modified: [don't] treat unmodified files during delta detection as modified files
  • --undeploy [<file> ..]: explicitly schedule the given files for undeploy
  • --parameter [<key>=<value> ..]: pass the given list of key-value parameters to the deployment
  • --path-parameter [<path>:<key>=<value> ..]: pass the given list of path-key-value parameters to the deployment
  • --[no-]auto-undeploy: [don't] undeploy artifacts automatically based on delta detection and ignore the undeploy.json file
  • --[no-]treat-warnings-as-errors: [don't] enable server-side feature for treating warnings as errors
  • --[no-]treat-deployer-warnings-as-errors: [don't] enable deployer-side feature for treating warnings as errors
  • --[no-]validate-external-dependencies: [don't] start a make, even if no files are in the deploy/undeploy sets; all deployed synonyms, projection views, and virtual tables in the container will be checked for changes to referenced objects and redeployed, if a change is detected.
  • --[no-]simulate-make: [don't] simulate the make and skip post-make activities; pre-make activities still take effect, e.g. grants
  • --[no-]stop-on-error: [don't] collect as many erros as possible during the deployment
  • --connection-timeout <ms>: number of milliseconds to wait for the database connection(s)
  • --delete-timeout <ms>: number of milliseconds to wait for the DELETE call
  • --write-timeout <ms>: number of milliseconds to wait for the WRITE call
  • --async-make-timeout <ms>: number of milliseconds to wait for the async make job to finish when --async-make is active; by default 1800000 ms (30 minutes)
  • --lock-container-timeout <ms>: number of milliseconds to wait for the container lock
  • --exclude-filter [<path> ..]: exclude the given paths during: file walk, delta detection and when explicitly scheduled via --(un)deploy
  • --[no-]optimise-file-upload : [don't] perform delta detection via local SHA256 calculation instead of DELETE and WRITE calls. Will not have any positive effect when used along with --treat-unmodified-as-modified.
  • --[no-]delta-detection : [don't] perform delta detection. The --no-delta-detection deploys only what passed in --deploy parameter and undeploys what passed in --undeploy parameter. The --no-delta-detection can be combined with the --exclude-filter. However, it will not have any beneficial effect when used with the --optimise-file-upload, --include-filter, or --treat-unmodified-as-modified options.
  • --[no-]treat-wrong-ownership-as-errors: [don't] treat wrong ownership of objects as errors, not enabled by default
  • --[no-]migrationtable-development-mode: [don't] pass the development mode flag for migration tables to HDI, if the parameter is supported by the server, not enabled by default
  • --[no-]liveness-ping: [don't] send a sign of life from time to time, by default, a sign of life will be sent
  • --[no-]live-messages: [don't] display the make messages while the make is still in progress, by default, the messages will be displayed while the make is in progress
  • --[no-]async-make: [don't] use MAKE_ASYNC instead of MAKE for the HDI make step; prevents connection timeouts for very long-running deployments; by default, the synchronous MAKE is used
  • --[no-]trace-vcap-services: [don't] log VCAP services information, by default, the following VCAP services properties will be logged: name, label, plan, tags, schema, database_id, user, hdi_user, and service_key_name (with --trace, the rest of the properties will also be logged)
  • --write-batch-size <integer>: number of files to write in one batch. Must be a positive integer. Default: 8000

See --help for details and defaults.

Options can also be passed to @sap/hdi-deploy via the HDI_DEPLOY_OPTIONS environment variable. Options from HDI_DEPLOY_OPTIONS and the command line are merged. HDI_DEPLOY_OPTIONS have priority over options from the command line.

Supported Features

@sap/hdi-deploy exposes its set of features via the info option, which can be passed as --option or via HDI_DEPLOY_OPTIONS, e.g.

node deploy --info [<component> [<component> [...]]]

where a list of components can be specified.

The info option allows to pass multiple components. The info request for these components is optional, e.g. if the HDI Deployer doesn't support the component, then it will not throw an error, but simply not return information for that component. The special component all will return the information for all known components; all is the default if no component is specified. For certain future components, e.g. server, the HDI Deployer might need to connect to the HDI container in the database and retrieve feature information from there.

Examples:

node deploy --info all
node deploy --info client server

The result of an info call is a JSON document where the top-level objects correspond to the requested components. Each component should at least report its name, its version, and the set of supported features with name and version number (version numbers are simple numbers (no dots, no double-dots)).

If a version number is negative, then the feature is supported by the client, but not supported by the server.

For a --info client call, the document looks as follows:

{
    "client": {
        "name": "@sap/hdi-deploy",
        "version": "5.7.0",
        "features": {
            "info": 2,
            "verbose": 1,
            "structured-log": 1,
            "lock-container": 1,
            "default-access-role": 1,
            "grants": 4,
            "working-set": 1,
            "include-filter": 1,
            "deploy": 1,
            "treat-unmodified-as-modified": 1,
            "undeploy": 1,
            "parameter": 1,
            "path-parameter": 1,
            "treat-warnings-as-errors": 1,
            "validate-external-dependencies": 1,
            "simulate-make": 1,
            "service-replacements": 1,
            "modules": 2,
            "config-templates": 2,
            "environment-options": 1,
            "undeploy-allowlist": 1
        }
    }
}

For the server component, the document would also contain the following data:

{
...
    "server": {
        "name": "sap-hana-database",
        "version": "1.00.120.04.0000000000",
        "features": {}
    }
}

Deployment via hdi-dynamic-deploy

The standard XSA/CF way for deploying HDI content at runtime is to make use of @sap/hdi-dynamic-deploy instead of @sap/hdi-deploy directly. The @sap/hdi-dynamic-deploy app is an http server that calls @sap/hdi-deploy when it receives a corresponding HTTP POST request. See the @sap/hdi-dynamic-deploy module for more information.

Using hdi-deploy as a Node.js library

Since version 3.3.0 of @sap/hdi-deploy it is also possible to use it as a Node.js library. By requiring the library.js file from the project root it is possible to start the deployer app from within another Node.js app. The module exports the function

function deploy(contentDir, deployerEnv, callback, io)

with the following parameters:

  • contentDir: string containing a path pointing to the root of the db module to be deployed
  • deployerEnv: javascript object containing the OS environment for the call to the deployer (e.g. containing VCAP_SERVICES)
  • callback: a standard callback of the form (errors, result), where result is the result of the call to the deployer of the form:
{
  messages: [<list of result messages from the di server>],
  exitCode: <exit code of the call to the deployer app, one of -1, 0, 1.>,
  signal: <signal that the child process was closed with>
}
  • io (optional): javascript object containing two callback functions io.stdoutCB and io.stderrCB of the form function(data) for streaming stdout and stderr of the call to the deployer, defaults to piping stdout and stderr of the deployer to stdout and stderr of the calling Node.js app

The exit codes have different meanings:

  • -1: The child process was most likely killed externally, check the signal property for details.
  • 0: Deployment done succesfully.
  • 1: Deployment failed, errors occurred.

The signal property is only set, if exitCode is -1.

SAP DEVELOPER LICENSE AGREEMENT 3.2, read licence

History

Latest

v5.7.0

Other 6

Notes

Features:

  • Added support for grant_using_group and revoke_using_group in .hdbgrants and .hdbrevokes files
  • Added option --async-make to run the HDI make operation asynchronously
  • Added structured logging support in dynamic deploy (library mode)
  • Use @sap/hdi@^4.8.1

Fixes:

  • Fixed license field in package.json to use npm-standard format for proper recognition by SCA tools
  • Updated license to SAP Developer License Agreement version 3.2
  1. v5.6.1

    Other 2

    Notes

    Fixes:

    • Fixed X.509 certificate authentication issue
    • Patched an issue classified under CWE‑89 (SQL injection vulnerability)
  2. v5.6.0

    Other 3

    Notes

    Features:

    • Added support for the VCAP_SERVICES_FILE_PATH environment variable
    • Enhancements in VCAP_SERVICES logging
    • Use @sap/xsenv@^6.0.0
  3. v5.5.1

    Other 2

    Notes

    Features:

    • Fail with error if credentials.schema property is not a string

    Fixes:

    • Error: write EPIPE
  4. v5.5.0

    Other 4

    Notes

    Features:

    • Added option --write-batch-size <integer>
    • Use @sap/hdi@^4.8.0
    • hdb@^2 support

    Fixes:

    • Error: EMFILE, too many open files
  5. v5.4.2

    Other 2

    Notes

    Features:

    • Added support for certificate authentication

    Fixes:

    • --optimise-file-upload error: "Cannot read properties of undefined (reading 'digest')"
  6. v5.4.1

    Other 1

    Notes

    Fixes:

    • The --use-hdb flag did not take effect in some situations
  7. v5.4.0

    Other 8

    Notes

    Features:

    • Set --optimise-file-upload option to true by default
    • Added option --[no-]delta-detection to enable [don't] perform delta detection
    • Added implicit fallback to hdb client
    • Node >=18.x support
    • use @sap/hdi@^4.7.0

    Fixes:

    • Merge parameters from command line and HDI_DEPLOY_OPTIONS
    • Log skipped delted filepath instead of filename
    • Added support for HANA Cloud tenants credential format
  8. v5.3.2

    Other 1

    Notes

    Fixes:

    • Removed postinstall check for SAP HANA clients
  9. v5.3.1

    Other 1

    Notes

    Fixes:

    • Fixed logging client version
  10. v5.3.0

    Other 2

    Notes

    Features:

    • Add range dependencies in package.json

    Removed:

    • Removed shrinkwrap
  11. v5.2.3

    Other 1

    Notes

    Fixes:

    • added reference property to validation checks of privilege names and their properties in .hdbgrants and .hdbrevokes files
  12. v5.2.2

    Other 2

    Notes

    Fixes:

    • use micromatch@4.0.8
    • use async@3.2.6
  13. v5.2.1

    Other 4

    Notes

    Features:

    • added option --treat-deployer-warnings-as-errors to enable deployer-side feature for treating warnings as errors
    • enhanced liveness ping status messages

    Fixes:

    • fixed error message truncation in hdicallback
    • use @sap/xsenv@5.2.0
  14. v5.2.0

    Other 5

    Notes

    Features:

    • added warning message if explicit parameters passed on the command line are overwritten by parameters specified in HDI_DEPLOY_OPTIONS
    • provide --skipped-deleted-files-log <filepath> | local | stdout option to log deleted files that are not in undeploy.json

    Fixes:

    • use micromatch@4.0.7
    • use dotenv@16.4.5
    • use @sap/xsenv@5.1.0
  15. v5.1.1

    Other 1

    Notes

    Fixes:

    • fixed accessing undefined data from readableBuffer when using the --optimise-file-upload option
  16. v5.1.0

    Other 3

    Notes

    Features:

    • validation checks to ensure the correctness of privilege names and their properties in .hdbgrants and .hdbrevokes files.
    • enhanced global object privileges with additional support

    Fixes:

    • fixed accessing undefined data from readableBuffer when using the --optimise-file-upload option
  17. v5.0.1

    Other 1

    Notes

    Fixes:

    • hana-client dependency issue while using hdb
  18. v5.0.0

    Other 7

    Notes

    Features:

    • Moved hana-client and hdb from dependencies to peerDependencies to allow choice of using either hana-client or hdb.
    • hana-client ^2 >= 2.6 support
    • hdb ^0 support
    • use dotenv@16.3.1
    • use handlebars@4.7.8
    • use micromatch@4.0.5

    Removed:

    • Node 12.x, 14.x, and 16.x support
  19. v4.9.5

    Other 3

    Notes

    Fixes:

    • use micromatch@4.0.7
    • use @sap/hana-client@2.20.22
    • use hdb@0.19.8
  20. v4.9.4

    Other 2

    Notes

    Fixes:

    • fixed accessing undefined data from readableBuffer when using the --optimise-file-upload option
    • use @sap/hana-client@2.20.15
  21. v4.9.3

    Other 1

    Notes

    Fixes:

    • fixed accessing undefined data from readableBuffer when using the --optimise-file-upload option
  22. v4.9.2

    Other 2

    Notes

    Fixes:

    • use @sap/hana-client@2.19.21
    • use @sap/xsenv@4.2.0
  23. v4.9.1

    Other 2

    Notes

    Fixes:

    • fixed npm dependency resolution fault
    • use @sap/hdi@4.5.2
  24. v4.9.0

    Other 2

    Notes

    Features:

    • only log VCAP_SERVICES of hana service or user-provided service with hana tag
    • use @sap/hana-client@2.19.18
  25. v4.8.2

    Other 1

    Notes

    Fixes:

    • removed extraneous packages in shrinkwrap
  26. v4.8.1

    Other 2

    Notes

    Features:

    • use @sap/hdi@4.5.1
    • use @sap/hana-client@2.18.24
  27. v4.8.0

    Other 3

    Notes

    Features:

    • use @sap/hdi@4.5.0
    • use @sap/hana-client@2.17.22
    • Node 20.x support
  28. v4.7.1

    Other 1

    Notes

    Fixes:

    • removed extraneous packages in shrinkwrap
  29. v4.7.0

    Other 7

    Notes

    Features:

    • use @sap/hana-client@2.17.21
    • log deleted files before applying undeploy.json
    • added option --stop-on-error to stop deploying further files after an error occurs while deploying a file
    • merge custom parameters passed via --parameter instead of overriding

    Fixes :

    • log all errors in stderr instead of stdout
    • fix extra space while logging delta time
    • set default hdb timeout to 1000 ms
  30. v4.6.1

    Other 2

    Notes

    Features:

    • use @sap/hana-client@2.16.26
    • log client version during deployment
  31. v4.6.0

    Other 6

    Notes

    Features:

    • use @sap/hana-client@2.16.21
    • log cloud version when server is hana cloud
    • added support for granting/revoking service in kyma

    Fixes :

    • log grantor/revoker type used when throwing unknown grantor type error
    • log detailed error messages when write call fails
    • ensure that the complete VCAP_SERVICES are logged without --trace
  32. v4.5.3

    Other 1

    Notes

    Features:

    • use @sap/hana-client@2.15.19
  33. v4.5.2

    Other 2

    Notes

    Features:

    • use @sap/hana-client@2.15.17
    • use @sap/xsenv@3.4.0
  34. v4.5.1

    Other 1

    Notes

    Features:

    • use @sap/hana-client@2.14.22
  35. v4.5.0

    Other 3

    Notes

    Features:

    • use @sap/hana-client@2.13.22
    • added option --optimise-file-upload to perform delta detection via local SHA256 calculation instead of DELETE and WRITE calls
    • Node 18.x support
  36. v4.4.1

    Other 3

    Notes

    Features:

    • use @sap/hana-client@2.13.13
    • use hdb@0.19.3
    • use @sap/xsenv@3.3.2
  37. v4.4.0

    Other 2

    Notes

    Features:

    • added option --use-hdb to enable using hdb client instead of @sap/hana-client for connecting to the database
    • use @sap/hana-client@2.12.25
  38. v4.3.3

    Other 4

    Notes

    Features:

    • use @sap/hdi@4.3.1
    • use @sap/hana-client@2.12.20
    • use async@3.2.3

    Fixes :

    • handle empty user-provided services
  39. v4.3.2

    Other 1

    Notes

    Fixes:

    • maintain shrinkwrap with minimist@1.2.6
  40. v4.3.1

    Other 5

    Notes

    Features:

    • added support for retrieving credentials from kubernetes
    • use @sap/hdi@4.3.0
    • use @sap/hana-client@2.11.20

    Fixes:

    • log long lists without truncation
    • fixed passing arbitrary parameters to @sap/hana-client
  41. v4.3.0

    Other 3

    Notes

    Features:

    • allow passing arbitrary parameters to @sap/hana-client
    • use @sap/hdi@4.2.0
    • use @sap/hana-client@2.10.20
  42. v4.2.3

    Other 1

    Notes

    Features:

    • allow pattern negations in the undeploy.json file
  43. v4.2.2

    Other 1

    Notes

    Fixes:

    • removed extraneous packages in shrinkwrap
  44. v4.2.1

    Other 4

    Notes

    Features:

    • added option --hana-client-trace to enable tracing for the SAP HANA client interactions with the SAP HANA server
    • added option --hana-client-packet-trace to enable packet tracing for the SAP HANA client interactions with the SAP HANA server
    • added custom listeners to handle SIGBUS errors

    Fixes:

    • log client messages and errors to structured log
  45. v4.2.0

    Other 6

    Notes

    Features:

    • allow wildcard paths in the undeploy.json file to enable the undeployment of a set of files without having to specify every single file
    • added, modified, deleted and "treated as modified" files are logged during deployment
    • use @sap/hdi@4.1.0
    • use @sap/hana-client@2.9.28
    • Node 16.x support

    Removed:

    • Node 8.x and 10.x support
  46. v4.1.0

    Other 6

    Notes

    Features:

    • provide --validate-external-dependencies option to always start a make, even if no files are in the deploy/undeploy sets
    • change wording for "whitelist" to "allowlist"
    • use @sap/hdi@4.0.2
    • use @sap/hana-client@2.8.20
    • added support for reading a .env file in the absence of default-env.json file

    Fixes:

    • with --trace, ensure that the complete VCAP_SERVICES are logged
  47. v4.0.6

    Other 1

    Notes

    Features:

    • with --trace, log target credentials before checking server version
  48. v4.0.5

    Other 1

    Notes

    Fixes:

    • updated handlebars to 4.7.7
  49. v4.0.4

    Other 3

    Notes

    Features:

    • use @sap/hdi@4.0.1
    • use @sap/hana-client@2.7.26

    Fixes:

    • corrected improper representation of time in log
  50. v4.0.3

    Other 2

    Notes

    Fixes:

    • ensure all the messages returned by library.js are structured
    • stricter tag validation
  51. v4.0.2

    Other 3

    Notes

    Features:

    • use @sap/hdi@3.0.2
    • use @sap/hana-client@2.7.21
    • log start and end time of deployments
  52. v4.0.1

    Other 1

    Notes

    Fixes:

    • use @sap/xsenv@3.1.0 for full node 14 support
  53. v4.0.0

    Other 4

    Notes

    Features:

    • use @sap/hdi@3.0.1
    • use @sap/hana-client@2.7.16
    • Node 14.x support

    Removed:

    • Node 6.x support
  54. v3.11.15

    Other 1

    Notes

    Fixes:

    • set default for --delete-timeout and --write-timeout to 15 minutes instead of 15 seconds
  55. v3.11.14

    Other 1

    Notes

    Features:

    • introduce options --delete-timeout and --write-timeout, that can be used to set a timeout for the DELETE and WRITE HDI calls.
  56. v3.11.13

    Other 5

    Notes

    Features:

    • better logging of WRITE/DELETE calls

    Fixes:

    • update dependencies
    • only handle "CDS METADATA" on non-HANA Cloud systems
    • always log errors to the parent process when using library.js
    • gracefully handle "trace":false via HDI_DEPLOY_OPTIONS
  57. v3.11.12

    Other 2

    Notes

    Changes:

    • segfault-handler is no longer installed as a optional dependency - needs to be provided via parallel installation if required

    Fixes:

    • check the return code of HDI API calls to correctly detect errors
  58. v3.11.11

    Other 1

    Notes

    Fixes:

    • close all connections before calling process.exit() to work around sporadic segmentation fault
  59. v3.11.10

    Other 1

    Notes

    Fixes:

    • fixed a memory leak with --live-messages
  60. v3.11.9

    Other 3

    Notes

    Features:

    • node 12 support

    Fixes:

    • updated dependencies
    • gracefully handle a missing grantor service when using library.js
  61. v3.11.8

    Other 1

    Notes

    Fixes:

    • specify segfault-handler as an optional dependency
  62. v3.11.7

    Other 1

    Notes

    Fixes:

    • better debugging capabilities for segmentation faults
  63. v3.11.6

    Other 2

    Notes

    Fixes:

    • remove duplicate messages when using the deployer as a library
    • update dependencies
  64. v3.11.5

    Other 2

    Notes

    Fixes:

    • when used as a library, do not exit until all messages have been sent to the parent process

    Features:

    • use hana-client 2.4.162
  65. v3.11.4

    Other 1

    Notes

    Fixes:

    • update handlebars
  66. v3.11.3

    Other 2

    Notes

    Features:

    • update dependencies

    Fixes:

    • correctly handle SQL grantors
  67. v3.11.2

    Other 1

    Notes

    Features:

    • update dependencies
  68. v3.11.1

    Other 2

    Notes

    Features:

    • node 10 support
    • updated dependencies
  69. v3.11.0

    Other 6

    Notes

    Features:

    • added option --liveness-ping to periodically send a signal that notifies the user that the deployer is still working
    • added option --live-messages to display the make messages while the make is still in progress
    • added function clean-env to library.js to allow cleaning a passed environment of all deployer-related variables

    Fixes:

    • library.js would sometimes return with exitCode null because of unexpected closing of the child process
    • update dependencies
    • add missing options to HDI_DEPLOY_OPTIONS
  70. v3.10.0

    Other 1

    Notes

    Features:

    • passwords can be split over multiple services
  71. v3.9.4

    Other 1

    Notes

    Fixes:

    • update handlebars
  72. v3.9.3

    Other 1

    Notes

    Fixes:

    • add full support for .hdbmigrationtable files by adding the --[no-]migrationtable-development-mode flag
  73. v3.9.2

    Other 3

    Notes

    Fixes:

    • the private key used for mutual authentication was logged if tracing is enabled
    • mutual auth was missing on some database connections
    • some database connections were not closed correctly
  74. v3.9.1

    Other 1

    Notes

    Fixes:

    • revert changes to hdi actions that could possibly cause a behavior change
  75. v3.9.0

    Other 11

    Notes

    Features:

    • allow passing ssl connection parameters in service binding
    • allow mutual auth via parameters in service binding
    • set session variable APPLICATION on all HANA connections
    • support path parameters for HDI
    • allow development debug role similar to the default access role
    • update @sap/hdi dependency
    • better handling of invalid undeploy.json files
    • improved timestamps in logging output
    • check ownership of objects in the container via --treat-wrong-ownership-as-errors
    • allow logging of additional application data

    Fixes:

    • issue with schema privileges and global roles in the same .hdbgrants file
  76. v3.8.2

    Other 12

    Notes

    Features:

    • introduced .hdbrevokes as a counterpart to .hdbgrants
    • automatically find target service: if only one HDI service is bound, TARGET_CONTAINER does not have to be set
    • print timestamp of HDI messages
    • print the status of the last build
    • fallback to the .hdiconfig in src/ if it is missing in cfg/
    • switch to @sap/hdi 2.1.2
    • switch from hdb to @sap/hana-client
    • check if the container supports locking and skip it if not

    Fixes:

    • support \n and \r\n as line endings in .hdiignore files
    • correctly process grantor files in ZDM mode
    • fix 'Maximum call stack size exceeded' in ZDM mode
    • don't escape schema names in .hdbgrants
  77. v3.7.0

    Other 9

    Notes

    Features:

    • warning messages will now be prepended with "WARNING:"
    • error messages in case of a bad service binding now offer more detail on what caused the error
    • now supports comments in JSON files like default services file
    • allow file patterns in --deploy option
    • added new options --exclude-filter and .hdiignore file that basically work like .gitignore
    • improved error reporting when using the deployer as a library

    Fixes:

    • correctly handle component names of system privileges in .hdbgrants files
    • handle empty privilege objects
    • filter client files like .hdbgrants before deploying
  78. v3.6.0

    Other 3

    Notes

    Features:

    • support ZDM deployment of HDI artifacts modeled in data/ and access/ folders inside db module
    • support ZDM deployment of .hdbrole files in access schema
    • target service is logged during deployment
  79. v3.5.1

    Other 2

    Notes

    Features:

    • support ZDM deployment
    • added warning message when using .hdbsysnonymtemplate or .hdbsynonymgrantor
  80. v3.4.1

    Other 1

    Notes

    Features:

    • update dependencies
  81. v3.4.0

    Other 5

    Notes

    Features:

    • provide --treat-unmodified-as-modified option to schedule also unmodified for deploy
    • support procedure-type granting services
    • improve Readme

    Fixes:

    • fix handling of grantor services which have a db_hosts value, but no host value
    • fix occasional 'Callback was already called' error in case of deployment failures
  82. v3.3.0

    Other 2

    Notes

    Features:

    • provide library.js to fork the deployer from a node.js app for a given content directory including support for stdio callbacks

    Fixes:

    • don't look at server folders outside cfg/, src/, and lib/
  83. v3.2.0

    Other 1

    Notes

    Features:

    • support for @sap/hdi-dynamic-deploy
  84. v3.1.2

    Other 2

    Notes

    Fixes:

    • use db_hosts from VCAP_SERVICES if it exists
    • transform paths from --include-filter, --deploy, --undeploy, --working-set to the server format where reusable modules are located at lib/ instead of node_modules/
  85. v3.1.1

    Other 1

    Notes

    Fixes:

    • support @-scoped reusable modules
  86. v3.1.0

    Other 3

    Notes

    Features:

    • support --parameter option to pass key-value parameters to the deployment

    Fixes:

    • use non-sync write to stdout (and stderr), and on exit, wait until stdout is drained to avoid loss of log output in case of crashes, etc.
    • container locking is available since server version 2.0.1.0, not 2.0.0.0
  87. v3.0.0

    Other 19

    Notes

    Features:

    • check src/defaults/default_access_role.hdbrole file against the working set
    • check .hdbgrants files against the working set
    • show the processing of individual .hdbgrants files
    • on newer server versions, acquire the container lock while working with the container
    • support --lock-container-timeout <ms> option for setting the number of milliseconds to wait for the container lock, defaults to 120.000 ms
    • also support grantor services with only "user", "password", "schema"; and take "host", "port", "certificate" from the target container
    • in .hdbgrants files, use the first non-undefined schema value ("schema", "reference", "schema" from grantor service); "reference" is only used for "schema_privileges"
    • support schema roles in .hdbgrants files
    • reject explicit delta detection of files outside the working set
    • switch to Node.js 6.9.1 as minimal Node.js version
    • provide --working-set option to restrict the set of files which can be modified in the container
    • support global roles with admin option in .hdbgrants files
    • support system privileges with admin option in .hdbgrants files
    • support --connection-timeout <ms> option for setting the number of milliseconds to wait for the database connection(s)

    Fixes:

    • lock the container before showing the synchronizing message
    • support .hdbgrants files without a name (folder/.hdbgrants)
    • support the string-array style in schema_roles, too
    • support typed global object privileges in .hdbgrants files
    • correctly pass certificate to hdi client
  88. v2.3.0

    Other 1

    Notes

    Features:

    • rename module to @sap/hdi-deploy
  89. v2.2.0

    Other 3

    Notes

    Fixes:

    • fix schema name handling to allow schema names with special characters
    • fix handling of more than 1 privilege in a single element in .hdbgrants files
    • fix trace handling for VCAP_SERVICES and connection data
  90. v2.1.0

    Other 14

    Notes

    Features:

    • detect server version; provide --[no-]detect-server-version option
    • invert client feature version numbers if they are not available due to the detected server version
    • support server in --info
    • generalize handling of configuration file templating for cfg/**/*config files
    • provide --structured-log option to send messages in a JSON-structured format into a log file
    • provide --[no-]verbose option to suppress detailed messages at the console output
    • allow consumption of reusable database modules via package.json and npm install
    • provide --simulate-make option to enable server-side feature for simulating the make activities
    • provide --treat-warnings-as-errors option to enable server-side feature for treating warnings as errors
    • provide --deploy option to explicitly include a set of files in the deploy set
    • provide --undeploy option to explicitly include a set of files in the undeploy set

    Fixes:

    • reject --simulate-make and --treat-warnings-as-errors if the server doesn't support these features
    • consider the root path when looking for reuse modules
    • throw an error if we find a nested node_modules folder inside a reuse module
  91. v2.0.1

    Other 4

    Notes

    Fixes:

    • pass the certificate from the service binding down to the database (certificate field in the binding, ca field in the database connection)
    • fix handling of file templating in cfg/ folder and include-filter handling on Windows
    • fix handling of multiple roles in container_roles elements in .hdbgrants files
    • fix handling of .hdbgrants files with more than 1 grantors inside
  92. v2.0.0

    Other 20

    Notes

    Features:

    • allow .hdbgrants as suffix for privilege grants / grantor mechanism files
    • apply consistency check on file src/defaults/default_access_role.hdbrole
    • show information about used service replacements
    • reworked reporting of hdideploy.js errors and HDI errors/warnings
    • refactored JSON parser handling
    • automatic assignment of the deployed role default_access_role if the file src/defaults/default_access_role.hdbrole is in the processing file set
    • provide --info option to show supported features
    • provide timing information for certain actions, e.g. time spent for collecting files, time spent for synchronizing files with the server, etc.
    • provide --include-filter option to define a filter for restricting the set of files which are processed by the deployer app for deploy/undeploy
    • allow the indirection of service names via a SERVICE_REPLACEMENTS environment variables
    • provide a generic templating mechanism for cfg/**/*config files, replacing the hdbsynonymtemplate files
    • support default-services.json and default-env.json for local development
    • show information about the effects of the undeploy.json file
    • always show application name plus version number; for support cases
    • always consider all deploy directories, even if they do not exist locally
    • write the log message Application can be stopped. only once
    • ignore errors when deleting non-existing directories
    • show information about the steps that are performed
    • provide --[no-]strip-cr-from-csv option to [not] strip carriage return characters from CSV files; not enabled by default anymore

    Fixes:

    • don't report a missing undeploy.json file as an error
  93. v1.1.0

    Other 5

    Notes

    Features:

    • replace --autoUndeploy with --auto-undeploy; keep --autoUndeploy for backwards compatibility
    • provide --no-auto-undeploy option to revert --auto-undeploy
    • provide --root option
    • provide --exit and --no-exit options
    • allow to pass options via JSON structured HDI_DEPLOY_OPTIONS environment variable
107,436downloads per week, npm
Weekly downloads for @sap/hdi-deploy26 complete calendar weeks from 2026-04-20 to 2026-10-18; the latest total is 107436.20 Apr – 26 Apr: 277,46427 Apr – 3 May: 245,5364 May – 10 May: 265,60111 May – 17 May: 260,39218 May – 24 May: 261,92325 May – 31 May: 251,4341 Jun – 7 Jun: 201,4528 Jun – 14 Jun: 260,03315 Jun – 21 Jun: 258,82422 Jun – 28 Jun: 289,90529 Jun – 5 Jul: 292,2106 Jul – 12 Jul: 281,31113 Jul – 19 Jul: 313,75820 Jul – 26 Jul: 314,35127 Jul – 2 Aug: 262,8953 Aug – 9 Aug: 258,76210 Aug – 16 Aug: 213,97117 Aug – 23 Aug: 257,21724 Aug – 30 Aug: 290,56031 Aug – 6 Sept: 216,9167 Sept – 13 Sept: 190,95914 Sept – 20 Sept: 202,61621 Sept – 27 Sept: 216,81628 Sept – 4 Oct: 246,3845 Oct – 11 Oct: 206,94712 Oct – 18 Oct: 107,436

Others providing8

Schema evolution
  1. @cap-js-community/commonSix CAP features in one package, from replication cache to rate limits
  2. cds-dbmDelta deployment and migrations for CAP database adapters
  3. @quadrio/cds-dbmFork of cds-dbm with deploy, load, diff and drop tasks
  4. @sap/cds-mtxsMultitenancy, tenant provisioning and extensibility for CAP
  5. @sap/cdsCAP Node.js runtime
Native SAP HANA artifacts
  1. cds-federation-synonymsCAP-to-CAP data federation over SAP HANA synonyms
  2. @sap/cds-dkCommand line client and development toolkit for CAP
  3. @sap/cdsCAP Node.js runtime
  4. SAP-samples/hana-developer-cli-tool-exampleDeveloper-centric command line for SAP HANA

Details

Sources3
Added by handdiscovered herechecked
npm registry, @sap/hdi-deployversion, releases, installschecked
README.mdquoted, and what the entry declareschecked

Sources are graph entities: the same page may back several entries, and an unreachable source flags every row that rests on it.

Compatibility and provenance
runtimesnode
deploymentCloud Foundry, local
latestv5.7.0
first release
releases and cadence67, ~64d median
discovered viaAdded by hand
first seen in the atlas
ecosystem and domaincap, data-and-persistence
History in the atlas2
  1. Hand-fed from its npm page. Written from the 5.7.0 README and changelog as published on the registry, and from capire's SAP HANA guide for how cds deploy uses it, all read today.
  2. First seen.
For your agent
Ref
artifact:sap-hdi-deploy
JSON
/artifacts/sap-hdi-deploy.json
MCP
Connecting an agent