feat: sync all workspaces (#4353)
This commit is contained in:
@ -9,6 +9,16 @@ import { kebabCase } from 'src/utils/kebab-case';
|
|||||||
export class CommandLogger {
|
export class CommandLogger {
|
||||||
constructor(private readonly className: string) {}
|
constructor(private readonly className: string) {}
|
||||||
|
|
||||||
|
async createSubDirectory(subDirectory: string): Promise<void> {
|
||||||
|
const path = `./logs/${kebabCase(this.className)}/${subDirectory}`;
|
||||||
|
|
||||||
|
if (existsSync(path) === false) {
|
||||||
|
await fs.mkdir(path, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
async writeLog(
|
async writeLog(
|
||||||
fileName: string,
|
fileName: string,
|
||||||
data: unknown,
|
data: unknown,
|
||||||
|
|||||||
@ -64,4 +64,10 @@ export class WorkspaceService extends TypeOrmQueryService<Workspace> {
|
|||||||
|
|
||||||
return workspace;
|
return workspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getWorkspaceIds() {
|
||||||
|
return this.workspaceRepository
|
||||||
|
.find()
|
||||||
|
.then((workspaces) => workspaces.map((workspace) => workspace.id));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,66 +13,70 @@ export class SyncWorkspaceLoggerService {
|
|||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
async saveLogs(
|
async saveLogs(
|
||||||
|
workspaceId: string,
|
||||||
storage: WorkspaceSyncStorage,
|
storage: WorkspaceSyncStorage,
|
||||||
workspaceMigrations: WorkspaceMigrationEntity[],
|
workspaceMigrations: WorkspaceMigrationEntity[],
|
||||||
) {
|
) {
|
||||||
|
// Create sub directory
|
||||||
|
await this.commandLogger.createSubDirectory(workspaceId);
|
||||||
|
|
||||||
// Save workspace migrations
|
// Save workspace migrations
|
||||||
await this.commandLogger.writeLog(
|
await this.commandLogger.writeLog(
|
||||||
'workspace-migrations',
|
`${workspaceId}/workspace-migrations`,
|
||||||
workspaceMigrations,
|
workspaceMigrations,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Save object metadata create collection
|
// Save object metadata create collection
|
||||||
await this.commandLogger.writeLog(
|
await this.commandLogger.writeLog(
|
||||||
'object-metadata-create-collection',
|
`${workspaceId}/object-metadata-create-collection`,
|
||||||
storage.objectMetadataCreateCollection,
|
storage.objectMetadataCreateCollection,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Save object metadata update collection
|
// Save object metadata update collection
|
||||||
await this.commandLogger.writeLog(
|
await this.commandLogger.writeLog(
|
||||||
'object-metadata-update-collection',
|
`${workspaceId}/object-metadata-update-collection`,
|
||||||
storage.objectMetadataUpdateCollection,
|
storage.objectMetadataUpdateCollection,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Save object metadata delete collection
|
// Save object metadata delete collection
|
||||||
await this.commandLogger.writeLog(
|
await this.commandLogger.writeLog(
|
||||||
'object-metadata-delete-collection',
|
`${workspaceId}/object-metadata-delete-collection`,
|
||||||
storage.objectMetadataDeleteCollection,
|
storage.objectMetadataDeleteCollection,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Save field metadata create collection
|
// Save field metadata create collection
|
||||||
await this.commandLogger.writeLog(
|
await this.commandLogger.writeLog(
|
||||||
'field-metadata-create-collection',
|
`${workspaceId}/field-metadata-create-collection`,
|
||||||
storage.fieldMetadataCreateCollection,
|
storage.fieldMetadataCreateCollection,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Save field metadata update collection
|
// Save field metadata update collection
|
||||||
await this.commandLogger.writeLog(
|
await this.commandLogger.writeLog(
|
||||||
'field-metadata-update-collection',
|
`${workspaceId}/field-metadata-update-collection`,
|
||||||
storage.fieldMetadataUpdateCollection,
|
storage.fieldMetadataUpdateCollection,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Save field metadata delete collection
|
// Save field metadata delete collection
|
||||||
await this.commandLogger.writeLog(
|
await this.commandLogger.writeLog(
|
||||||
'field-metadata-delete-collection',
|
`${workspaceId}/field-metadata-delete-collection`,
|
||||||
storage.fieldMetadataDeleteCollection,
|
storage.fieldMetadataDeleteCollection,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Save relation metadata create collection
|
// Save relation metadata create collection
|
||||||
await this.commandLogger.writeLog(
|
await this.commandLogger.writeLog(
|
||||||
'relation-metadata-create-collection',
|
`${workspaceId}/relation-metadata-create-collection`,
|
||||||
storage.relationMetadataCreateCollection,
|
storage.relationMetadataCreateCollection,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Save relation metadata update collection
|
// Save relation metadata update collection
|
||||||
await this.commandLogger.writeLog(
|
await this.commandLogger.writeLog(
|
||||||
'relation-metadata-update-collection',
|
`${workspaceId}/relation-metadata-update-collection`,
|
||||||
storage.relationMetadataUpdateCollection,
|
storage.relationMetadataUpdateCollection,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Save relation metadata delete collection
|
// Save relation metadata delete collection
|
||||||
await this.commandLogger.writeLog(
|
await this.commandLogger.writeLog(
|
||||||
'relation-metadata-delete-collection',
|
`${workspaceId}/relation-metadata-delete-collection`,
|
||||||
storage.relationMetadataDeleteCollection,
|
storage.relationMetadataDeleteCollection,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,12 +5,13 @@ import { Command, CommandRunner, Option } from 'nest-commander';
|
|||||||
import { DataSourceService } from 'src/metadata/data-source/data-source.service';
|
import { DataSourceService } from 'src/metadata/data-source/data-source.service';
|
||||||
import { WorkspaceSyncMetadataService } from 'src/workspace/workspace-sync-metadata/workspace-sync-metadata.service';
|
import { WorkspaceSyncMetadataService } from 'src/workspace/workspace-sync-metadata/workspace-sync-metadata.service';
|
||||||
import { WorkspaceHealthService } from 'src/workspace/workspace-health/workspace-health.service';
|
import { WorkspaceHealthService } from 'src/workspace/workspace-health/workspace-health.service';
|
||||||
|
import { WorkspaceService } from 'src/core/workspace/services/workspace.service';
|
||||||
|
|
||||||
import { SyncWorkspaceLoggerService } from './services/sync-workspace-logger.service';
|
import { SyncWorkspaceLoggerService } from './services/sync-workspace-logger.service';
|
||||||
|
|
||||||
// TODO: implement dry-run
|
// TODO: implement dry-run
|
||||||
interface RunWorkspaceMigrationsOptions {
|
interface RunWorkspaceMigrationsOptions {
|
||||||
workspaceId: string;
|
workspaceId?: string;
|
||||||
dryRun?: boolean;
|
dryRun?: boolean;
|
||||||
force?: boolean;
|
force?: boolean;
|
||||||
}
|
}
|
||||||
@ -27,6 +28,7 @@ export class SyncWorkspaceMetadataCommand extends CommandRunner {
|
|||||||
private readonly workspaceHealthService: WorkspaceHealthService,
|
private readonly workspaceHealthService: WorkspaceHealthService,
|
||||||
private readonly dataSourceService: DataSourceService,
|
private readonly dataSourceService: DataSourceService,
|
||||||
private readonly syncWorkspaceLoggerService: SyncWorkspaceLoggerService,
|
private readonly syncWorkspaceLoggerService: SyncWorkspaceLoggerService,
|
||||||
|
private readonly workspaceService: WorkspaceService,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@ -35,56 +37,63 @@ export class SyncWorkspaceMetadataCommand extends CommandRunner {
|
|||||||
_passedParam: string[],
|
_passedParam: string[],
|
||||||
options: RunWorkspaceMigrationsOptions,
|
options: RunWorkspaceMigrationsOptions,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const issues = await this.workspaceHealthService.healthCheck(
|
const workspaceIds = options.workspaceId
|
||||||
options.workspaceId,
|
? [options.workspaceId]
|
||||||
);
|
: await this.workspaceService.getWorkspaceIds();
|
||||||
|
|
||||||
// Security: abort if there are issues.
|
for (const workspaceId of workspaceIds) {
|
||||||
if (issues.length > 0) {
|
const issues = await this.workspaceHealthService.healthCheck(workspaceId);
|
||||||
if (!options.force) {
|
|
||||||
this.logger.error(
|
// Security: abort if there are issues.
|
||||||
`Workspace contains ${issues.length} issues, aborting.`,
|
if (issues.length > 0) {
|
||||||
|
if (!options.force) {
|
||||||
|
this.logger.error(
|
||||||
|
`Workspace contains ${issues.length} issues, aborting.`,
|
||||||
|
);
|
||||||
|
|
||||||
|
this.logger.log(
|
||||||
|
'If you want to force the migration, use --force flag',
|
||||||
|
);
|
||||||
|
this.logger.log(
|
||||||
|
'Please use `workspace:health` command to check issues and fix them before running this command.',
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.warn(
|
||||||
|
`Workspace contains ${issues.length} issues, sync has been forced.`,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.logger.log('If you want to force the migration, use --force flag');
|
|
||||||
this.logger.log(
|
|
||||||
'Please use `workspace:health` command to check issues and fix them before running this command.',
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.warn(
|
const dataSourceMetadata =
|
||||||
`Workspace contains ${issues.length} issues, sync has been forced.`,
|
await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail(
|
||||||
);
|
workspaceId,
|
||||||
}
|
);
|
||||||
|
|
||||||
const dataSourceMetadata =
|
const { storage, workspaceMigrations } =
|
||||||
await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail(
|
await this.workspaceSyncMetadataService.syncStandardObjectsAndFieldsMetadata(
|
||||||
options.workspaceId,
|
{
|
||||||
);
|
workspaceId,
|
||||||
|
dataSourceId: dataSourceMetadata.id,
|
||||||
|
},
|
||||||
|
{ applyChanges: !options.dryRun },
|
||||||
|
);
|
||||||
|
|
||||||
const { storage, workspaceMigrations } =
|
if (options.dryRun) {
|
||||||
await this.workspaceSyncMetadataService.syncStandardObjectsAndFieldsMetadata(
|
await this.syncWorkspaceLoggerService.saveLogs(
|
||||||
{
|
workspaceId,
|
||||||
workspaceId: options.workspaceId,
|
storage,
|
||||||
dataSourceId: dataSourceMetadata.id,
|
workspaceMigrations,
|
||||||
},
|
);
|
||||||
{ applyChanges: !options.dryRun },
|
}
|
||||||
);
|
|
||||||
|
|
||||||
if (options.dryRun) {
|
|
||||||
await this.syncWorkspaceLoggerService.saveLogs(
|
|
||||||
storage,
|
|
||||||
workspaceMigrations,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Option({
|
@Option({
|
||||||
flags: '-w, --workspace-id [workspace_id]',
|
flags: '-w, --workspace-id [workspace_id]',
|
||||||
description: 'workspace id',
|
description: 'workspace id',
|
||||||
required: true,
|
required: false,
|
||||||
})
|
})
|
||||||
parseWorkspaceId(value: string): string {
|
parseWorkspaceId(value: string): string {
|
||||||
return value;
|
return value;
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { Module } from '@nestjs/common';
|
|||||||
import { DataSourceModule } from 'src/metadata/data-source/data-source.module';
|
import { DataSourceModule } from 'src/metadata/data-source/data-source.module';
|
||||||
import { WorkspaceSyncMetadataModule } from 'src/workspace/workspace-sync-metadata/workspace-sync-metadata.module';
|
import { WorkspaceSyncMetadataModule } from 'src/workspace/workspace-sync-metadata/workspace-sync-metadata.module';
|
||||||
import { WorkspaceHealthModule } from 'src/workspace/workspace-health/workspace-health.module';
|
import { WorkspaceHealthModule } from 'src/workspace/workspace-health/workspace-health.module';
|
||||||
|
import { WorkspaceModule } from 'src/core/workspace/workspace.module';
|
||||||
|
|
||||||
import { SyncWorkspaceMetadataCommand } from './sync-workspace-metadata.command';
|
import { SyncWorkspaceMetadataCommand } from './sync-workspace-metadata.command';
|
||||||
|
|
||||||
@ -12,6 +13,7 @@ import { SyncWorkspaceLoggerService } from './services/sync-workspace-logger.ser
|
|||||||
imports: [
|
imports: [
|
||||||
WorkspaceSyncMetadataModule,
|
WorkspaceSyncMetadataModule,
|
||||||
WorkspaceHealthModule,
|
WorkspaceHealthModule,
|
||||||
|
WorkspaceModule,
|
||||||
DataSourceModule,
|
DataSourceModule,
|
||||||
],
|
],
|
||||||
providers: [SyncWorkspaceMetadataCommand, SyncWorkspaceLoggerService],
|
providers: [SyncWorkspaceMetadataCommand, SyncWorkspaceLoggerService],
|
||||||
|
|||||||
Reference in New Issue
Block a user