added scene manager

This commit is contained in:
IDONTSUDO 2024-01-23 17:23:10 +03:00
parent ae9842d5e1
commit 2adb939f37
36 changed files with 703 additions and 196 deletions

1
server/.gitignore vendored
View file

@ -9,3 +9,4 @@ package-lock.json
build/
model_create.ts
public
p.ts

View file

@ -12,7 +12,7 @@ export abstract class CallbackStrategyWithEmpty {
}
export abstract class CallbackStrategyWithValidationModel<V> {
abstract validationModel: V;
abstract call(a: V): ResponseBase;
abstract call(model: V): ResponseBase;
}
export abstract class CallbackStrategyWithIdQuery {
abstract idValidationExpression: CoreValidation;
@ -25,7 +25,8 @@ export abstract class CallBackStrategyWithQueryPage {
export abstract class CallbackStrategyWithFileUpload {
abstract checkingFileExpression: RegExp;
abstract call(file: File): ResponseBase;
abstract idValidationExpression: CoreValidation;
abstract call(file: File, id: string, description: string): ResponseBase;
}
interface ISubSetFeatureRouter<T> {
@ -116,17 +117,32 @@ export class CoreHttpController<V> implements ICoreHttpController {
res.status(400).json("need files to form-data request");
return;
}
if (req["files"]["file"] === undefined) {
res.status(400).json("need file to form data request");
return;
}
if (req.query.description === undefined) {
res
.status(400)
.json("request query description is null, need query description &description={description:String}");
return;
}
if (req.query.id === undefined) {
res.status(400).json("request query id is null, need query id ?id={id:String}");
return;
}
if (!el.fn.idValidationExpression.regExp.test(req.query.id)) {
res.status(400).json(el.fn.idValidationExpression.message);
return;
}
if (el.fn instanceof CallbackStrategyWithFileUpload) {
if (!el.fn.checkingFileExpression.test(req["files"]["file"]["name"])) {
res.status(400).json("a file with this extension is expected: " + String(el.fn.checkingFileExpression));
return;
}
}
await this.responseHelper(res, el.fn.call(req["files"]["file"]));
await this.responseHelper(res, el.fn.call(req["files"]["file"], req.query.id, req.query.description));
}
});
});

View file

@ -1,7 +1,10 @@
import { NixStoreManagerPresentation } from "../../features/nix_store_manager/nix_store_manager";
import { PipelinePresentation } from "../../features/pipelines/pipeline_presentation";
import { ProcessPresentation } from "../../features/process/process_presentation";
import { ProjectInstancePresentation } from "../../features/project_instance/project_instance_presentation";
import {
ProjectInstancePresentation,
RobossemblerAssetsPresentation,
} from "../../features/project_instance/project_instance_presentation";
import { ProjectsPresentation } from "../../features/projects/projects_presentation";
import { RealTimePresentation } from "../../features/realtime/realtime_presentation";
import { TriggerPresentation } from "../../features/triggers/triggers_presentation";
@ -21,6 +24,7 @@ export const httpRoutes: Routes[] = [
new RealTimePresentation(),
new ProjectInstancePresentation(),
new NixStoreManagerPresentation(),
new RobossemblerAssetsPresentation(),
]
.concat(routersImplementPureCrud)
.map((el) => el.call());

View file

@ -1,24 +1,27 @@
export class ActivePipeline {
pipelineIsRunning: boolean;
projectUUID?: string | null;
projectId?: string | null;
lastProcessCompleteCount: number | null;
error: any;
rootDir: string;
path: string;
constructor(
pipelineIsRunning: boolean,
lastProcessCompleteCount: number | null,
error: any,
path: string | null,
projectUUID?: string | null
projectId: string | null,
rootDir: string | null
) {
this.pipelineIsRunning = pipelineIsRunning;
this.projectUUID = projectUUID;
this.projectId = projectId;
this.lastProcessCompleteCount = lastProcessCompleteCount;
this.error = error;
this.path = path;
this.rootDir = rootDir;
}
static empty() {
return new ActivePipeline(false, null, null, null, null);
return new ActivePipeline(false, null, null, null, null, null);
}
}

