@@ -9,6 +9,7 @@ import * as constants from './constants'
99import { asError } from './errors'
1010import flags from './flags'
1111import * as helper from './helper'
12+ import { amqpToMDC , getMdc } from './mdc'
1213import * as message from './message'
1314import { getPublishExchangeProps } from './message.process'
1415import {
@@ -42,7 +43,7 @@ export function getUserPublisher<T>(messageClass: ClassConstructor<T>) {
4243
4344 return async (
4445 msg : T ,
45- user : string | AmqpMessage ,
46+ user ? : string | AmqpMessage ,
4647 pubOpts ?: publishI . PublishOptionsI ,
4748 ) : Promise < boolean > => publishToUser ( messageClass , msg , user , pubOpts )
4849}
@@ -57,21 +58,21 @@ export const publish = async <T>(
5758 * Send the mesaage to `user` exchange,
5859 * ignoring the exchange set on event being published.
5960 *
60- * @{ param user} - user id or AmqpMessage
61+ * @param { string } [user] - user id or AmqpMessage
6162 * when processing a message from user, AmqpMessage can
6263 * be used to get user id from consumed message.
64+ *
65+ * When omitted it is obtained from the MDC via mdcProvider.
66+ *
67+ *
6368 */
6469export const publishToUser = async < T > (
6570 messageClass : ClassConstructor < T > ,
6671 msg : T ,
67- user : string | AmqpMessage ,
72+ user ? : string | AmqpMessage ,
6873 pubOpts ?: publishI . PublishOptionsI ,
6974) : Promise < boolean > => {
70- const userIdString = typeof user === 'string'
71- const hasOriginalMsg = ! userIdString && isAmqpMessageClass ( user )
72- const userId = userIdString
73- ? user
74- : _ . get ( user , `properties.headers[${ MESSAGE_HEADERS . MESSAGE . USER_ID } ]` )
75+ const userId = await obtainUserId ( user || pubOpts ?. amqpPublishOpts )
7576
7677 if ( ! _ . isString ( userId ) || _ . isEmpty ( userId ) ) {
7778 throw new Error ( 'ERR_IRIS_PUBLISHER_USER_ID_NOT_RESOLVED' )
@@ -81,7 +82,7 @@ export const publishToUser = async <T>(
8182 messageClass ,
8283 msg ,
8384 Object . assign ( { } , pubOpts , { userId } ) ,
84- hasOriginalMsg ? < AmqpMessage > user : undefined ,
85+ isAmqpMessageClass ( user ) ? < AmqpMessage > user : undefined ,
8586 message . Scope . USER ,
8687 )
8788}
@@ -122,7 +123,12 @@ async function internalPublish<T>(
122123 msgMeta ,
123124 msgString ,
124125 routingKey ,
125- getAmqpBasicProperties ( exchangeName , msgMeta , originalMessage , pubOpts ) ,
126+ await getAmqpBasicProperties (
127+ exchangeName ,
128+ msgMeta ,
129+ originalMessage ,
130+ pubOpts ,
131+ ) ,
126132 overrideScope ,
127133 )
128134}
@@ -133,6 +139,7 @@ export async function doPublish(
133139 routingKeyArg : string ,
134140 options ?: amqplib . Options . Publish ,
135141 overrideScope ?: message . Scope ,
142+ originalMessage ?: Pick < amqplib . Message , 'properties' > ,
136143) : Promise < boolean > {
137144 validateBeforePublish ( msgMeta , options , overrideScope )
138145
@@ -146,12 +153,25 @@ export async function doPublish(
146153
147154 const routingKey = publishingExchangeRoutingKey ?? routingKeyArg
148155
149- logger . debug ( TAG , `Publishing message to " ${ publishingExchangeName } "` , {
156+ const logInfo : any = {
150157 evt : msg ,
151158 routingKey,
152159 publishingExchangeName,
153160 options : amqpHelper . safeAmqpObjectForLogging ( options ) ,
154- } )
161+ }
162+
163+ const mdc =
164+ originalMessage !== undefined ? amqpToMDC ( originalMessage ) : await getMdc ( )
165+
166+ if ( mdc !== undefined ) {
167+ logInfo . mdc = mdc
168+ }
169+
170+ logger . debug (
171+ TAG ,
172+ `Publishing message to "${ publishingExchangeName } "` ,
173+ logInfo ,
174+ )
155175
156176 const channel = await connection . assureDefaultChannel ( )
157177
@@ -190,13 +210,13 @@ async function msg2String<T>(
190210 return JSON . stringify ( msg )
191211}
192212
193- function getAmqpBasicProperties (
213+ async function getAmqpBasicProperties (
194214 exchangeName : string ,
195215 msgMeta : message . ProcessedMessageMetadataI ,
196216 originalMsg ?: Pick < amqplib . Message , 'properties' > ,
197217 pubOpts ?: publishI . PublishOptionsI ,
198- ) : Partial < amqplib . MessageProperties > {
199- const amqpProperties = getAmqpPropsWithoutHeaders ( originalMsg , pubOpts )
218+ ) : Promise < Partial < amqplib . MessageProperties > > {
219+ const amqpProperties = await getAmqpPropsWithoutHeaders ( originalMsg , pubOpts )
200220 const amqpHeaders = getAmqpHeaders ( exchangeName , originalMsg , pubOpts )
201221
202222 // TODO: subscription updates, set cache ttl, subcription id etc.
@@ -208,11 +228,7 @@ function getAmqpBasicProperties(
208228
209229 if ( pubOpts ?. userId !== undefined ) {
210230 const serviceId = helper . getServiceName ( )
211- const correlationId = randomUUID ( )
212231
213- // when overriding user header make sure
214- // to clean possible existing event context properties
215- amqpProperties . correlationId = correlationId
216232 amqpHeaders [ MESSAGE_HEADERS . MESSAGE . ORIGIN_SERVICE_ID ] = serviceId
217233 amqpHeaders [ MESSAGE_HEADERS . MESSAGE . USER_ID ] = pubOpts . userId
218234 delete amqpHeaders [ MESSAGE_HEADERS . MESSAGE . ROUTER ]
@@ -225,12 +241,12 @@ function getAmqpBasicProperties(
225241 }
226242}
227243
228- function getAmqpPropsWithoutHeaders (
244+ async function getAmqpPropsWithoutHeaders (
229245 originalMsg ?: Pick < amqplib . Message , 'properties' > ,
230246 pubOpts ?: publishI . PublishOptionsI ,
231- ) : Partial < Omit < amqplib . MessageProperties , 'headers' > > {
247+ ) : Promise < Partial < Omit < amqplib . MessageProperties , 'headers' > > > {
232248 const forceOptions = pubOpts ?. amqpPublishOpts
233- const correlationId = randomUUID ( )
249+ const correlationId = ( await getMdc ( ) ) ?. requestId ?? randomUUID ( )
234250
235251 const inheritedProperties :
236252 | Omit < amqplib . MessageProperties , 'headers' >
@@ -295,3 +311,35 @@ function validateBeforePublish(
295311 }
296312 }
297313}
314+
315+ async function obtainUserId (
316+ user ?:
317+ | string
318+ | AmqpMessage
319+ | Pick < amqplib . Options . Publish , 'headers' | 'userId' > ,
320+ ) : Promise < string | undefined > {
321+ if ( typeof user === 'string' ) {
322+ return user
323+ }
324+
325+ if ( isAmqpMessageClass ( user ) ) {
326+ return (
327+ _ . get ( user , 'properties.userId' ) ||
328+ _ . get ( user , `properties.headers[${ MESSAGE_HEADERS . MESSAGE . USER_ID } ]` )
329+ )
330+ }
331+
332+ // MessageProperties
333+ if ( typeof user === 'object' ) {
334+ return (
335+ _ . get ( user , 'userId' ) ||
336+ _ . get ( user , `headers[${ MESSAGE_HEADERS . MESSAGE . USER_ID } ]` )
337+ )
338+ }
339+
340+ const mdc = await getMdc ( )
341+
342+ if ( mdc !== undefined ) {
343+ return mdc . userId
344+ }
345+ }
0 commit comments