MTX Services Reference
Introduction & Overview
The @sap/cds-mtxs
package provides a set of CAP services which implement multitenancy, features toggles and extensibility ('MTX' stands for these three functionalities). These services work in concert as depicted in the following diagram.
MTX services are implemented in Node.js and can run in the same Node.js server as your application services or in separate micro services called sidecars. All services can be consumed via REST APIs.
As all services are defined and implemented as standard CAP services, with service definitions in CDS and implementations based on the CAP Node.js framework, application projects can hook into all events to add custom logic using CAP Node.js.
Getting Started…
Add @sap/cds-mtxs
Package Dependency
npm add @sap/cds-mtxs
Enable MTX Functionality
Add one or more of the following convenience configuration flags, for example, to your package.json
in a Node.js-based project:
"cds": {
"requires": {
"multitenancy": true,
"extensibility": true,
"toggles": true
}
}
Java-based projects require a sidecar setup.
Test-Drive Locally
After enabling MTX features, you can test MTX functionality with local development setups and in-memory databases as usual, for example, using cds watch
to start your server:
cds watch
This shows the MTX services being served in addition to your application services:
[cds] - loaded model from 6 file(s):
db/schema.cds
srv/admin-service.cds
srv/cat-service.cds
../../db/extensions.cds
../../srv/deployment-service.cds
../../srv/bootstrap.cds
[cds] - connect to db > sqlite { url: 'db.sqlite' }
[cds] - serving cds.xt.SaasProvisioningService { path: '/-/cds/saas-provisioning' }
[cds] - serving cds.xt.DeploymentService { path: '/-/cds/deployment' }
[cds] - serving cds.xt.ModelProviderService { path: '/-/cds/model-provider' }
[cds] - serving cds.xt.ExtensibilityService { path: '/-/cds/extensibility' }
[cds] - serving cds.xt.JobsService { path: '/-/cds/jobs' }
[cds] - serving AdminService { path: '/admin' }
[cds] - serving CatalogService { path: '/browse', impl: 'srv/cat-service.js' }
[cds] - server listening on { url: 'http://localhost:4004' }
[cds] - launched at 5/6/2023, 9:31:11 AM, in: 863.803ms
Grow As You Go...
Follow CAP principles of 'Grow as you go...' to minimize complexity of setups, stay in inner loops with fast turnarounds, and hence minimize costs and accelerate development.
Enable MTX Only if Required
During development you rarely need to run your servers with MTX functionality enabled. Only do so when you really need it. For example, in certain tests and/or by using configuration profiles.
This configuration would have development not use MTX by default. You could still run with MTX enabled on demand and even have it always active in production:
"cds": {
"requires": {
"[with-mtx]": {
"multitenancy": true,
"extensibility": true,
"toggles": true
},
"[production]": {
"multitenancy": true,
"extensibility": true,
"toggles": true
}
}
}
During development you could occasionally run with MTX:
cds watch --profile with-mtx
Testing With Minimal Setup
When designing test suites that run frequently in CI/CD pipelines, you can shorten runtimes and reduce costs. First run a set of functional tests which use MTX in minimized setups – that is, with local servers and in-memory databases as introduced in the Multitenancy guide.
Only in the second and third phases, you would then run the more advanced hybrid tests. These hybrid tests could include testing tenant subscriptions with SAP HANA, or integration tests with the full set of required cloud services.
Consumption
Via Programmatic APIs
Consume the MTX services using standard Service APIs. For example, in cds repl
:
await cds.test()
var { 'cds.xt.ModelProviderService': mps } = cds.services
var { 'cds.xt.DeploymentService': ds } = cds.services
var db = await ds.subscribe ('t1')
var csn = await mps.getCsn('t1')
cds.context = { tenant:'t1' }
await db.run('SELECT type, name from sqlite_master')
Via REST APIs
Common usage of the MTX services is through REST APIs. Here's an example:
Start the server
shcds watch
Subscribe a tenant
httpPOST http://localhost:4004/-/cds/deployment/subscribe HTTP/1.1 Content-Type: application/json { "tenant": "t1" }
Get CSN from
ModelProviderService
httpPOST http://localhost:4004/-/cds/model-provider/getCsn HTTP/1.1 Content-Type: application/json Authorization: Basic yves: { "tenant": "t1", "toggles": ["*"] }
Configuration
Shortcuts cds.requires.multitenancy / extensibility / toggles
The easiest way to enable multitenancy, extensibility, and feature toggles is as follows:
{
"cds": {
"requires": {
"multitenancy": true,
"extensibility": true,
"toggles": true,
}
}
}
On the one hand, these settings are interpreted by the CAP runtime to support features such as tenant-specific database connection pooling when multitenancy
is enabled.
On the other hand, these flags are checked during server bootstrapping to ensure the required combinations of services are served by default. The following tables shows which services are enabled by one of the shortcuts:
multitenancy | extensibility | toggles | |
---|---|---|---|
SaasProvisioningService | yes | no | no |
DeploymentService | yes | no | no |
ExtensibilityService | no | yes | no |
ModelProviderService | yes | yes | yes |
Configuring Individual Services
In addition or alternatively to the convenient shortcuts above you can configure each service individually, as shown in the following examples:
"cds": {
"requires": {
"cds.xt.DeploymentService": true
}
}
The names of the service-individual configuration options are:
cds/requires/<service definition name>
Allowed Values:
false
— deactivates the service selectivelytrue
— activates the service with defaults for embedded usage<preset name>
— uses preset, for example, with defaults for sidecar usage{ ...options }
— add/override individual configuration options
Common Config Options
model
— specifies/overrides the service model to be usedimpl
— specifies/overrides the service implementation to be usedkind
— the kind of service/consumption, for example,rest
for remote usage
These options are supported by all services.
Combined with Convenience Flags
"cds": {
"requires": {
"multitenancy": true,
"cds.xt.SaasProvisioningService": false,
"cds.xt.DeploymentService": false,
"cds.xt.ModelProviderService": { "kind": "rest" }
}
}
This tells the CAP runtime to enable multitenancy, but neither serve the DeploymentService, nor the SaasProvisioningService, and to use a remote ModelProviderService via REST protocol.
Individual Configurations Only
We can also use only the individual service configurations:
"cds": {
"requires": {
"cds.xt.DeploymentService": true,
"cds.xt.ModelProviderService": { "root": "../.." }
}
}
In this case, the server will not run in multitenancy mode. Also extensibility and feature toggles are not supported. Yet the DeploymentService and the ModelProviderService are served selectively. For example, this kind of configuration can be used in sidecars.
Using Configuration Presets
Some MTX services come with pre-defined configuration presets, which can easily be used by referring to the preset suffixes. For example, to simplify and standardize sidecar configuration, ModelProviderService supports the in-sidecar
preset which can be used like that:
"cds": {
"requires": {
"cds.xt.ModelProviderService": "in-sidecar"
}
}
These presets are actually configured in cds.env
defaults like that:
cds: {
requires: {
// Configuration Presets (in cds.env.requires.kinds)
kinds: {
"cds.xt.ModelProviderService-in-sidecar": {
"[development]": { root: "../.." },
"[production]": { root: "_main" },
},
"cds.xt.ModelProviderService": {
model: "@sap/cds/srv/model-provider"
},
// ...
}
}
}
Inspecting Effective Configurations
You can always inspect the effective configuration by executing cds env get requires
within the mtx/sidecar folder, as shown in the logs below.
$ ./sidecar cds env get requires
{
auth: { strategy: 'dummy', kind: 'dummy' },
'cds.xt.ModelProviderService': {
root:'../..',
model:'@sap/cds/srv/model-provider',
kind:'in-sidecar'
}
}
Add CLI option --profile
to inspect configurations as in different profiles:
cds env get requires --profile development
cds env get requires --profile production
Customization
All services are defined and implemented as standard CAP services, with service definitions in CDS, and implementations based on CAP Node.js framework. That means for you, you can easily do both, adapt service definitions, as well as hook into all events to add custom logic using CAP Node.js.
Customizing Service Definitions
For example, you could override the endpoints to serve a service:
using { cds.xt.ModelProviderService } from '@sap/cds-mtxs';
annotate ModelProviderService with @path: '/mtx/mps';
For sidecar scenarios, define the annotations in the Node.js sidecar application and not as part of the main application.
Adding Custom Lifecycle Event Handlers
Register handlers in server.js
files:
const cds = require('@sap/cds')
cds.on('served', ()=>{
const { 'cds.xt.ModelProviderService': mps } = cds.services
const { 'cds.xt.DeploymentService': ds } = cds.services
ds.before ('upgrade', (req) => { ... })
ds.after ('subscribe', (_,req) => { ... })
mps.after ('getCsn', (csn) => { ... })
})
Custom hooks for CLI usage
For CLI usage via cds subscribe|upgrade|unsubscribe
you can create a mtx/sidecar/cli.js
file, which works analogously to a server.js
.
Sidecar Setups
In the minimal setup introduced in the Getting Started... chapter, we had the MTX services being served embedded with our main app, that is, in the same server as our application services. While this is possible for Node.js and even recommended to reduce complexity during development, quite frequently, we'd want to run them in a separate micro service. Reasons for that include:
- For Java-based projects — As these services are implemented in Node.js we need to run them separately and consume them remotely for Java-based apps.
- To scale independently — As some operations, especially
upgrade
, are very resource-intensive, we want to scale these services separate from our main application.
As these services are built and consumed as CAP services, we benefit from CAP's agnostic design and can easily move them to separate services.
Create Sidecar as a Node.js Subproject
An MTX sidecar is a standard, yet minimal Node.js CAP project. By default it's added to a subfolder mtx/sidecar
within your main project, containing just a package.json file.
Create a folder named
mtx/sidecar
.Add a
package.json
in there with content like that:json{ "name": "mtx-sidecar", "version": "0.0.0", "dependencies": { "@sap/cds-mtxs": "^1", "@sap/cds": "^7", "express": "^4" }, "cds": { "requires": { "cds.xt.ModelProviderService": "in-sidecar", "cds.xt.SaasProvisioningService": true, "cds.xt.DeploymentService": true, "cds.xt.ExtensibilityService": true, "[development]": { "db": { "kind": "sqlite", "credentials": { "url": "../../sqlite.db" }} } }, "[development]": { "requires": { "auth": "dummy" }, "server": { "port": 4005 } } } }
Let's dissect the content above one by one...
Package Dependencies
...
"dependencies": {
"@sap/cds": "^7",
"@sap/cds-mtxs": "^1",
"express": "^4"
},
...
This ensures we have the required software installed, in particular @sap/cds
and @sap/cds-mtxs
.
Required MTX Services
...
"cds": {
"requires": {
"cds.xt.ModelProviderService": "in-sidecar",
"cds.xt.SaasProvisioningService": true,
"cds.xt.DeploymentService": true,
"cds.xt.ExtensibilityService": true,
...
}
}
This selectively enables the services we want to be served in the sidecar using individual configuration. Here we enable all MTX services. You can choose to only serve some of which, according to your needs, of course.
TIP
Important: ModelProviderService
in sidecar always needs special configuration, as provided by the in-sidecar
preset.
Using Shared Database
...
"[development]": {
"db": { "kind": "sqlite", "credentials": {
"url": "../../db.sqlite"
}}
}
...
In case of multitenancy the DeploymentService needs to deploy the very database instances, which are subsequently used by the main application. This setting ensures that for local development with SQLite.
Additional [development]
Settings
...
"[development]": {
"requires": { "auth": "dummy" },
"server": { "port": 4005 }
}
...
These additional settings for profile [development]
are to support local tests with default values for the server port (different from the default port 4004
of the main app), and to allow any local calls to the sidecar (secured by default in production).
Using Sidecars with Node.js
As we are running the MTX services in the sidecar, we need to configure the main app to not run certain services, using some from sidecars and using shared databases.
Not Serving Services Twice
As we are running the MTX services in the sidecar we need to add configuration to the main app to overrule the default service provisioning involved with the convenience shortcuts like cds.requires.multitenancy
:
...
"cds": {
"requires": {
"multitenancy": "true",
"cds.xt.DeploymentService": false,
...
}
}
...
This setting disables both, DeploymentService as well as the SaasProvisioningService, as the latter depends on the former.
Using Services from Sidecar
TIP
In Node.js apps we usually don't consume services from the sidecar. The ModelProviderService is usually served both, embedded in the main app as well as in the sidecar. The following is documented for the sake of completeness only...
We can use the from-sidecar
preset to tell the CAP runtime to use the remote model provider from the sidecar:
"cds": {
"requires": {
"cds.xt.ModelProviderService": "from-sidecar"
}
}
Using Shared Database
In addition we have to ensure we use a shared database, which has to be a persistent one. So we override the default :memory:
for SQLite as follows:
...
"cds": {
"requires": {
...
"[development]": { "db": "sqlite" }
}
}
...
Using Sidecars with Java
Java applications need to run and maintain the MTX services in a sidecar application. How you can achieve this is described in the corresponding documentation.
Testing Sidecar Setups
With the above setup in place, we can test-drive the sidecar mode locally. To do so we'll simply start the sidecar and the main app in separate shells.
Run sidecar in first shell:
log[bookshop] cds watch mtx/sidecar cd mtx/sidecar cds serve all --with-mocks --in-memory? live reload enabled for browsers ___________________________ [cds] - loaded model from 2 file(s): ../../../srv/model-provider.cds ../../../srv/deployment-service.cds [cds] - connect using bindings from: { registry: '~/.cds-services.json' } [cds] - connect to db > sqlite { database: ':memory:' } [cds] - serving cds.xt.DeploymentService { path: '/-/cds/deployment' } [cds] - serving cds.xt.ModelProviderService { path: '/-/cds/model-provider' } [cds] - loaded model from 1 file(s): ../../../db/t0.cds [mtx] - (re-)deploying SQLite database for tenant: t0 /> successfully deployed to in-memory database. [cds] - server listening on { url: 'http://localhost:4004' } [cds] - launched at 5/6/2023, 1:08:33 AM, version: 6.8.0, in: 772.25ms [cds] - [ terminate with ^C ]
Run the main app as before in a second shell:
shcds watch
ModelProviderService serving models from main app
When we use our application, we can see model-provider/getCsn
requests in the sidecar's trace log. In response to those requests, the sidecar reads and returns the main app's models, that is, the models from two levels up the folder hierarchy as configured by the in-sidecar
preset for development.
Note: Service Bindings by cds watch
Required service bindings are done automatically by cds watch
's built-in runtime service registry. This is how it works:
Each server started using
cds watch
registers all served services in~/cds-services.json
.Every subsequently started server binds automatically all
required
remote services, to equally named services already registered in~/cds-services.json
.
In our case: The main app's ModelProviderService
automatically receives the service binding credentials, for example url
, to talk to the one served by the sidecar.
Build Sidecar for Production
When deploying a sidecar for production, it doesn't have access to the main app's models two levels up the deployed folder hierarchy. Instead we have to prepare deployment by running cds build
in the project's root:
cds build
One of the build tasks that are executed is the mtx-sidecar
build task. It generates log output similar to the following:
[cds] - the following build tasks will be executed
{"for":"mtx-sidecar", "src":"mtx/sidecar", "options":... }
[cds] - done > wrote output to:
gen/mtx/sidecar/_main/fts/isbn/csn.json
gen/mtx/sidecar/_main/fts/reviews/csn.json
gen/mtx/sidecar/_main/resources.tgz
gen/mtx/sidecar/_main/srv/_i18n/i18n.json
gen/mtx/sidecar/_main/srv/csn.json
gen/mtx/sidecar/package.json
gen/mtx/sidecar/srv/_i18n/i18n.json
gen/mtx/sidecar/srv/csn.json
[cds] - build completed in 687 ms
The outcome of that build task is a compiled and deployable version of the sidecar in the gen/mtx/sidecar staging areas, as shown in this screenshot:

