Skip to content

Commit

Permalink
1623 add db publication (#667)
Browse files Browse the repository at this point in the history
  • Loading branch information
suwarnoong authored Feb 19, 2025
1 parent 46b97d5 commit 9fe5daf
Show file tree
Hide file tree
Showing 12 changed files with 156 additions and 19 deletions.
3 changes: 3 additions & 0 deletions functions/alp-db-credentials/import.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"./src/common/data-source/migrations/1700709870313-create-db-credential": "./src/common/data-source/migrations/1700709870313-create-db-credential.ts",
"./src/common/data-source/migrations/1706832297709-add-vocab-schema": "./src/common/data-source/migrations/1706832297709-add-vocab-schema.ts",
"./src/common/data-source/migrations/1739258149345-add-authentication-mode": "./src/common/data-source/migrations/1739258149345-add-authentication-mode.ts",
"./src/common/data-source/migrations/1739349524222-create-db-publication": "./src/common/data-source/migrations/1739349524222-create-db-publication.ts",
"./src/common/data-source/migration-data-source": "./src/common/data-source/migration-data-source.ts",
"./src/common/data-source/data-source": "./src/common/data-source/data-source.ts",
"./src/common/hook": "./src/common/hook/index.ts",
Expand All @@ -48,13 +49,15 @@
"./src/db/repository/db-credential.repository": "./src/db/repository/db-credential.repository.ts",
"./src/db/repository": "./src/db/repository/index.ts",
"./src/db/repository/db-extra.repository": "./src/db/repository/db-extra.repository.ts",
"./src/db/repository/db-publication.repository": "./src/db/repository/db-publication.repository.ts",
"./src/db/repository/db.repository": "./src/db/repository/db.repository.ts",
"./src/db/db.router.spec": "./src/db/db.router.spec.ts",
"./src/db/db.router": "./src/db/db.router.ts",
"./src/db/entity/db.entity": "./src/db/entity/db.entity.ts",
"./src/db/entity/db-credential.entity": "./src/db/entity/db-credential.entity.ts",
"./src/db/entity/db-extra.entity": "./src/db/entity/db-extra.entity.ts",
"./src/db/entity/db-vocab-schema.entity": "./src/db/entity/db-vocab-schema.entity.ts",
"./src/db/entity/db-publication.entity": "./src/db/entity/db-publication.entity.ts",
"./src/db/entity": "./src/db/entity/index.ts",
"./src/db/db.service": "./src/db/db.service.ts",
"./src/vocab/vocab.router": "./src/vocab/vocab.router.ts",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Database } from '../../db/entity/db.entity'
import { DbCredential } from '../../db/entity/db-credential.entity'
import { DbExtra } from '../../db/entity/db-extra.entity'
import { DbVocabSchema } from '../../db/entity/db-vocab-schema.entity'
import { DbPublication } from '../../db/entity/db-publication.entity'

const logger = createLogger('DataSource')

Expand Down Expand Up @@ -40,7 +41,7 @@ export const dataSourceOptions: DataSourceOptions = {
ssl: getSsl(),
poolSize: env.PG_MAX_POOL,
logging: getLogLevels(),
entities: [Audit, Database, DbCredential, DbExtra, DbVocabSchema]
entities: [Audit, Database, DbCredential, DbExtra, DbVocabSchema, DbPublication]
}

const dataSource = new DataSource(dataSourceOptions)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import { Database } from '../../db/entity/db.entity'
import { DbCredential } from '../../db/entity/db-credential.entity'
import { DbExtra } from '../../db/entity/db-extra.entity'
import { DbVocabSchema } from '../../db/entity/db-vocab-schema.entity'
import { DbPublication } from "../../db/entity/db-publication.entity";
import { CreateDbCredential1700709870313 } from './migrations/1700709870313-create-db-credential'
import { CreateDbExtra1701667241462 } from './migrations/1701667241462-create-db-extra'
import { AddUserScopeToDbCredential1703139369074 } from './migrations/1703139369074-add-user-scope-to-db-credential'
import { UpdateDbExtra1704846290461 } from './migrations/1704846290461-update-db-extra'
import { AddCodeToDb1706063894993 } from './migrations/1706063894993-add-code-to-db'
import { AddVocabSchema1706832297709 } from './migrations/1706832297709-add-vocab-schema'
import { AddAuthenticationMode1739258149345 } from './migrations/1739258149345-add-authentication-mode'
import { CreateDbPublication1739349524222 } from './migrations/1739349524222-create-db-publication'

