UBERF-7583: Fix workspace upgrade (#6062)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2024-07-12 20:10:33 +07:00 committed by GitHub
parent e4192b27fc
commit c94076087d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 54 additions and 24 deletions

View File

@ -453,7 +453,7 @@ export class ApplyOperations extends TxOperations {
findAll: (_class, query, options?) => ops.client.findAll(_class, query, options),
searchFulltext: (query, options) => ops.client.searchFulltext(query, options),
tx: async (tx): Promise<TxResult> => {
if (ops.getHierarchy().isDerived(tx._class, core.class.TxCUD)) {
if (TxProcessor.isExtendsCUD(tx._class)) {
this.txes.push(tx as TxCUD<Doc>)
}
return {}
@ -518,7 +518,7 @@ export class TxBuilder extends TxOperations {
findAll: async (_class, query, options?) => toFindResult([]),
searchFulltext: async (query, options) => ({ docs: [] }),
tx: async (tx): Promise<TxResult> => {
if (this.hierarchy.isDerived(tx._class, core.class.TxCUD)) {
if (TxProcessor.isExtendsCUD(tx._class)) {
this.txes.push(tx as TxCUD<Doc>)
}
return {}

View File

@ -438,6 +438,16 @@ export abstract class TxProcessor implements WithTx {
return doc as D
}
static isExtendsCUD (_class: Ref<Class<Doc>>): boolean {
return (
_class === core.class.TxCreateDoc ||
_class === core.class.TxUpdateDoc ||
_class === core.class.TxRemoveDoc ||
_class === core.class.TxCollectionCUD ||
_class === core.class.TxMixin
)
}
static extractTx (tx: Tx): Tx {
if (tx._class === core.class.TxCollectionCUD) {
const ctx = tx as TxCollectionCUD<Doc, AttachedDoc>

View File

@ -200,7 +200,7 @@ class UIClient extends TxOperations implements Client, OptimisticTxes {
return
}
if (!this.getHierarchy().isDerived(tx._class, core.class.TxCUD)) {
if (!TxProcessor.isExtendsCUD(tx._class)) {
return
}

View File

@ -303,7 +303,7 @@ export class AnalyticsMiddleware extends BasePresentationMiddleware implements P
const applyIf = etx as TxApplyIf
void this.handleTx(...applyIf.txes)
}
if (this.client.getHierarchy().isDerived(etx._class, core.class.TxCUD)) {
if (TxProcessor.isExtendsCUD(etx._class)) {
const cud = etx as TxCUD<Doc>
const _class = this.client.getHierarchy().getClass(cud.objectClass)
if (_class.label !== undefined) {

View File

@ -115,7 +115,7 @@ async function performCompletion (
export async function AsyncOnGPTRequest (tx: Tx, tc: TriggerControl): Promise<Tx[]> {
const actualTx = TxProcessor.extractTx(tx)
if (tc.hierarchy.isDerived(actualTx._class, core.class.TxCUD) && actualTx.modifiedBy !== openai.account.GPT) {
if (TxProcessor.isExtendsCUD(actualTx._class) && actualTx.modifiedBy !== openai.account.GPT) {
const cud: TxCUD<Doc> = actualTx as TxCUD<Doc>
//
if (tc.hierarchy.isDerived(cud.objectClass, chunter.class.ChatMessage)) {

View File

@ -33,6 +33,7 @@ import core, {
type TxCUD,
type TxCollectionCUD,
TxFactory,
TxProcessor,
type TxResult,
type WorkspaceId,
docKey,
@ -84,7 +85,7 @@ export class FullTextIndex implements WithFind {
attachedToClass = txcol.objectClass
tx = txcol.tx
}
if (this.hierarchy.isDerived(tx._class, core.class.TxCUD)) {
if (TxProcessor.isExtendsCUD(tx._class)) {
const cud = tx as TxCUD<Doc>
if (!isClassIndexable(this.hierarchy, cud.objectClass)) {

View File

@ -255,7 +255,7 @@ export class TServerStorage implements ServerStorage {
for (const tx of txes) {
const txCUD = TxProcessor.extractTx(tx) as TxCUD<Doc>
if (!this.hierarchy.isDerived(txCUD._class, core.class.TxCUD)) {
if (!TxProcessor.isExtendsCUD(txCUD._class)) {
// Skip unsupported tx
ctx.error('Unsupported transaction', tx)
continue
@ -444,6 +444,9 @@ export class TServerStorage implements ServerStorage {
if (query?.$search !== undefined) {
return await ctx.with(p + '-fulltext-find-all', {}, (ctx) => this.fulltext.findAll(ctx, clazz, query, options))
}
if (domain === DOMAIN_MODEL) {
return this.modelDb.findAllSync(clazz, query, options)
}
const st = Date.now()
const result = await ctx.with(
p + '-find-all',
@ -656,11 +659,11 @@ export class TServerStorage implements ServerStorage {
): Promise<void> => {
const classes = new Set<Ref<Class<Doc>>>()
for (const dtx of derived) {
if (this.hierarchy.isDerived(dtx._class, core.class.TxCUD)) {
if (TxProcessor.isExtendsCUD(dtx._class)) {
classes.add((dtx as TxCUD<Doc>).objectClass)
}
const etx = TxProcessor.extractTx(dtx)
if (this.hierarchy.isDerived(etx._class, core.class.TxCUD)) {
if (TxProcessor.isExtendsCUD(etx._class)) {
classes.add((etx as TxCUD<Doc>).objectClass)
}
}
@ -876,7 +879,7 @@ export class TServerStorage implements ServerStorage {
for (const tx of txes) {
if (!this.hierarchy.isDerived(tx._class, core.class.TxApplyIf)) {
if (tx.space !== core.space.DerivedTx) {
if (this.hierarchy.isDerived(tx._class, core.class.TxCUD)) {
if (TxProcessor.isExtendsCUD(tx._class)) {
const objectClass = (tx as TxCUD<Doc>).objectClass
if (
objectClass !== core.class.BenchmarkDoc &&

View File

@ -25,7 +25,8 @@ import core, {
MeasureContext,
Ref,
Tx,
TxCUD
TxCUD,
TxProcessor
} from '@hcengineering/core'
import platform, { PlatformError, Severity, Status } from '@hcengineering/platform'
import { Middleware, SessionContext, TxMiddlewareResult, type ServerStorage } from '@hcengineering/server-core'
@ -51,7 +52,7 @@ export class ConfigurationMiddleware extends BaseMiddleware implements Middlewar
}
async tx (ctx: SessionContext, tx: Tx): Promise<TxMiddlewareResult> {
if (this.storage.hierarchy.isDerived(tx._class, core.class.TxCUD)) {
if (TxProcessor.isExtendsCUD(tx._class)) {
const txCUD = tx as TxCUD<Doc>
const domain = this.storage.hierarchy.getDomain(txCUD.objectClass)
if (this.targetDomains.includes(domain)) {

View File

@ -26,6 +26,7 @@ import core, {
Ref,
Tx,
TxCUD,
TxProcessor,
systemAccountEmail
} from '@hcengineering/core'
import platform, { PlatformError, Severity, Status } from '@hcengineering/platform'
@ -50,7 +51,7 @@ export class PrivateMiddleware extends BaseMiddleware implements Middleware {
async tx (ctx: SessionContext, tx: Tx): Promise<TxMiddlewareResult> {
let target: string[] | undefined
if (this.storage.hierarchy.isDerived(tx._class, core.class.TxCUD)) {
if (TxProcessor.isExtendsCUD(tx._class)) {
const txCUD = tx as TxCUD<Doc>
const domain = this.storage.hierarchy.getDomain(txCUD.objectClass)
if (this.targetDomains.includes(domain)) {
@ -98,7 +99,7 @@ export class PrivateMiddleware extends BaseMiddleware implements Middleware {
)
;(findResult as FindResult<Doc> as FindResult<Tx>).filter(
(p) =>
!hierarchy.isDerived(p._class, core.class.TxCUD) ||
!TxProcessor.isExtendsCUD(p._class) ||
!targetClasses.has((p as TxCUD<Doc>).objectClass) ||
p.createdBy === account._id
)

View File

@ -250,9 +250,8 @@ export class SpacePermissionsMiddleware extends BaseMiddleware implements Middle
return
}
const h = this.storage.hierarchy
const actualTx = TxProcessor.extractTx(tx)
if (!h.isDerived(actualTx._class, core.class.TxCUD)) {
if (!TxProcessor.isExtendsCUD(actualTx._class)) {
return
}
@ -322,8 +321,7 @@ export class SpacePermissionsMiddleware extends BaseMiddleware implements Middle
}
private async processPermissionsUpdatesFromTx (ctx: SessionContext, tx: Tx): Promise<void> {
const h = this.storage.hierarchy
if (!h.isDerived(tx._class, core.class.TxCUD)) {
if (!TxProcessor.isExtendsCUD(tx._class)) {
return
}

View File

@ -328,7 +328,7 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
const h = this.storage.hierarchy
let targets: string[] | undefined
if (h.isDerived(tx._class, core.class.TxCUD)) {
if (TxProcessor.isExtendsCUD(tx._class)) {
const account = await getUser(this.storage, ctx)
if (tx.objectSpace === (account._id as string)) {
targets = [account.email, systemAccountEmail]
@ -384,7 +384,7 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
private async processTx (ctx: SessionContext, tx: Tx): Promise<void> {
const h = this.storage.hierarchy
if (h.isDerived(tx._class, core.class.TxCUD)) {
if (TxProcessor.isExtendsCUD(tx._class)) {
const cudTx = tx as TxCUD<Doc>
const isSpace = h.isDerived(cudTx.objectClass, core.class.Space)
if (isSpace) {
@ -429,8 +429,7 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
exclude?: string[] | undefined
): Promise<void> {
for (const tx of txes) {
const h = this.storage.hierarchy
if (h.isDerived(tx._class, core.class.TxCUD)) {
if (TxProcessor.isExtendsCUD(tx._class)) {
// TODO: Do we need security check here?
const cudTx = tx as TxCUD<Doc>
await this.processTxSpaceDomain(cudTx)

View File

@ -28,6 +28,8 @@ import core, {
MeasureContext,
MigrationState,
ModelDb,
systemAccountEmail,
toWorkspaceString,
Tx,
WorkspaceId,
type Doc,
@ -44,6 +46,7 @@ import toolPlugin from './plugin'
import { MigrateClientImpl } from './upgrade'
import { getMetadata } from '@hcengineering/platform'
import { generateToken } from '@hcengineering/server-token'
import fs from 'fs'
import path from 'path'
@ -411,6 +414,20 @@ export async function upgradeModel (
i++
}
})
if (connection === undefined) {
// We need to send reboot for workspace
console.info('send force close')
const serverEndpoint = transactorUrl.replaceAll('wss://', 'https://').replace('ws://', 'http://')
const token = generateToken(systemAccountEmail, workspaceId, { admin: 'true' })
await fetch(
serverEndpoint +
`/api/v1/manage?token=${token}&operation=force-close&wsId=${toWorkspaceString(workspaceId, '@')}`,
{
method: 'PUT'
}
)
}
} finally {
await connection?.sendForceClose()
await connection?.close()

View File

@ -305,11 +305,11 @@ export class ClientSession implements Session {
): Promise<void> {
const classes = new Set<Ref<Class<Doc>>>()
for (const dtx of derived) {
if (this._pipeline.storage.hierarchy.isDerived(dtx._class, core.class.TxCUD)) {
if (TxProcessor.isExtendsCUD(dtx._class)) {
classes.add((dtx as TxCUD<Doc>).objectClass)
}
const etx = TxProcessor.extractTx(dtx)
if (this._pipeline.storage.hierarchy.isDerived(etx._class, core.class.TxCUD)) {
if (TxProcessor.isExtendsCUD(etx._class)) {
classes.add((etx as TxCUD<Doc>).objectClass)
}
}