@sap/cds-mtxs
Version:
SAP Cloud Application Programming Model - Multitenancy library
60 lines (54 loc) • 2.51 kB
JavaScript
const cds = require('@sap/cds/lib')
const LOG = cds.log('mtx'), DEBUG = cds.debug('mtx')
module.exports = class SaasProvisioningService extends require('./abstract-provisioning-service') {
async init() {
this.on('UPDATE', 'tenant', this._create)
this.on('READ', 'tenant', super._read)
this.on('DELETE', 'tenant', super._delete)
this.on('getAppUrl', super._getAppUrl)
this.on('dependencies', super._dependencies)
this.on('upgrade', super._upgrade)
super.init()
}
async _create(context) {
if (context.data.eventType === 'UPDATE' && cds.requires['cds.xt.SaasProvisioningService']?.alwaysUpgradeModel === false) {
const { headers } = cds.context?.http?.req ?? {}
const { isSync } = this._parseHeaders(headers)
// reject async use case for now, rarely used
if (!isSync) throw new cds.error({ message: 'Synchronous processing required when using "alwaysUpgradeModel: false"', code: 422 })
const sps = await cds.connect.to(this.name)
return sps.getAppUrl(context.data, context.headers)
}
return super._create(context, context.data)
}
_parseHeaders(headers) {
const { prefer, status_callback, mtx_status_callback } = headers ?? {}
const { saas_registry_url } = this._getCredentials()
const callbackUrl = mtx_status_callback ?? (status_callback && saas_registry_url && new URL(status_callback, saas_registry_url).toString())
return {
callbackUrl,
isCustomCallback: !!mtx_status_callback,
saasCallbackUrlPath: status_callback,
isSync: !(prefer?.includes('respond-async') || callbackUrl)
}
}
async _sendCallback(status, message, subscriptionUrl) {
const { body, headers } = cds.context?.http?.req ?? {}
const { isSync, isCustomCallback, saasCallbackUrlPath, callbackUrl } = this._parseHeaders(headers)
if (!isSync && callbackUrl) {
const tenant = this._getSubscribedTenant(body)
const payload = { status, message, subscriptionUrl }
let customPayload // additional payload for internal callback (java)
if (isCustomCallback) {
customPayload = { saasRequestPayload: body, saasCallbackUrl: saasCallbackUrlPath, tenant }
}
DEBUG?.('sending callback to', callbackUrl)
try {
const authHeader = isCustomCallback ? headers.authorization : `Bearer ${await this._token()}`
await this.sendResult(callbackUrl, payload, customPayload, authHeader)
} catch (error) {
LOG.error(error)
}
}
}
}