const migrationDataSourceOptions: DataSourceOptions = {
type: 'postgres',
Expand All @@ -25,15 +27,16 @@ const migrationDataSourceOptions: DataSourceOptions = {
ssl: getSsl(),
poolSize: env.PG_MAX_POOL,
logging: getLogLevels(),
entities: [Audit, Database, DbCredential, DbExtra, DbVocabSchema],
entities: [Audit, Database, DbCredential, DbExtra, DbVocabSchema, DbPublication],
migrations: [
CreateDbCredential1700709870313,
CreateDbExtra1701667241462,
AddUserScopeToDbCredential1703139369074,
UpdateDbExtra1704846290461,
AddCodeToDb1706063894993,
AddVocabSchema1706832297709,
AddAuthenticationMode1739258149345
AddAuthenticationMode1739258149345,
CreateDbPublication1739349524222
]
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { MigrationInterface, QueryRunner } from 'typeorm'

export class CreateDbPublication1739349524222 implements MigrationInterface {
name = 'CreateDbPublication1739349524222'

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE "db_credentials_mgr"."db_publication" ("id" SERIAL NOT NULL, "publication" character varying NOT NULL, "slot" character varying NOT NULL, "db_id" uuid NOT NULL, "created_by" character varying NOT NULL, "created_date" TIMESTAMP NOT NULL DEFAULT now(), "modified_by" character varying NOT NULL, "modified_date" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "UQ_2c00d40454a74a07284f53c3e41" UNIQUE ("publication", "db_id"), CONSTRAINT "PK_692b25da07a6fce963c98a1c445" PRIMARY KEY ("id"))`
)
await queryRunner.query(
`ALTER TABLE "db_credentials_mgr"."db_publication" ADD CONSTRAINT "FK_90722678a5543b197d244e87fab" FOREIGN KEY ("db_id") REFERENCES "db_credentials_mgr"."db"("id") ON DELETE CASCADE ON UPDATE NO ACTION`
)
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "db_credentials_mgr"."db_publication" DROP CONSTRAINT "FK_90722678a5543b197d244e87fab"`
)
await queryRunner.query(`DROP TABLE "db_credentials_mgr"."db_publication"`)
}
}
67 changes: 52 additions & 15 deletions functions/alp-db-credentials/src/db/db.service.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import { Service } from 'typedi'
import { v4 as uuidv4 } from 'uuid'
import { createLogger } from '../logger'
import { DbRepository, DbExtraRepository, DbCredentialRepository, DbVocabSchemaRepository } from './repository'
import {
DbRepository,
DbExtraRepository,
DbCredentialRepository,
DbPublicationRepository,
DbVocabSchemaRepository
} from './repository'
import { DbDialect, IDbCredentialDto, IDbCredentialUpdateDto, IDbDto, IDbExtraDto, IDbUpdateDto } from '../types'
import { getReqContext } from '../common/hook'
import { SERVICE_SCOPE } from '../common/const'
import { IDbPublicationDto } from '../types'

