mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-15 12:55:59 +00:00
UBERF-7583: Fix workspace upgrade (#6062)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
e4192b27fc
commit
c94076087d
@ -453,7 +453,7 @@ export class ApplyOperations extends TxOperations {
|
|||||||
findAll: (_class, query, options?) => ops.client.findAll(_class, query, options),
|
findAll: (_class, query, options?) => ops.client.findAll(_class, query, options),
|
||||||
searchFulltext: (query, options) => ops.client.searchFulltext(query, options),
|
searchFulltext: (query, options) => ops.client.searchFulltext(query, options),
|
||||||
tx: async (tx): Promise<TxResult> => {
|
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>)
|
this.txes.push(tx as TxCUD<Doc>)
|
||||||
}
|
}
|
||||||
return {}
|
return {}
|
||||||
@ -518,7 +518,7 @@ export class TxBuilder extends TxOperations {
|
|||||||
findAll: async (_class, query, options?) => toFindResult([]),
|
findAll: async (_class, query, options?) => toFindResult([]),
|
||||||
searchFulltext: async (query, options) => ({ docs: [] }),
|
searchFulltext: async (query, options) => ({ docs: [] }),
|
||||||
tx: async (tx): Promise<TxResult> => {
|
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>)
|
this.txes.push(tx as TxCUD<Doc>)
|
||||||
}
|
}
|
||||||
return {}
|
return {}
|
||||||
|
@ -438,6 +438,16 @@ export abstract class TxProcessor implements WithTx {
|
|||||||
return doc as D
|
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 {
|
static extractTx (tx: Tx): Tx {
|
||||||
if (tx._class === core.class.TxCollectionCUD) {
|
if (tx._class === core.class.TxCollectionCUD) {
|
||||||
const ctx = tx as TxCollectionCUD<Doc, AttachedDoc>
|
const ctx = tx as TxCollectionCUD<Doc, AttachedDoc>
|
||||||
|
@ -200,7 +200,7 @@ class UIClient extends TxOperations implements Client, OptimisticTxes {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.getHierarchy().isDerived(tx._class, core.class.TxCUD)) {
|
if (!TxProcessor.isExtendsCUD(tx._class)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +303,7 @@ export class AnalyticsMiddleware extends BasePresentationMiddleware implements P
|
|||||||
const applyIf = etx as TxApplyIf
|
const applyIf = etx as TxApplyIf
|
||||||
void this.handleTx(...applyIf.txes)
|
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 cud = etx as TxCUD<Doc>
|
||||||
const _class = this.client.getHierarchy().getClass(cud.objectClass)
|
const _class = this.client.getHierarchy().getClass(cud.objectClass)
|
||||||
if (_class.label !== undefined) {
|
if (_class.label !== undefined) {
|
||||||
|
@ -115,7 +115,7 @@ async function performCompletion (
|
|||||||
export async function AsyncOnGPTRequest (tx: Tx, tc: TriggerControl): Promise<Tx[]> {
|
export async function AsyncOnGPTRequest (tx: Tx, tc: TriggerControl): Promise<Tx[]> {
|
||||||
const actualTx = TxProcessor.extractTx(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>
|
const cud: TxCUD<Doc> = actualTx as TxCUD<Doc>
|
||||||
//
|
//
|
||||||
if (tc.hierarchy.isDerived(cud.objectClass, chunter.class.ChatMessage)) {
|
if (tc.hierarchy.isDerived(cud.objectClass, chunter.class.ChatMessage)) {
|
||||||
|
@ -33,6 +33,7 @@ import core, {
|
|||||||
type TxCUD,
|
type TxCUD,
|
||||||
type TxCollectionCUD,
|
type TxCollectionCUD,
|
||||||
TxFactory,
|
TxFactory,
|
||||||
|
TxProcessor,
|
||||||
type TxResult,
|
type TxResult,
|
||||||
type WorkspaceId,
|
type WorkspaceId,
|
||||||
docKey,
|
docKey,
|
||||||
@ -84,7 +85,7 @@ export class FullTextIndex implements WithFind {
|
|||||||
attachedToClass = txcol.objectClass
|
attachedToClass = txcol.objectClass
|
||||||
tx = txcol.tx
|
tx = txcol.tx
|
||||||
}
|
}
|
||||||
if (this.hierarchy.isDerived(tx._class, core.class.TxCUD)) {
|
if (TxProcessor.isExtendsCUD(tx._class)) {
|
||||||
const cud = tx as TxCUD<Doc>
|
const cud = tx as TxCUD<Doc>
|
||||||
|
|
||||||
if (!isClassIndexable(this.hierarchy, cud.objectClass)) {
|
if (!isClassIndexable(this.hierarchy, cud.objectClass)) {
|
||||||
|
@ -255,7 +255,7 @@ export class TServerStorage implements ServerStorage {
|
|||||||
|
|
||||||
for (const tx of txes) {
|
for (const tx of txes) {
|
||||||
const txCUD = TxProcessor.extractTx(tx) as TxCUD<Doc>
|
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
|
// Skip unsupported tx
|
||||||
ctx.error('Unsupported transaction', tx)
|
ctx.error('Unsupported transaction', tx)
|
||||||
continue
|
continue
|
||||||
@ -444,6 +444,9 @@ export class TServerStorage implements ServerStorage {
|
|||||||
if (query?.$search !== undefined) {
|
if (query?.$search !== undefined) {
|
||||||
return await ctx.with(p + '-fulltext-find-all', {}, (ctx) => this.fulltext.findAll(ctx, clazz, query, options))
|
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 st = Date.now()
|
||||||
const result = await ctx.with(
|
const result = await ctx.with(
|
||||||
p + '-find-all',
|
p + '-find-all',
|
||||||
@ -656,11 +659,11 @@ export class TServerStorage implements ServerStorage {
|
|||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
const classes = new Set<Ref<Class<Doc>>>()
|
const classes = new Set<Ref<Class<Doc>>>()
|
||||||
for (const dtx of derived) {
|
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)
|
classes.add((dtx as TxCUD<Doc>).objectClass)
|
||||||
}
|
}
|
||||||
const etx = TxProcessor.extractTx(dtx)
|
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)
|
classes.add((etx as TxCUD<Doc>).objectClass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -876,7 +879,7 @@ export class TServerStorage implements ServerStorage {
|
|||||||
for (const tx of txes) {
|
for (const tx of txes) {
|
||||||
if (!this.hierarchy.isDerived(tx._class, core.class.TxApplyIf)) {
|
if (!this.hierarchy.isDerived(tx._class, core.class.TxApplyIf)) {
|
||||||
if (tx.space !== core.space.DerivedTx) {
|
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
|
const objectClass = (tx as TxCUD<Doc>).objectClass
|
||||||
if (
|
if (
|
||||||
objectClass !== core.class.BenchmarkDoc &&
|
objectClass !== core.class.BenchmarkDoc &&
|
||||||
|
@ -25,7 +25,8 @@ import core, {
|
|||||||
MeasureContext,
|
MeasureContext,
|
||||||
Ref,
|
Ref,
|
||||||
Tx,
|
Tx,
|
||||||
TxCUD
|
TxCUD,
|
||||||
|
TxProcessor
|
||||||
} from '@hcengineering/core'
|
} from '@hcengineering/core'
|
||||||
import platform, { PlatformError, Severity, Status } from '@hcengineering/platform'
|
import platform, { PlatformError, Severity, Status } from '@hcengineering/platform'
|
||||||
import { Middleware, SessionContext, TxMiddlewareResult, type ServerStorage } from '@hcengineering/server-core'
|
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> {
|
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 txCUD = tx as TxCUD<Doc>
|
||||||
const domain = this.storage.hierarchy.getDomain(txCUD.objectClass)
|
const domain = this.storage.hierarchy.getDomain(txCUD.objectClass)
|
||||||
if (this.targetDomains.includes(domain)) {
|
if (this.targetDomains.includes(domain)) {
|
||||||
|
@ -26,6 +26,7 @@ import core, {
|
|||||||
Ref,
|
Ref,
|
||||||
Tx,
|
Tx,
|
||||||
TxCUD,
|
TxCUD,
|
||||||
|
TxProcessor,
|
||||||
systemAccountEmail
|
systemAccountEmail
|
||||||
} from '@hcengineering/core'
|
} from '@hcengineering/core'
|
||||||
import platform, { PlatformError, Severity, Status } from '@hcengineering/platform'
|
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> {
|
async tx (ctx: SessionContext, tx: Tx): Promise<TxMiddlewareResult> {
|
||||||
let target: string[] | undefined
|
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 txCUD = tx as TxCUD<Doc>
|
||||||
const domain = this.storage.hierarchy.getDomain(txCUD.objectClass)
|
const domain = this.storage.hierarchy.getDomain(txCUD.objectClass)
|
||||||
if (this.targetDomains.includes(domain)) {
|
if (this.targetDomains.includes(domain)) {
|
||||||
@ -98,7 +99,7 @@ export class PrivateMiddleware extends BaseMiddleware implements Middleware {
|
|||||||
)
|
)
|
||||||
;(findResult as FindResult<Doc> as FindResult<Tx>).filter(
|
;(findResult as FindResult<Doc> as FindResult<Tx>).filter(
|
||||||
(p) =>
|
(p) =>
|
||||||
!hierarchy.isDerived(p._class, core.class.TxCUD) ||
|
!TxProcessor.isExtendsCUD(p._class) ||
|
||||||
!targetClasses.has((p as TxCUD<Doc>).objectClass) ||
|
!targetClasses.has((p as TxCUD<Doc>).objectClass) ||
|
||||||
p.createdBy === account._id
|
p.createdBy === account._id
|
||||||
)
|
)
|
||||||
|
@ -250,9 +250,8 @@ export class SpacePermissionsMiddleware extends BaseMiddleware implements Middle
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const h = this.storage.hierarchy
|
|
||||||
const actualTx = TxProcessor.extractTx(tx)
|
const actualTx = TxProcessor.extractTx(tx)
|
||||||
if (!h.isDerived(actualTx._class, core.class.TxCUD)) {
|
if (!TxProcessor.isExtendsCUD(actualTx._class)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,8 +321,7 @@ export class SpacePermissionsMiddleware extends BaseMiddleware implements Middle
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async processPermissionsUpdatesFromTx (ctx: SessionContext, tx: Tx): Promise<void> {
|
private async processPermissionsUpdatesFromTx (ctx: SessionContext, tx: Tx): Promise<void> {
|
||||||
const h = this.storage.hierarchy
|
if (!TxProcessor.isExtendsCUD(tx._class)) {
|
||||||
if (!h.isDerived(tx._class, core.class.TxCUD)) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,7 +328,7 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
|
|||||||
const h = this.storage.hierarchy
|
const h = this.storage.hierarchy
|
||||||
let targets: string[] | undefined
|
let targets: string[] | undefined
|
||||||
|
|
||||||
if (h.isDerived(tx._class, core.class.TxCUD)) {
|
if (TxProcessor.isExtendsCUD(tx._class)) {
|
||||||
const account = await getUser(this.storage, ctx)
|
const account = await getUser(this.storage, ctx)
|
||||||
if (tx.objectSpace === (account._id as string)) {
|
if (tx.objectSpace === (account._id as string)) {
|
||||||
targets = [account.email, systemAccountEmail]
|
targets = [account.email, systemAccountEmail]
|
||||||
@ -384,7 +384,7 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
|
|||||||
|
|
||||||
private async processTx (ctx: SessionContext, tx: Tx): Promise<void> {
|
private async processTx (ctx: SessionContext, tx: Tx): Promise<void> {
|
||||||
const h = this.storage.hierarchy
|
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 cudTx = tx as TxCUD<Doc>
|
||||||
const isSpace = h.isDerived(cudTx.objectClass, core.class.Space)
|
const isSpace = h.isDerived(cudTx.objectClass, core.class.Space)
|
||||||
if (isSpace) {
|
if (isSpace) {
|
||||||
@ -429,8 +429,7 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
|
|||||||
exclude?: string[] | undefined
|
exclude?: string[] | undefined
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
for (const tx of txes) {
|
for (const tx of txes) {
|
||||||
const h = this.storage.hierarchy
|
if (TxProcessor.isExtendsCUD(tx._class)) {
|
||||||
if (h.isDerived(tx._class, core.class.TxCUD)) {
|
|
||||||
// TODO: Do we need security check here?
|
// TODO: Do we need security check here?
|
||||||
const cudTx = tx as TxCUD<Doc>
|
const cudTx = tx as TxCUD<Doc>
|
||||||
await this.processTxSpaceDomain(cudTx)
|
await this.processTxSpaceDomain(cudTx)
|
||||||
|
@ -28,6 +28,8 @@ import core, {
|
|||||||
MeasureContext,
|
MeasureContext,
|
||||||
MigrationState,
|
MigrationState,
|
||||||
ModelDb,
|
ModelDb,
|
||||||
|
systemAccountEmail,
|
||||||
|
toWorkspaceString,
|
||||||
Tx,
|
Tx,
|
||||||
WorkspaceId,
|
WorkspaceId,
|
||||||
type Doc,
|
type Doc,
|
||||||
@ -44,6 +46,7 @@ import toolPlugin from './plugin'
|
|||||||
import { MigrateClientImpl } from './upgrade'
|
import { MigrateClientImpl } from './upgrade'
|
||||||
|
|
||||||
import { getMetadata } from '@hcengineering/platform'
|
import { getMetadata } from '@hcengineering/platform'
|
||||||
|
import { generateToken } from '@hcengineering/server-token'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
|
||||||
@ -411,6 +414,20 @@ export async function upgradeModel (
|
|||||||
i++
|
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 {
|
} finally {
|
||||||
await connection?.sendForceClose()
|
await connection?.sendForceClose()
|
||||||
await connection?.close()
|
await connection?.close()
|
||||||
|
@ -305,11 +305,11 @@ export class ClientSession implements Session {
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const classes = new Set<Ref<Class<Doc>>>()
|
const classes = new Set<Ref<Class<Doc>>>()
|
||||||
for (const dtx of derived) {
|
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)
|
classes.add((dtx as TxCUD<Doc>).objectClass)
|
||||||
}
|
}
|
||||||
const etx = TxProcessor.extractTx(dtx)
|
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)
|
classes.add((etx as TxCUD<Doc>).objectClass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user