Merge remote-tracking branch 'origin/master' into

2428-feature-federation-implement-multiple-apollo-graphql-endpoints
plus validateCommunities-Tests
This commit is contained in:
Claus-Peter Hübner 2023-01-18 02:05:49 +01:00
parent 9769cf7610
commit 15cb8dff3a
2 changed files with 196 additions and 33 deletions

View File

@ -0,0 +1,159 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import CONFIG from '@/config'
import { logger } from '@test/testSetup'
import { Community as DbCommunity } from '@entity/Community'
import { testEnvironment, cleanDB } from '@test/helpers'
import { startValidateCommunities, validateCommunities } from './validateCommunities'
let con: any
let testEnv: any
beforeAll(async () => {
testEnv = await testEnvironment(logger)
con = testEnv.con
await cleanDB()
})
afterAll(async () => {
// await cleanDB()
await con.close()
})
describe('validate Communities', () => {
/*
describe('start validation loop', () => {
beforeEach(async () => {
jest.clearAllMocks()
startValidateCommunities(0)
})
it('logs loop started', () => {
expect(logger.info).toBeCalledWith(
`Federation: startValidateCommunities loop with an interval of 0 ms...`,
)
})
})
*/
describe('start validation logic without loop', () => {
beforeEach(async () => {
jest.clearAllMocks()
await validateCommunities()
})
it('logs zero communities found', () => {
expect(logger.debug).toBeCalledWith(`Federation: found 0 dbCommunities`)
})
describe('with one Community of api 1_0', () => {
beforeEach(async () => {
const variables1 = {
publicKey: Buffer.from('11111111111111111111111111111111'),
apiVersion: '1_0',
endPoint: 'http//localhost:5001/api/',
lastAnnouncedAt: new Date(),
}
await DbCommunity.createQueryBuilder()
.insert()
.into(DbCommunity)
.values(variables1)
.orUpdate({
conflict_target: ['id', 'publicKey', 'apiVersion'],
overwrite: ['end_point', 'last_announced_at'],
})
.execute()
jest.clearAllMocks()
await validateCommunities()
})
it('logs one community found', () => {
expect(logger.debug).toBeCalledWith(`Federation: found 1 dbCommunities`)
})
it('logs requestGetPublicKey for community api 1_0 ', () => {
expect(logger.info).toBeCalledWith(
`requestGetPublicKey with endpoint='http//localhost:5001/api/1_0/getPublicKey'...`,
)
})
})
describe('with two Communities of api 1_0 and 1_1', () => {
beforeEach(async () => {
const variables2 = {
publicKey: Buffer.from('11111111111111111111111111111111'),
apiVersion: '1_1',
endPoint: 'http//localhost:5001/api/',
lastAnnouncedAt: new Date(),
}
await DbCommunity.createQueryBuilder()
.insert()
.into(DbCommunity)
.values(variables2)
.orUpdate({
conflict_target: ['id', 'publicKey', 'apiVersion'],
overwrite: ['end_point', 'last_announced_at'],
})
.execute()
jest.clearAllMocks()
await validateCommunities()
})
it('logs two communities found', () => {
expect(logger.debug).toBeCalledWith(`Federation: found 2 dbCommunities`)
})
it('logs requestGetPublicKey for community api 1_0 ', () => {
expect(logger.info).toBeCalledWith(
`requestGetPublicKey with endpoint='http//localhost:5001/api/1_0/getPublicKey'...`,
)
})
it('logs requestGetPublicKey for community api 1_1 ', () => {
expect(logger.info).toBeCalledWith(
`requestGetPublicKey with endpoint='http//localhost:5001/api/1_1/getPublicKey'...`,
)
})
})
describe('with three Communities of api 1_0, 1_1 and 2_0', () => {
let dbCom: DbCommunity
beforeEach(async () => {
const variables3 = {
publicKey: Buffer.from('11111111111111111111111111111111'),
apiVersion: '2_0',
endPoint: 'http//localhost:5001/api/',
lastAnnouncedAt: new Date(),
}
await DbCommunity.createQueryBuilder()
.insert()
.into(DbCommunity)
.values(variables3)
.orUpdate({
conflict_target: ['id', 'publicKey', 'apiVersion'],
overwrite: ['end_point', 'last_announced_at'],
})
.execute()
dbCom = await DbCommunity.findOneOrFail({
where: { publicKey: variables3.publicKey, apiVersion: variables3.apiVersion },
})
jest.clearAllMocks()
await validateCommunities()
})
it('logs three community found', () => {
expect(logger.debug).toBeCalledWith(`Federation: found 3 dbCommunities`)
})
it('logs requestGetPublicKey for community api 1_0 ', () => {
expect(logger.info).toBeCalledWith(
`requestGetPublicKey with endpoint='http//localhost:5001/api/1_0/getPublicKey'...`,
)
})
it('logs requestGetPublicKey for community api 1_1 ', () => {
expect(logger.info).toBeCalledWith(
`requestGetPublicKey with endpoint='http//localhost:5001/api/1_1/getPublicKey'...`,
)
})
it('logs unsupported api for community with api 2_0 ', () => {
expect(logger.warn).toBeCalledWith(
`Federation: dbCom: ${dbCom.id} with unsupported apiVersion=2_0; supported versions=1_0,1_1`,
)
})
})
})
})

