@sap/cds-mtxs
Advanced tools
Comparing version 1.13.0 to 1.13.1
@@ -9,2 +9,13 @@ # Change Log | ||
## Version 1.13.1 - 2023-11-27 | ||
### Added | ||
- `DEBUG=mtx` will now log all outgoing requests to Service Manager. | ||
- For `multitenancy.jobs.clusterSize > 1` the Service Manager request will throw an error for a corrupt tenant without credentials. | ||
### Changed | ||
- For non-extensibility projects, a shared deployment folder is used across tenants for resource extraction. For `n` simultaneous tenant upgrades, this decreases the number of extracted files `n`-fold. | ||
## Version 1.13.0 - 2023-11-13 | ||
@@ -11,0 +22,0 @@ |
{ | ||
"name": "@sap/cds-mtxs", | ||
"version": "1.13.0", | ||
"version": "1.13.1", | ||
"description": "SAP Cloud Application Programming Model - Multitenancy library", | ||
@@ -5,0 +5,0 @@ "homepage": "https://cap.cloud.sap/", |
@@ -11,2 +11,3 @@ const cds = require('@sap/cds/lib') | ||
const { t0 = 't0' } = cds.env.requires.multitenancy | ||
const isExtensible = !!cds.requires.extensibility || !!cds.requires['cds.xt.ExtensibilityService'] | ||
@@ -32,5 +33,7 @@ module.exports = class SaasProvisioningService extends cds.ApplicationService { | ||
const hana = require('../plugins/hana/srv-mgr') | ||
tenantToDbUrl = (await hana.getAll(tenants)).reduce((res, t) => | ||
({ ...res, [t.labels.tenant_id[0]]: `${t.credentials.host}:${t.credentials.port}` }) | ||
, {}) | ||
tenantToDbUrl = (await hana.getAll(tenants)).reduce((res, t) => { | ||
const id = t.labels.tenant_id[0] | ||
if (!t.credentials) throw new Error('Credentials for tenant ' + id + ' are not available.') | ||
return { ...res, [id]: `${t.credentials.host}:${t.credentials.port}` } | ||
}, {}) | ||
} else { | ||
@@ -119,6 +122,13 @@ tenantToDbUrl = tenants.reduce((res, t) => ({ ...res, [t]: cds.db.url4(t) }), {}) | ||
async upgrade(tenantsIds, options) { | ||
if (!tenantsIds?.length) return | ||
const tenantList = tenantsIds.includes('*') ? undefined : tenantsIds | ||
const tenants = tenantList ?? await this._getTenants() | ||
async upgrade(tenantIds, options = {}) { | ||
if (!tenantIds?.length) return | ||
const all = tenantIds.includes('*') | ||
const sharedGenDir = (all || tenantIds.length > 1) && !isExtensible | ||
if (sharedGenDir) options.skipResources ??= sharedGenDir | ||
const tenants = all ? await this._getTenants() : tenantIds | ||
if (sharedGenDir && cds.requires.db.kind === 'hana') { // REVISIT: Ideally part of HANA plugin | ||
const { resources4, csvs4 } = require('../plugins/hana') | ||
await resources4() | ||
await csvs4() | ||
} | ||
const { isSync } = parseHeaders(cds.context.http?.req.headers) | ||
@@ -125,0 +135,0 @@ const { |
@@ -14,4 +14,2 @@ const cds = require ('@sap/cds/lib') | ||
plugins.push(path.join(dir,'common.js')) | ||
const loaded = plugins.map(each => ({ file:each, module:require(each) })) | ||
@@ -18,0 +16,0 @@ |
@@ -34,3 +34,3 @@ const cds = require('@sap/cds/lib'), {db} = cds.env.requires | ||
try { existingContainer = await hana.get(t, { disableCache: true }) } catch (e) { | ||
if (e.status === 404) return _deploy(req, hana.create(t, _imCreateParams(t, params, metadata)), true) | ||
if (e.status === 404) return _deploy(req, hana.create(t, _imCreateParams(t, params, metadata)), { skipExt: true }) | ||
else throw e | ||
@@ -42,4 +42,4 @@ } | ||
ds.on (['upgrade', 'extend'], req => { | ||
const { tenant:t } = req.data | ||
return _deploy(req, hana.get(t)) | ||
const { tenant:t, options } = req.data | ||
return _deploy(req, hana.get(t), options) | ||
}) | ||
@@ -136,3 +136,3 @@ ds.on ('deploy', async req => { | ||
const { 'cds.xt.ModelProviderService': mp } = cds.services | ||
const out = await fs.mkdirp ('gen',tenant) | ||
const out = await fs.mkdirp ('gen',tenant ?? 'base') | ||
try { | ||
@@ -153,5 +153,6 @@ const rscs = await mp.getResources(true) | ||
} | ||
module.exports.resources4 = resources4 // required in SPS to prepare shared deployment directory | ||
function _buildGenDir(tenant) { | ||
return path.join('gen',tenant,'src','gen') | ||
function _genDir4(tenant) { | ||
return path.join('gen',tenant ?? 'base','src','gen') | ||
} | ||
@@ -162,3 +163,3 @@ | ||
if (!csvs) return | ||
const out = await fs.mkdirp (_buildGenDir(tenant),'data'), gen = [] | ||
const out = await fs.mkdirp (_genDir4(tenant),'data'), gen = [] | ||
for (const [filename,csv] of Object.entries(csvs)) { | ||
@@ -171,2 +172,3 @@ // store files in src/gen/data | ||
} | ||
module.exports.csvs4 = csvs4 // required in SPS to prepare shared deployment directory | ||
@@ -189,3 +191,3 @@ async function _readExtCsvs(tenant) { | ||
async function build (csn, tenant, updateCsvs) { | ||
const out = await fs.mkdirp(_buildGenDir(tenant)), gen = [] | ||
const out = await fs.mkdirp(_genDir4(tenant)), gen = [] | ||
const options = { messages: [], sql_mapping: cds.env.sql.names } | ||
@@ -214,3 +216,3 @@ const { definitions: hanaArtifacts } = cds.compiler.to.hdi.migration(csn, options); | ||
const toHdbtabledata = cds.compile.to.hdbtabledata ?? require(path.join(cds.home, 'bin/build/provider/hana/2tabledata')) // cds@6 compatibility | ||
const tdata = await toHdbtabledata(csn, { dirs: [path.join('gen', tenant, 'src', 'gen', 'data')] }) | ||
const tdata = await toHdbtabledata(csn, { dirs: [path.join(_genDir4(tenant), 'data')] }) | ||
@@ -225,3 +227,3 @@ for (const [data, { file, csvFolder }] of tdata) { | ||
async function _deploy (req, _container, skipExt = false) { | ||
async function _deploy (req, _container, { skipExt = false, skipResources = false } = {}) { | ||
const { tenant, options: { _: params = {}, csn: csnFromParameter } = {} } = req.data | ||
@@ -234,3 +236,3 @@ | ||
const out = await fs.mkdirp ('gen',tenant) | ||
const out = await fs.mkdirp ('gen',isExtensible ? tenant : 'base') | ||
@@ -250,3 +252,3 @@ DEBUG?.('preparing HANA deployment artifacts') | ||
// 1. Unpack what comes from getResources() | ||
if (!csnFromParameter) await resources4(tenant) | ||
if (!csnFromParameter && !skipResources) await resources4(tenant) | ||
@@ -253,0 +255,0 @@ // 2. Get csvs from extensions |
@@ -9,5 +9,9 @@ const https = require('https') | ||
const api = axios.create({ baseURL: sm_url + '/v1/', headers: { 'Content-Type': 'application/json' }}) | ||
api.interceptors.request.use(async config => { | ||
config.headers.Authorization = await _token() | ||
return config | ||
api.interceptors.request.use(async conf => { | ||
conf.headers.Authorization = await _token() | ||
DEBUG?.(conf.method.toUpperCase(), conf.baseURL + conf.url, { | ||
...(conf.params && { params: conf.params }), | ||
...(conf.data && { data: conf.data }) | ||
}) | ||
return conf | ||
}) | ||
@@ -14,0 +18,0 @@ api.interceptors.response.use(response => response, require('../../../lib/pruneAxiosErrors')) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
235278
4518