Skip to content

Commit

Permalink
feat: add internal polling inbound transporter (#323)
Browse files Browse the repository at this point in the history
  • Loading branch information
TimoGlastra authored Jun 17, 2021
1 parent f2e3a06 commit 6dd273b
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 93 deletions.
57 changes: 7 additions & 50 deletions docs/getting-started/1-transports.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,65 +27,22 @@ agent.setOutboundTransporter(wsOutboundTransporter)

## Inbound Transport

Inbound transports allow you to receive messages from other agents. No inbound transports are exported from the framework at the moment. See the example transports below to get started.
Inbound transports allow you to receive messages from other agents. Only `PollingInboundTransporter` is exported from the framework at the moment. Make sure you provide a `mediatorUrl` if using the polling inbound transporters. See the example transports below for other inbound transports.

```ts
import { Agent, PollingInboundTransporter } from 'aries-framework'

const agentConfig = {
// ... agent config ... //
mediatorUrl: 'https://your-afj-mediator-url.com',
}

const someInboundTransport = new SomeInboundTransport()

const agent = new Agent(agentConfig)
agent.setInboundTransporter(someInboundTransport)
```

### Example `PollingInboundTransporter`

This is an example of a polling inbound transport. This is mostly useful for edge agents, that use a mediator to receive inbound messages. Make sure to provide a `mediatorUrl` in the agent config when using this transport. See [3. Routing](./3-routing.md) for more information.

```ts
import { Agent, InboundTransporter } from 'aries-framework'

// In React Native you don't have to import node-fetch
// Fetch is globally available in React Native
import fetch from 'node-fetch'

class PollingInboundTransporter implements InboundTransporter {
public stop: boolean
// Construct polling inbound transporter with optional polling interval in ms
const pollingInboundTransporter = new PollingInboundTransporter(5000)

public constructor() {
this.stop = false
}
public async start(agent: Agent) {
await this.registerMediator(agent)
}

public async registerMediator(agent: Agent) {
const mediatorUrl = agent.getMediatorUrl()

if (!mediatorUrl) {
throw new AriesFrameworkError(
'Agent has no mediator URL. Make sure to provide the `mediatorUrl` in the agent config.'
)
}

const mediatorInvitationUrl = await get(`${mediatorUrl}/invitation`)
const { verkey: mediatorVerkey } = JSON.parse(await get(`${mediatorUrl}/`))
await agent.routing.provision({
verkey: mediatorVerkey,
invitationUrl: mediatorInvitationUrl,
})
this.pollDownloadMessages(agent)
}

private async pollDownloadMessages(agent: Agent) {
while (!this.stop) {
await agent.routing.downloadMessages()
await sleep(5000)
}
}
}
agent.setInboundTransporter(pollingInboundTransporter)
```

### Example `HttpInboundTransporter`
Expand Down
2 changes: 0 additions & 2 deletions src/__tests__/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ export const genesisPath = process.env.GENESIS_TXN_PATH

export const publicDidSeed = process.env.TEST_AGENT_PUBLIC_DID_SEED ?? '000000000000000000000000Trustee9'

export const sleep = (ms: number) => new Promise((res) => setTimeout(res, ms))

export function getBaseConfig(name: string, extraConfig: Partial<InitConfig> = {}) {
const config: InitConfig = {
label: `Agent: ${name}`,
Expand Down
3 changes: 2 additions & 1 deletion src/__tests__/ledger.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import indy from 'indy-sdk'

import { Agent } from '../agent/Agent'
import { DID_IDENTIFIER_REGEX, VERKEY_REGEX, isFullVerkey, isAbbreviatedVerkey } from '../utils/did'
import { sleep } from '../utils/sleep'

import { genesisPath, getBaseConfig, sleep } from './helpers'
import { genesisPath, getBaseConfig } from './helpers'
import testLogger from './logger'

const faberConfig = getBaseConfig('Faber Ledger', { genesisPath })
Expand Down
49 changes: 49 additions & 0 deletions src/transport/PollingInboundTransporter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import type { Agent } from '../agent/Agent'
import type { InboundTransporter } from './InboundTransporter'

import { AriesFrameworkError } from '../error/AriesFrameworkError'
import { fetch } from '../utils/fetch'
import { sleep } from '../utils/sleep'

export class PollingInboundTransporter implements InboundTransporter {
public stop: boolean
private pollingInterval: number

public constructor(pollingInterval = 5000) {
this.stop = false
this.pollingInterval = pollingInterval
}

public async start(agent: Agent) {
await this.registerMediator(agent)
}

public async registerMediator(agent: Agent) {
const mediatorUrl = agent.getMediatorUrl()

if (!mediatorUrl) {
throw new AriesFrameworkError(
'Agent has no mediator URL. Make sure to provide the `mediatorUrl` in the agent config.'
)
}

const invitationResponse = await fetch(`${mediatorUrl}/invitation`)
const invitationUrl = await invitationResponse.text()

const mediatorDidResponse = await fetch(`${mediatorUrl}`)
const { verkey } = await mediatorDidResponse.json()

await agent.routing.provision({
verkey,
invitationUrl,
})
this.pollDownloadMessages(agent)
}

private async pollDownloadMessages(agent: Agent) {
while (!this.stop) {
await agent.routing.downloadMessages()
await sleep(this.pollingInterval)
}
}
}
1 change: 1 addition & 0 deletions src/transport/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './InboundTransporter'
export * from './OutboundTransporter'
export * from './HttpOutboundTransporter'
export * from './WsOutboundTransporter'
export * from './PollingInboundTransporter'
3 changes: 3 additions & 0 deletions src/utils/sleep.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function sleep(ms: number) {
return new Promise((res) => setTimeout(res, ms))
}
42 changes: 2 additions & 40 deletions tests/__tests__/e2e.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import type { InboundTransporter } from '../../src'

import { Agent, AriesFrameworkError, HttpOutboundTransporter } from '../../src'
import { getBaseConfig, sleep, waitForBasicMessage } from '../../src/__tests__/helpers'
import { Agent, HttpOutboundTransporter, PollingInboundTransporter } from '../../src'
import { getBaseConfig, waitForBasicMessage } from '../../src/__tests__/helpers'
import logger from '../../src/__tests__/logger'
import { get } from '../http'

Expand Down Expand Up @@ -93,39 +91,3 @@ describe('with mediator', () => {
expect(basicMessage.content).toBe(message)
})
})

class PollingInboundTransporter implements InboundTransporter {
public stop: boolean

public constructor() {
this.stop = false
}
public async start(agent: Agent) {
await this.registerMediator(agent)
}

public async registerMediator(agent: Agent) {
const mediatorUrl = agent.getMediatorUrl()

if (!mediatorUrl) {
throw new AriesFrameworkError(
'Agent has no mediator URL. Make sure to provide the `mediatorUrl` in the agent config.'
)
}

const mediatorInvitationUrl = await get(`${mediatorUrl}/invitation`)
const { verkey: mediatorVerkey } = JSON.parse(await get(`${mediatorUrl}/`))
await agent.routing.provision({
verkey: mediatorVerkey,
invitationUrl: mediatorInvitationUrl,
})
this.pollDownloadMessages(agent)
}

private async pollDownloadMessages(agent: Agent) {
while (!this.stop) {
await agent.routing.downloadMessages()
await sleep(5000)
}
}
}

0 comments on commit 6dd273b

Please sign in to comment.