From 6906e6814236b4389d6dd07606f065f7255902dc Mon Sep 17 00:00:00 2001 From: Vladislav Leonkev Date: Fri, 25 Apr 2025 17:33:53 +0200 Subject: [PATCH] add multitenancy --- .deploy/app-router/xs-app.json | 5 +++ bookstore/package.json | 8 +++- db | 1 + mta.yaml | 79 ++++++++++++++++++++++++++++------ mtx/sidecar/package.json | 19 ++++++++ orders/package.json | 7 ++- package.json | 14 +++++- reviews/package.json | 7 ++- xs-security.json | 7 +++ 9 files changed, 126 insertions(+), 21 deletions(-) create mode 120000 db create mode 100644 mtx/sidecar/package.json diff --git a/.deploy/app-router/xs-app.json b/.deploy/app-router/xs-app.json index c578d52c..23663367 100644 --- a/.deploy/app-router/xs-app.json +++ b/.deploy/app-router/xs-app.json @@ -1,6 +1,11 @@ { "welcomeFile": "app/bookshop/index.html", "routes": [ + { + "source": "^/-/cds/.*", + "destination": "mtx-api", + "authenticationType": "none" + }, { "source": "^/app/(.*)$", "target": "$1", diff --git a/bookstore/package.json b/bookstore/package.json index cb637dd6..d6ba3268 100644 --- a/bookstore/package.json +++ b/bookstore/package.json @@ -11,7 +11,8 @@ "@sap-cloud-sdk/resilience": "^4", "@sap/cds": ">=5", "express": "^4.17.1", - "@cap-js/hana": "^1" + "@cap-js/hana": "^1", + "@sap/cds-mtxs": "^2" }, "cds": { "requires": { @@ -24,7 +25,10 @@ "model": "@capire/orders" }, "messaging": true, - "db": true + "db": true, + "multitenancy": true, + "auth": "xsuaa" + }, "log": { "service": true } }, diff --git a/db b/db new file mode 120000 index 00000000..12e1c82f --- /dev/null +++ b/db @@ -0,0 +1 @@ +shared-db/db \ No newline at end of file diff --git a/mta.yaml b/mta.yaml index 8e406b2f..b6cfcb44 100644 --- a/mta.yaml +++ b/mta.yaml @@ -9,7 +9,7 @@ build-parameters: - builder: custom commands: - npm ci - - npx cds build shared-db --for hana --production + - npx cds build --production - npx cds build orders --for nodejs --production --ws-pack - npx cds build reviews --for nodejs --production - npx cds build bookstore --for nodejs --production --ws-pack @@ -78,14 +78,6 @@ modules: - name: samples-auth - name: samples-destination - - name: samples-db-deployer - type: hdb - path: shared-db/gen/db - parameters: - buildpack: nodejs_buildpack - requires: - - name: samples-db - - name: samples type: approuter.nodejs path: .deploy/app-router @@ -93,6 +85,8 @@ modules: keep-existing-routes: true disk-quota: 256M memory: 256M + properties: + TENANT_HOST_PATTERN: "^(.*)-${default-uri}" requires: - name: orders-api group: destinations @@ -112,7 +106,17 @@ modules: name: bookstore-api # must be used in xs-app.json as well url: ~{srv-url} forwardAuthToken: true + - name: mtx-api + group: destinations + properties: + name: mtx-api # must be used in xs-app.json as well + url: ~{mtx-url} - name: samples-auth + provides: + - name: app-api + properties: + app-protocol: ${protocol} + app-uri: ${default-uri} - name: destination-content type: com.sap.application.content @@ -145,6 +149,27 @@ modules: TokenServiceInstanceName: samples-auth TokenServiceKeyName: xsuaa-service-key + - name: samples-mtx + type: nodejs + path: gen/mtx/sidecar + build-parameters: + builder: npm + parameters: + instances: 1 + memory: 256M + disk-quota: 512M + provides: + - name: mtx-api + properties: + mtx-url: ${default-url} + requires: + - name: samples-db + - name: samples-registry + - name: samples-auth + - name: app-api + properties: + SUBSCRIPTION_URL: ~{app-protocol}://\${tenant_subdomain}-~{app-uri} + resources: - name: samples-messaging type: org.cloudfoundry.managed-service @@ -156,23 +181,51 @@ resources: emname: bookstore-${org}-${space} namespace: cap/samples/${space} - name: samples-db - type: com.sap.xs.hdi-container + type: org.cloudfoundry.managed-service parameters: - service: hana - service-plan: hdi-shared + service: service-manager + service-plan: container + - name: samples-auth type: org.cloudfoundry.managed-service processed-after: - samples-messaging + requires: + - name: app-api parameters: service: xsuaa service-plan: application path: ./xs-security.json config: xsappname: samples-${org}-${space} - tenant-mode: dedicated + tenant-mode: shared + oauth2-configuration: + redirect-uris: + - https://*-~{app-api/app-uri}/** + - name: samples-destination type: org.cloudfoundry.managed-service parameters: service: destination service-plan: lite + + - name: samples-registry + type: org.cloudfoundry.managed-service + requires: + - name: mtx-api + parameters: + service: saas-registry + service-plan: application + config: + xsappname: samples-${org}-${space} + appName: samples-${org}-${space} + displayName: samples-shared-db + description: CAP Samples with shared-db and multitenancy + category: 'Samples shared-db' + appUrls: + getDependencies: ~{mtx-api/mtx-url}/-/cds/saas-provisioning/dependencies + onSubscription: ~{mtx-api/mtx-url}/-/cds/saas-provisioning/tenant/{tenantId} + onSubscriptionAsync: true + onUnSubscriptionAsync: true + onUpdateDependenciesAsync: true + callbackTimeoutMillis: 300000 # Increase if your deployments are taking longer than that diff --git a/mtx/sidecar/package.json b/mtx/sidecar/package.json new file mode 100644 index 00000000..2c7d0539 --- /dev/null +++ b/mtx/sidecar/package.json @@ -0,0 +1,19 @@ +{ + "name": "samples-mtx", + "dependencies": { + "@cap-js/hana": "^1", + "@sap/cds": "^8", + "@sap/cds-mtxs": "^2", + "@sap/xssec": "^4", + "express": "^4" + }, + "devDependencies": { + "@cap-js/sqlite": "^1" + }, + "scripts": { + "start": "cds-serve" + }, + "cds": { + "profile": "mtx-sidecar" + } +} diff --git a/orders/package.json b/orders/package.json index 2c895c13..fbf0c800 100644 --- a/orders/package.json +++ b/orders/package.json @@ -5,12 +5,15 @@ "@cap-js/hana": "^1", "@capire/common": "*", "@sap/cds": ">=5", - "@sap/xssec": "^4" + "@sap/xssec": "^4", + "@sap/cds-mtxs": "^2" }, "cds": { "requires": { "messaging": true, - "db": true + "db": true, + "multitenancy": true, + "auth": "xsuaa" } }, "scripts": { diff --git a/package.json b/package.json index 70995a09..2d6c94bd 100644 --- a/package.json +++ b/package.json @@ -33,5 +33,15 @@ "timeout": 6666 }, "license": "SEE LICENSE IN LICENSE", - "private": true -} \ No newline at end of file + "private": true, + "dependencies": { + "@sap/cds-mtxs": "^2" + }, + "cds": { + "profile": "with-mtx-sidecar", + "requires": { + "multitenancy": true, + "auth": "xsuaa" + } + } +} diff --git a/reviews/package.json b/reviews/package.json index 27845197..0f91a592 100644 --- a/reviews/package.json +++ b/reviews/package.json @@ -10,12 +10,15 @@ "@cap-js/hana": "^1", "@sap/cds": ">=5", "@sap/xssec": "^4.2.7", - "express": "^4.17.1" + "express": "^4.17.1", + "@sap/cds-mtxs": "^2" }, "cds": { "requires": { "messaging": true, - "db": true + "db": true, + "multitenancy": true, + "auth": "xsuaa" } }, "scripts": { diff --git a/xs-security.json b/xs-security.json index c7a1025d..b30299e7 100644 --- a/xs-security.json +++ b/xs-security.json @@ -14,6 +14,13 @@ { "name": "$XSAPPNAME.emmanagement", "description": "Enterprise-Messaging Management Access" + }, + { + "name": "$XSAPPNAME.mtcallback", + "description": "Subscription via SaaS Registry", + "grant-as-authority-to-apps": [ + "$XSAPPNAME(application,sap-provisioning,tenant-onboarding)" + ] } ], "attributes": [],