@Service()
export class DbService {
Expand All @@ -14,7 +21,8 @@ export class DbService {
private readonly dbRepo: DbRepository,
private readonly dbExtraRepo: DbExtraRepository,
private readonly credentialRepo: DbCredentialRepository,
private readonly vocabSchemaRepo: DbVocabSchemaRepository
private readonly vocabSchemaRepo: DbVocabSchemaRepository,
private readonly publicationRepo: DbPublicationRepository
) {}

async list() {
Expand All @@ -32,13 +40,15 @@ export class DbService {
)
.leftJoinAndSelect('db.vocabSchemas', 'dbVocabSchema')
.leftJoinAndSelect('db.extra', 'dbExtra')
.leftJoinAndSelect('db.publications', 'dbPublication')
const result = await query.select(this.getDbColumns(isClientCredentials)).getMany()
return result.map(r => {
const { extra, vocabSchemas, ...entity } = r
const { extra, vocabSchemas, publications, ...entity } = r
return {
...entity,
extra,
vocabSchemas: vocabSchemas.map(vocabSchema => vocabSchema.name)
vocabSchemas: vocabSchemas.map(vocabSchema => vocabSchema.name),
publications
}
})
}
Expand All @@ -63,11 +73,11 @@ export class DbService {
if (grantType !== 'client_credentials') {
db.credentials.forEach(c => {
c.password = maskedValue
if(c !== undefined) delete c.salt
if (c !== undefined) delete c.salt
})
}

const extra = db.extra.find(ext => (ext !== undefined && ext.serviceScope === serviceScope))?.value
const extra = db.extra.find(ext => ext !== undefined && ext.serviceScope === serviceScope)?.value

return {
...db,
Expand All @@ -91,37 +101,40 @@ export class DbService {

async create(dbDto: IDbDto) {
const dbId = uuidv4()
const { credentials, extra, vocabSchemas, ...newDbDto } = dbDto
const { credentials, extra, vocabSchemas, publications, ...newDbDto } = dbDto

const credEntities = this.mapCredentialsToEntity(credentials, dbId)
const entity = this.dbRepo.create({
...newDbDto,
id: dbId,
extra: this.mapExtraToEntity(extra, dbId),
credentials: credEntities,
vocabSchemas: this.mapVocabSchemasToEntity(vocabSchemas, dbId)
vocabSchemas: this.mapVocabSchemasToEntity(vocabSchemas, dbId),
publications: this.mapPublicationsToEntity(publications, dbId)
})
await this.dbRepo.save(this.addOwner(entity))
this.logger.debug(`Created db: ${JSON.stringify(entity)}`)
return entity.id
}

async update(dbDto: IDbUpdateDto) {
const { id, name, port, host, vocabSchemas, extra } = dbDto
const { id, name, port, host, vocabSchemas, extra, publications } = dbDto

const existingDb = await this.dbRepo
const existingDb = (await this.dbRepo
.createQueryBuilder('db')
.leftJoinAndSelect('db.vocabSchemas', 'vocabSchema')
.leftJoinAndSelect('db.extra', 'dbExtra')
.leftJoinAndSelect('db.publications', 'dbPublication')
.where('db.id = :id', { id })
.getOne() as { vocabSchemas, extra, name, host, port }
.getOne()) as { vocabSchemas; extra; name; host; port; publications }

const {
vocabSchemas: existingVocabSchemaEntities,
extra: existingExtraEntities,
name: existingName,
host: existingHost,
port: existingPort
port: existingPort,
publications: existingPublicationEntities
} = existingDb

if (name !== existingName || host !== existingHost || port !== existingPort) {
Expand Down Expand Up @@ -152,16 +165,28 @@ export class DbService {
await this.dbExtraRepo.delete({ dbId: id })
}

if (publications) {
const pubEntities = this.mapPublicationsToEntity(publications, dbDto.id)
await this.publicationRepo.upsert(pubEntities, ['publication', 'dbId'])
existingPublicationEntities
.filter(o => pubEntities.find(n => o.publication === n.publication) === undefined)
.forEach(async existingPublication => {
await this.publicationRepo.delete({ publication: existingPublication.publication, dbId: id })
})
} else {
await this.publicationRepo.delete({ dbId: id })
}

this.logger.debug(`Updated db: ${JSON.stringify(dbDto)}`)
return id
}
async updateCredentials(dbDto: IDbCredentialUpdateDto) {
const { id, credentials } = dbDto
const existingDb = await this.dbRepo
const existingDb = (await this.dbRepo
.createQueryBuilder('db')
.leftJoinAndSelect('db.credentials', 'dbCredential')
.where('db.id = :id', { id })
.getOne() as { credentials }
.getOne()) as { credentials }

const { credentials: existingCredEntities } = existingDb
if (credentials) {
Expand Down Expand Up @@ -200,7 +225,9 @@ export class DbService {
'dbCredential.serviceScope',
'dbVocabSchema.name',
'dbExtra.value',
'dbExtra.serviceScope'
'dbExtra.serviceScope',
'dbPublication.publication',
'dbPublication.slot'
]
if (hasSecret) {
return [...baseColumns, 'dbCredential.password', 'dbCredential.salt']
Expand Down Expand Up @@ -247,4 +274,14 @@ export class DbService {
return this.vocabSchemaRepo.create(entity)
})
}

private mapPublicationsToEntity(publications: IDbPublicationDto[], dbId: string) {
return publications?.map(pub => {
const pubEntity = this.publicationRepo.create({
...pub,
dbId: dbId
})
return this.addOwner(pubEntity)
})
}
}
25 changes: 24 additions & 1 deletion functions/alp-db-credentials/src/db/dto/db.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import type {
IDbCredentialUpdateDto,
IDbDto,
IDbExtraDto,
IDbUpdateDto
IDbUpdateDto,
IDbPublicationDto
} from '../../types'
import { SERVICE_SCOPES, DB_DIALECTS, SERVICE_SCOPE, USER_SCOPES, AuthenticationMode } from '../../common/const'
import { IsExistingDb, IsValidSchema, IsValidSchemaUpdate } from '../../common/validator'
Expand Down Expand Up @@ -72,6 +73,12 @@ export class DbDto implements IDbDto {
@ArrayMinSize(1)
@IsValidSchema({ each: true })
vocabSchemas: string[]

@IsOptional()
@IsArray()
@ValidateNested({ each: true })
@Type(() => DbPublicationDto)
publications: DbPublicationDto[]
}

export class DbUpdateDto implements IDbUpdateDto {
Expand Down Expand Up @@ -101,6 +108,12 @@ export class DbUpdateDto implements IDbUpdateDto {
@ValidateNested()
@Type(() => DbExtraDto)
extra: DbExtraDto

@IsOptional()
@IsArray()
@ValidateNested({ each: true })
@Type(() => DbPublicationDto)
publications: DbPublicationDto[]
}

export class DbCredentialUpdateDto implements IDbCredentialUpdateDto {
Expand Down Expand Up @@ -142,3 +155,13 @@ export class DbCredentialDto implements IDbCredentialDto {
@IsIn(SERVICE_SCOPES)
serviceScope: string
}

export class DbPublicationDto implements IDbPublicationDto {
@IsNotEmpty()
@IsString()
publication: string

@IsNotEmpty()
@IsString()
slot: string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Entity, Column, ManyToOne, PrimaryGeneratedColumn, JoinColumn, Unique, type Relation } from 'typeorm'
import { Database } from './db.entity'
import { Audit } from '../../common/entity'

@Entity()
@Unique(['publication', 'dbId'])
export class DbPublication extends Audit {
@PrimaryGeneratedColumn()
id: number

@Column()
publication: string

@Column()
slot: string

@Column({ name: 'db_id' })
dbId: string

@ManyToOne(() => Database, db => db, {
onDelete: 'CASCADE'
})
@JoinColumn({ name: 'db_id' })
db: Relation<Database>
}
4 changes: 4 additions & 0 deletions functions/alp-db-credentials/src/db/entity/db.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Entity, Column, PrimaryColumn, OneToMany } from 'typeorm'
import { DbCredential } from './db-credential.entity'
import { DbExtra } from './db-extra.entity'
import { DbVocabSchema } from './db-vocab-schema.entity'
import { DbPublication } from './db-publication.entity'
import { Audit } from '../../common/entity'
import { AuthenticationMode } from '../../common/const'

Expand Down Expand Up @@ -36,4 +37,7 @@ export class Database extends Audit {

@OneToMany(() => DbVocabSchema, dbVocabSchema => dbVocabSchema.db, { nullable: true, cascade: ['insert'] })
vocabSchemas: DbVocabSchema[]

@OneToMany(() => DbPublication, dbPublication => dbPublication.db, { nullable: true, cascade: ['insert'] })
publications: DbPublication[]
}
1 change: 1 addition & 0 deletions functions/alp-db-credentials/src/db/entity/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './db.entity'
export * from './db-extra.entity'
export * from './db-credential.entity'
export * from './db-publication.entity'
export * from './db-vocab-schema.entity'
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Service } from 'typedi'
import { Repository } from 'typeorm'
import dataSource from '../../common/data-source/data-source'
import { DbPublication } from '../entity'

@Service()
export class DbPublicationRepository extends Repository<DbPublication> {
constructor() {
super(DbPublication, dataSource.createEntityManager())
}
}
1 change: 1 addition & 0 deletions functions/alp-db-credentials/src/db/repository/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './db.repository'
export * from './db-extra.repository'
export * from './db-credential.repository'
export * from './db-publication.repository'
export * from './db-vocab-schema.repository'
Loading

0 comments on commit 9fe5daf

Please sign in to comment.