View file

@ -1,11 +1,6 @@
import { IsEnum, IsNumber, IsOptional, IsString, ValidateNested } from "class-validator";
import { IsArray, IsEnum, IsNumber, IsOptional, IsString, ValidateNested } from "class-validator";
import { Type } from "class-transformer";
export enum AssetsType {
Asset = "asset",
Light = "light",
}
export class Gravity {
@IsNumber()
x: number;
@ -14,6 +9,7 @@ export class Gravity {
@IsNumber()
z: number;
}
export class Pose {
@IsNumber()
x: number;
@ -29,37 +25,47 @@ export class Pose {
yaw: number;
}
export class Instance {
@IsString()
model_name: string;
@IsString()
model_id: string;
@IsString()
id: string;
@ValidateNested()
@Type(() => Pose)
pose: Pose;
export class Position {
@IsNumber()
scale: number;
@IsEnum(AssetsType)
type: AssetsType;
@IsOptional()
@IsString()
parent?: string;
@IsOptional()
@IsString()
light_type?: string;
@IsOptional()
@IsString()
intencity?: number;
@IsOptional()
@IsString()
diffuse?: number[];
@IsOptional()
x: number;
@IsNumber()
spot_angle?: number;
y: number;
@IsNumber()
z: number;
}
export enum InstanceType {
RGB_CAMERA = "rgb_camera",
SCENE_SIMPLE_OBJECT = "scene_simple_object",
}
abstract class CoreInstances {}
export class Instance extends CoreInstances {
@IsEnum(InstanceType)
instanceType: InstanceType;
@Type(() => Position)
position: Position;
@IsArray()
quaternion: number[];
@IsOptional()
@IsString()
instanceAt: null | string = null;
}
export class SceneSimpleObject extends Instance {}
export class InstanceRgbCamera extends Instance {
@IsString()
cameraLink: string;
@IsString()
topicCameraInfo: string;
@IsOptional()
@IsString()
topicDepth: string | null;
@IsString()
topicImage: string;
}
export class Asset {
@IsString()
name: string;
@ -113,14 +119,24 @@ export class RobossemblerAssets {
@Type(() => Asset)
assets: Asset[];
@ValidateNested()
@Type(() => Instance)
@IsArray()
@Type(() => Instance, {
discriminator: {
property: "type",
subTypes: [
{ value: InstanceRgbCamera, name: InstanceType.RGB_CAMERA },
{ value: SceneSimpleObject, name: InstanceType.SCENE_SIMPLE_OBJECT },
],
},
keepDiscriminatorProperty: true,
})
instances: Instance[];
@IsOptional()
@ValidateNested()
@Type(() => Physics)
physics: Physics;
convertLocalPathsToServerPaths(server_address: string): RobossemblerAssets {
this.assets = this.assets.map((el) => {
el.meshPath = server_address + el.meshPath;
@ -128,4 +144,17 @@ export class RobossemblerAssets {
});
return this;
}
getAssetPath(assetName: string): string {
const findElement = this.assets.find((el) => el.name === assetName);
if (findElement === undefined) {
throw new Error("RobossemblerAssets.getAssetPath not found asset by name:" + assetName);
}
return findElement.meshPath;
}
getAssetAtInstance(instanceAt: string): Asset {
return this.assets.filter((el) => el.name === instanceAt)[0];
}
}

View file

@ -6,24 +6,28 @@ const skipMissingProperties = false,
whitelist = true,
forbidNonWhitelisted = true;
export class ReadingJsonFileAndConvertingToInstanceClass<T> {
export class ReadingJsonFileAndConvertingToInstanceClassScenario<T> {
model: ClassConstructor<T>;
constructor(cls: ClassConstructor<T>) {
this.model = cls;
}
call = async (path: string): Promise<Result<string, T>> => {
const result = await new ReadFileAndParseJsonUseCase().call(path);
if (result.isFailure()) {
return result.forward();
}
const json = result.value;
const model = plainToInstance(this.model, json);
const errors = await validate(model as object, { skipMissingProperties, whitelist, forbidNonWhitelisted });
if (errors.length > 0) {
const message = errors.map((error: ValidationError) => Object.values(error.constraints)).join(", ");
return Result.error(message);
} else {
return Result.ok(model as T);
try {
const result = await new ReadFileAndParseJsonUseCase().call(path);
if (result.isFailure()) {
return result.forward();
}
const json = result.value;
const model = plainToInstance(this.model, json);
const errors = await validate(model as object, { skipMissingProperties, whitelist, forbidNonWhitelisted });
if (errors.length > 0) {
const message = errors.map((error: ValidationError) => Object.values(error.constraints)).join(", ");
return Result.error("ReadingJsonFileAndConvertingToInstanceClassScenario:" + message);
} else {
return Result.ok(model as T);
}
} catch (error) {
return Result.error("ReadingJsonFileAndConvertingToInstanceClassScenario" + String(error));
}
};
}

View file

@ -9,14 +9,24 @@ import { SearchDataBaseModelUseCase } from "../usecases/search_database_model_us
export class SetLastActivePipelineToRealTimeServiceScenario {
call = async (): Promise<void> => {
const result = await new SearchDataBaseModelUseCase<IProjectInstanceModel>(ProjectInstanceDbModel).call({
isActive: true,
});
await result.map(async (el) => {
const projectModel = el;
const projectPath = App.staticFilesStoreDir() + projectModel.rootDir + "/";
await new CreateFolderUseCase().call(projectPath);
pipelineRealTimeService.setPipelineDependency(projectModel.project.pipelines, projectPath, projectModel._id);
});
return (
await new SearchDataBaseModelUseCase<IProjectInstanceModel>(ProjectInstanceDbModel).call({
isActive: true,
})
).fold(
async (projectModel) => {
const projectPath = App.staticFilesStoreDir() + projectModel.rootDir + "/";
await new CreateFolderUseCase().call(projectPath);
pipelineRealTimeService.setPipelineDependency(
projectModel.project.pipelines,
projectPath,
projectModel._id,
projectModel.rootDir
);
},
async (_e) => {
console.log("not found active pipeline");
}
);
};
}

View file

@ -32,9 +32,8 @@ export class PipelineRealTimeService extends TypedEvent<ActivePipeline> {
this.iterationLogSaver(iteration);
}
iterationLogSaver(iteration: Iteration): void {
iterationLogSaver(_iteration: Iteration): void {
// throw new Error("Method not implemented.");
// citeration.result.data
}
iterationErrorObserver(iteration: Iteration): void {
@ -59,10 +58,11 @@ export class PipelineRealTimeService extends TypedEvent<ActivePipeline> {
this.status.pipelineIsRunning = false;
}
}
setPipelineDependency(pipelineModels: IPipeline[], path: string, projectUUID: string) {
setPipelineDependency(pipelineModels: IPipeline[], path: string, projectId: string, rootDir: string) {
this.pipelineModels = pipelineModels;
this.status["projectUUID"] = projectUUID;
this.status["projectId"] = projectId;
this.status["path"] = path;
this.status["rootDir"] = rootDir;
}
runPipeline(): void {
const stack = new StackService(this.pipelineModels, this.status.path);

View file

@ -8,7 +8,8 @@ export class CreateFileUseCase {
}
async call(path: string, buffer: Buffer): Promise<Result<Error, void>> {
try {
await this.fileSystemRepository.writeFileAsync(path, buffer);
await this.fileSystemRepository.writeFileAsync(path.pathNormalize(), buffer);
return Result.ok();
} catch (err) {
return Result.error(err as Error);

View file

@ -13,9 +13,13 @@ export class ReadFileAndParseJsonUseCase {
return Result.error(`ReadFileAndParseJsonUseCase got the bad way: ${path}`);
}
const file = await this.fileSystemRepository.readFileAsync(path);
return Result.ok(JSON.parse(file.toString()));
try {
return Result.ok(JSON.parse(file.toString()));
} catch {
return Result.error(`ReadFileAndParseJsonUseCase is not json type file parse path: ${path}`);
}
} catch (error) {
return Result.error(`ReadFileAndParseJsonUseCase is not json type file parse path:${path}`);
return Result.error(`ReadFileAndParseJsonUseCase error:${error}`);
}
}
}

View file

@ -0,0 +1,13 @@
import { Result } from "../helpers/result";
import { FileSystemRepository } from "../repository/file_system_repository";
export class WriteFileSystemFileUseCase {
call = async (path: string, fileData: string): Promise<Result<string, void>> => {
try {
await new FileSystemRepository().writeFileAsync(path, fileData);
return Result.ok(undefined);
} catch (error) {
return Result.error(`WriteFileSystemFileUseCase error: ${error}`);
}
};
}

View file

@ -1,4 +1,8 @@
interface IMessage {
message: string;
}
export abstract class CoreValidation {
abstract regExp: RegExp;
abstract message: string;
abstract message: IMessage;
}

View file

@ -2,5 +2,5 @@ import { CoreValidation } from "./core_validation";
export class MongoIdValidation extends CoreValidation {
regExp = RegExp("^[0-9a-fA-F]{24}$");
message = "is do not mongo db object uuid";
message = { message: "is do not mongo db object uuid" };
}

View file

@ -2,28 +2,20 @@ import { App } from "../../../core/controllers/app";
import { Result } from "../../../core/helpers/result";
import { CreateDataBaseModelUseCase } from "../../../core/usecases/create_database_model_usecase";
import { CreateFolderUseCase } from "../../../core/usecases/create_folder_usecase";
import { pipelineRealTimeService } from "../../realtime/realtime_presentation";
import { ProjectInstanceDbModel } from "../models/project_instance_database_model";
import { ProjectInstanceValidationModel } from "../models/project_instance_validation_model";
import { v4 as uuidv4 } from "uuid";
import { SetActiveProjectScenario } from "./set_active_project_use_scenario";
export class CreateNewProjectInstanceScenario {
call = async (model: ProjectInstanceValidationModel): Promise<Result<Error, any>> => {
call = async (): Promise<Result<Error, any>> => {
try {
const folderName = uuidv4() + "/";
const createFolderUseCase = await new CreateFolderUseCase().call(App.staticFilesStoreDir() + folderName);
if (createFolderUseCase.isFailure()) {
return createFolderUseCase.forward();
}
model.rootDir = folderName;
const createDataBaseModelUseCase = await new CreateDataBaseModelUseCase(ProjectInstanceDbModel).call(model);
if (createDataBaseModelUseCase.isFailure()) {
return createDataBaseModelUseCase.forward();
}
return Result.ok({ status: "ok" });
// (await new SetActiveProjectScenario().call(id)).map(() => {
// return Result.ok({ status: "ok" });
// });
} catch (error) {
console.log(error);
return Result.error(error as Error);
}
};

View file

@ -2,7 +2,7 @@ import { CallbackStrategyWithEmpty, ResponseBase } from "../../../core/controlle
import { Result } from "../../../core/helpers/result";
import { RobossemblerAssets } from "../../../core/models/robossembler_assets";
import { StaticFiles } from "../../../core/models/static_files";
import { ReadingJsonFileAndConvertingToInstanceClass } from "../../../core/scenarios/read_file_and_json_to_plain_instance_class_scenario";
import { ReadingJsonFileAndConvertingToInstanceClassScenario } from "../../../core/scenarios/read_file_and_json_to_plain_instance_class_scenario";
import { GetServerAddressUseCase } from "../../../core/usecases/get_server_address_usecase";
import { PipelineStatusUseCase } from "../../realtime/domain/pipeline_status_usecase";
@ -13,13 +13,15 @@ export class RobossemblerAssetsNetworkMapperScenario extends CallbackStrategyWit
return await result.map(async (activeInstanceModel) => {
return (
await new ReadingJsonFileAndConvertingToInstanceClass(RobossemblerAssets).call(
await new ReadingJsonFileAndConvertingToInstanceClassScenario(RobossemblerAssets).call(
`${activeInstanceModel.path}${StaticFiles.robossembler_assets}`
)
).map((robossemblerAssets) => {
return new GetServerAddressUseCase().call().map((address) => {
return Result.ok(
robossemblerAssets.convertLocalPathsToServerPaths(`${address}/${activeInstanceModel.projectUUID}`)
robossemblerAssets.convertLocalPathsToServerPaths(
`${address}/${activeInstanceModel.rootDir.pathNormalize()}`
)
);
});
});

View file

@ -0,0 +1,28 @@
import { CallbackStrategyWithValidationModel, ResponseBase } from "../../../core/controllers/http_controller";
import { Result } from "../../../core/helpers/result";
import { RobossemblerAssets } from "../../../core/models/robossembler_assets";
import { StaticFiles } from "../../../core/models/static_files";
import { ReadingJsonFileAndConvertingToInstanceClassScenario } from "../../../core/scenarios/read_file_and_json_to_plain_instance_class_scenario";
import { WriteFileSystemFileUseCase } from "../../../core/usecases/write_file_system_file_usecase";
import { PipelineStatusUseCase } from "../../realtime/domain/pipeline_status_usecase";
export class SaveActiveSceneScenario extends CallbackStrategyWithValidationModel<RobossemblerAssets> {
validationModel: RobossemblerAssets = new RobossemblerAssets();
async call(model: RobossemblerAssets): ResponseBase {
return (await new PipelineStatusUseCase().call()).map(async (activeInstanceModel) =>
(
await new ReadingJsonFileAndConvertingToInstanceClassScenario(RobossemblerAssets).call(
`${activeInstanceModel.path}${StaticFiles.robossembler_assets}`.pathNormalize()
)
).map(async (prevModel) => {
model.assets = prevModel.assets;
return (
await new WriteFileSystemFileUseCase().call(
`${activeInstanceModel.path}${StaticFiles.robossembler_assets}`.pathNormalize(),
JSON.stringify(model)
)
).map(() => Result.ok("assets is rewrite"));
})
);
}
}

View file

@ -1,8 +1,8 @@
import { App } from "../../../core/controllers/app";
import { CallbackStrategyWithIdQuery, ResponseBase } from "../../../core/controllers/http_controller";
import { Result } from "../../../core/helpers/result";
import { SetLastActivePipelineToRealTimeServiceScenario } from "../../../core/scenarios/set_active_pipeline_to_realtime_service_scenario";
import { CreateFolderUseCase } from "../../../core/usecases/create_folder_usecase";
import { FindPredicateModelAndUpdateDatabaseModelUseCase } from "../../../core/usecases/find_and_update_database_model_usecase";
import { ReadByIdDataBaseModelUseCase } from "../../../core/usecases/read_by_id_database_model_usecase";
import { UpdateDataBaseModelUseCase } from "../../../core/usecases/update_database_model_usecase";
import { MongoIdValidation } from "../../../core/validations/mongo_id_validation";
@ -13,16 +13,21 @@ export class SetActiveProjectScenario extends CallbackStrategyWithIdQuery {
async call(id: string): ResponseBase {
const result = await new ReadByIdDataBaseModelUseCase<IProjectInstanceModel>(ProjectInstanceDbModel).call(id);
// id
if (result.isFailure()) {
return result.forward();
}
const model = result.value;
return (await new CreateFolderUseCase().call(App.staticFilesStoreDir() + model.rootDir)).map(async () => {
return await (
await new CreateFolderUseCase().call(App.staticFilesStoreDir() + model.rootDir)
).map(async () => {
model.isActive = true;
new FindPredicateModelAndUpdateDatabaseModelUseCase(ProjectInstanceDbModel).call({}, {});
return (await new UpdateDataBaseModelUseCase(ProjectInstanceDbModel).call(model)).map(() => {
return (await new UpdateDataBaseModelUseCase(ProjectInstanceDbModel).call(model)).map(async (el) => {
// TODO(IDONTSUDO): move it to a separate UseCase
await ProjectInstanceDbModel.updateMany({ _id: { $ne: el._id }, isActive: { $eq: true } }, { isActive: false });
await new SetLastActivePipelineToRealTimeServiceScenario().call();
return Result.ok(`project ${id} is active`);
});
});

View file

@ -1,23 +1,37 @@
import { App } from "../../../core/controllers/app";
import { CallbackStrategyWithFileUpload, ResponseBase } from "../../../core/controllers/http_controller";
import { Result } from "../../../core/helpers/result";
import { IFile } from "../../../core/interfaces/file";
import { CreateDataBaseModelUseCase } from "../../../core/usecases/create_database_model_usecase";
import { CreateFileUseCase } from "../../../core/usecases/create_file_usecase";
import { PipelineStatusUseCase } from "../../realtime/domain/pipeline_status_usecase";
import { CreateFolderUseCase } from "../../../core/usecases/create_folder_usecase";
import { MongoIdValidation } from "../../../core/validations/mongo_id_validation";
import { ProjectInstanceDbModel } from "../models/project_instance_database_model";
import { ProjectInstanceValidationModel } from "../models/project_instance_validation_model";
import { v4 as uuidv4 } from "uuid";
import { SetActiveProjectScenario } from "./set_active_project_use_scenario";
export class UploadCadFileToProjectScenario extends CallbackStrategyWithFileUpload {
checkingFileExpression: RegExp = RegExp(".FCStd");
idValidationExpression = new MongoIdValidation();
async call(file: IFile): ResponseBase {
const pipelineStatusUseCase = await new PipelineStatusUseCase().call();
if (pipelineStatusUseCase.isFailure()) {
return pipelineStatusUseCase.forward();
}
const projectFolder = pipelineStatusUseCase.value.path;
const createFileUseCase = await new CreateFileUseCase().call(projectFolder + file.name, file.data);
if (createFileUseCase.isFailure()) {
return createFileUseCase.forward();
}
return Result.ok("ok");
async call(file: IFile, id: string, description: string): ResponseBase {
const folderName = uuidv4() + "/";
const model = new ProjectInstanceValidationModel();
model["project"] = id;
model["description"] = description;
model["rootDir"] = folderName;
model["isActive"] = true;
return (await new CreateFolderUseCase().call(App.staticFilesStoreDir() + folderName)).map(async () =>
(await new CreateDataBaseModelUseCase(ProjectInstanceDbModel).call(model)).map(async (databaseModel) =>
(await new SetActiveProjectScenario().call(databaseModel.id)).map(async () =>
(await new CreateFileUseCase().call(App.staticFilesStoreDir() + folderName + file.name, file.data)).map(
() => {
return Result.ok("ok");
}
)
)
)
);
}
}

View file

@ -9,4 +9,7 @@ export class ProjectInstanceValidationModel {
@IsOptional()
public rootDir: string;
@IsOptional()
public isActive: boolean;
}

View file

@ -1,7 +1,10 @@
import { CrudController } from "../../core/controllers/crud_controller";
import { CoreHttpController } from "../../core/controllers/http_controller";
import { RobossemblerAssets } from "../../core/models/robossembler_assets";
import { CreateNewProjectInstanceScenario } from "./domain/create_new_project_scenario";
import { RobossemblerAssetsNetworkMapperScenario } from "./domain/robossembler_assets_network_mapper_scenario";
import { SaveActiveSceneScenario } from "./domain/save_active_scene_scenario";
import { SetActiveProjectScenario } from "./domain/set_active_project_use_scenario";
import { UploadCadFileToProjectScenario } from "./domain/upload_file_to_to_project_scenario";
import { ProjectInstanceDbModel } from "./models/project_instance_database_model";
@ -31,11 +34,16 @@ export class ProjectInstancePresentation extends CrudController<
subUrl: "upload",
fn: new UploadCadFileToProjectScenario(),
});
this.subRoutes.push({
method: "GET",
subUrl: "assets",
fn: new RobossemblerAssetsNetworkMapperScenario(),
});
}
}
export class RobossemblerAssetsPresentation extends CoreHttpController<RobossemblerAssets> {
constructor() {
super({
url: "robossembler_assets",
validationModel: RobossemblerAssets,
});
super.get(new RobossemblerAssetsNetworkMapperScenario().call);
super.post(new SaveActiveSceneScenario().call);
}
}

View file

@ -6,11 +6,11 @@ export class PipelineStatusUseCase {
async call(): Promise<Result<Error, ActivePipeline>> {
try {
const status = pipelineRealTimeService.status;
if (status.projectUUID !== null) {
if (status.projectId !== null) {
return Result.ok(status);
}
if (status.projectUUID === null) {
if (status.projectId === null) {
return Result.error(new Error("pipelineRealTimeService does not have an active project instance"));
}
} catch (error) {

View file

@ -1,4 +1,5 @@
import { App } from "../../../core/controllers/app";
import { CallbackStrategyWithEmpty } from "../../../core/controllers/http_controller";
import { Result } from "../../../core/helpers/result";
import { IPipeline } from "../../../core/models/process_model";
import { ReadByIdDataBaseModelUseCase } from "../../../core/usecases/read_by_id_database_model_usecase";
@ -28,30 +29,32 @@ const mongoPipelineModelMapper = (el: PipelineValidationModel): IPipeline => {
};
return mapObj;
};
export class RunInstancePipelineUseCase {
async call(): Promise<Result<Error, any>> {
const r = await new PipelineStatusUseCase().call();
if (r.isFailure()) {
return r;
}
const readByIdDataBaseModelUseCase = await new ReadByIdDataBaseModelUseCase<IProjectInstanceModel>(
ProjectInstanceDbModel
).call(r.value.projectUUID);
if (readByIdDataBaseModelUseCase.isFailure()) {
return readByIdDataBaseModelUseCase.forward();
}
const projectModel = readByIdDataBaseModelUseCase.value;
const resultMapper = projectModel.project.pipelines.map((el) => mongoPipelineModelMapper(el));
export class RunInstancePipelineUseCase extends CallbackStrategyWithEmpty {
async call(): Promise<Result<any, string>> {
return (await new PipelineStatusUseCase().call()).map(async (activePipelineModel) => {
if (activePipelineModel.pipelineIsRunning) {
return Result.error("pipeline is running");
}
const readByIdDataBaseModelUseCase = await new ReadByIdDataBaseModelUseCase<IProjectInstanceModel>(
ProjectInstanceDbModel
).call(activePipelineModel.projectId);
pipelineRealTimeService.setPipelineDependency(
resultMapper,
App.staticFilesStoreDir() + projectModel.rootDir + "/",
projectModel._id
);
if (readByIdDataBaseModelUseCase.isFailure()) {
return readByIdDataBaseModelUseCase.forward();
}
const projectModel = readByIdDataBaseModelUseCase.value;
const resultMapper = projectModel.project.pipelines.map((el) => mongoPipelineModelMapper(el));
pipelineRealTimeService.runPipeline();
pipelineRealTimeService.setPipelineDependency(
resultMapper,
App.staticFilesStoreDir() + projectModel.rootDir + "/",
projectModel._id,
projectModel.rootDir
);
return Result.ok({ status: "ok" });
pipelineRealTimeService.runPipeline();
return Result.ok("ok");
});
}
}

View file

@ -18,7 +18,11 @@ export class RealTimePresentation extends CoreHttpController<RealTimeValidationM
url: "realtime",
databaseModel: null,
});
super.post(new RunInstancePipelineUseCase().call);
super.get(new PipelineStatusUseCase().call);
this.subRoutes.push({
method: "POST",
subUrl: "run",
fn: new RunInstancePipelineUseCase(),
});
}
}

View file

@ -4,9 +4,11 @@ import { SocketSubscriber } from "./core/controllers/socket_controller";
import { extensions } from "./core/extensions/extensions";
import { httpRoutes } from "./core/controllers/routes";
import { pipelineRealTimeService } from "./features/realtime/realtime_presentation";
import { main } from "./p";
extensions();
const socketSubscribers = [new SocketSubscriber(pipelineRealTimeService, "realtime")];
new App(httpRoutes, socketSubscribers).listen();
main();