In essence, the mtx-sidecar
build task does the following:
- It runs a standard Node.js build for the sidecar.
- It pre-compiles the main app's models, including all features into respective csn.json files, packaged into the
_main
subfolder. - It collects all additional sources required for subsequent deployments to
resources.tgz
. For example, these include .csv and i18n files.
Test-Drive Production Locally
We can also test-drive the production-ready variant of the sidecar locally before actual deployment, again using two separate shells.
First, start sidecar from
gen/mtx/sidecar
inprod
simulation mode:shcds watch gen/mtx/sidecar --profile development,prod
Second, start main app as usual:
shcds watch
ModelProviderService serving models from main app
When we now use our application again, and inspect the sidecar's trace logs, we see that the sidecar reads and returns the main app's precompiled models from _main
now:
[cds] – POST /-/cds/model-provider/getCsn
[cds] – model loaded from 3 file(s):
gen/mtx/sidecar/_main/srv/csn.json
gen/mtx/sidecar/_main/fts/isbn/csn.json
gen/mtx/sidecar/_main/fts/reviews/csn.json
ModelProviderService
The ModelProviderService serves model variants, which may include tenant-specific extensions and/or feature-toggled aspects.
Service Definition | @sap/cds-mtxs/srv/model-provider |
Service Definition Name | cds.xt.ModelProviderService |
Default HTTP Endpoint | /-/cds/model-provider |
Configuration
ModelProviderService is activated and configured automatically whenever one of the shortcut settings cds.requires.multitenancy
, .extensibility
, or .toggles
is activated as described in the Configuration.
In addition, it can be activated — or deactivated — selectively by the like of:
"cds": {
"requires": {
"cds.xt.ModelProviderService": true
}
}
Supported values as documented in Configuring Individual Services above
Individual Config Options
- Common Config Options
root
— a directory name, absolute or relative to the package.json's location, specifying the location to search for models and resources to be served by the model provider services. Default is undefined, for embedded usage of model provider. In case of a sidecar, it refers to the main app's model; usually"../.."
during development, and"_main"
in production.
Supported Presets
in-sidecar
— provides defaults for usage in sidecarsfrom-sidecar
— shortcut for{ "kind": "rest" }
getCsn
(tenant, toggles) → CSN
Returns the application's effective CSN document for the given tenant + feature toggles vector. CAP runtimes call that method to obtain the effective models to serve.
Arguments | Description |
---|---|
tenant | A string identifying the tenant |
toggles | An array listing toggled features; ['*'] for all features |
Example Usage
POST http://localhost:4004/-/cds/model-provider/getCsn HTTP/1.1
Content-Type: application/json
Authorization: Basic yves:
{
"tenant": "t1",
"toggles": ["*"]
}
getEdmx
(tenant, toggles, service, locale) → EDMX
Returns the EDMX document for a given service in context of the given tenant and feature toggles vector. CAP runtimes call this to get the EDMX document they return in response to OData $metadata
requests.
Arguments | Description |
---|---|
tenant | A string identifying the tenant |
toggles | An array listing toggled features; ['*'] for all features |
service | Fully-qualified name of a service definition |
locale | Requested locale, i.e. as from accept-language header |
Example Usage
POST http://localhost:4004/-/cds/model-provider/getEdmx HTTP/1.1
Content-Type: application/json
Authorization: Basic yves:
{
"tenant": "t1",
"toggles": ["*"],
"service": "CatalogService",
"locale": "en"
}
getResources
() → TAR
Returns a .tar archive containing CSV files, I18n files, as well as native database artifacts, required for deployment to databases. DeploymentService
calls that whenever it receives a subscribe
or upgrade
event.
getExtensions
(tenant) → CSN
Returns a parsed CSN document containing all the extensions stored in cds.xt.Extensions
for the given tenant.
Arguments | Description |
---|---|
tenant | A string identifying the tenant |
isExtended
(tenant) → true|false
Returns true
if the given tenant
has extensions applied.
Arguments | Description |
---|---|
tenant | A string identifying the tenant |
ExtensibilityService
The ExtensibilityService allows to add and activate tenant-specific extensions at runtime.
Learn the facts in the following table:
Service Definition | @sap/cds-mtxs/srv/extensibility-service |
Service Definition Name | cds.xt.ExtensibilityService |
Default HTTP Endpoint | /-/cds/extensibility |
See the extensibility guide for more context
Configuration
ExtensibilityService is activated and configured automatically whenever the shortcut setting cds.requires.extensibility
is activated as described in Configuration.
In addition, it can be activated — or deactivated — selectively by the like of:
"cds": {
"requires": {
"cds.xt.ExtensibilityService": true
}
}
Supported values as documented in Configuring Individual Services above
Extension Restrictions
Define which namespaces, entities, and elements are allowed or blocked in extensions. In the following example,
- All elements (fields) must start with either
x_
orxx_
. - Namespaces starting with
com.sap.
orsap.
are blocked. - There can be at most 2 new fields in entities from the
my.bookshop
namespace.Without
extension-allowlist
configured, extensions are forbidden. - In
CatalogService
(which is just a namespace), there can be at most 2 new entities.
"cds.xt.ExtensibilityService": {
"element-prefix": ["x_", "xx_"],
"namespace-blocklist": ["com.sap.", "sap."],
"extension-allowlist": [
{
"for": ["my.bookshop"],
"kind": "entity",
"new-fields": 2
},
{
"for": ["CatalogService"],
"new-entities": 2
}
]
}
Use "for": ["*"]
to allow all names. See the list of possible kind
values.
GET Extensions/<ID>
→ [{ ID, csn, timestamp }]
Returns a list of all tenant-specific extensions.
PUT Extensions/<ID>
([csn]) → [{ ID, csn, timestamp }]
Creates a new tenant-specific extension.
DELETE Extensions/<ID>
Deletes a tenant-specific extension.
DeploymentService
The DeploymentService handles subscribe
, unsubscribe
, and upgrade
events for single tenants and single apps / micro-services. Actual implementation is provided through internal plugins, for example, for SAP HANA and SQLite.
Learn the facts in the following table:
Service Definition | @sap/cds-mtxs/srv/deployment-service |
Service Definition Name | cds.xt.DeploymentService |
Default HTTP Endpoint | /-/cds/deployment |
Configuration
DeploymentService is activated and configured automatically whenever the shortcut setting cds.requires.multitenancy
is activated as described in Configuration.
In addition, it can be activated — or deactivated — selectively by the like of:
"cds": {
"requires": {
"cds.xt.DeploymentService": true
}
}
Supported values as documented in Configuring Individual Services above
Individual Config Options
"cds.xt.DeploymentService": {
"hdi": {
"deploy": {
...
},
"create": {
"database_id": "<SAP HANA Cloud instance ID>",
...
},
"bind": {
...
}
}
}
hdi
bundles HDI-specific settingsdeploy
: HDI deployment parameterscreate
: tenant creation parameters (=cf create-service
)database_id
: SAP HANA Cloud instance ID
bind
: binding parameters (=cf bind-service
)
Supported Presets
in-sidecar
— provides defaults for usage in sidecarsfrom-sidecar
— shortcut for{ "kind": "rest" }
subscribe
(tenant)
Received when a new tenant subscribes.
The implementations create and initialize required resources, that is, creating and initializing tenant-specific HDI containers in case of SAP HANA, or tenant-specific databases in case of SQLite.
upgrade
(tenant)
Used to upgrade a subscribed tenant.
Implementations read the latest models and content from the latest deployed version of the application and re-deploy that to the tenant's database.
Drop-Creating Databases for SQLite
In case of SQLite, especially in case of in-memory databases, an upgrade will simply drop and create a new tenant-specific database. Which means all data is lost.
Schema Evolution for SAP HANA
In case of SAP HANA, the delta to the former database layout will be determined, and corresponding CREATE TABLE, DROP-CREATE VIEW, and ALTER TABLE statements will eventually be executed without any data loss.
unsubscribe
(tenant)
Received when a tenant is deleted.
The implementations free required resources, that is, dispose tenant-specific HDI containers in case of SAP HANA, or tenant-specific databases in case of SQLite.
SaasProvisioningService
The SaasProvisioningService is a facade for the DeploymentService to adapt to the API expected by SAP BTP's SaaS Provisioning service, hence providing out-of-the-box integration.
Learn the facts in the following table:
Service Definition | @sap/cds-mtxs/srv/cf/saas-provisioning-service |
Service Definition Name | cds.xt.SaasProvisioningService |
Default HTTP Endpoint | /-/cds/saas-provisioning |
Configuration
SaasProvisioningService is activated and configured automatically whenever the shortcut setting cds.requires.multitenancy
is activated as described in Configuration.
In addition, it can be activated — or deactivated — selectively by the like of:
"cds": {
"requires": {
"cds.xt.SaasProvisioningService": true
}
}
Supported values as documented in Configuring Individual Services.
Individual Config Options
"cds.xt.SaasProvisioningService": {
"jobs": {
"workerSize": 5, // default: 1
"clusterSize": 5, // default: 1
},
"dependencies": ["xsappname-1", "xsappname-2"]
}
jobs
lets you specify settings of the built-in job orchestratorworkerSize
is the maximum number of parallel asynchronous jobs for one databaseclusterSize
is the maximum number of database clusters, runningworkerSize
jobs each
dependencies
lets you specify SAP BTP SaaS Provisioning service dependencies
HTTP Request Options
Request Header | Example Value | Description |
---|---|---|
prefer | respond-async | Trigger subscription, upgrade or unsubscription request asynchronously. |
status_callback | /saas-manager/v1/subscription-callback/123456/result | Callback path for SAP BTP SaaS Provisioning service. Set automatically if asynchronous subscription is configured for saas-registry service. |
No prefer: respond-async
needed with callback
Requests are implicitly asynchronous when status_callback
is set.
Sample Requests
With @sap/hdi-deploy
parameters trace
and auto_undeploy
:
POST http://localhost:4004/-/cds/saas-provisioning/upgrade HTTP/1.1
Content-Type: application/json
Authorization: Basic yves:
{
"tenants": ["t1"],
"options": {
"_": {
"hdi": {
"deploy": {
"trace": "true",
"auto_undeploy": "true"
}
}
}
}
}
GET tenant/<tenant>
Returns tenant-specific metadata if <tenant>
is set, and a list of all tenants' metadata if omitted.
Query Parameters | Description |
---|---|
tenant | A string identifying the tenant. |
Example Usage
Specific Tenant
GET http://localhost:4004/-/cds/saas-provisioning/tenant/t1 HTTP/1.1
Content-Type: application/json
Authorization: Basic yves:
All Tenants
GET http://localhost:4004/-/cds/saas-provisioning/tenant HTTP/1.1
Content-Type: application/json
Authorization: Basic yves:
Response Body
If onboarded via the SAP SaaS Provisioning service, the response body typically looks like this, corresponding to the information sent by the SaaS registry:
{
"subscribedTenantId": "tenant-1",
"eventType": "CREATE",
"subscribedSubdomain": "subdomain-1",
"subscriptionAppName": "app-1",
"subscribedSubaccountId": "subaccount-1"
}
PUT tenant/<tenant>
(...)
Creates tenant resources required for onboarding.
Learn about query parameters, arguments, and their description in the following table:
Query Parameters | |
---|---|
tenant | A string identifying the tenant |
Arguments | |
subscribedTenantId | A string identifying the tenant |
subscribedSubdomain | A string identifying the tenant-specific subdomain |
eventType | The saas-registry event (CREATE or UPDATE ) |
Example Usage
PUT http://localhost:4004/-/cds/saas-provisioning/tenant/t1 HTTP/1.1
Content-Type: application/json
Authorization: Basic yves:
{
"subscribedTenantId": "t1",
"subscribedSubdomain": "subdomain1",
"eventType": "CREATE"
}
DELETE tenant/<tenant>
Deletes all tenant resources.
GET dependencies
→ [{ xsappname }]
Lets you specify SAP BTP SaaS Provisioning service dependencies. If they are static, they can also be defined in the service configuration.
upgrade
[tenants] → Jobs
Use the upgrade
endpoint to upgrade tenant base models.
Arguments | Description |
---|---|
tenants | A list of tenants, or [*] for all tenants |
Example Usage
Upgrade a List of Tenants
POST http://localhost:4004/-/cds/saas-provisioning/upgrade HTTP/1.1
Content-Type: application/json
Authorization: Basic yves:
prefer: respond-async
{
"tenants": ["t1", "t2"]
}
Upgrade All Tenants
POST http://localhost:4004/-/cds/saas-provisioning/upgrade HTTP/1.1
Content-Type: application/json
Authorization: Basic yves:
prefer: respond-async
{
"tenants": ["*"]
}
We recommended to execute the upgrades asynchronously by setting the prefer: respond-async
header. You can use the URL returned in the location
response header to poll the job status.
In addition, the response returns a body in this format:
{
"ID": "<jobID>",
"createdAt": "2022-12-12T13:07:15.817Z",
"op": "upgrade",
"tenants": {
"t1": {
"ID": "<taskID>"
}
}
}
You can poll the status for individual tenants using its individual task ID:
GET /-/cds/jobs/pollTask(ID='<taskID>') HTTP/1.1
The response is similar to the following:
{
"status": "FINISHED",
"op": "upgrade"
}
The job and task status can take on the values RUNNING
, FINISHED
and FAILED
.