Migration from Old MTX
Towards new multitenancy capabilities
Explains how to migrate from @sap/cds-mtx
(aka Old MTX) to @sap/cds-mtxs
(‘streamlined’ MTX)
This guide is still work in progress and will be updated.
Content
Functional Differences
Before you start to migrate towards the ‘streamlined’ MTX, read about the differences compared to the old MTX.
Extensibility
For ‘streamlined’ MTX, we have no support for the following:
- async extensibility (push) [temporary limitation]
- undeploy [temporary limitation]
- hdbmigrationtable for extensibility
- setup of extension projects via
cds extend
- custom content
Multitenancy
For ‘streamlined’ MTX, we have no support for the following:
- diagnose API [temporary limitation]
- configurable scopes
- tenant-individual basemodel version stored
Pitfalls
served
event is not emitted if you use your own bootstrap inserver.js
w/o delegating tocds.server
- When filtering all services to get your own application services, you will catch the
cds.xt.ModelProviderService
as well.
Adapt Project Configuration
To switch your project to ‘streamlined’ MTX, perform the following steps:
- Remove
@sap/cds-mtx
:npm remove @sap/cds-mtx
- Add
@sap/cds-mtxs
:npm add @sap/cds-mtxs
- Open your package.json and add the following:
"cds": { "requires": { "multitenancy": true, "extensibility": true // if needed }
Build Configuration
cds build
will create the correct cloud deployment contents if your project matches the default layout as proposed for CAP projects and created by cds init
.
Note: Additional changes might be required if custom build tasks are configured. So, check if defaults would fit and if a custom build configuration is really needed. cds build
logs the effective build configuration to the console. The default values will kick in for all build task properties that have not been configured.
Configuration for Custom Build Tasks
In case you need custom build tasks, make sure the CDS models for multitenancy, extensibility and toggles are defined as options.model
in your build configuration. They represent the CDS model description of the required MTX Services. Otherwise, database artifacts will be missing or required services couldn’t be loaded in the cloud environment.
"cds": {"build": {"tasks": [
{"for": "nodejs", "options": {"model":[...,"@sap/cds-mtxs/srv/bootstrap","@sap/cds-mtxs/db/extensions"]}}
]}}
MTX Service | Required CDS Model |
---|---|
requires.multitenancy: true |
"@sap/cds-mtxs/srv/bootstrap" |
requires.extensibility: true |
"@sap/cds-mtxs/srv/bootstrap","@sap/cds-mtxs/db/extensions" |
requires.toggles: true |
"@sap/cds-mtxs/srv/bootstrap" |
Handler Registration
A typical handler registration in server.js
now looks like
cds.on('served', async () => {
const { 'cds.xt.SaasProvisioningService': provisioning } = cds.services
const { 'cds.xt.DeploymentService': deployment } = cds.services
await provisioning.prepend(() => {
provisioning.on('UPDATE', 'tenant', async (req, next) => { ... })
provisioning.on('dependencies', async (req, next) => { ... })
...
})
await deployment.prepend(() => {
// previously this was `upgradeTenant`
deployment.on('upgrade', async (req) => {
// HDI container credentials are not yet available here
})
// previously this was `deployToDb`
deployment.on('deploy', async (req) => {
const { tenant, options: { container } } = req.data
...
})
...
})
})
Here’s what has changed:
ProvisioningService
changed tocds.xt.SaasProvisioningService
DeploymentService
changed tocds.xt.DeploymentService
- Use
cds.on('served')
instead ofcds.on('mtx')
.
Saas Registry Endpoints
For Node.js, the saas-registry
endpoints in mta.yaml
need to be changed to .../-/cds/saas-provisioning/...
:
parameters:
service: saas-registry
config:
appUrls:
getDependencies: ~{mtx-api/mtx-url}/-/cds/saas-provisioning/dependencies
onSubscription: ~{mtx-api/mtx-url}/-/cds/saas-provisioning/tenant/{tenantId}
Java-based projects do not need to modify their saas-registry
configuration.
Extensibility
Scopes ExtendCDS
and ExtendCDSdelete
have changed to cds.ExtensionDeveloper
.
- Communicate to customer admins and extension developers to add the new scope to their role collection.
- Adjust the documentation for the SaaS application accordingly.
Use Local Sandbox
- Run locally (w/ sqlite)
- Try build for SAP HANA deployment w/
cds build
- Call MTX endpoints locally
Migrate Tenant Content of Existing Applications
Depending on the MTX features that your existing application has used, you need to execute some steps to move your data to the persistence used by @sap/cds-mtxs
.
Configuration Changes Only
In case you only used the multitenancy features such as subscription/unsubscription, you just need to make the configuration changes described earlier.
When does this scenario apply?
- Your application doesn’t support extensibility.
- You don’t need to read all tenant IDs or the tenant metadata using
GET /-/cds/saas-provisioning/tenant/
orGET /-/cds/saas-provisioning/tenant/<tenantId>
.
The tenant metadata is the data that is sent to the MTX API by the SAP BTP SaaS Provisioning Service on subscription, similar to this:
{
"subscriptionAppId": "...",
"subscriptionAppName": "..." ,
"subscribedTenantId": "...",
...
}
Migration of tenant Metadata
If your application needs access to the tenant list or tenant metadata, you need to update this data for @sap/cds-mtxs
.
When does this scenario apply?
- Your application doesn’t support extensibility.
- Your application needs to read all tenant IDs or the tenant metadata using
GET /-/cds/saas-provisioning/tenant/
orGET /-/cds/saas-provisioning/tenant/<tenantId>
.
Run the Migration Script
The migration script is part of @sap/cds-mtxs
. You can call it locally or during application deployment. Before running the script, you need to make the configuration changes mentioned earlier.
Run it in the application environment so that it can launch the @sap/cds-mtxs
services such as cds.xt.DeploymentService
.
It also needs access to the application bindings. That means, when running locally, it has to run in hybrid mode.
To run the migration for all or a set of tenants, you need to run:
cds migrate <tenant>[,<tenant>]|"*"
The option --dry
allows you to perform a dry run, database won’t be changed.
Please keep in mind that, depending on the number of tenants, the script requires some time to run. This is important when you consider to run it in combination with the application deployment.
Migration of Extensions
If your application supports extensibility, you’ll also need to update the existing extensions for @sap/cds-mtxs
. You can do this with the same migration script mentioned earlier.
In addition, you can use the migration script to save the content of the subscribers’ extension projects.
Using parameter -d
, you can specify a directory that is used by the script to store the existing, migrated extension projects.
cds migrate <tenant>[,<tenant>]|"*" -d <your directory>
Separate Extensions Based on Extension File Names
The concept of extensions has slightly changed with @sap/cds-mtxs
. Extensions sources are no longer stored in the backend. Instead, each extension gets a tag and the extension is stored as csn
with the tag as key.
When running the migration script, all extension files are compiled to one csn
and are stored with a default tag: migrated
.
You can change the default tag by passing your own tag using the --tag
parameter:
cds migrate "*" -d migration_projects --tag "mytag"
In addition, you can separate your extensions into several csn
-files with different tags. For example, if your original extension files follow a pattern, you can do so by passing parameter --tagRule
with a regular expression.
Let’s use the following extension project structure:
You can split your extensions as follows:
cds migrate "*" -d migration_projects --tagRule "(?:ext_|extension_)(.*)\.cds"
As a result, you get two extensions with tags id_1
and id_2
. The tag is taken from the first captured group of the regular expression.
Best Practice:
It’s not always easy to find the right regular expression.
To verify if the result meets your expectations, you can make a dry-run:
cds migrate "*" -d migration_projects --tagRule "(?:ext_|extension_)(.*)\.cds" --dry
You can find the result in the folder migrated_projects.