From 150b0bf8975343fa194cde4f685d861465ca6cb1 Mon Sep 17 00:00:00 2001 From: Timo Glastra Date: Sat, 25 Jun 2022 15:30:23 +0200 Subject: [PATCH] feat: add agent context provider Signed-off-by: Timo Glastra --- packages/core/src/agent/Agent.ts | 36 ++++++++++++++----- packages/core/src/agent/AgentContext.ts | 17 --------- packages/core/src/agent/EnvelopeService.ts | 2 +- packages/core/src/agent/EventEmitter.ts | 2 +- packages/core/src/agent/Events.ts | 1 + packages/core/src/agent/MessageReceiver.ts | 23 +++++++++--- packages/core/src/agent/MessageSender.ts | 2 +- .../core/src/agent/context/AgentContext.ts | 14 ++++++++ .../src/agent/context/AgentContextProvider.ts | 17 +++++++++ .../src/agent/context/DefaultAgentContext.ts | 15 ++++++++ .../context/DefaultAgentContextProvider.ts | 20 +++++++++++ .../DefaultAgentContextProvider.test.ts | 20 +++++++++++ packages/core/src/agent/context/index.ts | 4 +++ packages/core/src/agent/index.ts | 2 +- .../src/agent/models/InboundMessageContext.ts | 2 +- packages/core/src/constants.ts | 1 + packages/core/src/index.ts | 3 +- .../core/src/modules/oob/OutOfBandModule.ts | 2 ++ .../proofs/ProofResponseCoordinator.ts | 2 +- .../__tests__/mediationRecipient.test.ts | 2 ++ .../modules/routing/handlers/BatchHandler.ts | 1 + .../services/MediationRecipientService.ts | 1 + .../src/transport/HttpOutboundTransport.ts | 5 ++- packages/core/tests/mocks/MockAgentContext.ts | 1 + .../src/transport/HttpInboundTransport.ts | 7 ++-- .../node/src/transport/WsInboundTransport.ts | 6 ++-- tests/transport/SubjectInboundTransport.ts | 4 ++- tests/transport/SubjectOutboundTransport.ts | 5 +-- 28 files changed, 171 insertions(+), 46 deletions(-) delete mode 100644 packages/core/src/agent/AgentContext.ts create mode 100644 packages/core/src/agent/context/AgentContext.ts create mode 100644 packages/core/src/agent/context/AgentContextProvider.ts create mode 100644 packages/core/src/agent/context/DefaultAgentContext.ts create mode 100644 packages/core/src/agent/context/DefaultAgentContextProvider.ts create mode 100644 packages/core/src/agent/context/__tests__/DefaultAgentContextProvider.test.ts create mode 100644 packages/core/src/agent/context/index.ts diff --git a/packages/core/src/agent/Agent.ts b/packages/core/src/agent/Agent.ts index a068134f73..eba4dde408 100644 --- a/packages/core/src/agent/Agent.ts +++ b/packages/core/src/agent/Agent.ts @@ -3,10 +3,10 @@ import type { InboundTransport } from '../transport/InboundTransport' import type { OutboundTransport } from '../transport/OutboundTransport' import type { InitConfig } from '../types' import type { Wallet } from '../wallet/Wallet' -import type { AgentContext } from './AgentContext' import type { AgentDependencies } from './AgentDependencies' import type { AgentMessageReceivedEvent } from './Events' import type { TransportSession } from './TransportService' +import type { AgentContext } from './context' import type { Subscription } from 'rxjs' import type { DependencyContainer } from 'tsyringe' @@ -38,12 +38,12 @@ import { WalletModule } from '../wallet/WalletModule' import { WalletError } from '../wallet/error' import { AgentConfig } from './AgentConfig' -import { DefaultAgentContext } from './AgentContext' import { EventEmitter } from './EventEmitter' import { AgentEventTypes } from './Events' import { MessageReceiver } from './MessageReceiver' import { MessageSender } from './MessageSender' import { TransportService } from './TransportService' +import { DefaultAgentContextProvider, DefaultAgentContext } from './context' export class Agent { protected agentConfig: AgentConfig @@ -115,16 +115,23 @@ export class Agent { ) } + this.walletService = this.container.resolve(IndyWallet) + + // Bind the default agent context to the container for use in modules etc. + this.agentContext = new DefaultAgentContext(this.walletService, this.agentConfig, 'default') + this.container.registerInstance(InjectionSymbols.AgentContext, this.agentContext) + + // If no agent context has been registered we use the default agent context. + if (!this.container.isRegistered(InjectionSymbols.AgentContextProvider)) { + const agentContextProvider = new DefaultAgentContextProvider(this.agentContext) + this.container.registerInstance(InjectionSymbols.AgentContextProvider, agentContextProvider) + } + // Resolve instances after everything is registered this.eventEmitter = this.container.resolve(EventEmitter) this.messageSender = this.container.resolve(MessageSender) this.messageReceiver = this.container.resolve(MessageReceiver) this.transportService = this.container.resolve(TransportService) - this.walletService = this.container.resolve(IndyWallet) - - // Bind the default agent context to the container for use in modules etc. - this.agentContext = new DefaultAgentContext(this.walletService, this.agentConfig) - this.container.registerInstance(InjectionSymbols.AgentContext, this.agentContext) // We set the modules in the constructor because that allows to set them as read-only this.connections = this.container.resolve(ConnectionsModule) @@ -147,8 +154,9 @@ export class Agent { .pipe( takeUntil(this.stop$), concatMap((e) => - this.messageReceiver.receiveMessage(this.agentContext, e.payload.message, { + this.messageReceiver.receiveMessage(e.payload.message, { connection: e.payload.connection, + contextCorrelationId: e.payload.contextCorrelationId, }) ) ) @@ -278,8 +286,18 @@ export class Agent { return this.walletService.publicDid } + /** + * Receive a message. This should mainly be used for receiving connection-less messages. + * + * If you want to receive messages that originated from e.g. a transport make sure to use the {@link MessageReceiver} + * for this. The `receiveMessage` method on the `Agent` class will associate the current context to the message, which + * may not be what should happen (e.g. in case of multi tenancy). + */ public async receiveMessage(inboundMessage: unknown, session?: TransportSession) { - return await this.messageReceiver.receiveMessage(this.agentContext, inboundMessage, { session }) + return await this.messageReceiver.receiveMessage(inboundMessage, { + session, + contextCorrelationId: this.agentContext.contextCorrelationId, + }) } public get injectionContainer() { diff --git a/packages/core/src/agent/AgentContext.ts b/packages/core/src/agent/AgentContext.ts deleted file mode 100644 index 647973016f..0000000000 --- a/packages/core/src/agent/AgentContext.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { Wallet } from '../wallet' -import type { AgentConfig } from './AgentConfig' - -export interface AgentContext { - wallet: Wallet - config: AgentConfig -} - -export class DefaultAgentContext implements AgentContext { - public readonly wallet: Wallet - public readonly config: AgentConfig - - public constructor(wallet: Wallet, config: AgentConfig) { - this.wallet = wallet - this.config = config - } -} diff --git a/packages/core/src/agent/EnvelopeService.ts b/packages/core/src/agent/EnvelopeService.ts index 58125e9944..bc4542b0ec 100644 --- a/packages/core/src/agent/EnvelopeService.ts +++ b/packages/core/src/agent/EnvelopeService.ts @@ -1,6 +1,6 @@ import type { EncryptedMessage, PlaintextMessage } from '../types' -import type { AgentContext } from './AgentContext' import type { AgentMessage } from './AgentMessage' +import type { AgentContext } from './context' import { inject, scoped, Lifecycle } from 'tsyringe' diff --git a/packages/core/src/agent/EventEmitter.ts b/packages/core/src/agent/EventEmitter.ts index ed1f709271..01c0ad9ee8 100644 --- a/packages/core/src/agent/EventEmitter.ts +++ b/packages/core/src/agent/EventEmitter.ts @@ -1,5 +1,5 @@ -import type { AgentContext } from './AgentContext' import type { BaseEvent } from './Events' +import type { AgentContext } from './context' import type { EventEmitter as NativeEventEmitter } from 'events' import { fromEventPattern, Subject } from 'rxjs' diff --git a/packages/core/src/agent/Events.ts b/packages/core/src/agent/Events.ts index f6bc64a7bb..9c34620ca4 100644 --- a/packages/core/src/agent/Events.ts +++ b/packages/core/src/agent/Events.ts @@ -16,6 +16,7 @@ export interface AgentMessageReceivedEvent extends BaseEvent { payload: { message: unknown connection?: ConnectionRecord + contextCorrelationId?: string } } diff --git a/packages/core/src/agent/MessageReceiver.ts b/packages/core/src/agent/MessageReceiver.ts index 134eed833f..4c61590e2a 100644 --- a/packages/core/src/agent/MessageReceiver.ts +++ b/packages/core/src/agent/MessageReceiver.ts @@ -1,10 +1,10 @@ import type { ConnectionRecord } from '../modules/connections' import type { InboundTransport } from '../transport' import type { PlaintextMessage, EncryptedMessage } from '../types' -import type { AgentContext } from './AgentContext' import type { AgentMessage } from './AgentMessage' import type { DecryptedMessageContext } from './EnvelopeService' import type { TransportSession } from './TransportService' +import type { AgentContext } from './context' import { inject, Lifecycle, scoped } from 'tsyringe' @@ -21,6 +21,7 @@ import { Dispatcher } from './Dispatcher' import { EnvelopeService } from './EnvelopeService' import { MessageSender } from './MessageSender' import { TransportService } from './TransportService' +import { AgentContextProvider } from './context' import { createOutboundMessage } from './helpers' import { InboundMessageContext } from './models/InboundMessageContext' @@ -32,6 +33,7 @@ export class MessageReceiver { private dispatcher: Dispatcher private logger: Logger private connectionService: ConnectionService + private agentContextProvider: AgentContextProvider public readonly inboundTransports: InboundTransport[] = [] public constructor( @@ -40,6 +42,7 @@ export class MessageReceiver { messageSender: MessageSender, connectionService: ConnectionService, dispatcher: Dispatcher, + @inject(InjectionSymbols.AgentContextProvider) agentContextProvider: AgentContextProvider, @inject(InjectionSymbols.Logger) logger: Logger ) { this.envelopeService = envelopeService @@ -47,6 +50,7 @@ export class MessageReceiver { this.messageSender = messageSender this.connectionService = connectionService this.dispatcher = dispatcher + this.agentContextProvider = agentContextProvider this.logger = logger } @@ -55,17 +59,26 @@ export class MessageReceiver { } /** - * Receive and handle an inbound DIDComm message. It will decrypt the message, transform it + * Receive and handle an inbound DIDComm message. It will determine the agent context, decrypt the message, transform it * to it's corresponding message class and finally dispatch it to the dispatcher. * * @param inboundMessage the message to receive and handle */ public async receiveMessage( - agentContext: AgentContext, inboundMessage: unknown, - { session, connection }: { session?: TransportSession; connection?: ConnectionRecord } + { + session, + connection, + contextCorrelationId, + }: { session?: TransportSession; connection?: ConnectionRecord; contextCorrelationId?: string } = {} ) { - this.logger.debug(`Agent ${agentContext.config.label} received message`) + this.logger.debug(`Agent received message`) + + // Find agent context for the inbound message + const agentContext = await this.agentContextProvider.getContextForInboundMessage(inboundMessage, { + contextCorrelationId, + }) + if (this.isEncryptedMessage(inboundMessage)) { await this.receiveEncryptedMessage(agentContext, inboundMessage as EncryptedMessage, session) } else if (this.isPlaintextMessage(inboundMessage)) { diff --git a/packages/core/src/agent/MessageSender.ts b/packages/core/src/agent/MessageSender.ts index b37f255a01..fd2d37fc9c 100644 --- a/packages/core/src/agent/MessageSender.ts +++ b/packages/core/src/agent/MessageSender.ts @@ -3,10 +3,10 @@ import type { DidDocument, Key } from '../modules/dids' import type { OutOfBandRecord } from '../modules/oob/repository' import type { OutboundTransport } from '../transport/OutboundTransport' import type { OutboundMessage, OutboundPackage, EncryptedMessage } from '../types' -import type { AgentContext } from './AgentContext' import type { AgentMessage } from './AgentMessage' import type { EnvelopeKeys } from './EnvelopeService' import type { TransportSession } from './TransportService' +import type { AgentContext } from './context' import { inject, Lifecycle, scoped } from 'tsyringe' diff --git a/packages/core/src/agent/context/AgentContext.ts b/packages/core/src/agent/context/AgentContext.ts new file mode 100644 index 0000000000..b5dfdcfbd7 --- /dev/null +++ b/packages/core/src/agent/context/AgentContext.ts @@ -0,0 +1,14 @@ +import type { Wallet } from '../../wallet' +import type { AgentConfig } from '../AgentConfig' + +export interface AgentContext { + readonly wallet: Wallet + readonly config: AgentConfig + + /** + * An identifier that allows to correlate this context across usages. An example of the contextCorrelationId could be + * the id of the `TenantRecord` that is associated with this context. The AgentContextProvider can use this identifier to + * correlate an inbound message to a specific context (if the message is not encrypted, it's impossible to correlate it to a tenant) + */ + readonly contextCorrelationId: string +} diff --git a/packages/core/src/agent/context/AgentContextProvider.ts b/packages/core/src/agent/context/AgentContextProvider.ts new file mode 100644 index 0000000000..09047d38b6 --- /dev/null +++ b/packages/core/src/agent/context/AgentContextProvider.ts @@ -0,0 +1,17 @@ +import type { AgentContext } from './AgentContext' + +export interface AgentContextProvider { + /** + * Find the agent context based for an inbound message. It's possible to provide a contextCorrelationId to make it + * easier for the context provider implementation to correlate inbound messages to the correct context. This can be useful if + * a plaintext message is passed and the context provider can't determine the context based on the recipient public keys + * of the inbound message. + * + * The implementation of this method could range from a very simple one that always returns the same context to + * a complex one that manages the context for a multi-tenant agent. + */ + getContextForInboundMessage( + inboundMessage: unknown, + options?: { contextCorrelationId?: string } + ): Promise +} diff --git a/packages/core/src/agent/context/DefaultAgentContext.ts b/packages/core/src/agent/context/DefaultAgentContext.ts new file mode 100644 index 0000000000..b35e1cf41e --- /dev/null +++ b/packages/core/src/agent/context/DefaultAgentContext.ts @@ -0,0 +1,15 @@ +import type { Wallet } from '../../wallet' +import type { AgentConfig } from '../AgentConfig' +import type { AgentContext } from './AgentContext' + +export class DefaultAgentContext implements AgentContext { + public readonly wallet: Wallet + public readonly config: AgentConfig + public readonly contextCorrelationId: string + + public constructor(wallet: Wallet, config: AgentConfig, contextCorrelationId: string) { + this.wallet = wallet + this.config = config + this.contextCorrelationId = contextCorrelationId + } +} diff --git a/packages/core/src/agent/context/DefaultAgentContextProvider.ts b/packages/core/src/agent/context/DefaultAgentContextProvider.ts new file mode 100644 index 0000000000..f2f4511cb1 --- /dev/null +++ b/packages/core/src/agent/context/DefaultAgentContextProvider.ts @@ -0,0 +1,20 @@ +import type { AgentContext } from './AgentContext' +import type { AgentContextProvider } from './AgentContextProvider' + +/** + * Default implementation of AgentContextProvider. + * + * Holds a single `AgentContext` instance that will be used for all messages, i.e. a + * a single tenant agent. + */ +export class DefaultAgentContextProvider implements AgentContextProvider { + private agentContext: AgentContext + + public constructor(agentContext: AgentContext) { + this.agentContext = agentContext + } + + public async getContextForInboundMessage(): Promise { + return this.agentContext + } +} diff --git a/packages/core/src/agent/context/__tests__/DefaultAgentContextProvider.test.ts b/packages/core/src/agent/context/__tests__/DefaultAgentContextProvider.test.ts new file mode 100644 index 0000000000..e1c3dfae0f --- /dev/null +++ b/packages/core/src/agent/context/__tests__/DefaultAgentContextProvider.test.ts @@ -0,0 +1,20 @@ +import type { AgentContextProvider } from '../AgentContextProvider' + +import { getAgentConfig } from '../../../../tests/helpers' +import { MockAgentContext } from '../../../../tests/mocks' +import { DefaultAgentContextProvider } from '../DefaultAgentContextProvider' + +const agentConfig = getAgentConfig('DefaultAgentContextProvider') + +describe('DefaultAgentContextProvider', () => { + describe('getContextForInboundMessage()', () => { + test('returns the agent context provided in the constructor', async () => { + const agentContext = new MockAgentContext(agentConfig) + const agentContextProvider: AgentContextProvider = new DefaultAgentContextProvider(agentContext) + + const message = {} + + await expect(agentContextProvider.getContextForInboundMessage(message)).resolves.toBe(agentContext) + }) + }) +}) diff --git a/packages/core/src/agent/context/index.ts b/packages/core/src/agent/context/index.ts new file mode 100644 index 0000000000..79ce4ea459 --- /dev/null +++ b/packages/core/src/agent/context/index.ts @@ -0,0 +1,4 @@ +export * from './AgentContext' +export * from './DefaultAgentContext' +export * from './AgentContextProvider' +export * from './DefaultAgentContextProvider' diff --git a/packages/core/src/agent/index.ts b/packages/core/src/agent/index.ts index 615455eb43..630b4d7e78 100644 --- a/packages/core/src/agent/index.ts +++ b/packages/core/src/agent/index.ts @@ -1 +1 @@ -export * from './AgentContext' +export * from './context' diff --git a/packages/core/src/agent/models/InboundMessageContext.ts b/packages/core/src/agent/models/InboundMessageContext.ts index 35c21acbe6..16874efb0e 100644 --- a/packages/core/src/agent/models/InboundMessageContext.ts +++ b/packages/core/src/agent/models/InboundMessageContext.ts @@ -1,7 +1,7 @@ import type { ConnectionRecord } from '../../modules/connections' import type { Key } from '../../modules/dids' -import type { AgentContext } from '../AgentContext' import type { AgentMessage } from '../AgentMessage' +import type { AgentContext } from '../context' import { AriesFrameworkError } from '../../error' diff --git a/packages/core/src/constants.ts b/packages/core/src/constants.ts index e2759b1f39..2bf75965d5 100644 --- a/packages/core/src/constants.ts +++ b/packages/core/src/constants.ts @@ -3,6 +3,7 @@ export const InjectionSymbols = { StorageService: Symbol('StorageService'), Logger: Symbol('Logger'), AgentContext: Symbol('AgentContext'), + AgentContextProvider: Symbol('AgentContextProvider'), AgentDependencies: Symbol('AgentDependencies'), Stop$: Symbol('Stop$'), FileSystem: Symbol('FileSystem'), diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 28a3490f46..e2024395fc 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,7 +1,8 @@ // reflect-metadata used for class-transformer + class-validator import 'reflect-metadata' -export { AgentContext } from './agent/AgentContext' +export { AgentContext } from './agent' +export { MessageReceiver } from './agent/MessageReceiver' export { Agent } from './agent/Agent' export { EventEmitter } from './agent/EventEmitter' export { Handler, HandlerInboundMessage } from './agent/Handler' diff --git a/packages/core/src/modules/oob/OutOfBandModule.ts b/packages/core/src/modules/oob/OutOfBandModule.ts index 5c5045cd62..b796963421 100644 --- a/packages/core/src/modules/oob/OutOfBandModule.ts +++ b/packages/core/src/modules/oob/OutOfBandModule.ts @@ -604,6 +604,7 @@ export class OutOfBandModule { payload: { message: plaintextMessage, connection: connectionRecord, + contextCorrelationId: this.agentContext.contextCorrelationId, }, }) } @@ -644,6 +645,7 @@ export class OutOfBandModule { type: AgentEventTypes.AgentMessageReceived, payload: { message: plaintextMessage, + contextCorrelationId: this.agentContext.contextCorrelationId, }, }) } diff --git a/packages/core/src/modules/proofs/ProofResponseCoordinator.ts b/packages/core/src/modules/proofs/ProofResponseCoordinator.ts index 92ff286b03..c85f6ee275 100644 --- a/packages/core/src/modules/proofs/ProofResponseCoordinator.ts +++ b/packages/core/src/modules/proofs/ProofResponseCoordinator.ts @@ -1,4 +1,4 @@ -import type { AgentContext } from '../../agent/AgentContext' +import type { AgentContext } from '../../agent/context' import type { ProofRecord } from './repository' import { scoped, Lifecycle } from 'tsyringe' diff --git a/packages/core/src/modules/routing/__tests__/mediationRecipient.test.ts b/packages/core/src/modules/routing/__tests__/mediationRecipient.test.ts index c6c3500f42..b55c465ae2 100644 --- a/packages/core/src/modules/routing/__tests__/mediationRecipient.test.ts +++ b/packages/core/src/modules/routing/__tests__/mediationRecipient.test.ts @@ -234,12 +234,14 @@ describe('MediationRecipientService', () => { type: AgentEventTypes.AgentMessageReceived, payload: { message: { first: 'value' }, + contextCorrelationId: agentContext.contextCorrelationId, }, }) expect(eventEmitter.emit).toHaveBeenNthCalledWith(2, agentContext, { type: AgentEventTypes.AgentMessageReceived, payload: { message: { second: 'value' }, + contextCorrelationId: agentContext.contextCorrelationId, }, }) }) diff --git a/packages/core/src/modules/routing/handlers/BatchHandler.ts b/packages/core/src/modules/routing/handlers/BatchHandler.ts index e5bcb31b1e..25b35f29b7 100644 --- a/packages/core/src/modules/routing/handlers/BatchHandler.ts +++ b/packages/core/src/modules/routing/handlers/BatchHandler.ts @@ -24,6 +24,7 @@ export class BatchHandler implements Handler { type: AgentEventTypes.AgentMessageReceived, payload: { message: message.message, + contextCorrelationId: messageContext.agentContext.contextCorrelationId, }, }) }) diff --git a/packages/core/src/modules/routing/services/MediationRecipientService.ts b/packages/core/src/modules/routing/services/MediationRecipientService.ts index 39139e2d3c..c64e0fde3c 100644 --- a/packages/core/src/modules/routing/services/MediationRecipientService.ts +++ b/packages/core/src/modules/routing/services/MediationRecipientService.ts @@ -315,6 +315,7 @@ export class MediationRecipientService { type: AgentEventTypes.AgentMessageReceived, payload: { message: attachment.getDataAsJson(), + contextCorrelationId: messageContext.agentContext.contextCorrelationId, }, }) } diff --git a/packages/core/src/transport/HttpOutboundTransport.ts b/packages/core/src/transport/HttpOutboundTransport.ts index 3f331d9ded..b15652b601 100644 --- a/packages/core/src/transport/HttpOutboundTransport.ts +++ b/packages/core/src/transport/HttpOutboundTransport.ts @@ -6,6 +6,7 @@ import type fetch from 'node-fetch' import { AbortController } from 'abort-controller' +import { MessageReceiver } from '../agent/MessageReceiver' import { AriesFrameworkError } from '../error/AriesFrameworkError' import { isValidJweStructure, JsonEncoder } from '../utils' @@ -81,7 +82,9 @@ export class HttpOutboundTransport implements OutboundTransport { ) return } - await this.agent.receiveMessage(encryptedMessage) + + const messageReceiver = this.agent.injectionContainer.resolve(MessageReceiver) + await messageReceiver.receiveMessage(encryptedMessage) } catch (error) { this.logger.debug('Unable to parse response message') } diff --git a/packages/core/tests/mocks/MockAgentContext.ts b/packages/core/tests/mocks/MockAgentContext.ts index 2e1a87dfc5..53e8dbf7ed 100644 --- a/packages/core/tests/mocks/MockAgentContext.ts +++ b/packages/core/tests/mocks/MockAgentContext.ts @@ -6,6 +6,7 @@ import { MockWallet } from './MockWallet' export class MockAgentContext implements AgentContext { public wallet: Wallet public config: AgentConfig + public contextCorrelationId = 'mock' public constructor(config: AgentConfig, wallet?: Wallet) { this.wallet = wallet ?? new MockWallet() diff --git a/packages/node/src/transport/HttpInboundTransport.ts b/packages/node/src/transport/HttpInboundTransport.ts index cc81adae30..53a15a2080 100644 --- a/packages/node/src/transport/HttpInboundTransport.ts +++ b/packages/node/src/transport/HttpInboundTransport.ts @@ -2,7 +2,7 @@ import type { InboundTransport, Agent, TransportSession, EncryptedMessage } from import type { Express, Request, Response } from 'express' import type { Server } from 'http' -import { DidCommMimeType, AriesFrameworkError, TransportService, utils } from '@aries-framework/core' +import { DidCommMimeType, AriesFrameworkError, TransportService, utils, MessageReceiver } from '@aries-framework/core' import express, { text } from 'express' export class HttpInboundTransport implements InboundTransport { @@ -30,6 +30,7 @@ export class HttpInboundTransport implements InboundTransport { public async start(agent: Agent) { const transportService = agent.injectionContainer.resolve(TransportService) + const messageReceiver = agent.injectionContainer.resolve(MessageReceiver) agent.config.logger.debug(`Starting HTTP inbound transport`, { port: this.port, @@ -40,7 +41,9 @@ export class HttpInboundTransport implements InboundTransport { try { const message = req.body const encryptedMessage = JSON.parse(message) - await agent.receiveMessage(encryptedMessage, session) + await messageReceiver.receiveMessage(encryptedMessage, { + session, + }) // If agent did not use session when processing message we need to send response here. if (!res.headersSent) { diff --git a/packages/node/src/transport/WsInboundTransport.ts b/packages/node/src/transport/WsInboundTransport.ts index 414416ccb3..6e593b3928 100644 --- a/packages/node/src/transport/WsInboundTransport.ts +++ b/packages/node/src/transport/WsInboundTransport.ts @@ -1,6 +1,6 @@ import type { Agent, InboundTransport, Logger, TransportSession, EncryptedMessage } from '@aries-framework/core' -import { AriesFrameworkError, TransportService, utils } from '@aries-framework/core' +import { AriesFrameworkError, TransportService, utils, MessageReceiver } from '@aries-framework/core' import WebSocket, { Server } from 'ws' export class WsInboundTransport implements InboundTransport { @@ -58,11 +58,13 @@ export class WsInboundTransport implements InboundTransport { } private listenOnWebSocketMessages(agent: Agent, socket: WebSocket, session: TransportSession) { + const messageReceiver = agent.injectionContainer.resolve(MessageReceiver) + // eslint-disable-next-line @typescript-eslint/no-explicit-any socket.addEventListener('message', async (event: any) => { this.logger.debug('WebSocket message event received.', { url: event.target.url, data: event.data }) try { - await agent.receiveMessage(JSON.parse(event.data), session) + await messageReceiver.receiveMessage(JSON.parse(event.data), { session }) } catch (error) { this.logger.error('Error processing message') } diff --git a/tests/transport/SubjectInboundTransport.ts b/tests/transport/SubjectInboundTransport.ts index f50e0b4d04..d6578c738c 100644 --- a/tests/transport/SubjectInboundTransport.ts +++ b/tests/transport/SubjectInboundTransport.ts @@ -3,6 +3,7 @@ import type { TransportSession } from '../../packages/core/src/agent/TransportSe import type { EncryptedMessage } from '../../packages/core/src/types' import type { Subject, Subscription } from 'rxjs' +import { MessageReceiver } from '../../packages/core/src' import { TransportService } from '../../packages/core/src/agent/TransportService' import { uuid } from '../../packages/core/src/utils/uuid' @@ -27,6 +28,7 @@ export class SubjectInboundTransport implements InboundTransport { private subscribe(agent: Agent) { const logger = agent.config.logger const transportService = agent.injectionContainer.resolve(TransportService) + const messageReceiver = agent.injectionContainer.resolve(MessageReceiver) this.subscription = this.ourSubject.subscribe({ next: async ({ message, replySubject }: SubjectMessage) => { @@ -44,7 +46,7 @@ export class SubjectInboundTransport implements InboundTransport { }) } - await agent.receiveMessage(message, session) + await messageReceiver.receiveMessage(message, { session }) }, }) } diff --git a/tests/transport/SubjectOutboundTransport.ts b/tests/transport/SubjectOutboundTransport.ts index 51f9dcd053..7a4cb16523 100644 --- a/tests/transport/SubjectOutboundTransport.ts +++ b/tests/transport/SubjectOutboundTransport.ts @@ -3,7 +3,7 @@ import type { OutboundPackage, OutboundTransport, Agent, Logger } from '@aries-f import { takeUntil, Subject, take } from 'rxjs' -import { InjectionSymbols, AriesFrameworkError } from '@aries-framework/core' +import { MessageReceiver, InjectionSymbols, AriesFrameworkError } from '@aries-framework/core' export class SubjectOutboundTransport implements OutboundTransport { private logger!: Logger @@ -29,6 +29,7 @@ export class SubjectOutboundTransport implements OutboundTransport { } public async sendMessage(outboundPackage: OutboundPackage) { + const messageReceiver = this.agent.injectionContainer.resolve(MessageReceiver) this.logger.debug(`Sending outbound message to endpoint ${outboundPackage.endpoint}`, { endpoint: outboundPackage.endpoint, }) @@ -53,7 +54,7 @@ export class SubjectOutboundTransport implements OutboundTransport { next: async ({ message }: SubjectMessage) => { this.logger.test('Received message') - await this.agent.receiveMessage(message) + await messageReceiver.receiveMessage(message) }, })