View File

@ -12,45 +12,49 @@ export async function startValidateCommunities(timerInterval: number): Promise<v
`Federation: startValidateCommunities loop with an interval of ${timerInterval} ms...`,
)
while (true) {
const dbCommunities: DbCommunity[] = await DbCommunity.createQueryBuilder()
.where({ verifiedAt: IsNull() })
.orWhere('verified_at < last_announced_at')
.getMany()
/*
const dbCommunities: DbCommunity[] = await DbCommunity.getRepository().manager.query(
'SELECT * FROM `communities` `Community` WHERE (`Community`.`verified_at` IS NULL OR `Community`.`verified_at` < `Community`.`last_announced_at`)',
)
*/
logger.debug(`Federation: found ${dbCommunities.length} dbCommunities`)
if (dbCommunities) {
dbCommunities.forEach(async function (dbCom) {
logger.debug(`Federation: dbCom: ${JSON.stringify(dbCom)}`)
const apiValueStrings: string[] = Object.values(ApiVersionType)
logger.debug(`suppported ApiVersions=`, apiValueStrings)
if (apiValueStrings.includes(dbCom.apiVersion)) {
logger.debug(
`Federation: validate publicKey for dbCom: ${dbCom.id} with apiVersion=${dbCom.apiVersion}`,
)
const pubKey = await invokeVersionedRequestGetPublicKey(dbCom)
logger.debug(`Federation: received publicKey: ${pubKey}`)
if (pubKey && pubKey === dbCom.publicKey.toString('hex')) {
logger.debug(`Federation: matching publicKey: ${pubKey}`)
DbCommunity.update({ id: dbCom.id }, { verifiedAt: new Date() })
logger.debug(`Federation: updated dbCom: ${JSON.stringify(dbCom)}`)
}
} else {
logger.debug(
`Federation: dbCom: ${dbCom.id} with unsupported apiVersion=${dbCom.apiVersion}; supported versions=${apiValueStrings}`,
)
}
})
}
validateCommunities()
logger.debug(`Federation: loop starts sleeping...`)
await sleep(timerInterval)
logger.debug(`Federation: loop ends sleeping`)
}
}
export async function validateCommunities(): Promise<void> {
const dbCommunities: DbCommunity[] = await DbCommunity.createQueryBuilder()
.where({ verifiedAt: IsNull() })
.orWhere('verified_at < last_announced_at')
.getMany()
/*
const dbCommunities: DbCommunity[] = await DbCommunity.getRepository().manager.query(
'SELECT * FROM `communities` `Community` WHERE (`Community`.`verified_at` IS NULL OR `Community`.`verified_at` < `Community`.`last_announced_at`)',
)
*/
logger.debug(`Federation: found ${dbCommunities.length} dbCommunities`)
if (dbCommunities) {
dbCommunities.forEach(async function (dbCom) {
logger.debug(`Federation: dbCom: ${JSON.stringify(dbCom)}`)
const apiValueStrings: string[] = Object.values(ApiVersionType)
logger.debug(`suppported ApiVersions=`, apiValueStrings)
if (apiValueStrings.includes(dbCom.apiVersion)) {
logger.debug(
`Federation: validate publicKey for dbCom: ${dbCom.id} with apiVersion=${dbCom.apiVersion}`,
)
const pubKey = await invokeVersionedRequestGetPublicKey(dbCom)
logger.debug(`Federation: received publicKey: ${pubKey}`)
if (pubKey && pubKey === dbCom.publicKey.toString('hex')) {
logger.debug(`Federation: matching publicKey: ${pubKey}`)
DbCommunity.update({ id: dbCom.id }, { verifiedAt: new Date() })
logger.debug(`Federation: updated dbCom: ${JSON.stringify(dbCom)}`)
}
} else {
logger.warn(
`Federation: dbCom: ${dbCom.id} with unsupported apiVersion=${dbCom.apiVersion}; supported versions=${apiValueStrings}`,
)
}
})
}
}
function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms))
}