@sap/cds 5.8.2 → 5.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +214 -78
- package/app/fiori/preview.js +16 -11
- package/app/fiori/routes.js +3 -0
- package/app/index.js +1 -1
- package/bin/build/buildTaskFactory.js +3 -3
- package/bin/build/buildTaskProviderFactory.js +1 -1
- package/bin/build/constants.js +1 -1
- package/bin/build/provider/buildTaskHandlerEdmx.js +12 -7
- package/bin/build/provider/buildTaskHandlerInternal.js +1 -1
- package/bin/build/provider/buildTaskProviderInternal.js +8 -2
- package/bin/build/provider/hana/2migration.js +27 -24
- package/bin/build/provider/hana/index.js +17 -18
- package/bin/build/provider/hana/migrationtable.js +9 -10
- package/bin/build/provider/java-cf/index.js +4 -5
- package/bin/build/provider/node-cf/index.js +99 -6
- package/bin/cds.js +20 -17
- package/bin/deploy/to-hana/cfUtil.js +16 -19
- package/bin/deploy/to-hana/hana.js +7 -24
- package/bin/deploy/to-hana/hdiDeployUtil.js +8 -4
- package/bin/mtx/in-cds.js +2 -2
- package/bin/serve.js +12 -5
- package/bin/utils/modules.js +7 -0
- package/bin/version.js +56 -3
- package/lib/compile/cdsc.js +26 -3
- package/lib/compile/etc/_localized.js +36 -25
- package/lib/compile/etc/csv.js +8 -8
- package/lib/compile/for/drafts.js +9 -0
- package/lib/compile/for/java.js +16 -0
- package/lib/compile/for/nodejs.js +12 -0
- package/lib/compile/for/odata.js +1 -1
- package/lib/compile/index.js +3 -0
- package/lib/compile/minify.js +16 -2
- package/lib/compile/parse.js +2 -2
- package/lib/compile/resolve.js +35 -18
- package/lib/compile/to/json.js +3 -1
- package/lib/compile/to/sql.js +2 -2
- package/lib/compile/to/srvinfo.js +4 -2
- package/lib/connect/index.js +1 -1
- package/lib/core/entities.js +15 -14
- package/lib/core/index.js +39 -36
- package/lib/core/reflect.js +4 -2
- package/lib/deploy.js +114 -127
- package/lib/env/defaults.js +1 -0
- package/lib/env/index.js +165 -165
- package/lib/env/presets.js +1 -0
- package/lib/env/requires.js +120 -49
- package/lib/index.js +1 -0
- package/lib/log/format/kibana.js +2 -2
- package/lib/ql/SELECT.js +10 -0
- package/lib/ql/parse.js +1 -0
- package/lib/req/cds-context.js +4 -1
- package/lib/req/context.js +50 -56
- package/lib/req/event.js +1 -6
- package/lib/req/locale.js +6 -5
- package/lib/req/request.js +2 -0
- package/lib/req/user.js +7 -5
- package/lib/serve/Service-api.js +10 -7
- package/lib/serve/Service-dispatch.js +9 -11
- package/lib/serve/Service-methods.js +30 -41
- package/lib/serve/Transaction.js +10 -7
- package/lib/serve/adapters.js +7 -5
- package/lib/serve/index.js +24 -12
- package/lib/utils/data.js +1 -1
- package/lib/utils/index.js +27 -30
- package/lib/utils/resources/index.js +101 -0
- package/lib/utils/resources/tar.js +71 -0
- package/lib/utils/resources/utils.js +11 -0
- package/libx/_runtime/audit/Service.js +36 -39
- package/libx/_runtime/audit/generic/personal/access.js +3 -4
- package/libx/_runtime/audit/generic/personal/modification.js +3 -4
- package/libx/_runtime/audit/utils/v2.js +1 -2
- package/libx/_runtime/auth/index.js +126 -84
- package/libx/_runtime/auth/strategies/JWT.js +12 -19
- package/libx/_runtime/auth/strategies/dummy.js +1 -5
- package/libx/_runtime/auth/strategies/dwc.js +11 -9
- package/libx/_runtime/auth/strategies/mock.js +0 -4
- package/libx/_runtime/auth/strategies/{utils/xssec.js → xssecUtils.js} +7 -4
- package/libx/_runtime/auth/strategies/xsuaa.js +12 -19
- package/libx/_runtime/auth/utils.js +22 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +104 -98
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +13 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/language.js +2 -8
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +4 -29
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +2 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +3 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +4 -6
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +24 -21
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +8 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriHelper.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/deserializer/DeserializerFactory.js +2 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/deserializer/ResourceJsonDeserializer.js +5 -6
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/DispatcherCommand.js +2 -6
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/utils/UriHelper.js +4 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/to.js +1 -12
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +33 -9
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/dispatcherUtils.js +50 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/request.js +10 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +9 -11
- package/libx/_runtime/cds-services/adapter/rest/RestRequest.js +6 -3
- package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +4 -2
- package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/utils.js +1 -1
- package/libx/_runtime/cds-services/adapter/rest/utils/binary.js +1 -1
- package/libx/_runtime/cds-services/adapter/rest/utils/key-value-utils.js +2 -3
- package/libx/_runtime/cds-services/adapter/rest/utils/parse-url.js +6 -4
- package/libx/_runtime/cds-services/adapter/rest/utils/result.js +1 -0
- package/libx/_runtime/cds-services/adapter/rest/utils/validation-checks.js +8 -5
- package/libx/_runtime/cds-services/services/Service.js +40 -0
- package/libx/_runtime/cds-services/services/utils/columns.js +4 -3
- package/libx/_runtime/cds-services/services/utils/compareJson.js +4 -4
- package/libx/_runtime/cds-services/services/utils/differ.js +3 -3
- package/libx/_runtime/cds-services/services/utils/handlerUtils.js +4 -4
- package/libx/_runtime/cds-services/services/utils/restrictions.js +78 -0
- package/libx/_runtime/cds-services/util/assert.js +20 -14
- package/libx/_runtime/cds.js +9 -1
- package/libx/_runtime/common/aspects/any.js +5 -0
- package/libx/_runtime/common/aspects/entity.js +25 -7
- package/libx/_runtime/common/aspects/utils.js +2 -2
- package/libx/_runtime/common/composition/data.js +6 -0
- package/libx/_runtime/common/composition/insert.js +3 -2
- package/libx/_runtime/common/composition/tree.js +4 -10
- package/libx/_runtime/common/composition/update.js +4 -4
- package/libx/_runtime/common/constants/draft.js +29 -26
- package/libx/_runtime/common/error/constants.js +2 -2
- package/libx/_runtime/common/error/frontend.js +7 -15
- package/libx/_runtime/common/generic/auth/capabilities.js +59 -0
- package/libx/_runtime/common/generic/auth/constants.js +20 -0
- package/libx/_runtime/common/generic/auth/expand.js +54 -0
- package/libx/_runtime/common/generic/auth/index.js +32 -0
- package/libx/_runtime/common/generic/auth/insertOnly.js +15 -0
- package/libx/_runtime/common/generic/auth/readOnly.js +26 -0
- package/libx/_runtime/common/generic/auth/requires.js +34 -0
- package/libx/_runtime/common/generic/auth/restrict.js +296 -0
- package/libx/_runtime/common/generic/auth/utils.js +213 -0
- package/libx/_runtime/common/generic/crud.js +14 -10
- package/libx/_runtime/common/generic/etag.js +1 -1
- package/libx/_runtime/common/generic/input.js +35 -35
- package/libx/_runtime/common/generic/sorting.js +2 -3
- package/libx/_runtime/common/generic/temporal.js +2 -2
- package/libx/_runtime/common/i18n/index.js +2 -31
- package/libx/_runtime/common/i18n/messages.properties +1 -1
- package/libx/_runtime/common/toggles/handler.js +21 -0
- package/libx/_runtime/common/utils/copy.js +10 -1
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +100 -29
- package/libx/_runtime/common/utils/csn.js +63 -1
- package/libx/_runtime/common/utils/dollar.js +10 -1
- package/libx/_runtime/common/utils/draft.js +46 -7
- package/libx/_runtime/common/utils/entityFromCqn.js +13 -9
- package/libx/_runtime/common/utils/extensibilityUtils.js +18 -0
- package/libx/_runtime/common/utils/foreignKeyPropagations.js +88 -104
- package/libx/_runtime/common/utils/generateOnCond.js +9 -6
- package/libx/_runtime/common/utils/quotingStyles.js +2 -0
- package/libx/_runtime/common/utils/resolveStructured.js +25 -9
- package/libx/_runtime/common/utils/resolveView.js +4 -1
- package/libx/_runtime/common/utils/rewriteAsterisks.js +3 -16
- package/libx/_runtime/common/utils/structured.js +33 -37
- package/libx/_runtime/common/utils/template.js +17 -8
- package/libx/_runtime/common/utils/templateProcessor.js +28 -28
- package/libx/_runtime/db/data-conversion/post-processing.js +118 -417
- package/libx/_runtime/db/expand/expandCQNToJoin.js +45 -41
- package/libx/_runtime/db/expand/rawToExpanded.js +29 -8
- package/libx/_runtime/db/generic/index.js +1 -3
- package/libx/_runtime/db/generic/input.js +5 -10
- package/libx/_runtime/db/generic/rewrite.js +5 -2
- package/libx/_runtime/db/generic/structured.js +2 -2
- package/libx/_runtime/db/query/delete.js +2 -2
- package/libx/_runtime/db/query/insert.js +1 -1
- package/libx/_runtime/db/query/update.js +9 -14
- package/libx/_runtime/db/sql-builder/CreateBuilder.js +4 -3
- package/libx/_runtime/db/sql-builder/InsertBuilder.js +14 -1
- package/libx/_runtime/db/sql-builder/SelectBuilder.js +3 -2
- package/libx/_runtime/db/sql-builder/dataTypes.js +3 -3
- package/libx/_runtime/db/utils/columns.js +3 -3
- package/libx/_runtime/db/utils/normalizeTimeData.js +2 -2
- package/libx/_runtime/db/utils/propagateForeignKeys.js +6 -2
- package/libx/_runtime/extensibility/mps/index.js +5 -0
- package/libx/_runtime/extensibility/mps/service.js +111 -0
- package/libx/_runtime/extensibility/mps/tar.js +42 -0
- package/libx/_runtime/extensibility/mps/utils.js +11 -0
- package/libx/_runtime/{fiori → extensibility}/uiflex/handler/transformREAD.js +0 -0
- package/libx/_runtime/{fiori → extensibility}/uiflex/handler/transformRESULT.js +17 -5
- package/libx/_runtime/{fiori → extensibility}/uiflex/handler/transformWRITE.js +1 -0
- package/libx/_runtime/extensibility/uiflex/index.js +54 -0
- package/libx/_runtime/extensibility/uiflex/service.js +276 -0
- package/libx/_runtime/{fiori → extensibility}/uiflex/utils.js +22 -7
- package/libx/_runtime/fiori/generic/activate.js +2 -2
- package/libx/_runtime/fiori/generic/before.js +4 -4
- package/libx/_runtime/fiori/generic/new.js +3 -3
- package/libx/_runtime/fiori/generic/patch.js +1 -1
- package/libx/_runtime/fiori/generic/read.js +58 -66
- package/libx/_runtime/fiori/generic/readOverDraft.js +71 -16
- package/libx/_runtime/fiori/utils/handler.js +6 -13
- package/libx/_runtime/fiori/utils/where.js +6 -5
- package/libx/_runtime/hana/Service.js +4 -10
- package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +2 -2
- package/libx/_runtime/hana/driver.js +2 -2
- package/libx/_runtime/hana/execute.js +29 -75
- package/libx/_runtime/hana/pool.js +1 -1
- package/libx/_runtime/hana/streaming.js +2 -1
- package/libx/_runtime/index.js +6 -6
- package/libx/_runtime/messaging/AMQPWebhookMessaging.js +5 -21
- package/libx/_runtime/messaging/Outbox.js +2 -2
- package/libx/_runtime/messaging/common-utils/AMQPClient.js +4 -14
- package/libx/_runtime/messaging/common-utils/connections.js +5 -7
- package/libx/_runtime/messaging/common-utils/normalizeIncomingMessage.js +30 -0
- package/libx/_runtime/messaging/enterprise-messaging-shared.js +2 -1
- package/libx/_runtime/messaging/enterprise-messaging-utils/EMManagement.js +36 -30
- package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +19 -12
- package/libx/_runtime/messaging/enterprise-messaging.js +8 -8
- package/libx/_runtime/messaging/file-based.js +5 -5
- package/libx/_runtime/messaging/message-queuing.js +14 -12
- package/libx/_runtime/messaging/outbox/utils.js +18 -19
- package/libx/_runtime/messaging/redis-messaging.js +91 -0
- package/libx/_runtime/messaging/service.js +8 -6
- package/libx/_runtime/remote/Service.js +44 -8
- package/libx/_runtime/remote/utils/client.js +25 -13
- package/libx/_runtime/remote/utils/data.js +11 -11
- package/libx/_runtime/sqlite/Service.js +6 -9
- package/libx/_runtime/sqlite/customBuilder/CustomFunctionBuilder.js +5 -2
- package/libx/_runtime/types/api.js +10 -2
- package/libx/common/utils/ucsn.js +109 -0
- package/libx/gql/resolvers/crud/create.js +6 -1
- package/libx/gql/resolvers/crud/delete.js +6 -1
- package/libx/gql/resolvers/crud/read.js +6 -1
- package/libx/gql/resolvers/crud/update.js +9 -1
- package/libx/gql/resolvers/parse/ast2cqn/columns.js +3 -1
- package/libx/gql/schema/typeDefMap.js +2 -2
- package/libx/odata/afterburner.js +110 -16
- package/libx/odata/grammar.pegjs +9 -1
- package/libx/odata/parseToCqn.js +39 -0
- package/libx/odata/parser.js +1 -1
- package/libx/rest/RestAdapter.js +9 -1
- package/libx/rest/middleware/input.js +54 -0
- package/libx/rest/middleware/operation.js +14 -1
- package/libx/rest/middleware/parse.js +11 -7
- package/package.json +1 -1
- package/server.js +34 -19
- package/srv/audit-log.cds +2 -2
- package/srv/flex.cds +8 -2
- package/srv/flex.js +1 -1
- package/srv/mps.cds +23 -0
- package/srv/mps.js +1 -0
- package/libx/_runtime/auth/strategies/utils/uaa.js +0 -21
- package/libx/_runtime/common/generic/auth.js +0 -874
- package/libx/_runtime/common/toggles/alpha.js +0 -43
- package/libx/_runtime/db/generic/arrayed.js +0 -33
- package/libx/_runtime/fiori/uiflex/index.js +0 -35
- package/libx/_runtime/fiori/uiflex/service.js +0 -150
- package/libx/rest/utils/data.js +0 -60
package/libx/_runtime/index.js
CHANGED
|
@@ -5,12 +5,12 @@ module.exports = {
|
|
|
5
5
|
return this._odatav4 || (this._odatav4 = require('./cds-services/adapter/odata-v4/to'))
|
|
6
6
|
},
|
|
7
7
|
|
|
8
|
-
get
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return this.
|
|
8
|
+
get old_rest() {
|
|
9
|
+
return this._old_rest || (this._old_rest = require('./cds-services/adapter/rest/to'))
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
get new_rest() {
|
|
13
|
+
return this._new_rest || (this._new_rest = require('../rest'))
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
16
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const cds = require('../cds')
|
|
2
|
-
const LOG = cds.log('messaging')
|
|
3
2
|
const MessagingService = require('./service.js')
|
|
4
3
|
const { queueName } = require('./common-utils/naming-conventions')
|
|
5
4
|
const optionsApp = require('../common/utils/vcap.js')
|
|
5
|
+
const normalizeIncomingMessage = require('./common-utils/normalizeIncomingMessage')
|
|
6
6
|
|
|
7
7
|
class AMQPWebhookMessaging extends MessagingService {
|
|
8
8
|
async init() {
|
|
@@ -33,25 +33,9 @@ class AMQPWebhookMessaging extends MessagingService {
|
|
|
33
33
|
const management = this.getManagement()
|
|
34
34
|
if (!opt.doNotDeploy) this.queued(management.createQueueAndSubscriptions.bind(management))()
|
|
35
35
|
this.queued(this.listenToClient.bind(this))(async (_topic, _payload, _other, { done, failed }) => {
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
let data, headers
|
|
40
|
-
if (typeof _payload === 'object' && 'data' in _payload) {
|
|
41
|
-
data = _payload.data
|
|
42
|
-
headers = { ..._payload }
|
|
43
|
-
delete headers.data
|
|
44
|
-
} else {
|
|
45
|
-
data = _payload
|
|
46
|
-
headers = {}
|
|
47
|
-
}
|
|
48
|
-
const msg = {
|
|
49
|
-
event,
|
|
50
|
-
data,
|
|
51
|
-
headers,
|
|
52
|
-
inbound: true,
|
|
53
|
-
...(_other || {})
|
|
54
|
-
}
|
|
36
|
+
const msg = Object.assign(normalizeIncomingMessage(_payload), _other || {})
|
|
37
|
+
msg.event = _topic
|
|
38
|
+
|
|
55
39
|
if (!msg._) msg._ = {}
|
|
56
40
|
msg._.topic = _topic
|
|
57
41
|
try {
|
|
@@ -61,7 +45,7 @@ class AMQPWebhookMessaging extends MessagingService {
|
|
|
61
45
|
// In case of AMQP and Solace, the `failed` callback must be called
|
|
62
46
|
// with an error, otherwise there are problems with the redelivery count.
|
|
63
47
|
failed(new Error('processing failed'))
|
|
64
|
-
LOG.error('ERROR occured in asynchronous event processing:', e)
|
|
48
|
+
this.LOG.error('ERROR occured in asynchronous event processing:', e)
|
|
65
49
|
}
|
|
66
50
|
})
|
|
67
51
|
}
|
|
@@ -19,7 +19,7 @@ class OutboxService extends cds.Service {
|
|
|
19
19
|
this.emit = async function (...args) {
|
|
20
20
|
const msg = typeof args[0] === 'object' ? args[0] : { event: args[0], data: args[1], headers: args[2] }
|
|
21
21
|
const context = this.context || cds.context
|
|
22
|
-
if (this.options.outbox && context
|
|
22
|
+
if (this.options.outbox && context) {
|
|
23
23
|
const outboxOpts = Object.assign(
|
|
24
24
|
{},
|
|
25
25
|
(typeof cds.requires.outbox === 'object' && cds.requires.outbox) || {},
|
|
@@ -38,7 +38,7 @@ class OutboxService extends cds.Service {
|
|
|
38
38
|
try {
|
|
39
39
|
await this._emitImmediate(msg)
|
|
40
40
|
} catch (e) {
|
|
41
|
-
LOG.
|
|
41
|
+
LOG.error('Emit failed', { event: msg.event, cause: e })
|
|
42
42
|
// opts.crashOnError is not official!!!
|
|
43
43
|
if (isUnrecoverable(this, e) && outboxOpts.crashOnError !== false) process.exit(1)
|
|
44
44
|
}
|
|
@@ -1,17 +1,8 @@
|
|
|
1
1
|
const cds = require('../../cds.js')
|
|
2
|
-
const LOG = cds.log('messaging')
|
|
3
2
|
const ClientAmqp = require('@sap/xb-msg-amqp-v100').Client
|
|
4
3
|
const { connect, disconnect } = require('./connections')
|
|
5
4
|
const { hasPersistentOutbox } = require('../outbox/utils')
|
|
6
5
|
|
|
7
|
-
const _JSONorString = string => {
|
|
8
|
-
try {
|
|
9
|
-
return JSON.parse(string)
|
|
10
|
-
} catch (e) {
|
|
11
|
-
return string
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
6
|
const addDataListener = (client, queue, prefix, cb) =>
|
|
16
7
|
new Promise((resolve, reject) => {
|
|
17
8
|
const source = `${prefix}${queue}`
|
|
@@ -19,8 +10,7 @@ const addDataListener = (client, queue, prefix, cb) =>
|
|
|
19
10
|
.receiver(queue)
|
|
20
11
|
.attach(source)
|
|
21
12
|
.on('data', async raw => {
|
|
22
|
-
const
|
|
23
|
-
const payload = buffer && _JSONorString(buffer.toString())
|
|
13
|
+
const payload = raw.payload && Buffer.concat(raw.payload.chunks).toString()
|
|
24
14
|
const topic =
|
|
25
15
|
raw.source &&
|
|
26
16
|
raw.source.properties &&
|
|
@@ -36,7 +26,7 @@ const addDataListener = (client, queue, prefix, cb) =>
|
|
|
36
26
|
|
|
37
27
|
const sender = (client, optionsApp) => client.sender(`${optionsApp.appName}-${optionsApp.appID}`)
|
|
38
28
|
|
|
39
|
-
const emit = ({ data, event: topic, headers = {} }, stream, prefix) =>
|
|
29
|
+
const emit = ({ data, event: topic, headers = {} }, stream, prefix, LOG) =>
|
|
40
30
|
new Promise((resolve, reject) => {
|
|
41
31
|
LOG._info && LOG.info('Emit', { topic })
|
|
42
32
|
const message = { ...headers, data }
|
|
@@ -69,7 +59,7 @@ class AMQPClient {
|
|
|
69
59
|
this.client = new ClientAmqp(this.optionsAMQP)
|
|
70
60
|
this.sender = sender(this.client, this.service.optionsApp)
|
|
71
61
|
this.stream = this.sender.attach('')
|
|
72
|
-
return connect(this.client, this.keepAlive)
|
|
62
|
+
return connect(this.client, this.service.LOG, this.keepAlive)
|
|
73
63
|
}
|
|
74
64
|
|
|
75
65
|
async disconnect() {
|
|
@@ -84,7 +74,7 @@ class AMQPClient {
|
|
|
84
74
|
// REVISIT: Is this a robust way to find out if the connection is working?
|
|
85
75
|
if (hasPersistentOutbox(this.service, cds.context && cds.context.tenant) && !this.sender.opened())
|
|
86
76
|
throw new Error('AMQP: Sender is not open')
|
|
87
|
-
await emit(msg, this.stream, this.prefix.topic)
|
|
77
|
+
await emit(msg, this.stream, this.prefix.topic, this.service.LOG)
|
|
88
78
|
if (!this.keepAlive) return this.disconnect()
|
|
89
79
|
}
|
|
90
80
|
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
const cds = require('../../cds')
|
|
2
|
-
const LOG = cds.log('messaging')
|
|
3
1
|
const waitingTime = require('./waitingTime')
|
|
4
2
|
|
|
5
|
-
const _connectUntilConnected = (client, x) => {
|
|
3
|
+
const _connectUntilConnected = (client, LOG, x) => {
|
|
6
4
|
const _waitingTime = waitingTime(x)
|
|
7
5
|
setTimeout(() => {
|
|
8
|
-
connect(client, true)
|
|
6
|
+
connect(client, LOG, true)
|
|
9
7
|
.then(() => {
|
|
10
8
|
LOG._warn && LOG.warn('Reconnected to Enterprise Messaging Client')
|
|
11
9
|
})
|
|
@@ -14,12 +12,12 @@ const _connectUntilConnected = (client, x) => {
|
|
|
14
12
|
LOG.warn(
|
|
15
13
|
`Connection to Enterprise Messaging Client lost: Reconnecting in ${Math.round(_waitingTime / 1000)} s`
|
|
16
14
|
)
|
|
17
|
-
_connectUntilConnected(client, x + 1)
|
|
15
|
+
_connectUntilConnected(client, LOG, x + 1)
|
|
18
16
|
})
|
|
19
17
|
}, _waitingTime)
|
|
20
18
|
}
|
|
21
19
|
|
|
22
|
-
const connect = (client, keepAlive) => {
|
|
20
|
+
const connect = (client, LOG, keepAlive) => {
|
|
23
21
|
return new Promise((resolve, reject) => {
|
|
24
22
|
client
|
|
25
23
|
.once('connected', function () {
|
|
@@ -37,7 +35,7 @@ const connect = (client, keepAlive) => {
|
|
|
37
35
|
client.once('disconnected', () => {
|
|
38
36
|
client.removeAllListeners('error')
|
|
39
37
|
client.removeAllListeners('connected')
|
|
40
|
-
_connectUntilConnected(client, 0)
|
|
38
|
+
_connectUntilConnected(client, LOG, 0)
|
|
41
39
|
})
|
|
42
40
|
}
|
|
43
41
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const _JSONorString = string => {
|
|
2
|
+
try {
|
|
3
|
+
return JSON.parse(string)
|
|
4
|
+
} catch (e) {
|
|
5
|
+
return string
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Some messaging systems don't adhere to the standard that the payload has a `data` property.
|
|
10
|
+
// For these cases, we interpret the whole payload as `data`.
|
|
11
|
+
const normalizeIncomingMessage = message => {
|
|
12
|
+
const _payload = typeof message === 'object' ? message : _JSONorString(message)
|
|
13
|
+
let data, headers
|
|
14
|
+
if (typeof _payload === 'object' && 'data' in _payload) {
|
|
15
|
+
data = _payload.data
|
|
16
|
+
headers = { ..._payload }
|
|
17
|
+
delete headers.data
|
|
18
|
+
} else {
|
|
19
|
+
data = _payload
|
|
20
|
+
headers = {}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
data,
|
|
25
|
+
headers,
|
|
26
|
+
inbound: true
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = normalizeIncomingMessage
|
|
@@ -34,7 +34,8 @@ class EnterpriseMessagingShared extends AMQPWebhookMessaging {
|
|
|
34
34
|
queueName,
|
|
35
35
|
subscribedTopics: this.subscribedTopics,
|
|
36
36
|
alternativeTopics: this.alternativeTopics,
|
|
37
|
-
namespace: this.options.credentials && this.options.credentials.namespace
|
|
37
|
+
namespace: this.options.credentials && this.options.credentials.namespace,
|
|
38
|
+
LOG: this.LOG
|
|
38
39
|
})
|
|
39
40
|
return this.management
|
|
40
41
|
}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
const authorizedRequest = require('../common-utils/authorizedRequest')
|
|
2
|
-
const cds = require('../../cds.js')
|
|
3
|
-
const LOG = cds.log('messaging')
|
|
4
2
|
const sleep = require('util').promisify(setTimeout)
|
|
5
3
|
|
|
6
4
|
const _getWebhookName = queueName => queueName
|
|
@@ -19,7 +17,8 @@ class EMManagement {
|
|
|
19
17
|
subscribedTopics,
|
|
20
18
|
maxRetries,
|
|
21
19
|
subdomain,
|
|
22
|
-
namespace
|
|
20
|
+
namespace,
|
|
21
|
+
LOG
|
|
23
22
|
}) {
|
|
24
23
|
this.subdomain = subdomain
|
|
25
24
|
this.options = optionsManagement
|
|
@@ -33,6 +32,7 @@ class EMManagement {
|
|
|
33
32
|
this.maxRetries = maxRetries === undefined ? 10 : maxRetries
|
|
34
33
|
this.subdomainInfo = this.subdomain ? `(subdomain: ${this.subdomain})` : ''
|
|
35
34
|
this.namespace = namespace
|
|
35
|
+
this.LOG = LOG
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
async getQueue(queueName = this.queueName) {
|
|
@@ -42,8 +42,11 @@ class EMManagement {
|
|
|
42
42
|
path: `/hub/rest/api/v1/management/messaging/queues/${encodeURIComponent(queueName)}`,
|
|
43
43
|
oa2: this.options.oa2,
|
|
44
44
|
attemptInfo: () =>
|
|
45
|
-
LOG._info &&
|
|
46
|
-
LOG.info(
|
|
45
|
+
this.LOG._info &&
|
|
46
|
+
this.LOG.info(
|
|
47
|
+
'Get queue',
|
|
48
|
+
this.subdomain ? { queue: queueName, subdomain: this.subdomain } : { queue: queueName }
|
|
49
|
+
),
|
|
47
50
|
errMsg: `Queue "${queueName}" could not be retrieved ${this.subdomainInfo}`,
|
|
48
51
|
target: { kind: 'QUEUE', queue: queueName },
|
|
49
52
|
tokenStore: this
|
|
@@ -57,7 +60,8 @@ class EMManagement {
|
|
|
57
60
|
uri: this.options.uri,
|
|
58
61
|
path: `/hub/rest/api/v1/management/messaging/queues`,
|
|
59
62
|
oa2: this.options.oa2,
|
|
60
|
-
attemptInfo: () =>
|
|
63
|
+
attemptInfo: () =>
|
|
64
|
+
this.LOG._info && this.LOG.info('Get queues', this.subdomain ? { subdomain: this.subdomain } : {}),
|
|
61
65
|
errMsg: `Queues could not be retrieved ${this.subdomainInfo}`,
|
|
62
66
|
target: { kind: 'QUEUE' },
|
|
63
67
|
tokenStore: this
|
|
@@ -73,8 +77,8 @@ class EMManagement {
|
|
|
73
77
|
oa2: this.options.oa2,
|
|
74
78
|
dataObj: this.queueConfig,
|
|
75
79
|
attemptInfo: () =>
|
|
76
|
-
LOG._info &&
|
|
77
|
-
LOG.info(
|
|
80
|
+
this.LOG._info &&
|
|
81
|
+
this.LOG.info(
|
|
78
82
|
'Create queue',
|
|
79
83
|
this.subdomain ? { queue: queueName, subdomain: this.subdomain } : { queue: queueName }
|
|
80
84
|
),
|
|
@@ -91,8 +95,8 @@ class EMManagement {
|
|
|
91
95
|
path: `/hub/rest/api/v1/management/messaging/queues/${encodeURIComponent(queueName)}`,
|
|
92
96
|
oa2: this.options.oa2,
|
|
93
97
|
attemptInfo: () =>
|
|
94
|
-
LOG._info &&
|
|
95
|
-
LOG.info(
|
|
98
|
+
this.LOG._info &&
|
|
99
|
+
this.LOG.info(
|
|
96
100
|
'Delete queue',
|
|
97
101
|
this.subdomain ? { queue: queueName, subdomain: this.subdomain } : { queue: queueName }
|
|
98
102
|
),
|
|
@@ -109,8 +113,8 @@ class EMManagement {
|
|
|
109
113
|
path: `/hub/rest/api/v1/management/messaging/queues/${encodeURIComponent(queueName)}/subscriptions`,
|
|
110
114
|
oa2: this.options.oa2,
|
|
111
115
|
attemptInfo: () =>
|
|
112
|
-
LOG._info &&
|
|
113
|
-
LOG.info(
|
|
116
|
+
this.LOG._info &&
|
|
117
|
+
this.LOG.info(
|
|
114
118
|
'Get subscriptions',
|
|
115
119
|
this.subdomain ? { queue: queueName, subdomain: this.subdomain } : { queue: queueName }
|
|
116
120
|
),
|
|
@@ -130,8 +134,8 @@ class EMManagement {
|
|
|
130
134
|
)}/subscriptions/${encodeURIComponent(topicPattern)}`,
|
|
131
135
|
oa2: this.options.oa2,
|
|
132
136
|
attemptInfo: () =>
|
|
133
|
-
LOG._info &&
|
|
134
|
-
LOG.info(
|
|
137
|
+
this.LOG._info &&
|
|
138
|
+
this.LOG.info(
|
|
135
139
|
'Create subscription',
|
|
136
140
|
this.subdomain
|
|
137
141
|
? { topic: topicPattern, queue: queueName, subdomain: this.subdomain }
|
|
@@ -152,8 +156,8 @@ class EMManagement {
|
|
|
152
156
|
)}/subscriptions/${encodeURIComponent(topicPattern)}`,
|
|
153
157
|
oa2: this.options.oa2,
|
|
154
158
|
attemptInfo: () =>
|
|
155
|
-
LOG._info &&
|
|
156
|
-
LOG.info(
|
|
159
|
+
this.LOG._info &&
|
|
160
|
+
this.LOG.info(
|
|
157
161
|
'Delete subscription',
|
|
158
162
|
this.subdomain
|
|
159
163
|
? { topic: topicPattern, queue: queueName, subdomain: this.subdomain }
|
|
@@ -173,8 +177,8 @@ class EMManagement {
|
|
|
173
177
|
path: `/messagingrest/v1/subscriptions/${encodeURIComponent(webhookName)}`,
|
|
174
178
|
oa2: this.optionsMessagingREST.oa2,
|
|
175
179
|
attemptInfo: () =>
|
|
176
|
-
LOG._info &&
|
|
177
|
-
LOG.info(
|
|
180
|
+
this.LOG._info &&
|
|
181
|
+
this.LOG.info(
|
|
178
182
|
'Get webhook',
|
|
179
183
|
this.subdomain
|
|
180
184
|
? { webhook: webhookName, queue: queueName, subdomain: this.subdomain }
|
|
@@ -195,8 +199,8 @@ class EMManagement {
|
|
|
195
199
|
path: `/messagingrest/v1/subscriptions/${encodeURIComponent(webhookName)}`,
|
|
196
200
|
oa2: this.optionsMessagingREST.oa2,
|
|
197
201
|
attemptInfo: () =>
|
|
198
|
-
LOG._info &&
|
|
199
|
-
LOG.info(
|
|
202
|
+
this.LOG._info &&
|
|
203
|
+
this.LOG.info(
|
|
200
204
|
'Delete webhook',
|
|
201
205
|
this.subdomain
|
|
202
206
|
? { webhook: webhookName, queue: queueName, subdomain: this.subdomain }
|
|
@@ -245,8 +249,8 @@ class EMManagement {
|
|
|
245
249
|
oa2: this.optionsMessagingREST.oa2,
|
|
246
250
|
dataObj,
|
|
247
251
|
attemptInfo: () =>
|
|
248
|
-
LOG._info &&
|
|
249
|
-
LOG.info(
|
|
252
|
+
this.LOG._info &&
|
|
253
|
+
this.LOG.info(
|
|
250
254
|
'Create webhook',
|
|
251
255
|
this.subdomain
|
|
252
256
|
? { webhook: webhookName, queue: queueName, subdomain: this.subdomain }
|
|
@@ -266,8 +270,8 @@ class EMManagement {
|
|
|
266
270
|
path: `/messagingrest/v1/subscriptions/${encodeURIComponent(webhookName)}`,
|
|
267
271
|
oa2: this.optionsMessagingREST.oa2,
|
|
268
272
|
attemptInfo: () =>
|
|
269
|
-
LOG._info &&
|
|
270
|
-
LOG.info(
|
|
273
|
+
this.LOG._info &&
|
|
274
|
+
this.LOG.info(
|
|
271
275
|
'Delete webhook',
|
|
272
276
|
this.subdomain
|
|
273
277
|
? { webhook: webhookName, queue: queueName, subdomain: this.subdomain }
|
|
@@ -280,7 +284,7 @@ class EMManagement {
|
|
|
280
284
|
}
|
|
281
285
|
|
|
282
286
|
async createQueueAndSubscriptions() {
|
|
283
|
-
LOG._info && LOG.info(`Create messaging artifacts ${this.subdomainInfo}`)
|
|
287
|
+
this.LOG._info && this.LOG.info(`Create messaging artifacts ${this.subdomainInfo}`)
|
|
284
288
|
|
|
285
289
|
const created = await this.createQueue()
|
|
286
290
|
if (created && created.statusCode === 200) {
|
|
@@ -297,7 +301,7 @@ class EMManagement {
|
|
|
297
301
|
for (const [s, _] of this.subscribedTopics) {
|
|
298
302
|
if (existingSubscriptions.some(e => s === e)) unchangedSubs.push(s)
|
|
299
303
|
}
|
|
300
|
-
LOG._info && LOG.info('Unchanged subscriptions', unchangedSubs, ' ', this.subdomainInfo)
|
|
304
|
+
this.LOG._info && this.LOG.info('Unchanged subscriptions', unchangedSubs, ' ', this.subdomainInfo)
|
|
301
305
|
await Promise.all([
|
|
302
306
|
...obsoleteSubs.map(s => this.deleteSubscription(s)),
|
|
303
307
|
...additionalSubs.map(async s => this._createSubscription(s))
|
|
@@ -331,7 +335,7 @@ class EMManagement {
|
|
|
331
335
|
}
|
|
332
336
|
|
|
333
337
|
async undeploy() {
|
|
334
|
-
LOG._info && LOG.info(`Delete messaging artifacts ${this.subdomainInfo}`)
|
|
338
|
+
this.LOG._info && this.LOG.info(`Delete messaging artifacts ${this.subdomainInfo}`)
|
|
335
339
|
await this.deleteQueue()
|
|
336
340
|
if (this.optionsMessagingREST) await this.deleteWebhook()
|
|
337
341
|
}
|
|
@@ -342,7 +346,7 @@ class EMManagement {
|
|
|
342
346
|
uri: this.options.uri,
|
|
343
347
|
path: `/hub/rest/api/v1/management/messaging/readinessCheck`,
|
|
344
348
|
oa2: this.options.oa2,
|
|
345
|
-
attemptInfo: () => LOG._info && LOG.info(`Readiness Check ${this.subdomainInfo}`),
|
|
349
|
+
attemptInfo: () => this.LOG._info && this.LOG.info(`Readiness Check ${this.subdomainInfo}`),
|
|
346
350
|
errMsg: `Readiness Check failed ${this.subdomainInfo}`,
|
|
347
351
|
target: { kind: 'READINESSCHECK' },
|
|
348
352
|
tokenStore: this
|
|
@@ -365,8 +369,10 @@ class EMManagement {
|
|
|
365
369
|
}
|
|
366
370
|
const retryAfter = e.response && e.response.headers && e.response.headers['retry-after']
|
|
367
371
|
const _waitingPeriod = waitingPeriod || (retryAfter && Number(retryAfter) * 1000) || 120 * 1000
|
|
368
|
-
LOG._info &&
|
|
369
|
-
LOG.info(
|
|
372
|
+
this.LOG._info &&
|
|
373
|
+
this.LOG.info(
|
|
374
|
+
`Readiness Check failed ${this.subdomainInfo}, retrying in ${_waitingPeriod / 1000} seconds...`
|
|
375
|
+
)
|
|
370
376
|
await sleep(_waitingPeriod)
|
|
371
377
|
await check()
|
|
372
378
|
} else {
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
const cds = require('../../cds.js')
|
|
2
|
-
const LOG = cds.log('messaging')
|
|
3
2
|
const express = require('express')
|
|
4
3
|
const getTenantInfo = require('./getTenantInfo.js')
|
|
5
|
-
const isSecured = () => cds.requires.
|
|
6
|
-
const { getTenant } = require('../../auth/strategies/
|
|
4
|
+
const isSecured = () => cds.requires.auth && cds.requires.auth.credentials
|
|
5
|
+
const { getTenant } = require('../../auth/strategies/xssecUtils')
|
|
7
6
|
|
|
8
7
|
const _isAll = a => a && a.includes('all')
|
|
9
|
-
const _hasScope = (scope, req) =>
|
|
10
|
-
req && req.authInfo && req.authInfo.checkLocalScope && req.authInfo.checkLocalScope(scope)
|
|
11
8
|
|
|
12
9
|
class EndpointRegistry {
|
|
13
|
-
constructor(basePath) {
|
|
10
|
+
constructor(basePath, LOG) {
|
|
14
11
|
const deployPath = basePath + '/deploy'
|
|
15
12
|
const paths = [basePath, deployPath]
|
|
16
13
|
this.webhookCallbacks = new Map()
|
|
@@ -18,11 +15,20 @@ class EndpointRegistry {
|
|
|
18
15
|
if (isSecured()) {
|
|
19
16
|
const JWTStrategy = require('../../auth/strategies/JWT.js')
|
|
20
17
|
const passport = require('passport')
|
|
21
|
-
|
|
18
|
+
// REVISIT: It's unclear if the credentials from cds.requires.auth need to be used here.
|
|
19
|
+
// In principle, user-facing endpoints might differ from messaging ones.
|
|
20
|
+
passport.use(new JWTStrategy(cds.requires.auth.credentials))
|
|
22
21
|
paths.forEach(path => {
|
|
23
22
|
cds.app.use(path, passport.initialize())
|
|
24
23
|
cds.app.use(path, passport.authenticate('JWT', { session: false }))
|
|
24
|
+
cds.app.use(path, (req, res, next) => {
|
|
25
|
+
// unsuccessful auth doesn't automatically reject!
|
|
26
|
+
if (!req.user) return res.status(401).json({ message: 'Unauthorized' })
|
|
27
|
+
next()
|
|
28
|
+
})
|
|
25
29
|
})
|
|
30
|
+
} else if (process.env.NODE_ENV === 'production') {
|
|
31
|
+
LOG.warn('Messaging endpoints not secured')
|
|
26
32
|
}
|
|
27
33
|
paths.forEach(path => {
|
|
28
34
|
cds.app.use(path, express.json({ type: 'application/*+json' }))
|
|
@@ -43,7 +49,7 @@ class EndpointRegistry {
|
|
|
43
49
|
|
|
44
50
|
cds.app.options(basePath, (req, res) => {
|
|
45
51
|
try {
|
|
46
|
-
if (isSecured() && !
|
|
52
|
+
if (isSecured() && !req.user.is('emcallback')) return res.sendStatus(403)
|
|
47
53
|
res.set('WebHook-Allowed-Origin', req.headers['webhook-request-origin'])
|
|
48
54
|
res.sendStatus(200)
|
|
49
55
|
} catch (error) {
|
|
@@ -53,7 +59,7 @@ class EndpointRegistry {
|
|
|
53
59
|
LOG._debug && LOG.debug('Register inbound endpoint', { basePath, method: 'POST' })
|
|
54
60
|
cds.app.post(basePath, (req, res) => {
|
|
55
61
|
try {
|
|
56
|
-
if (isSecured() && !
|
|
62
|
+
if (isSecured() && !req.user.is('emcallback')) return res.sendStatus(403)
|
|
57
63
|
const queueName = req.query.q
|
|
58
64
|
const authInfo = req.authInfo
|
|
59
65
|
const xAddress = req.headers['x-address']
|
|
@@ -83,7 +89,7 @@ class EndpointRegistry {
|
|
|
83
89
|
})
|
|
84
90
|
cds.app.post(deployPath, async (req, res) => {
|
|
85
91
|
try {
|
|
86
|
-
if (isSecured() && !
|
|
92
|
+
if (isSecured() && !req.user.is('emmanagement')) return res.sendStatus(403)
|
|
87
93
|
const tenants = req.body && !_isAll(req.body.tenants) && req.body.tenants
|
|
88
94
|
const queues = req.body && !_isAll(req.body.queues) && req.body.queues
|
|
89
95
|
const options = { wipeData: req.body && req.body.wipeData }
|
|
@@ -120,9 +126,10 @@ class EndpointRegistry {
|
|
|
120
126
|
const registries = new Map()
|
|
121
127
|
|
|
122
128
|
// REVISIT: Use cds mechanism instead of express? -> Need option method and handler for specifica
|
|
123
|
-
const registerWebhookEndpoints = (basePath, queueName, cb) => {
|
|
129
|
+
const registerWebhookEndpoints = (basePath, queueName, LOG, cb) => {
|
|
124
130
|
const registry =
|
|
125
|
-
registries.get(basePath) ||
|
|
131
|
+
registries.get(basePath) ||
|
|
132
|
+
(registries.set(basePath, new EndpointRegistry(basePath, LOG)) && registries.get(basePath))
|
|
126
133
|
registry.registerWebhookCallback(queueName, cb)
|
|
127
134
|
}
|
|
128
135
|
|
|
@@ -10,7 +10,6 @@ const {
|
|
|
10
10
|
registerDeployEndpoints,
|
|
11
11
|
registerWebhookEndpoints
|
|
12
12
|
} = require('./enterprise-messaging-utils/registerEndpoints.js')
|
|
13
|
-
const LOG = cds.log('messaging')
|
|
14
13
|
const cloudEvents = require('./enterprise-messaging-utils/cloudEvents.js')
|
|
15
14
|
|
|
16
15
|
const BASE_PATH = '/messaging/enterprise-messaging'
|
|
@@ -61,12 +60,12 @@ class EnterpriseMessaging extends AMQPWebhookMessaging {
|
|
|
61
60
|
const management = await this.getManagement(subdomain).waitUntilReady()
|
|
62
61
|
await management.undeploy()
|
|
63
62
|
} catch (error) {
|
|
64
|
-
|
|
63
|
+
this.LOG.error('Failed to delete messaging artifacts for subdomain', subdomain, '(', error, ')')
|
|
65
64
|
}
|
|
66
65
|
return next()
|
|
67
66
|
})
|
|
68
67
|
provisioning.on('dependencies', async (req, next) => {
|
|
69
|
-
LOG._info && LOG.info('Include Enterprise-Messaging as SaaS dependency')
|
|
68
|
+
this.LOG._info && this.LOG.info('Include Enterprise-Messaging as SaaS dependency')
|
|
70
69
|
const res = await next()
|
|
71
70
|
const xsappname = this.options.credentials && this.options.credentials.xsappname
|
|
72
71
|
if (xsappname) {
|
|
@@ -80,7 +79,7 @@ class EnterpriseMessaging extends AMQPWebhookMessaging {
|
|
|
80
79
|
|
|
81
80
|
startListening() {
|
|
82
81
|
const doNotDeploy = cds._mtxEnabled && !this.options.deployForProvider
|
|
83
|
-
if (doNotDeploy) LOG._info && LOG.info('Skipping deployment of messaging artifacts for provider account')
|
|
82
|
+
if (doNotDeploy) this.LOG._info && this.LOG.info('Skipping deployment of messaging artifacts for provider account')
|
|
84
83
|
super.startListening({ doNotDeploy })
|
|
85
84
|
if (!doNotDeploy && this.subscribedTopics.size) {
|
|
86
85
|
const management = this.getManagement()
|
|
@@ -97,7 +96,7 @@ class EnterpriseMessaging extends AMQPWebhookMessaging {
|
|
|
97
96
|
|
|
98
97
|
async listenToClient(cb) {
|
|
99
98
|
_checkAppURL(this.optionsApp.appURL)
|
|
100
|
-
registerWebhookEndpoints(BASE_PATH, this.queueName, cb)
|
|
99
|
+
registerWebhookEndpoints(BASE_PATH, this.queueName, this.LOG, cb)
|
|
101
100
|
if (cds._mtxEnabled) {
|
|
102
101
|
await this.addMTXHandlers()
|
|
103
102
|
registerDeployEndpoints(BASE_PATH, this.queueName, async (tenantInfo, options) => {
|
|
@@ -110,7 +109,7 @@ class EnterpriseMessaging extends AMQPWebhookMessaging {
|
|
|
110
109
|
await management.deploy()
|
|
111
110
|
result.succeeded.push(info.tenant)
|
|
112
111
|
} catch (error) {
|
|
113
|
-
|
|
112
|
+
this.LOG.error('Failed to create messaging artifacts for subdomain', info.subdomain, ':', error)
|
|
114
113
|
result.failed.push({ error: error.message, tenant: info.tenant })
|
|
115
114
|
}
|
|
116
115
|
})
|
|
@@ -147,7 +146,8 @@ class EnterpriseMessaging extends AMQPWebhookMessaging {
|
|
|
147
146
|
subscribedTopics: this.subscribedTopics,
|
|
148
147
|
alternativeTopics: this.alternativeTopics,
|
|
149
148
|
subdomain: _subdomain,
|
|
150
|
-
namespace: this.options.credentials && this.options.credentials.namespace
|
|
149
|
+
namespace: this.options.credentials && this.options.credentials.namespace,
|
|
150
|
+
LOG: this.LOG
|
|
151
151
|
})
|
|
152
152
|
}
|
|
153
153
|
|
|
@@ -174,7 +174,7 @@ class EnterpriseMessaging extends AMQPWebhookMessaging {
|
|
|
174
174
|
headers: {
|
|
175
175
|
'x-qos': 1
|
|
176
176
|
},
|
|
177
|
-
attemptInfo: () => LOG._info && LOG.info('Emit', { topic }),
|
|
177
|
+
attemptInfo: () => this.LOG._info && this.LOG.info('Emit', { topic }),
|
|
178
178
|
errMsg,
|
|
179
179
|
target: { kind: 'MESSAGE', topic },
|
|
180
180
|
tokenStore: {}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const cds = require('../cds')
|
|
2
|
-
const LOG = cds.log('messaging')
|
|
3
2
|
|
|
4
3
|
const path = require('path')
|
|
5
4
|
const fs = require('fs').promises
|
|
@@ -25,11 +24,11 @@ class FileBasedMessaging extends MessagingService {
|
|
|
25
24
|
const e = _msg.event
|
|
26
25
|
delete _msg.event
|
|
27
26
|
await this.queued(lock)(this.file)
|
|
28
|
-
LOG._debug && LOG.debug('Emit', { topic: e, file: this.file })
|
|
27
|
+
this.LOG._debug && this.LOG.debug('Emit', { topic: e, file: this.file })
|
|
29
28
|
try {
|
|
30
29
|
await fs.appendFile(this.file, `\n${e} ${JSON.stringify(_msg)}`)
|
|
31
30
|
} catch (e) {
|
|
32
|
-
LOG._debug && LOG.debug('Error', e)
|
|
31
|
+
this.LOG._debug && this.LOG.debug('Error', e)
|
|
33
32
|
} finally {
|
|
34
33
|
unlock(this.file)
|
|
35
34
|
}
|
|
@@ -53,9 +52,10 @@ class FileBasedMessaging extends MessagingService {
|
|
|
53
52
|
if (this.subscribedTopics.has(topic)) {
|
|
54
53
|
const event = this.subscribedTopics.get(topic)
|
|
55
54
|
if (!event) return
|
|
55
|
+
// REVISIT: should we use this.dispatch instead of super.emit for inbound messages?
|
|
56
56
|
super
|
|
57
57
|
.emit({ event, ...json, inbound: true })
|
|
58
|
-
.catch(e => LOG.error('ERROR occured in asynchronous event processing:', e))
|
|
58
|
+
.catch(e => this.LOG.error('ERROR occured in asynchronous event processing:', e))
|
|
59
59
|
} else other.push(each + '\n')
|
|
60
60
|
}
|
|
61
61
|
} catch (e) {
|
|
@@ -65,7 +65,7 @@ class FileBasedMessaging extends MessagingService {
|
|
|
65
65
|
if (other.length < lines.length) await fs.writeFile(this.file, other.join(''))
|
|
66
66
|
this.recent = await touched(this.file)
|
|
67
67
|
} catch (e) {
|
|
68
|
-
LOG._debug && LOG.debug(e)
|
|
68
|
+
this.LOG._debug && this.LOG.debug(e)
|
|
69
69
|
} finally {
|
|
70
70
|
unlock(this.file)
|
|
71
71
|
}
|