In this blog post, we will guide you through the process of creating a multitenant SaaS application with a shared database architecture, combining CAP Java and Node.js projects into a mono repository.
1. Initialize the main project:
cds init onboarding
rm -rf app srv
2. Initialize sub-module projects within the main project:
cds init node_project
cds init java_project --java
3. Set up the workspace:
npm init -w ./node_project -w ./java_project
Step 2: Configure Multitenancy and HANA:
1. add multitenancy & hana
2. inside onboarding/mtx/sidecar/package.json, add build command in scripts.
"scripts": {
"start": "cds-serve",
"build": "cds build ../.. --for mtx-sidecar --ws --production && npm ci --prefix gen"
}
3. Create a .cdsrc.json file at the root of the onboarding project:
"build": {
"target": "."
}
}
4.inside node_project/mtx/sidecar/package.json and java_project/mtx/sidecar/package.json, disable cds.xt.SaasProvisioningService:
"cds": {
"requires": {
"multitenancy": true,
"extensibility": false,
"toggles": false,
"cds.xt.SaasProvisioningService": false,
"db": {
"kind": "hana-mt",
"deploy-format": "hdbtable"
}
}
5. Change the port of java_project/mtx/sidecar for local testing, e.g. 4006. Also change it in application.yaml.
"server": {
"port": 4006
}cds:
multi-tenancy:
sidecar:
url: http://localhost:4006/
6. Execute the build command in onboarding/mtx/sidecar. This will compose all DB artifacts from each workspace into the obboarding/db folder:
npm run build
Step 3: Deploy Database Artifacts
You can deploy the whole db artifacts with/without multitenancy.
1. For single tenant deployment:
cds build --ws --production
cds deploy --to hana:${hdi-name} --no-build
2. For multi-tenant deployment:
cds watch mtx/sidecar
cds subscribe ${tenant_id} --to http://localhost:4005 -u name:password
Step 4: Start the Projects
1. Start java_project and java_project-mtx:
# run java mtx first
cd java_project/mtx/sidecar
npm run build
cds watch
# run java second
cd java_project
mvn spring-boot:run -Dspring-boot.run.profiles=default
2. Start node_project and (using onboarding-mtx or start node_project-mtx):
# start node_project-mtx(optional)
cd node_project
cds build --production
cds watch mtx/sidecar
# start node_project
cd node_project
cds watch
Step 5: Local Testing
You can now test both the Node.js and Java applications locally.
Step 6: Add MTA Configuration and Deploy to BTP
1.Add the build:cf command to the package.json file of each workspace:
"build:cf": "cds build --production"
2. Create an mta.yaml file with the following content:
ID: com.sap.onboarding-mtxs
_schema-version: 3.3.0
version: 0.0.1
description: "Onboarding Service"
build-parameters:
before-all:
- builder: custom
commands:
- npm ci
- npm run build:cf --workspace=node_project
- npm run build:cf --workspace=java_project
modules:
- name: node-mtxs-srv
type: nodejs
path: node_project/gen/srv
parameters:
buildpack: nodejs_buildpack
readiness-health-check-type: http
readiness-health-check-http-endpoint: /health
properties:
DEBUG: all
build-parameters:
builder: npm
provides:
- name: srv_api # required by consumers of CAP services (e.g. approuter)
properties:
url: ${default-url}
requires:
- name: onboarding-mtxs-service-manager
- name: node-model-provider
properties:
CDS_MODEL_PROVIDER_URL: ~{url}
CDS_MULTITENANCY_SIDECAR_URL: ~{url}
- name: provisioning-service
properties:
CDS_MULTITENANCY_PROVISIONING_URL: ~{url}
CDS_MULTITENANCY_PROVISIONING_POLLINGINTERVAL: 5s
CDS_MULTITENANCY_PROVISIONING_POLLINGTIMEOUT: 5m
- name: onboarding-mtxs-uaa
- name: onboarding-mtxs-saas-registry
- name: java-mtxs-srv
type: java
path: java_project/srv
parameters:
memory: 1024M
disk-quota: 1024M
buildpack: sap_java_buildpack
properties:
DEBUG: all
JBP_CONFIG_COMPONENTS: "jres: ['com.sap.xs.java.buildpack.jdk.SAPMachineJDK']"
JBP_CONFIG_SAP_MACHINE_JDK: '{ use_offline_repository: false, version: 21.+ }'
JBP_CONFIG_JAVA_OPTS: "[java_opts: '-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n,onjcmd=y']"
SPRING_PROFILES_ACTIVE: cloud
CDS_MULTITENANCY_MTXS_ENABLED: true
build-parameters:
ignore: [ "*.md" ]
build-result: target/*.jar
provides:
- name: srv_java_api
properties:
url: '${default-url}'
requires:
- name: onboarding-mtxs-service-manager
- name: java-model-provider
properties:
CDS_MODEL_PROVIDER_URL: ~{url}
# CDS_MULTITENANCY_SIDECAR_URL: ~{url}
- name: provisioning-service
properties:
CDS_MULTITENANCY_PROVISIONING_URL: ~{url}
CDS_MULTITENANCY_PROVISIONING_POLLINGINTERVAL: 5s
CDS_MULTITENANCY_PROVISIONING_POLLINGTIMEOUT: 5m
- name: onboarding-mtxs-uaa
- name: onboarding-mtxs-mtx
type: nodejs
path: mtx/sidecar
parameters:
memory: 512M
disk-quota: 512M
build-parameters:
builder: custom
build-result: gen
commands:
- npm run build
properties:
DEBUG: all
requires:
- name: onboarding-mtxs-uaa
- name: onboarding-mtxs-service-manager
- name: onboarding-mtxs-saas-registry
provides:
- name: provisioning-service
properties:
url: ${default-url}
- name: onboarding-mtxs-node-model-provider
type: nodejs
path: node_project/gen/mtx/sidecar
parameters:
memory: 512M
disk-quota: 512M
build-parameters:
builder: npm-ci
# builder: custom
# build-result: gen
# commands:
# - npm run build
properties:
DEBUG: all
requires:
- name: onboarding-mtxs-uaa
- name: onboarding-mtxs-service-manager
provides:
- name: node-model-provider
properties:
url: ${default-url}
- name: onboarding-mtxs-java-model-provider
type: nodejs
path: java_project/mtx/sidecar
parameters:
memory: 512M
disk-quota: 512M
build-parameters:
builder: custom
build-result: gen
commands:
- npm run build
properties:
DEBUG: all
requires:
- name: onboarding-mtxs-uaa
- name: onboarding-mtxs-service-manager
provides:
- name: java-model-provider
properties:
url: ${default-url}
resources:
- name: onboarding-mtxs-service-manager
type: org.cloudfoundry.managed-service
parameters:
service: service-manager
service-plan: container
- name: onboarding-mtxs-uaa
type: org.cloudfoundry.managed-service
parameters:
service: xsuaa
service-plan: broker
config:
xsappname: onboarding-mtxs-${org}-${space}
tenant-mode: shared
scopes:
- name: $XSAPPNAME.mtcallback
description: Multi Tenancy Callback Access
grant-as-authority-to-apps:
- $XSAPPNAME(application,sap-provisioning,tenant-onboarding)
- name: $XSAPPNAME.mtdeployment
- name: $XSAPPNAME.ExtendCDS
description: Extend tenant models
- name: $XSAPPNAME.ExtendCDSdelete
description: Undeploy extensions
authorities:
- $XSAPPNAME.mtcallback
- $XSAPPNAME.mtdeployment
role-templates:
- name: admin
description: Admin
scope-references:
- $XSAPPNAME.mtcallback
- $XSAPPNAME.mtdeployment
- name: ExtensionDeveloper
scope-references:
- $XSAPPNAME.ExtendCDS
- uaa.user
description: CDS Extension Developer
- name: ExtensionDeveloperUndeploy
scope-references:
- $XSAPPNAME.ExtendCDSdelete
- $XSAPPNAME.ExtendCDS
- uaa.user
description: CDS Extension Developer with DB extension undeploy privilege (potential data loss!) -
# generate a user and password for dynamic hdi deployer
- name: onboarding-mtxs-saas-registry
type: org.cloudfoundry.managed-service
parameters:
service: saas-registry
service-plan: application
config:
appName: onboarding-mtxs-${org}-${space} # this is the text on the tile
xsappname: onboarding-mtxs-${org}-${space} # this is exactly the value from xsuaa.parameters.config.xsappname
appUrls:
# getDependencies: ~{srv_api/url}/mt/v1.0/subscriptions/dependencies
# onSubscription: ~{srv_api/url}/mt/v1.0/subscriptions/tenants/{tenantId}
getDependencies: ~{provisioning-service/url}/-/cds/saas-provisioning/dependencies
onSubscription: ~{provisioning-service/url}/-/cds/saas-provisioning/tenant/{tenantId}
onSubscriptionAsync: true
onUnSubscriptionAsync: true
onUpdateSubscriptionParametersAsync: true
callbackTimeoutMillis: 300000
requires:
- name: provisioning-service
3. mbt build & cf deploy app.
4. Subscribe to this SaaS application in the Service Marketplace on BTP.
By following these steps, you should be able to successfully create and deploy a multitenant SaaS application with a mixed CAP Java/Node.js mono repository and a shared database architecture. If you encounter any issues or have any questions, please leave a comment below. I hope you find this guide helpful!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
| User | Count |
|---|---|
| 47 | |
| 22 | |
| 18 | |
| 16 | |
| 15 | |
| 14 | |
| 13 | |
| 13 | |
| 13 | |
| 13 |